summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/libjson/src/libjson.def7
-rw-r--r--libs/libjson/src/libjson64.def7
-rw-r--r--libs/libjson/src/stdafx.cxx48
-rw-r--r--libs/libsodium/docs/AUTHORS135
-rw-r--r--libs/libsodium/docs/ChangeLog505
-rw-r--r--libs/libsodium/docs/LICENSE18
-rw-r--r--libs/libsodium/docs/README.markdown46
-rw-r--r--libs/libsodium/docs/THANKS91
-rw-r--r--libs/libsodium/libsodium.vcxproj493
-rw-r--r--libs/libsodium/libsodium.vcxproj.filters4
-rw-r--r--libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c1079
-rw-r--r--libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c399
-rw-r--r--libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c160
-rw-r--r--libs/libsodium/src/crypto_auth/crypto_auth.c41
-rw-r--r--libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c118
-rw-r--r--libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c118
-rw-r--r--libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c93
-rw-r--r--libs/libsodium/src/crypto_box/crypto_box.c114
-rw-r--r--libs/libsodium/src/crypto_box/crypto_box_easy.c115
-rw-r--r--libs/libsodium/src/crypto_box/crypto_box_seal.c68
-rw-r--r--libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c204
-rw-r--r--libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c79
-rw-r--r--libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c156
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/core_ed25519.c79
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c2031
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h1344
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h40
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h20
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h220
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h1344
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h40
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h21
-rw-r--r--libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h116
-rw-r--r--libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c93
-rw-r--r--libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c21
-rw-r--r--libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c95
-rw-r--r--libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c195
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c55
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h109
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c49
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h140
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c93
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c87
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h103
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c90
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h103
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h340
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h164
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h307
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c436
-rw-r--r--libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c111
-rw-r--r--libs/libsodium/src/crypto_generichash/crypto_generichash.c91
-rw-r--r--libs/libsodium/src/crypto_hash/crypto_hash.c20
-rw-r--r--libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c254
-rw-r--r--libs/libsodium/src/crypto_hash/sha256/hash_sha256.c13
-rw-r--r--libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c282
-rw-r--r--libs/libsodium/src/crypto_hash/sha512/hash_sha512.c13
-rw-r--r--libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c52
-rw-r--r--libs/libsodium/src/crypto_kdf/crypto_kdf.c49
-rw-r--r--libs/libsodium/src/crypto_kx/crypto_kx.c143
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c71
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c124
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h12
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h235
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h220
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c90
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h21
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c949
-rw-r--r--libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h12
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c549
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h297
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c305
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h33
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c239
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c244
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c233
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c238
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2.c277
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/argon2.h305
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c79
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h8
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h150
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h145
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h40
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h120
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c290
-rw-r--r--libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c234
-rw-r--r--libs/libsodium/src/crypto_pwhash/crypto_pwhash.c211
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c263
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h98
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c375
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c95
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h45
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c285
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c108
-rw-r--r--libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c400
-rw-r--r--libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c33
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c159
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h10
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S25
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h20
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c114
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h9
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h26
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h35
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c58
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S197
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h16
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S172
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S226
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c78
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S1440
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h18
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S1295
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h18
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h8
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h8
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S17
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c59
-rw-r--r--libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h11
-rw-r--r--libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c86
-rw-r--r--libs/libsodium/src/crypto_secretbox/crypto_secretbox.c67
-rw-r--r--libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c144
-rw-r--r--libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c177
-rw-r--r--libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c89
-rw-r--r--libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c311
-rw-r--r--libs/libsodium/src/crypto_shorthash/crypto_shorthash.c34
-rw-r--r--libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c65
-rw-r--r--libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h24
-rw-r--r--libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c71
-rw-r--r--libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c11
-rw-r--r--libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c11
-rw-r--r--libs/libsodium/src/crypto_sign/crypto_sign.c115
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c91
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c116
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/ref10/open.c93
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c144
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h18
-rw-r--r--libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c97
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c180
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h8
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c174
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h8
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h86
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h98
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h175
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h357
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c315
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h8
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c130
-rw-r--r--libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h22
-rw-r--r--libs/libsodium/src/crypto_stream/crypto_stream.c49
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c120
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h8
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c100
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h16
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S960
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c31
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h8
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c131
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h8
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c122
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h8
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h195
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h207
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h547
-rw-r--r--libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h476
-rw-r--r--libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c106
-rw-r--r--libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c26
-rw-r--r--libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c106
-rw-r--r--libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c26
-rw-r--r--libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c69
-rw-r--r--libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c66
-rw-r--r--libs/libsodium/src/crypto_verify/sodium/verify.c98
-rw-r--r--libs/libsodium/src/include/Makefile.am75
-rw-r--r--libs/libsodium/src/include/sodium.h70
-rw-r--r--libs/libsodium/src/include/sodium/core.h28
-rw-r--r--libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h171
-rw-r--r--libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h174
-rw-r--r--libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h97
-rw-r--r--libs/libsodium/src/include/sodium/crypto_auth.h44
-rw-r--r--libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h68
-rw-r--r--libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h67
-rw-r--r--libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h62
-rw-r--r--libs/libsodium/src/include/sodium/crypto_box.h173
-rw-r--r--libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h159
-rw-r--r--libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h109
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_ed25519.h37
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_hchacha20.h35
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h35
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_salsa20.h35
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_salsa2012.h35
-rw-r--r--libs/libsodium/src/include/sodium/crypto_core_salsa208.h39
-rw-r--r--libs/libsodium/src/include/sodium/crypto_generichash.h75
-rw-r--r--libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h117
-rw-r--r--libs/libsodium/src/include/sodium/crypto_hash.h40
-rw-r--r--libs/libsodium/src/include/sodium/crypto_hash_sha256.h57
-rw-r--r--libs/libsodium/src/include/sodium/crypto_hash_sha512.h57
-rw-r--r--libs/libsodium/src/include/sodium/crypto_kdf.h51
-rw-r--r--libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h42
-rw-r--r--libs/libsodium/src/include/sodium/crypto_kx.h64
-rw-r--r--libs/libsodium/src/include/sodium/crypto_onetimeauth.h62
-rw-r--r--libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h67
-rw-r--r--libs/libsodium/src/include/sodium/crypto_pwhash.h147
-rw-r--r--libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h122
-rw-r--r--libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h122
-rw-r--r--libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h120
-rw-r--r--libs/libsodium/src/include/sodium/crypto_scalarmult.h45
-rw-r--r--libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h40
-rw-r--r--libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h41
-rw-r--r--libs/libsodium/src/include/sodium/crypto_secretbox.h91
-rw-r--r--libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h68
-rw-r--r--libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h67
-rw-r--r--libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h102
-rw-r--r--libs/libsodium/src/include/sodium/crypto_shorthash.h39
-rw-r--r--libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h48
-rw-r--r--libs/libsodium/src/include/sodium/crypto_sign.h103
-rw-r--r--libs/libsodium/src/include/sodium/crypto_sign_ed25519.h114
-rw-r--r--libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h55
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream.h56
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_chacha20.h98
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_salsa20.h57
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h50
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_salsa208.h56
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h57
-rw-r--r--libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h57
-rw-r--r--libs/libsodium/src/include/sodium/crypto_verify_16.h23
-rw-r--r--libs/libsodium/src/include/sodium/crypto_verify_32.h23
-rw-r--r--libs/libsodium/src/include/sodium/crypto_verify_64.h23
-rw-r--r--libs/libsodium/src/include/sodium/export.h53
-rw-r--r--libs/libsodium/src/include/sodium/private/common.h246
-rw-r--r--libs/libsodium/src/include/sodium/private/ed25519_ref10.h125
-rw-r--r--libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h1050
-rw-r--r--libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h518
-rw-r--r--libs/libsodium/src/include/sodium/private/implementations.h11
-rw-r--r--libs/libsodium/src/include/sodium/private/mutex.h7
-rw-r--r--libs/libsodium/src/include/sodium/private/sse2_64_32.h50
-rw-r--r--libs/libsodium/src/include/sodium/randombytes.h68
-rw-r--r--libs/libsodium/src/include/sodium/randombytes_nativeclient.h23
-rw-r--r--libs/libsodium/src/include/sodium/randombytes_salsa20_random.h19
-rw-r--r--libs/libsodium/src/include/sodium/randombytes_sysrandom.h19
-rw-r--r--libs/libsodium/src/include/sodium/runtime.h52
-rw-r--r--libs/libsodium/src/include/sodium/utils.h170
-rw-r--r--libs/libsodium/src/include/sodium/version.h32
-rw-r--r--libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c61
-rw-r--r--libs/libsodium/src/randombytes/randombytes.c206
-rw-r--r--libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c564
-rw-r--r--libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c382
-rw-r--r--libs/libsodium/src/sodium/codecs.c333
-rw-r--r--libs/libsodium/src/sodium/core.c231
-rw-r--r--libs/libsodium/src/sodium/runtime.c286
-rw-r--r--libs/libsodium/src/sodium/utils.c737
-rw-r--r--libs/libsodium/src/sodium/version.c30
-rw-r--r--libs/libsodium/src/stdafx.cxx2
-rw-r--r--libs/libsodium/src/stdafx.h0
-rw-r--r--libs/pthreads/docs/ANNOUNCE483
-rw-r--r--libs/pthreads/docs/BUGS141
-rw-r--r--libs/pthreads/docs/Bmakefile268
-rw-r--r--libs/pthreads/docs/CONTRIBUTORS140
-rw-r--r--libs/pthreads/docs/COPYING150
-rw-r--r--libs/pthreads/docs/ChangeLog5211
-rw-r--r--libs/pthreads/docs/FAQ451
-rw-r--r--libs/pthreads/docs/GNUmakefile593
-rw-r--r--libs/pthreads/docs/MAINTAINERS4
-rw-r--r--libs/pthreads/docs/Makefile514
-rw-r--r--libs/pthreads/docs/NEWS1241
-rw-r--r--libs/pthreads/docs/Nmakefile24
-rw-r--r--libs/pthreads/docs/PROGRESS4
-rw-r--r--libs/pthreads/docs/README601
-rw-r--r--libs/pthreads/docs/TODO7
-rw-r--r--libs/pthreads/docs/WinCE-PORT222
-rw-r--r--libs/pthreads/pthreads.vcxproj93
-rw-r--r--libs/pthreads/pthreads.vcxproj.filters22
-rw-r--r--libs/pthreads/src/attr.c53
-rw-r--r--libs/pthreads/src/autostatic.c69
-rw-r--r--libs/pthreads/src/barrier.c47
-rw-r--r--libs/pthreads/src/cancel.c44
-rw-r--r--libs/pthreads/src/cleanup.c148
-rw-r--r--libs/pthreads/src/condvar.c50
-rw-r--r--libs/pthreads/src/config.h153
-rw-r--r--libs/pthreads/src/context.h74
-rw-r--r--libs/pthreads/src/create.c308
-rw-r--r--libs/pthreads/src/dll.c92
-rw-r--r--libs/pthreads/src/errno.c94
-rw-r--r--libs/pthreads/src/exit.c44
-rw-r--r--libs/pthreads/src/fork.c39
-rw-r--r--libs/pthreads/src/global.c107
-rw-r--r--libs/pthreads/src/implement.h943
-rw-r--r--libs/pthreads/src/misc.c50
-rw-r--r--libs/pthreads/src/mutex.c62
-rw-r--r--libs/pthreads/src/need_errno.h145
-rw-r--r--libs/pthreads/src/nonportable.c47
-rw-r--r--libs/pthreads/src/private.c54
-rw-r--r--libs/pthreads/src/pthread.c66
-rw-r--r--libs/pthreads/src/pthread.h1368
-rw-r--r--libs/pthreads/src/pthread_attr_destroy.c79
-rw-r--r--libs/pthreads/src/pthread_attr_getdetachstate.c86
-rw-r--r--libs/pthreads/src/pthread_attr_getinheritsched.c51
-rw-r--r--libs/pthreads/src/pthread_attr_getschedparam.c52
-rw-r--r--libs/pthreads/src/pthread_attr_getschedpolicy.c61
-rw-r--r--libs/pthreads/src/pthread_attr_getscope.c54
-rw-r--r--libs/pthreads/src/pthread_attr_getstackaddr.c97
-rw-r--r--libs/pthreads/src/pthread_attr_getstacksize.c100
-rw-r--r--libs/pthreads/src/pthread_attr_init.c117
-rw-r--r--libs/pthreads/src/pthread_attr_setdetachstate.c91
-rw-r--r--libs/pthreads/src/pthread_attr_setinheritsched.c57
-rw-r--r--libs/pthreads/src/pthread_attr_setschedparam.c63
-rw-r--r--libs/pthreads/src/pthread_attr_setschedpolicy.c55
-rw-r--r--libs/pthreads/src/pthread_attr_setscope.c62
-rw-r--r--libs/pthreads/src/pthread_attr_setstackaddr.c97
-rw-r--r--libs/pthreads/src/pthread_attr_setstacksize.c110
-rw-r--r--libs/pthreads/src/pthread_barrier_destroy.c103
-rw-r--r--libs/pthreads/src/pthread_barrier_init.c69
-rw-r--r--libs/pthreads/src/pthread_barrier_wait.c104
-rw-r--r--libs/pthreads/src/pthread_barrierattr_destroy.c83
-rw-r--r--libs/pthreads/src/pthread_barrierattr_getpshared.c95
-rw-r--r--libs/pthreads/src/pthread_barrierattr_init.c85
-rw-r--r--libs/pthreads/src/pthread_barrierattr_setpshared.c119
-rw-r--r--libs/pthreads/src/pthread_cancel.c189
-rw-r--r--libs/pthreads/src/pthread_cond_destroy.c253
-rw-r--r--libs/pthreads/src/pthread_cond_init.c167
-rw-r--r--libs/pthreads/src/pthread_cond_signal.c231
-rw-r--r--libs/pthreads/src/pthread_cond_wait.c567
-rw-r--r--libs/pthreads/src/pthread_condattr_destroy.c86
-rw-r--r--libs/pthreads/src/pthread_condattr_getpshared.c97
-rw-r--r--libs/pthreads/src/pthread_condattr_init.c87
-rw-r--r--libs/pthreads/src/pthread_condattr_setpshared.c117
-rw-r--r--libs/pthreads/src/pthread_delay_np.c172
-rw-r--r--libs/pthreads/src/pthread_detach.c136
-rw-r--r--libs/pthreads/src/pthread_equal.c76
-rw-r--r--libs/pthreads/src/pthread_exit.c106
-rw-r--r--libs/pthreads/src/pthread_getconcurrency.c45
-rw-r--r--libs/pthreads/src/pthread_getschedparam.c75
-rw-r--r--libs/pthreads/src/pthread_getspecific.c87
-rw-r--r--libs/pthreads/src/pthread_getunique_np.c47
-rw-r--r--libs/pthreads/src/pthread_getw32threadhandle_np.c65
-rw-r--r--libs/pthreads/src/pthread_join.c157
-rw-r--r--libs/pthreads/src/pthread_key_create.c108
-rw-r--r--libs/pthreads/src/pthread_key_delete.c125
-rw-r--r--libs/pthreads/src/pthread_kill.c105
-rw-r--r--libs/pthreads/src/pthread_mutex_consistent.c190
-rw-r--r--libs/pthreads/src/pthread_mutex_destroy.c148
-rw-r--r--libs/pthreads/src/pthread_mutex_init.c130
-rw-r--r--libs/pthreads/src/pthread_mutex_lock.c269
-rw-r--r--libs/pthreads/src/pthread_mutex_timedlock.c324
-rw-r--r--libs/pthreads/src/pthread_mutex_trylock.c158
-rw-r--r--libs/pthreads/src/pthread_mutex_unlock.c178
-rw-r--r--libs/pthreads/src/pthread_mutexattr_destroy.c83
-rw-r--r--libs/pthreads/src/pthread_mutexattr_getkind_np.c44
-rw-r--r--libs/pthreads/src/pthread_mutexattr_getpshared.c95
-rw-r--r--libs/pthreads/src/pthread_mutexattr_getrobust.c113
-rw-r--r--libs/pthreads/src/pthread_mutexattr_gettype.c56
-rw-r--r--libs/pthreads/src/pthread_mutexattr_init.c86
-rw-r--r--libs/pthreads/src/pthread_mutexattr_setkind_np.c44
-rw-r--r--libs/pthreads/src/pthread_mutexattr_setpshared.c119
-rw-r--r--libs/pthreads/src/pthread_mutexattr_setrobust.c119
-rw-r--r--libs/pthreads/src/pthread_mutexattr_settype.c143
-rw-r--r--libs/pthreads/src/pthread_num_processors_np.c56
-rw-r--r--libs/pthreads/src/pthread_once.c79
-rw-r--r--libs/pthreads/src/pthread_rwlock_destroy.c143
-rw-r--r--libs/pthreads/src/pthread_rwlock_init.c109
-rw-r--r--libs/pthreads/src/pthread_rwlock_rdlock.c102
-rw-r--r--libs/pthreads/src/pthread_rwlock_timedrdlock.c109
-rw-r--r--libs/pthreads/src/pthread_rwlock_timedwrlock.c139
-rw-r--r--libs/pthreads/src/pthread_rwlock_tryrdlock.c102
-rw-r--r--libs/pthreads/src/pthread_rwlock_trywrlock.c122
-rw-r--r--libs/pthreads/src/pthread_rwlock_unlock.c93
-rw-r--r--libs/pthreads/src/pthread_rwlock_wrlock.c133
-rw-r--r--libs/pthreads/src/pthread_rwlockattr_destroy.c84
-rw-r--r--libs/pthreads/src/pthread_rwlockattr_getpshared.c97
-rw-r--r--libs/pthreads/src/pthread_rwlockattr_init.c83
-rw-r--r--libs/pthreads/src/pthread_rwlockattr_setpshared.c120
-rw-r--r--libs/pthreads/src/pthread_self.c141
-rw-r--r--libs/pthreads/src/pthread_setcancelstate.c125
-rw-r--r--libs/pthreads/src/pthread_setcanceltype.c126
-rw-r--r--libs/pthreads/src/pthread_setconcurrency.c53
-rw-r--r--libs/pthreads/src/pthread_setschedparam.c123
-rw-r--r--libs/pthreads/src/pthread_setspecific.c167
-rw-r--r--libs/pthreads/src/pthread_spin_destroy.c111
-rw-r--r--libs/pthreads/src/pthread_spin_init.c123
-rw-r--r--libs/pthreads/src/pthread_spin_lock.c80
-rw-r--r--libs/pthreads/src/pthread_spin_trylock.c77
-rw-r--r--libs/pthreads/src/pthread_spin_unlock.c71
-rw-r--r--libs/pthreads/src/pthread_testcancel.c103
-rw-r--r--libs/pthreads/src/pthread_timechange_handler_np.c108
-rw-r--r--libs/pthreads/src/pthread_win32_attach_detach_np.c256
-rw-r--r--libs/pthreads/src/ptw32_MCS_lock.c278
-rw-r--r--libs/pthreads/src/ptw32_OLL_lock.c734
-rw-r--r--libs/pthreads/src/ptw32_callUserDestroyRoutines.c232
-rw-r--r--libs/pthreads/src/ptw32_calloc.c56
-rw-r--r--libs/pthreads/src/ptw32_cond_check_need_init.c78
-rw-r--r--libs/pthreads/src/ptw32_getprocessors.c91
-rw-r--r--libs/pthreads/src/ptw32_is_attr.c47
-rw-r--r--libs/pthreads/src/ptw32_mutex_check_need_init.c92
-rw-r--r--libs/pthreads/src/ptw32_new.c94
-rw-r--r--libs/pthreads/src/ptw32_processInitialize.c92
-rw-r--r--libs/pthreads/src/ptw32_processTerminate.c105
-rw-r--r--libs/pthreads/src/ptw32_relmillisecs.c132
-rw-r--r--libs/pthreads/src/ptw32_reuse.c151
-rw-r--r--libs/pthreads/src/ptw32_rwlock_cancelwrwait.c50
-rw-r--r--libs/pthreads/src/ptw32_rwlock_check_need_init.c77
-rw-r--r--libs/pthreads/src/ptw32_semwait.c135
-rw-r--r--libs/pthreads/src/ptw32_spinlock_check_need_init.c78
-rw-r--r--libs/pthreads/src/ptw32_threadDestroy.c79
-rw-r--r--libs/pthreads/src/ptw32_threadStart.c357
-rw-r--r--libs/pthreads/src/ptw32_throw.c189
-rw-r--r--libs/pthreads/src/ptw32_timespec.c83
-rw-r--r--libs/pthreads/src/ptw32_tkAssocCreate.c118
-rw-r--r--libs/pthreads/src/ptw32_tkAssocDestroy.c114
-rw-r--r--libs/pthreads/src/rwlock.c51
-rw-r--r--libs/pthreads/src/sched.c53
-rw-r--r--libs/pthreads/src/sched.h183
-rw-r--r--libs/pthreads/src/sched_get_priority_max.c134
-rw-r--r--libs/pthreads/src/sched_get_priority_min.c135
-rw-r--r--libs/pthreads/src/sched_getscheduler.c71
-rw-r--r--libs/pthreads/src/sched_setscheduler.c83
-rw-r--r--libs/pthreads/src/sched_yield.c71
-rw-r--r--libs/pthreads/src/sem_close.c58
-rw-r--r--libs/pthreads/src/sem_destroy.c144
-rw-r--r--libs/pthreads/src/sem_getvalue.c110
-rw-r--r--libs/pthreads/src/sem_init.c169
-rw-r--r--libs/pthreads/src/sem_open.c58
-rw-r--r--libs/pthreads/src/sem_post.c128
-rw-r--r--libs/pthreads/src/sem_post_multiple.c142
-rw-r--r--libs/pthreads/src/sem_timedwait.c238
-rw-r--r--libs/pthreads/src/sem_trywait.c117
-rw-r--r--libs/pthreads/src/sem_unlink.c58
-rw-r--r--libs/pthreads/src/sem_wait.c187
-rw-r--r--libs/pthreads/src/semaphore.c69
-rw-r--r--libs/pthreads/src/semaphore.h169
-rw-r--r--libs/pthreads/src/signal.c179
-rw-r--r--libs/pthreads/src/spin.c46
-rw-r--r--libs/pthreads/src/sync.c43
-rw-r--r--libs/pthreads/src/tsd.c44
-rw-r--r--libs/pthreads/src/w32_CancelableWait.c161
-rw-r--r--libs/win32/libjson.libbin63584 -> 65902 bytes
-rw-r--r--libs/win32/mir_app.libbin130706 -> 131618 bytes
-rw-r--r--libs/win32/mir_core.libbin318226 -> 318478 bytes
-rw-r--r--libs/win64/libjson.libbin64114 -> 66538 bytes
-rw-r--r--libs/win64/mir_app.libbin126274 -> 127106 bytes
-rw-r--r--libs/win64/mir_core.libbin319200 -> 319436 bytes
441 files changed, 71475 insertions, 1 deletions
diff --git a/libs/libjson/src/libjson.def b/libs/libjson/src/libjson.def
index 9d8b63ec49..027b0fd092 100644
--- a/libs/libjson/src/libjson.def
+++ b/libs/libjson/src/libjson.def
@@ -194,3 +194,10 @@ json_write @190
json_write_formatted @191
??6JSONNode@@QAEAAV0@ABV0@@Z @192 NONAME
??4JSONWorker@@QAEAAV0@$$QAV0@@Z @193 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUBOOL_PARAM@@@Z @194 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUCHAR_PARAM@@@Z @195 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUINT64_PARAM@@@Z @196 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUINT_PARAM@@@Z @197 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUWCHAR_PARAM@@@Z @198 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUJSON_PARAM@@@Z @199 NONAME
+??6@YGAAVJSONNode@@AAV0@ABUNULL_PARAM@@@Z @200 NONAME
diff --git a/libs/libjson/src/libjson64.def b/libs/libjson/src/libjson64.def
index 1e501cba21..e22d9f62ac 100644
--- a/libs/libjson/src/libjson64.def
+++ b/libs/libjson/src/libjson64.def
@@ -194,3 +194,10 @@ json_write @190
json_write_formatted @191
??6JSONNode@@QEAAAEAV0@AEBV0@@Z @192 NONAME
??4JSONWorker@@QEAAAEAV0@$$QEAV0@@Z @193 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUBOOL_PARAM@@@Z @194 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUCHAR_PARAM@@@Z @195 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUINT64_PARAM@@@Z @196 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUINT_PARAM@@@Z @197 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUWCHAR_PARAM@@@Z @198 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUJSON_PARAM@@@Z @199 NONAME
+??6@YAAEAVJSONNode@@AEAV0@AEBUNULL_PARAM@@@Z @200 NONAME
diff --git a/libs/libjson/src/stdafx.cxx b/libs/libjson/src/stdafx.cxx
index 6f97ed9a4e..b16af99abd 100644
--- a/libs/libjson/src/stdafx.cxx
+++ b/libs/libjson/src/stdafx.cxx
@@ -16,4 +16,50 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "stdafx.h" \ No newline at end of file
+#include "stdafx.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const INT_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, param.iValue));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const INT64_PARAM &param)
+{
+ char tmp[100];
+ _i64toa_s(param.iValue, tmp, _countof(tmp), 10);
+ json.push_back(JSONNode(param.szName, tmp));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const BOOL_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, param.bValue));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const CHAR_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, param.szValue));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const WCHAR_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, ptrA(mir_utf8encodeW(param.wszValue)).get()));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const NULL_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, nullptr));
+ return json;
+}
+
+LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const JSON_PARAM &param)
+{
+ json.push_back(JSONNode(param.szName, param.node));
+ return json;
+}
diff --git a/libs/libsodium/docs/AUTHORS b/libs/libsodium/docs/AUTHORS
new file mode 100644
index 0000000000..39e55f6288
--- /dev/null
+++ b/libs/libsodium/docs/AUTHORS
@@ -0,0 +1,135 @@
+
+Designers
+=========
+
+argon2 Alex Biryukov
+ Daniel Dinu
+ Dmitry Khovratovich
+
+blake2 Jean-Philippe Aumasson
+ Christian Winnerlein
+ Samuel Neves
+ Zooko Wilcox-O'Hearn
+
+chacha20 Daniel J. Bernstein
+
+chacha20poly1305 Adam Langley
+ Yoav Nir
+
+curve25519 Daniel J. Bernstein
+
+curve25519xsalsa20poly1305 Daniel J. Bernstein
+
+ed25519 Daniel J. Bernstein
+ Bo-Yin Yang
+ Niels Duif
+ Peter Schwabe
+ Tanja Lange
+
+poly1305 Daniel J. Bernstein
+
+salsa20 Daniel J. Bernstein
+
+scrypt Colin Percival
+
+siphash Jean-Philippe Aumasson
+ Daniel J. Bernstein
+
+Implementors
+============
+
+crypto_aead/aes256gcm/aesni Romain Dolbeau
+ Frank Denis
+
+crypto_aead/chacha20poly1305 Frank Denis
+
+crypto_aead/xchacha20poly1305 Frank Denis
+ Jason A. Donenfeld
+
+crypto_auth/hmacsha256 Colin Percival
+crypto_auth/hmacsha512
+crypto_auth/hmacsha512256
+
+crypto_box/curve25519xsalsa20poly1305 Daniel J. Bernstein
+
+crypto_box/curve25519xchacha20poly1305 Frank Denis
+
+crypto_core/ed25519 Daniel J. Bernstein
+ Adam Langley
+
+crypto_core/hchacha20 Frank Denis
+
+crypto_core/hsalsa20 Daniel J. Bernstein
+crypto_core/salsa
+
+crypto_generichash/blake2b Jean-Philippe Aumasson
+ Christian Winnerlein
+ Samuel Neves
+ Zooko Wilcox-O'Hearn
+
+crypto_hash/sha256 Colin Percival
+crypto_hash/sha512
+crypto_hash/sha512256
+
+crypto_kdf Frank Denis
+
+crypto_kx Frank Denis
+
+crypto_onetimeauth/poly1305/donna Andrew "floodyberry" Moon
+crypto_onetimeauth/poly1305/sse2
+
+crypto_pwhash/argon2 Samuel Neves
+ Dmitry Khovratovich
+ Jean-Philippe Aumasson
+ Daniel Dinu
+ Thomas Pornin
+
+crypto_pwhash/scryptsalsa208sha256 Colin Percival
+ Alexander Peslyak
+
+crypto_scalarmult/curve25519/ref10 Daniel J. Bernstein
+
+crypto_scalarmult/curve25519/sandy2x Tung Chou
+
+crypto_scalarmult/ed25519 Frank Denis
+
+crypto_secretbox/xsalsa20poly1305 Daniel J. Bernstein
+
+crypto_secretbox/xchacha20poly1305 Frank Denis
+
+crypto_secretstream/xchacha20poly1305 Frank Denis
+
+crypto_shorthash/siphash24 Jean-Philippe Aumasson
+ Daniel J. Bernstein
+
+crypto_sign/ed25519 Peter Schwabe
+ Daniel J. Bernstein
+ Niels Duif
+ Tanja Lange
+ Bo-Yin Yang
+
+crypto_stream/chacha20/ref Daniel J. Bernstein
+
+crypto_stream/chacha20/dolbeau Romain Dolbeau
+ Daniel J. Bernstein
+
+crypto_stream/salsa20/ref Daniel J. Bernstein
+crypto_stream/salsa20/xmm6
+
+crypto_stream/salsa20/xmm6int Romain Dolbeau
+ Daniel J. Bernstein
+
+crypto_stream/salsa2012/ref Daniel J. Bernstein
+crypto_stream/salsa2008/ref
+
+crypto_stream/xchacha20 Frank Denis
+
+crypto_verify Frank Denis
+
+sodium/codecs.c Frank Denis
+ Thomas Pornin
+ Christian Winnerlein
+
+sodium/core.c Frank Denis
+sodium/runtime.h
+sodium/utils.c
diff --git a/libs/libsodium/docs/ChangeLog b/libs/libsodium/docs/ChangeLog
new file mode 100644
index 0000000000..2c6f7f1777
--- /dev/null
+++ b/libs/libsodium/docs/ChangeLog
@@ -0,0 +1,505 @@
+
+* Version 1.0.16
+ - Signatures computations and verifications are now way faster on
+64-bit platforms with compilers supporting 128-bit arithmetic (gcc,
+clang, icc). This includes the WebAssembly target.
+ - New low-level APIs for computations over edwards25519:
+`crypto_scalarmult_ed25519()`, `crypto_scalarmult_ed25519_base()`,
+`crypto_core_ed25519_is_valid_point()`, `crypto_core_ed25519_add()`,
+`crypto_core_ed25519_sub()` and `crypto_core_ed25519_from_uniform()`
+(elligator representative to point).
+ - `crypto_sign_open()`, `crypto_sign_verify_detached() and
+`crypto_sign_edwards25519sha512batch_open` now reject public keys in
+non-canonical form in addition to low-order points.
+ - The library can be built with `ED25519_NONDETERMINISTIC` defined in
+order to use synthetic nonces for EdDSA. This is disabled by default.
+ - Webassembly: `crypto_pwhash_*()` functions are now included in
+non-sumo builds.
+ - `sodium_stackzero()` was added to wipe content off the stack.
+ - Android: support new SDKs where unified headers have become the
+default.
+ - The Salsa20-based PRNG example is now thread-safe on platforms with
+support for thread-local storage, optionally mixes bits from RDRAND.
+ - CMAKE: static library detection on Unix systems has been improved
+(thanks to @BurningEnlightenment, @nibua-r, @mellery451)
+ - Argon2 and scrypt are slightly faster on Linux.
+
+* Version 1.0.15
+ - The default password hashing algorithm is now Argon2id. The
+`pwhash_str_verify()` function can still verify Argon2i hashes
+without any changes, and `pwhash()` can still compute Argon2i hashes
+as well.
+ - The aes128ctr primitive was removed. It was slow, non-standard, not
+authenticated, and didn't seem to be used by any opensource project.
+ - Argon2id required at least 3 passes like Argon2i, despite a minimum
+of `1` as defined by the `OPSLIMIT_MIN` constant. This has been fixed.
+ - The secretstream construction was slightly changed to be consistent
+with forthcoming variants.
+ - The Javascript and Webassembly versions have been merged, and the
+module now returns a `.ready` promise that will resolve after the
+Webassembly code is loaded and compiled.
+ - Note that due to these incompatible changes, the library version
+major was bumped up.
+
+* Version 1.0.14
+ - iOS binaries should now be compatible with WatchOS and TVOS.
+ - WebAssembly is now officially supported. Special thanks to
+@facekapow and @pepyakin who helped to make it happen.
+ - Internal consistency checks failing and primitives used with
+dangerous/out-of-bounds/invalid parameters used to call abort(3).
+Now, a custom handler *that doesn't return* can be set with the
+`set_sodium_misuse()` function. It still aborts by default or if the
+handler ever returns. This is not a replacement for non-fatal,
+expected runtime errors. This handler will be only called in
+unexpected situations due to potential bugs in the library or in
+language bindings.
+ - `*_MESSAGEBYTES_MAX` macros (and the corresponding
+`_messagebytes_max()` symbols) have been added to represent the
+maximum message size that can be safely handled by a primitive.
+Language bindings are encouraged to check user inputs against these
+maximum lengths.
+ - The test suite has been extended to cover more edge cases.
+ - crypto_sign_ed25519_pk_to_curve25519() now rejects points that are
+not on the curve, or not in the main subgroup.
+ - Further changes have been made to ensure that smart compilers will
+not optimize out code that we don't want to be optimized.
+ - Visual Studio solutions are now included in distribution tarballs.
+ - The `sodium_runtime_has_*` symbols for CPU features detection are
+now defined as weak symbols, i.e. they can be replaced with an
+application-defined implementation. This can be useful to disable
+AVX* when temperature/power consumption is a concern.
+ - `crypto_kx_*()` now aborts if called with no non-NULL pointers to
+store keys to.
+ - SSE2 implementations of `crypto_verify_*()` have been added.
+ - Passwords can be hashed using a specific algorithm with the new
+`crypto_pwhash_str_alg()` function.
+ - Due to popular demand, base64 encoding (`sodium_bin2base64()`) and
+decoding (`sodium_base642bin()`) have been implemented.
+ - A new `crypto_secretstream_*()` API was added to safely encrypt files
+and multi-part messages.
+ - The `sodium_pad()` and `sodium_unpad()` helper functions have been
+added in order to add & remove padding.
+ - An AVX512 optimized implementation of Argon2 has been added (written
+by Ondrej Mosnáček, thanks!)
+ - The `crypto_pwhash_str_needs_rehash()` function was added to check if
+a password hash string matches the given parameters, or if it needs an
+update.
+ - The library can now be compiled with recent versions of
+emscripten/binaryen that don't allow multiple variables declarations
+using a single `var` statement.
+
+* Version 1.0.13
+ - Javascript: the sumo builds now include all symbols. They were
+previously limited to symbols defined in minimal builds.
+ - The public `crypto_pwhash_argon2i_MEMLIMIT_MAX` constant was
+incorrectly defined on 32-bit platforms. This has been fixed.
+ - Version 1.0.12 didn't compile on OpenBSD/i386 using the base gcc
+compiler. This has been fixed.
+ - The Android compilation scripts have been updated for NDK r14b.
+ - armv7s-optimized code was re-added to iOS builds.
+ - An AVX2 optimized implementation of the Argon2 round function was
+added.
+ - The Argon2id variant of Argon2 has been implemented. The
+high-level `crypto_pwhash_str_verify()` function automatically detects
+the algorithm and can verify both Argon2i and Argon2id hashed passwords.
+The default algorithm for newly hashed passwords remains Argon2i in
+this version to avoid breaking compatibility with verifiers running
+libsodium <= 1.0.12.
+ - A `crypto_box_curve25519xchacha20poly1305_seal*()` function set was
+implemented.
+ - scrypt was removed from minimal builds.
+ - libsodium is now available on NuGet.
+
+* Version 1.0.12
+ - Ed25519ph was implemented, adding a multi-part signature API
+(`crypto_sign_init()`, `crypto_sign_update()`, `crypto_sign_final_*()`).
+ - New constants and related accessors have been added for Scrypt and
+Argon2.
+ - XChaCha20 has been implemented. Like XSalsa20, this construction
+extends the ChaCha20 cipher to accept a 192-bit nonce. This makes it safe
+to use ChaCha20 with random nonces.
+ - `crypto_secretbox`, `crypto_box` and `crypto_aead` now offer
+variants leveraging XChaCha20.
+ - SHA-2 is about 20% faster, which also gives a speed boost to
+signature and signature verification.
+ - AVX2 implementations of Salsa20 and ChaCha20 have been added. They
+are twice as fast as the SSE2 implementations. The speed gain is
+even more significant on Windows, that previously didn't use
+vectorized implementations.
+ - New high-level API: `crypto_kdf`, to easily derive one or more
+subkeys from a master key.
+ - Siphash with a 128-bit output has been implemented, and is
+available as `crypto_shorthash_siphashx_*`.
+ - New `*_keygen()` helpers functions have been added to create secret
+keys for all constructions. This improves code clarity and can prevent keys
+from being partially initialized.
+ - A new `randombytes_buf_deterministic()` function was added to
+deterministically fill a memory region with pseudorandom data. This
+function can especially be useful to write reproducible tests.
+ - A preliminary `crypto_kx_*()` API was added to compute shared session
+keys.
+ - AVX2 detection is more reliable.
+ - The pthreads library is not required any more when using MingW.
+ - `contrib/Findsodium.cmake` was added as an example to include
+libsodium in a project using cmake.
+ - Compatibility with gcc 2.x has been restored.
+ - Minimal builds can be checked using `sodium_library_minimal()`.
+ - The `--enable-opt` compilation switch has become compatible with more
+platforms.
+ - Android builds are now using clang on platforms where it is
+available.
+
+* Version 1.0.11
+ - `sodium_init()` is now thread-safe, and can be safely called multiple
+times.
+ - Android binaries now properly support 64-bit Android, targeting
+platform 24, but without breaking compatibility with platforms 16 and
+21.
+ - Better support for old gcc versions.
+ - On FreeBSD, core dumps are disabled on regions allocated with
+sodium allocation functions.
+ - AVX2 detection was fixed, resulting in faster Blake2b hashing on
+platforms where it was not properly detected.
+ - The Sandy2x Curve25519 implementation was not as fast as expected
+on some platforms. This has been fixed.
+ - The NativeClient target was improved. Most notably, it now supports
+optimized implementations, and uses pepper_49 by default.
+ - The library can be compiled with recent Emscripten versions.
+Changes have been made to produce smaller code, and the default heap
+size was reduced in the standard version.
+ - The code can now be compiled on SLES11 service pack 4.
+ - Decryption functions can now accept a NULL pointer for the output.
+This checks the MAC without writing the decrypted message.
+ - crypto_generichash_final() now returns -1 if called twice.
+ - Support for Visual Studio 2008 was improved.
+
+* Version 1.0.10
+ - This release only fixes a compilation issue reported with some older
+gcc versions. There are no functional changes over the previous release.
+
+* Version 1.0.9
+ - The Javascript target now includes a `--sumo` option to include all
+the symbols of the original C library.
+ - A detached API was added to the ChaCha20-Poly1305 and AES256-GCM
+implementations.
+ - The Argon2i password hashing function was added, and is accessible
+directly and through a new, high-level `crypto_pwhash` API. The scrypt
+function remains available as well.
+ - A speed-record AVX2 implementation of BLAKE2b was added (thanks to
+Samuel Neves).
+ - The library can now be compiled using C++Builder (thanks to @jcolli44)
+ - Countermeasures for Ed25519 signatures malleability have been added
+to match the irtf-cfrg-eddsa draft (note that malleability is irrelevant to
+the standard definition of signature security). Signatures with a small-order
+`R` point are now also rejected.
+ - Some implementations are now slightly faster when using the Clang
+compiler.
+ - The HChaCha20 core function was implemented (`crypto_core_hchacha20()`).
+ - No-op stubs were added for all AES256-GCM public functions even when
+compiled on non-Intel platforms.
+ - `crypt_generichash_blake2b_statebytes()` was added.
+ - New macros were added for the IETF variant of the ChaCha20-Poly1305
+construction.
+ - The library can now be compiled on Minix.
+ - HEASLR is now enabled on MinGW builds.
+
+* Version 1.0.8
+ - Handle the case where the CPU supports AVX, but we are running
+on an hypervisor with AVX disabled/not supported.
+ - Faster (2x) scalarmult_base() when using the ref10 implementation.
+
+* Version 1.0.7
+ - More functions whose return value should be checked have been
+tagged with `__attribute__ ((warn_unused_result))`: `crypto_box_easy()`,
+`crypto_box_detached()`, `crypto_box_beforenm()`, `crypto_box()`, and
+`crypto_scalarmult()`.
+ - Sandy2x, the fastest Curve25519 implementation ever, has been
+merged in, and is automatically used on CPUs supporting the AVX
+instructions set.
+ - An SSE2 optimized implementation of Poly1305 was added, and is
+twice as fast as the portable one.
+ - An SSSE3 optimized implementation of ChaCha20 was added, and is
+twice as fast as the portable one.
+ - Faster `sodium_increment()` for common nonce sizes.
+ - New helper functions have been added: `sodium_is_zero()` and
+ `sodium_add()`.
+ - `sodium_runtime_has_aesni()` now properly detects the CPU flag when
+ compiled using Visual Studio.
+
+* Version 1.0.6
+ - Optimized implementations of Blake2 have been added for modern
+Intel platforms. `crypto_generichash()` is now faster than MD5 and SHA1
+implementations while being far more secure.
+ - Functions for which the return value should be checked have been
+tagged with `__attribute__ ((warn_unused_result))`. This will
+intentionally break code compiled with `-Werror` that didn't bother
+checking critical return values.
+ - The `crypto_sign_edwards25519sha512batch_*()` functions have been
+tagged as deprecated.
+ - Undocumented symbols that were exported, but were only useful for
+internal purposes have been removed or made private:
+`sodium_runtime_get_cpu_features()`, the implementation-specific
+`crypto_onetimeauth_poly1305_donna()` symbols,
+`crypto_onetimeauth_poly1305_set_implementation()`,
+`crypto_onetimeauth_poly1305_implementation_name()` and
+`crypto_onetimeauth_pick_best_implementation()`.
+ - `sodium_compare()` now works as documented, and compares numbers
+in little-endian format instead of behaving like `memcmp()`.
+ - The previous changes should not break actual applications, but to be
+safe, the library version major was incremented.
+ - `sodium_runtime_has_ssse3()` and `sodium_runtime_has_sse41()` have
+been added.
+ - The library can now be compiled with the CompCert compiler.
+
+* Version 1.0.5
+ - Compilation issues on some platforms were fixed: missing alignment
+directives were added (required at least on RHEL-6/i386), a workaround
+for a VRP bug on gcc/armv7 was added, and the library can now be compiled
+with the SunPro compiler.
+ - Javascript target: io.js is not supported any more. Use nodejs.
+
+* Version 1.0.4
+ - Support for AES256-GCM has been added. This requires
+a CPU with the aesni and pclmul extensions, and is accessible via the
+crypto_aead_aes256gcm_*() functions.
+ - The Javascript target doesn't use eval() any more, so that the
+library can be used in Chrome packaged applications.
+ - QNX and CloudABI are now supported.
+ - Support for NaCl has finally been added.
+ - ChaCha20 with an extended (96 bit) nonce and a 32-bit counter has
+been implemented as crypto_stream_chacha20_ietf(),
+crypto_stream_chacha20_ietf_xor() and crypto_stream_chacha20_ietf_xor_ic().
+An IETF-compatible version of ChaCha20Poly1305 is available as
+crypto_aead_chacha20poly1305_ietf_npubbytes(),
+crypto_aead_chacha20poly1305_ietf_encrypt() and
+crypto_aead_chacha20poly1305_ietf_decrypt().
+ - The sodium_increment() helper function has been added, to increment
+an arbitrary large number (such as a nonce).
+ - The sodium_compare() helper function has been added, to compare
+arbitrary large numbers (such as nonces, in order to prevent replay
+attacks).
+
+* Version 1.0.3
+ - In addition to sodium_bin2hex(), sodium_hex2bin() is now a
+constant-time function.
+ - crypto_stream_xsalsa20_ic() has been added.
+ - crypto_generichash_statebytes(), crypto_auth_*_statebytes() and
+crypto_hash_*_statebytes() have been added in order to retrieve the
+size of structures keeping states from foreign languages.
+ - The JavaScript target doesn't require /dev/urandom or an external
+randombytes() implementation any more. Other minor Emscripten-related
+improvements have been made in order to support libsodium.js
+ - Custom randombytes implementations do not need to provide their own
+implementation of randombytes_uniform() any more. randombytes_stir()
+and randombytes_close() can also be NULL pointers if they are not
+required.
+ - On Linux, getrandom(2) is being used instead of directly accessing
+/dev/urandom, if the kernel supports this system call.
+ - crypto_box_seal() and crypto_box_seal_open() have been added.
+ - Visual Studio 2015 is now supported.
+
+* Version 1.0.2
+ - The _easy and _detached APIs now support precalculated keys;
+crypto_box_easy_afternm(), crypto_box_open_easy_afternm(),
+crypto_box_detached_afternm() and crypto_box_open_detached_afternm()
+have been added as an alternative to the NaCl interface.
+ - Memory allocation functions can now be used on operating systems with
+no memory protection.
+ - crypto_sign_open() and crypto_sign_edwards25519sha512batch_open()
+now accept a NULL pointer instead of a pointer to the message size, if
+storing this information is not required.
+ - The close-on-exec flag is now set on the descriptor returned when
+opening /dev/urandom.
+ - A libsodium-uninstalled.pc file to use pkg-config even when
+libsodium is not installed, has been added.
+ - The iOS target now includes armv7s and arm64 optimized code, as well
+as i386 and x86_64 code for the iOS simulator.
+ - sodium_free() can now be called on regions with PROT_NONE protection.
+ - The Javascript tests can run on Ubuntu, where the node binary was
+renamed nodejs. io.js can also be used instead of node.
+
+* Version 1.0.1
+ - DLL_EXPORT was renamed SODIUM_DLL_EXPORT in order to avoid
+collisions with similar macros defined by other libraries.
+ - sodium_bin2hex() is now constant-time.
+ - crypto_secretbox_detached() now supports overlapping input and output
+regions.
+ - NaCl's donna_c64 implementation of curve25519 was reading an extra byte
+past the end of the buffer containing the base point. This has been
+fixed.
+
+* Version 1.0.0
+ - The API and ABI are now stable. New features will be added, but
+backward-compatibility is guaranteed through all the 1.x.y releases.
+ - crypto_sign() properly works with overlapping regions again. Thanks
+to @pysiak for reporting this regression introduced in version 0.6.1.
+ - The test suite has been extended.
+
+* Version 0.7.1 (1.0 RC2)
+ - This is the second release candidate of Sodium 1.0. Minor
+compilation, readability and portability changes have been made and the
+test suite was improved, but the API is the same as the previous release
+candidate.
+
+* Version 0.7.0 (1.0 RC1)
+ - Allocating memory to store sensitive data can now be done using
+sodium_malloc() and sodium_allocarray(). These functions add guard
+pages around the protected data to make it less likely to be
+accessible in a heartbleed-like scenario. In addition, the protection
+for memory regions allocated that way can be changed using
+sodium_mprotect_noaccess(), sodium_mprotect_readonly() and
+sodium_mprotect_readwrite().
+ - ed25519 keys can be converted to curve25519 keys with
+crypto_sign_ed25519_pk_to_curve25519() and
+crypto_sign_ed25519_sk_to_curve25519(). This allows using the same
+keys for signature and encryption.
+ - The seed and the public key can be extracted from an ed25519 key
+using crypto_sign_ed25519_sk_to_seed() and crypto_sign_ed25519_sk_to_pk().
+ - aes256 was removed. A timing-attack resistant implementation might
+be added later, but not before version 1.0 is tagged.
+ - The crypto_pwhash_scryptxsalsa208sha256_* compatibility layer was
+removed. Use crypto_pwhash_scryptsalsa208sha256_*.
+ - The compatibility layer for implementation-specific functions was
+removed.
+ - Compilation issues with Mingw64 on MSYS (not MSYS2) were fixed.
+ - crypto_pwhash_scryptsalsa208sha256_STRPREFIX was added: it contains
+the prefix produced by crypto_pwhash_scryptsalsa208sha256_str()
+
+* Version 0.6.1
+ - Important bug fix: when crypto_sign_open() was given a signed
+message too short to even contain a signature, it was putting an
+unlimited amount of zeros into the target buffer instead of
+immediately returning -1. The bug was introduced in version 0.5.0.
+ - New API: crypto_sign_detached() and crypto_sign_verify_detached()
+to produce and verify ed25519 signatures without having to duplicate
+the message.
+ - New ./configure switch: --enable-minimal, to create a smaller
+library, with only the functions required for the high-level API.
+Mainly useful for the JavaScript target and embedded systems.
+ - All the symbols are now exported by the Emscripten build script.
+ - The pkg-config .pc file is now always installed even if the
+pkg-config tool is not available during the installation.
+
+* Version 0.6.0
+ - The ChaCha20 stream cipher has been added, as crypto_stream_chacha20_*
+ - The ChaCha20Poly1305 AEAD construction has been implemented, as
+crypto_aead_chacha20poly1305_*
+ - The _easy API does not require any heap allocations any more and
+does not have any overhead over the NaCl API. With the password
+hashing function being an obvious exception, the library doesn't
+allocate and will not allocate heap memory ever.
+ - crypto_box and crypto_secretbox have a new _detached API to store
+the authentication tag and the encrypted message separately.
+ - crypto_pwhash_scryptxsalsa208sha256*() functions have been renamed
+crypto_pwhash_scryptsalsa208sha256*().
+ - The low-level crypto_pwhash_scryptsalsa208sha256_ll() function
+allows setting individual parameters of the scrypt function.
+ - New macros and functions for recommended crypto_pwhash_* parameters
+have been added.
+ - Similarly to crypto_sign_seed_keypair(), crypto_box_seed_keypair()
+has been introduced to deterministically generate a key pair from a seed.
+ - crypto_onetimeauth() now provides a streaming interface.
+ - crypto_stream_chacha20_xor_ic() and crypto_stream_salsa20_xor_ic()
+have been added to use a non-zero initial block counter.
+ - On Windows, CryptGenRandom() was replaced by RtlGenRandom(), which
+doesn't require the Crypt API.
+ - The high bit in curve25519 is masked instead of processing the key as
+a 256-bit value.
+ - The curve25519 ref implementation was replaced by the latest ref10
+implementation from Supercop.
+ - sodium_mlock() now prevents memory from being included in coredumps
+on Linux 3.4+
+
+* Version 0.5.0
+ - sodium_mlock()/sodium_munlock() have been introduced to lock pages
+in memory before storing sensitive data, and to zero them before
+unlocking them.
+ - High-level wrappers for crypto_box and crypto_secretbox
+(crypto_box_easy and crypto_secretbox_easy) can be used to avoid
+dealing with the specific memory layout regular functions depend on.
+ - crypto_pwhash_scryptsalsa208sha256* functions have been added
+to derive a key from a password, and for password storage.
+ - Salsa20 and ed25519 implementations now support overlapping
+inputs/keys/outputs (changes imported from supercop-20140505).
+ - New build scripts for Visual Studio, Emscripten, different Android
+architectures and msys2 are available.
+ - The poly1305-53 implementation has been replaced with Floodyberry's
+poly1305-donna32 and poly1305-donna64 implementations.
+ - sodium_hex2bin() has been added to complement sodium_bin2hex().
+ - On OpenBSD and Bitrig, arc4random() is used instead of reading
+/dev/urandom.
+ - crypto_auth_hmac_sha512() has been implemented.
+ - sha256 and sha512 now have a streaming interface.
+ - hmacsha256, hmacsha512 and hmacsha512256 now support keys of
+arbitrary length, and have a streaming interface.
+ - crypto_verify_64() has been implemented.
+ - first-class Visual Studio build system, thanks to @evoskuil
+ - CPU features are now detected at runtime.
+
+* Version 0.4.5
+ - Restore compatibility with OSX <= 10.6
+
+* Version 0.4.4
+ - Visual Studio is officially supported (VC 2010 & VC 2013)
+ - mingw64 is now supported
+ - big-endian architectures are now supported as well
+ - The donna_c64 implementation of curve25519_donna_c64 now handles
+non-canonical points like the ref implementation
+ - Missing scalarmult_curve25519 and stream_salsa20 constants are now exported
+ - A crypto_onetimeauth_poly1305_ref() wrapper has been added
+
+* Version 0.4.3
+ - crypto_sign_seedbytes() and crypto_sign_SEEDBYTES were added.
+ - crypto_onetimeauth_poly1305_implementation_name() was added.
+ - poly1305-ref has been replaced by a faster implementation,
+Floodyberry's poly1305-donna-unrolled.
+ - Stackmarkings have been added to assembly code, for Hardened Gentoo.
+ - pkg-config can now be used in order to retrieve compilations flags for
+using libsodium.
+ - crypto_stream_aes256estream_*() can now deal with unaligned input
+on platforms that require word alignment.
+ - portability improvements.
+
+* Version 0.4.2
+ - All NaCl constants are now also exposed as functions.
+ - The Android and iOS cross-compilation script have been improved.
+ - libsodium can now be cross-compiled to Windows from Linux.
+ - libsodium can now be compiled with emscripten.
+ - New convenience function (prototyped in utils.h): sodium_bin2hex().
+
+* Version 0.4.1
+ - sodium_version_*() functions were not exported in version 0.4. They
+are now visible as intended.
+ - sodium_init() now calls randombytes_stir().
+ - optimized assembly version of salsa20 is now used on amd64.
+ - further cleanups and enhanced compatibility with non-C99 compilers.
+
+* Version 0.4
+ - Most constants and operations are now available as actual functions
+instead of macros, making it easier to use from other languages.
+ - New operation: crypto_generichash, featuring a variable key size, a
+variable output size, and a streaming API. Currently implemented using
+Blake2b.
+ - The package can be compiled in a separate directory.
+ - aes128ctr functions are exported.
+ - Optimized versions of curve25519 (curve25519_donna_c64), poly1305
+(poly1305_53) and ed25519 (ed25519_ref10) are available. Optionally calling
+sodium_init() once before using the library makes it pick the fastest
+implementation.
+ - New convenience function: sodium_memzero() in order to securely
+wipe a memory area.
+ - A whole bunch of cleanups and portability enhancements.
+ - On Windows, a .REF file is generated along with the shared library,
+for use with Visual Studio. The installation path for these has become
+$prefix/bin as expected by MingW.
+
+* Version 0.3
+ - The crypto_shorthash operation has been added, implemented using
+SipHash-2-4.
+
+* Version 0.2
+ - crypto_sign_seed_keypair() has been added
+
+* Version 0.1
+ - Initial release.
+
diff --git a/libs/libsodium/docs/LICENSE b/libs/libsodium/docs/LICENSE
new file mode 100644
index 0000000000..2489a68143
--- /dev/null
+++ b/libs/libsodium/docs/LICENSE
@@ -0,0 +1,18 @@
+/*
+ * ISC License
+ *
+ * Copyright (c) 2013-2017
+ * Frank Denis <j at pureftpd dot org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/libs/libsodium/docs/README.markdown b/libs/libsodium/docs/README.markdown
new file mode 100644
index 0000000000..815240abea
--- /dev/null
+++ b/libs/libsodium/docs/README.markdown
@@ -0,0 +1,46 @@
+[![Build Status](https://travis-ci.org/jedisct1/libsodium.svg?branch=master)](https://travis-ci.org/jedisct1/libsodium?branch=master)
+[![Windows build status](https://ci.appveyor.com/api/projects/status/fu8s2elx25il98hj?svg=true)](https://ci.appveyor.com/project/jedisct1/libsodium)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/2397/badge.svg)](https://scan.coverity.com/projects/2397)
+
+![libsodium](https://raw.github.com/jedisct1/libsodium/master/logo.png)
+============
+
+Sodium is a new, easy-to-use software library for encryption,
+decryption, signatures, password hashing and more.
+
+It is a portable, cross-compilable, installable, packageable
+fork of [NaCl](http://nacl.cr.yp.to/), with a compatible API, and an
+extended API to improve usability even further.
+
+Its goal is to provide all of the core operations needed to build
+higher-level cryptographic tools.
+
+Sodium supports a variety of compilers and operating systems,
+including Windows (with MingW or Visual Studio, x86 and x64), iOS, Android,
+as well as Javascript and Webassembly.
+
+## Documentation
+
+The documentation is available on Gitbook:
+
+* [libsodium documentation](https://download.libsodium.org/doc/) -
+online, requires Javascript.
+* [offline documentation](https://www.gitbook.com/book/jedisct1/libsodium/details)
+in PDF, MOBI and ePUB formats.
+
+## Integrity Checking
+
+The integrity checking instructions (including the signing key for libsodium)
+are available in the [installation](https://download.libsodium.org/doc/installation/index.html#integrity-checking)
+section of the documentation.
+
+## Community
+
+A mailing-list is available to discuss libsodium.
+
+In order to join, just send a random mail to `sodium-subscribe` {at}
+`pureftpd` {dot} `org`.
+
+## License
+
+[ISC license](https://en.wikipedia.org/wiki/ISC_license).
diff --git a/libs/libsodium/docs/THANKS b/libs/libsodium/docs/THANKS
new file mode 100644
index 0000000000..0d0da788f3
--- /dev/null
+++ b/libs/libsodium/docs/THANKS
@@ -0,0 +1,91 @@
+Special thanks to people, companies and organizations having written
+libsodium bindings for their favorite programming languages:
+
+@alethia7
+@artemisc
+@carblue
+@dnaq
+@ektrah
+@graxrabble
+@harleqin
+@joshjdevl
+@jrmarino
+@jshahbazi
+@lvh
+@neheb
+
+Adam Caudill (@adamcaudill)
+Alexander Morris (@alexpmorris)
+Amit Murthy (@amitmurthy)
+Andrew Bennett (@potatosalad)
+Andrew Lambert (@charonn0)
+Bruce Mitchener (@waywardmonkeys)
+Bruno Oliveira (@abstractj)
+Caolan McMahon (@caolan)
+Chris Rebert (@cvrebert)
+Christian Hermann (@bitbeans)
+Christian Wiese (@morfoh)
+Christian Wiese (@morfoh)
+Colm MacCárthaigh (@colmmacc)
+David Parrish (@dmp1ce)
+Donald Stufft (@dstufft)
+Douglas Campos (@qmx)
+Drew Crawford (@drewcrawford)
+Emil Bay (@emilbayes)
+Eric Dong (@quantum1423)
+Eric Voskuil (@evoskuil)
+Farid Hajji (@fhajji)
+Frank Siebenlist (@franks42)
+Gabriel Handford (@gabriel)
+Geo Carncross (@geocar)
+Henrik Gassmann (BurningEnlightenment)
+Jachym Holecek (@freza)
+Jack Wink (@jackwink)
+James Ruan (@jamesruan)
+Jan de Muijnck-Hughes (@jfdm)
+Jason McCampbell (@jasonmccampbell)
+Jeroen Habraken (@VeXocide)
+Jeroen Ooms (@jeroen)
+Jesper Louis Andersen (@jlouis)
+Joe Eli McIlvain (@jemc)
+Jonathan Stowe (@jonathanstowe)
+Joseph Abrahamson (@tel)
+Julien Kauffmann (@ereOn)
+Kenneth Ballenegger (@kballenegger)
+Loic Maury (@loicmaury)
+Michael Gorlick (@mgorlick)
+Michael Gregorowicz (@mgregoro)
+Michał Zieliński (@zielmicha)
+Omar Ayub (@electricFeel)
+Pedro Paixao (@paixaop)
+Project ArteMisc (@artemisc)
+Rich FitzJohn (@richfitz)
+Ruben De Visscher (@rubendv)
+Rudolf Von Krugstein (@rudolfvonkrugstein)
+Samuel Neves (@sneves)
+Scott Arciszewski (@paragonie-scott)
+Stanislav Ovsiannikov (@naphaso)
+Stefan Marsiske (@stef)
+Stephan Touset (@stouset)
+Stephen Chavez (@redragonx)
+Steve Gibson (@sggrc)
+Tony Arcieri (@bascule)
+Tony Garnock-Jones (@tonyg)
+Y. T. Chung (@zonyitoo)
+
+Bytecurry Software
+Cryptotronix
+Facebook
+FSF France
+MaidSafe
+Paragonie Initiative Enterprises
+Python Cryptographic Authority
+
+(this list may not be complete, if you don't see your name, please
+submit a pull request!)
+
+Also thanks to:
+
+- Coverity, Inc. to provide static analysis.
+- FSF France for providing access to their compilation servers.
+- Private Internet Access for having sponsored a complete security audit.
diff --git a/libs/libsodium/libsodium.vcxproj b/libs/libsodium/libsodium.vcxproj
new file mode 100644
index 0000000000..182ac4184b
--- /dev/null
+++ b/libs/libsodium/libsodium.vcxproj
@@ -0,0 +1,493 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A185B162-6CB6-4502-B03F-B56F7699A8D9}</ProjectGuid>
+ <ProjectName>libsodium</ProjectName>
+ <RootNamespace>libsodium</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup>
+ <GenerateManifest>false</GenerateManifest>
+ <EmbedManifest>false</EmbedManifest>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <OutDir Condition="'$(Platform)'=='Win32'">$(SolutionDir)$(Configuration)\Libs\</OutDir>
+ <OutDir Condition="'$(Platform)'=='x64'">$(SolutionDir)$(Configuration)64\Libs\</OutDir>
+ </PropertyGroup>
+ <Import Project="$(ProjectDir)..\..\build\vc.common\common.props"/>
+ <PropertyGroup>
+ <TargetExt>.mir</TargetExt>
+ <TargetPath>$(OutDir)$(TargetName)$(TargetExt)</TargetPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PreprocessorDefinitions>SODIUM_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DisableSpecificWarnings>4244;4310;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>$(ProjectDir)src\include;$(ProjectDir)src\include\sodium;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\crypto_generichash\crypto_generichash.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\generichash_blake2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ssse3.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-avx2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-sse41.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\generichash_blake2b.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_kx\crypto_kx.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\crypto_sign.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\ed25519\sign_ed25519.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\ed25519\ref10\obsolete.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\ed25519\ref10\sign.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\ed25519\ref10\keypair.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_sign\ed25519\ref10\open.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_secretbox\crypto_secretbox.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_secretbox\crypto_secretbox_easy.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_secretbox\xsalsa20poly1305\secretbox_xsalsa20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_secretbox\xchacha20poly1305\secretbox_xchacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\crypto_pwhash.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\blake2b-long.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-core.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-avx512f.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-ssse3.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\pwhash_argon2i.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\pwhash_argon2id.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-avx2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\argon2\argon2-encoding.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\scrypt_platform.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\crypto_scrypt-common.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\pwhash_scryptsalsa208sha256.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\pbkdf2-sha256.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\nosse\pwhash_scryptsalsa208sha256_nosse.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\sse\pwhash_scryptsalsa208sha256_sse.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_verify\sodium\verify.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_auth\crypto_auth.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_auth\hmacsha512\auth_hmacsha512.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_auth\hmacsha512256\auth_hmacsha512256.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_auth\hmacsha256\auth_hmacsha256.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_kdf\crypto_kdf.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_kdf\blake2b\kdf_blake2b.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_shorthash\crypto_shorthash.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_shorthash\siphash24\shorthash_siphash24.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_shorthash\siphash24\shorthash_siphashx24.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_shorthash\siphash24\ref\shorthash_siphashx24_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_shorthash\siphash24\ref\shorthash_siphash24_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\crypto_scalarmult.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\ed25519\ref10\scalarmult_ed25519_ref10.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\curve25519\scalarmult_curve25519.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\curve25519_sandy2x.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\fe_frombytes_sandy2x.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\fe51_invert.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_scalarmult\curve25519\ref10\x25519_ref10.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_onetimeauth\crypto_onetimeauth.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_onetimeauth\poly1305\onetimeauth_poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_onetimeauth\poly1305\sse2\poly1305_sse2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\randombytes\randombytes.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\randombytes\sysrandom\randombytes_sysrandom.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\randombytes\salsa20\randombytes_salsa20_random.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\randombytes\nativeclient\randombytes_nativeclient.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\crypto_box_easy.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\crypto_box_seal.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\crypto_box.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\curve25519xsalsa20poly1305\box_curve25519xsalsa20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\curve25519xchacha20poly1305\box_curve25519xchacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_box\curve25519xchacha20poly1305\box_seal_curve25519xchacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\sodium\codecs.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\sodium\runtime.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\sodium\core.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\sodium\utils.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\sodium\version.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\crypto_stream.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\xchacha20\stream_xchacha20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\chacha20\stream_chacha20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\chacha20\ref\chacha20_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-avx2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-ssse3.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa20\stream_salsa20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa20\ref\salsa20_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-avx2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-sse2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa20\xmm6\salsa20_xmm6.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa2012\stream_salsa2012.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa2012\ref\stream_salsa2012_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa208\stream_salsa208.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\salsa208\ref\stream_salsa208_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_stream\xsalsa20\stream_xsalsa20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_hash\crypto_hash.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_hash\sha512\hash_sha512.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_hash\sha512\cp\hash_sha512_cp.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_hash\sha256\hash_sha256.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_hash\sha256\cp\hash_sha256_cp.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_aead\xchacha20poly1305\sodium\aead_xchacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_aead\aes256gcm\aesni\aead_aes256gcm_aesni.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_aead\chacha20poly1305\sodium\aead_chacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_secretstream\xchacha20poly1305\secretstream_xchacha20poly1305.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\salsa\ref\core_salsa_ref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\hchacha20\core_hchacha20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\hsalsa20\core_hsalsa20.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\hsalsa20\ref2\core_hsalsa20_ref2.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\ed25519\core_ed25519.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\crypto_core\ed25519\ref10\ed25519_ref10.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-sse2.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-avx2.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ssse3.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-sse41.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-avx2.h"/>
+ <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-sse41.h"/>
+ <ClInclude Include="src\crypto_sign\ed25519\ref10\sign_ed25519_ref10.h"/>
+ <ClInclude Include="src\include\sodium.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_salsa2012.h"/>
+ <ClInclude Include="src\include\sodium\crypto_auth.h"/>
+ <ClInclude Include="src\include\sodium\utils.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_hchacha20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_hash_sha512.h"/>
+ <ClInclude Include="src\include\sodium\core.h"/>
+ <ClInclude Include="src\include\sodium\export.h"/>
+ <ClInclude Include="src\include\sodium\randombytes_salsa20_random.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_salsa20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_shorthash_siphash24.h"/>
+ <ClInclude Include="src\include\sodium\randombytes.h"/>
+ <ClInclude Include="src\include\sodium\crypto_hash_sha256.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream.h"/>
+ <ClInclude Include="src\include\sodium\crypto_auth_hmacsha512.h"/>
+ <ClInclude Include="src\include\sodium\crypto_aead_xchacha20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_salsa20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_onetimeauth_poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_kx.h"/>
+ <ClInclude Include="src\include\sodium\crypto_hash.h"/>
+ <ClInclude Include="src\include\sodium\crypto_sign.h"/>
+ <ClInclude Include="src\include\sodium\crypto_kdf.h"/>
+ <ClInclude Include="src\include\sodium\crypto_auth_hmacsha256.h"/>
+ <ClInclude Include="src\include\sodium\crypto_box.h"/>
+ <ClInclude Include="src\include\sodium\crypto_verify_32.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_xchacha20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_salsa208.h"/>
+ <ClInclude Include="src\include\sodium\crypto_auth_hmacsha512256.h"/>
+ <ClInclude Include="src\include\sodium\crypto_aead_chacha20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\randombytes_sysrandom.h"/>
+ <ClInclude Include="src\include\sodium\runtime.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_salsa208.h"/>
+ <ClInclude Include="src\include\sodium\crypto_aead_aes256gcm.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_salsa2012.h"/>
+ <ClInclude Include="src\include\sodium\crypto_secretbox_xchacha20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\randombytes_nativeclient.h"/>
+ <ClInclude Include="src\include\sodium\crypto_scalarmult.h"/>
+ <ClInclude Include="src\include\sodium\crypto_pwhash.h"/>
+ <ClInclude Include="src\include\sodium\crypto_verify_16.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_chacha20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_stream_xsalsa20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_hsalsa20.h"/>
+ <ClInclude Include="src\include\sodium\crypto_kdf_blake2b.h"/>
+ <ClInclude Include="src\include\sodium\crypto_scalarmult_curve25519.h"/>
+ <ClInclude Include="src\include\sodium\crypto_shorthash.h"/>
+ <ClInclude Include="src\include\sodium\crypto_pwhash_argon2id.h"/>
+ <ClInclude Include="src\include\sodium\crypto_secretstream_xchacha20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_pwhash_scryptsalsa208sha256.h"/>
+ <ClInclude Include="src\include\sodium\crypto_sign_ed25519.h"/>
+ <ClInclude Include="src\include\sodium\crypto_onetimeauth.h"/>
+ <ClInclude Include="src\include\sodium\crypto_verify_64.h"/>
+ <ClInclude Include="src\include\sodium\crypto_box_curve25519xchacha20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_core_ed25519.h"/>
+ <ClInclude Include="src\include\sodium\crypto_pwhash_argon2i.h"/>
+ <ClInclude Include="src\include\sodium\crypto_generichash.h"/>
+ <ClInclude Include="src\include\sodium\crypto_secretbox_xsalsa20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_secretbox.h"/>
+ <ClInclude Include="src\include\sodium\crypto_scalarmult_ed25519.h"/>
+ <ClInclude Include="src\include\sodium\crypto_box_curve25519xsalsa20poly1305.h"/>
+ <ClInclude Include="src\include\sodium\crypto_generichash_blake2b.h"/>
+ <ClInclude Include="src\include\sodium\crypto_sign_edwards25519sha512batch.h"/>
+ <ClInclude Include="src\include\sodium\version.h"/>
+ <ClInclude Include="src\include\sodium\private\ed25519_ref10.h"/>
+ <ClInclude Include="src\include\sodium\private\ed25519_ref10_fe_25_5.h"/>
+ <ClInclude Include="src\include\sodium\private\ed25519_ref10_fe_51.h"/>
+ <ClInclude Include="src\include\sodium\private\sse2_64_32.h"/>
+ <ClInclude Include="src\include\sodium\private\common.h"/>
+ <ClInclude Include="src\include\sodium\private\mutex.h"/>
+ <ClInclude Include="src\include\sodium\private\implementations.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-ref.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-avx2.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\argon2.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-ssse3.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\argon2-encoding.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\blake2b-long.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-avx512f.h"/>
+ <ClInclude Include="src\crypto_pwhash\argon2\argon2-core.h"/>
+ <ClInclude Include="src\crypto_pwhash\scryptsalsa208sha256\crypto_scrypt.h"/>
+ <ClInclude Include="src\crypto_pwhash\scryptsalsa208sha256\pbkdf2-sha256.h"/>
+ <ClInclude Include="src\crypto_shorthash\siphash24\ref\shorthash_siphash_ref.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\scalarmult_curve25519.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\consts_namespace.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_namespace.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_base_namespace.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe51.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\curve25519_sandy2x.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe51_namespace.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_base.h"/>
+ <ClInclude Include="src\crypto_scalarmult\curve25519\ref10\x25519_ref10.h"/>
+ <ClInclude Include="src\crypto_onetimeauth\poly1305\onetimeauth_poly1305.h"/>
+ <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna.h"/>
+ <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna64.h"/>
+ <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna32.h"/>
+ <ClInclude Include="src\crypto_onetimeauth\poly1305\sse2\poly1305_sse2.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\stream_chacha20.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\ref\chacha20_ref.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u4.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-ssse3.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u0.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u1.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-avx2.h"/>
+ <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u8.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\stream_salsa20.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\ref\salsa20_ref.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u4.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u0.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u1.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-avx2.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u8.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-sse2.h"/>
+ <ClInclude Include="src\crypto_stream\salsa20\xmm6\salsa20_xmm6.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\constants.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\fe.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\base2.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\base.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\constants.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\fe.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\base2.h"/>
+ <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\base.h"/>
+ </ItemGroup>
+</Project>
diff --git a/libs/libsodium/libsodium.vcxproj.filters b/libs/libsodium/libsodium.vcxproj.filters
new file mode 100644
index 0000000000..8f90aeb3d5
--- /dev/null
+++ b/libs/libsodium/libsodium.vcxproj.filters
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
+</Project>
diff --git a/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c
new file mode 100644
index 0000000000..dc54bca76b
--- /dev/null
+++ b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c
@@ -0,0 +1,1079 @@
+
+/*
+ * AES256-GCM, based on the "Intel Carry-Less Multiplication Instruction and its Usage for Computing
+ * the GCM Mode" paper and reference code, using the aggregated reduction method.
+ * Originally adapted by Romain Dolbeau.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_aead_aes256gcm.h"
+#include "export.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "randombytes.h"
+#include "runtime.h"
+#include "utils.h"
+
+#if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("ssse3")
+# pragma GCC target("aes")
+# pragma GCC target("pclmul")
+# endif
+
+#include <tmmintrin.h>
+#include <wmmintrin.h>
+
+#ifndef ENOSYS
+# define ENOSYS ENXIO
+#endif
+
+#if defined(__INTEL_COMPILER) || defined(_bswap64)
+#elif defined(_MSC_VER)
+# define _bswap64(a) _byteswap_uint64(a)
+#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
+# define _bswap64(a) __builtin_bswap64(a)
+#else
+static inline uint64_t
+_bswap64(const uint64_t x)
+{
+ return
+ ((x << 56) & 0xFF00000000000000UL) | ((x << 40) & 0x00FF000000000000UL) |
+ ((x << 24) & 0x0000FF0000000000UL) | ((x << 8) & 0x000000FF00000000UL) |
+ ((x >> 8) & 0x00000000FF000000UL) | ((x >> 24) & 0x0000000000FF0000UL) |
+ ((x >> 40) & 0x000000000000FF00UL) | ((x >> 56) & 0x00000000000000FFUL);
+}
+#endif
+
+typedef struct context {
+ CRYPTO_ALIGN(16) unsigned char H[16];
+ __m128i rkeys[16];
+} context;
+
+static inline void
+aesni_key256_expand(const unsigned char *key, __m128i * const rkeys)
+{
+ __m128i X0, X1, X2, X3;
+ int i = 0;
+
+ X0 = _mm_loadu_si128((const __m128i *) &key[0]);
+ rkeys[i++] = X0;
+
+ X2 = _mm_loadu_si128((const __m128i *) &key[16]);
+ rkeys[i++] = X2;
+
+#define EXPAND_KEY_1(S) do { \
+ X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X2, (S)), 0xff); \
+ X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x10)); \
+ X0 = _mm_xor_si128(X0, X3); \
+ X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x8c)); \
+ X0 = _mm_xor_si128(_mm_xor_si128(X0, X3), X1); \
+ rkeys[i++] = X0; \
+} while (0)
+
+#define EXPAND_KEY_2(S) do { \
+ X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X0, (S)), 0xaa); \
+ X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x10)); \
+ X2 = _mm_xor_si128(X2, X3); \
+ X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x8c)); \
+ X2 = _mm_xor_si128(_mm_xor_si128(X2, X3), X1); \
+ rkeys[i++] = X2; \
+} while (0)
+
+ X3 = _mm_setzero_si128();
+ EXPAND_KEY_1(0x01); EXPAND_KEY_2(0x01);
+ EXPAND_KEY_1(0x02); EXPAND_KEY_2(0x02);
+ EXPAND_KEY_1(0x04); EXPAND_KEY_2(0x04);
+ EXPAND_KEY_1(0x08); EXPAND_KEY_2(0x08);
+ EXPAND_KEY_1(0x10); EXPAND_KEY_2(0x10);
+ EXPAND_KEY_1(0x20); EXPAND_KEY_2(0x20);
+ EXPAND_KEY_1(0x40);
+}
+
+/** single, by-the-book AES encryption with AES-NI */
+static inline void
+aesni_encrypt1(unsigned char *out, __m128i nv, const __m128i *rkeys)
+{
+ __m128i temp = _mm_xor_si128(nv, rkeys[0]);
+
+ temp = _mm_aesenc_si128(temp, rkeys[1]);
+ temp = _mm_aesenc_si128(temp, rkeys[2]);
+ temp = _mm_aesenc_si128(temp, rkeys[3]);
+ temp = _mm_aesenc_si128(temp, rkeys[4]);
+ temp = _mm_aesenc_si128(temp, rkeys[5]);
+ temp = _mm_aesenc_si128(temp, rkeys[6]);
+ temp = _mm_aesenc_si128(temp, rkeys[7]);
+ temp = _mm_aesenc_si128(temp, rkeys[8]);
+ temp = _mm_aesenc_si128(temp, rkeys[9]);
+ temp = _mm_aesenc_si128(temp, rkeys[10]);
+ temp = _mm_aesenc_si128(temp, rkeys[11]);
+ temp = _mm_aesenc_si128(temp, rkeys[12]);
+ temp = _mm_aesenc_si128(temp, rkeys[13]);
+
+ temp = _mm_aesenclast_si128(temp, rkeys[14]);
+ _mm_storeu_si128((__m128i *) out, temp);
+}
+
+/** multiple-blocks-at-once AES encryption with AES-NI ;
+ on Haswell, aesenc has a latency of 7 and a throughput of 1
+ so the sequence of aesenc should be bubble-free if you
+ have at least 8 blocks. Let's build an arbitratry-sized
+ function */
+/* Step 1 : loading the nonce */
+/* load & increment the n vector (non-vectorized, unused for now) */
+#define NVDECLx(a) \
+ __m128i nv##a
+
+#define NVx(a) \
+ nv##a = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) n), pt); \
+ n[3]++
+
+/* Step 2 : define value in round one (xor with subkey #0, aka key) */
+#define TEMPDECLx(a) \
+ __m128i temp##a
+
+#define TEMPx(a) \
+ temp##a = _mm_xor_si128(nv##a, rkeys[0])
+
+/* Step 3: one round of AES */
+#define AESENCx(a) \
+ temp##a = _mm_aesenc_si128(temp##a, rkeys[roundctr])
+
+/* Step 4: last round of AES */
+#define AESENCLASTx(a) \
+ temp##a = _mm_aesenclast_si128(temp##a, rkeys[14])
+
+/* Step 5: store result */
+#define STOREx(a) \
+ _mm_storeu_si128((__m128i *) (out + (a * 16)), temp##a)
+
+/* all the MAKE* macros are for automatic explicit unrolling */
+#define MAKE4(X) \
+ X(0); \
+ X(1); \
+ X(2); \
+ X(3)
+
+#define MAKE8(X) \
+ X(0); \
+ X(1); \
+ X(2); \
+ X(3); \
+ X(4); \
+ X(5); \
+ X(6); \
+ X(7)
+
+#define COUNTER_INC2(N) (N)[3] += 2
+
+/* create a function of unrolling N ; the MAKEN is the unrolling
+ macro, defined above. The N in MAKEN must match N, obviously. */
+#define FUNC(N, MAKEN) \
+ static inline void aesni_encrypt##N(unsigned char *out, uint32_t *n, const __m128i *rkeys) \
+ { \
+ const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+ int roundctr; \
+ MAKEN(NVDECLx); \
+ MAKEN(TEMPDECLx); \
+ \
+ MAKEN(NVx); \
+ MAKEN(TEMPx); \
+ for (roundctr = 1; roundctr < 14; roundctr++) { \
+ MAKEN(AESENCx); \
+ } \
+ MAKEN(AESENCLASTx); \
+ MAKEN(STOREx); \
+ }
+
+FUNC(8, MAKE8)
+
+/* all GF(2^128) fnctions are by the book, meaning this one:
+ <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf>
+*/
+
+static inline void
+addmul(unsigned char *c, const unsigned char *a, unsigned int xlen, const unsigned char *b)
+{
+ const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ __m128i A, B, C;
+ __m128i tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
+ __m128i tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18;
+ __m128i tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27;
+ __m128i tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36;
+
+ if (xlen >= 16) {
+ A = _mm_loadu_si128((const __m128i *) a);
+ } else {
+ CRYPTO_ALIGN(16) unsigned char padded[16];
+ unsigned int i;
+
+ memset(padded, 0, 16);
+ for (i = 0; i < xlen; i++) {
+ padded[i] = a[i];
+ }
+ A = _mm_load_si128((const __m128i *) padded);
+ }
+ A = _mm_shuffle_epi8(A, rev);
+ B = _mm_loadu_si128((const __m128i *) b);
+ C = _mm_loadu_si128((const __m128i *) c);
+ A = _mm_xor_si128(A, C);
+ tmp3 = _mm_clmulepi64_si128(A, B, 0x00);
+ tmp4 = _mm_clmulepi64_si128(A, B, 0x10);
+ tmp5 = _mm_clmulepi64_si128(A, B, 0x01);
+ tmp6 = _mm_clmulepi64_si128(A, B, 0x11);
+ tmp10 = _mm_xor_si128(tmp4, tmp5);
+ tmp13 = _mm_slli_si128(tmp10, 8);
+ tmp11 = _mm_srli_si128(tmp10, 8);
+ tmp15 = _mm_xor_si128(tmp3, tmp13);
+ tmp17 = _mm_xor_si128(tmp6, tmp11);
+ tmp7 = _mm_srli_epi32(tmp15, 31);
+ tmp8 = _mm_srli_epi32(tmp17, 31);
+ tmp16 = _mm_slli_epi32(tmp15, 1);
+ tmp18 = _mm_slli_epi32(tmp17, 1);
+ tmp9 = _mm_srli_si128(tmp7, 12);
+ tmp22 = _mm_slli_si128(tmp8, 4);
+ tmp25 = _mm_slli_si128(tmp7, 4);
+ tmp29 = _mm_or_si128(tmp16, tmp25);
+ tmp19 = _mm_or_si128(tmp18, tmp22);
+ tmp20 = _mm_or_si128(tmp19, tmp9);
+ tmp26 = _mm_slli_epi32(tmp29, 31);
+ tmp23 = _mm_slli_epi32(tmp29, 30);
+ tmp32 = _mm_slli_epi32(tmp29, 25);
+ tmp27 = _mm_xor_si128(tmp26, tmp23);
+ tmp28 = _mm_xor_si128(tmp27, tmp32);
+ tmp24 = _mm_srli_si128(tmp28, 4);
+ tmp33 = _mm_slli_si128(tmp28, 12);
+ tmp30 = _mm_xor_si128(tmp29, tmp33);
+ tmp2 = _mm_srli_epi32(tmp30, 1);
+ tmp12 = _mm_srli_epi32(tmp30, 2);
+ tmp14 = _mm_srli_epi32(tmp30, 7);
+ tmp34 = _mm_xor_si128(tmp2, tmp12);
+ tmp35 = _mm_xor_si128(tmp34, tmp14);
+ tmp36 = _mm_xor_si128(tmp35, tmp24);
+ tmp31 = _mm_xor_si128(tmp30, tmp36);
+ tmp21 = _mm_xor_si128(tmp20, tmp31);
+ _mm_storeu_si128((__m128i *) c, tmp21);
+}
+
+/* pure multiplication, for pre-computing powers of H */
+static inline __m128i
+mulv(__m128i A, __m128i B)
+{
+ __m128i tmp3 = _mm_clmulepi64_si128(A, B, 0x00);
+ __m128i tmp4 = _mm_clmulepi64_si128(A, B, 0x10);
+ __m128i tmp5 = _mm_clmulepi64_si128(A, B, 0x01);
+ __m128i tmp6 = _mm_clmulepi64_si128(A, B, 0x11);
+ __m128i tmp10 = _mm_xor_si128(tmp4, tmp5);
+ __m128i tmp13 = _mm_slli_si128(tmp10, 8);
+ __m128i tmp11 = _mm_srli_si128(tmp10, 8);
+ __m128i tmp15 = _mm_xor_si128(tmp3, tmp13);
+ __m128i tmp17 = _mm_xor_si128(tmp6, tmp11);
+ __m128i tmp7 = _mm_srli_epi32(tmp15, 31);
+ __m128i tmp8 = _mm_srli_epi32(tmp17, 31);
+ __m128i tmp16 = _mm_slli_epi32(tmp15, 1);
+ __m128i tmp18 = _mm_slli_epi32(tmp17, 1);
+ __m128i tmp9 = _mm_srli_si128(tmp7, 12);
+ __m128i tmp22 = _mm_slli_si128(tmp8, 4);
+ __m128i tmp25 = _mm_slli_si128(tmp7, 4);
+ __m128i tmp29 = _mm_or_si128(tmp16, tmp25);
+ __m128i tmp19 = _mm_or_si128(tmp18, tmp22);
+ __m128i tmp20 = _mm_or_si128(tmp19, tmp9);
+ __m128i tmp26 = _mm_slli_epi32(tmp29, 31);
+ __m128i tmp23 = _mm_slli_epi32(tmp29, 30);
+ __m128i tmp32 = _mm_slli_epi32(tmp29, 25);
+ __m128i tmp27 = _mm_xor_si128(tmp26, tmp23);
+ __m128i tmp28 = _mm_xor_si128(tmp27, tmp32);
+ __m128i tmp24 = _mm_srli_si128(tmp28, 4);
+ __m128i tmp33 = _mm_slli_si128(tmp28, 12);
+ __m128i tmp30 = _mm_xor_si128(tmp29, tmp33);
+ __m128i tmp2 = _mm_srli_epi32(tmp30, 1);
+ __m128i tmp12 = _mm_srli_epi32(tmp30, 2);
+ __m128i tmp14 = _mm_srli_epi32(tmp30, 7);
+ __m128i tmp34 = _mm_xor_si128(tmp2, tmp12);
+ __m128i tmp35 = _mm_xor_si128(tmp34, tmp14);
+ __m128i tmp36 = _mm_xor_si128(tmp35, tmp24);
+ __m128i tmp31 = _mm_xor_si128(tmp30, tmp36);
+ __m128i C = _mm_xor_si128(tmp20, tmp31);
+
+ return C;
+}
+
+/* 4 multiply-accumulate at once; again
+ <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf>
+ for the Aggregated Reduction Method & sample code.
+ Algorithm by Krzysztof Jankowski, Pierre Laurent - Intel */
+
+#define RED_DECL(a) __m128i H##a##_X##a##_lo, H##a##_X##a##_hi, tmp##a, tmp##a##B
+#define RED_SHUFFLE(a) X##a = _mm_shuffle_epi8(X##a, rev)
+#define RED_MUL_LOW(a) H##a##_X##a##_lo = _mm_clmulepi64_si128(H##a, X##a, 0x00)
+#define RED_MUL_HIGH(a) H##a##_X##a##_hi = _mm_clmulepi64_si128(H##a, X##a, 0x11)
+#define RED_MUL_MID(a) \
+ tmp##a = _mm_shuffle_epi32(H##a, 0x4e); \
+ tmp##a##B = _mm_shuffle_epi32(X##a, 0x4e); \
+ tmp##a = _mm_xor_si128(tmp##a, H##a); \
+ tmp##a##B = _mm_xor_si128(tmp##a##B, X##a); \
+ tmp##a = _mm_clmulepi64_si128(tmp##a, tmp##a##B, 0x00)
+
+#define MULREDUCE4(rev, H0_, H1_, H2_, H3_, X0_, X1_, X2_, X3_, accv) \
+do { \
+ MAKE4(RED_DECL); \
+ __m128i lo, hi; \
+ __m128i tmp8, tmp9; \
+ __m128i H0 = H0_; \
+ __m128i H1 = H1_; \
+ __m128i H2 = H2_; \
+ __m128i H3 = H3_; \
+ __m128i X0 = X0_; \
+ __m128i X1 = X1_; \
+ __m128i X2 = X2_; \
+ __m128i X3 = X3_; \
+\
+/* byte-revert the inputs & xor the first one into the accumulator */ \
+\
+ MAKE4(RED_SHUFFLE); \
+ X3 = _mm_xor_si128(X3, accv); \
+\
+/* 4 low H*X (x0*h0) */ \
+\
+ MAKE4(RED_MUL_LOW); \
+ lo = _mm_xor_si128(H0_X0_lo, H1_X1_lo); \
+ lo = _mm_xor_si128(lo, H2_X2_lo); \
+ lo = _mm_xor_si128(lo, H3_X3_lo); \
+\
+/* 4 high H*X (x1*h1) */ \
+\
+ MAKE4(RED_MUL_HIGH); \
+ hi = _mm_xor_si128(H0_X0_hi, H1_X1_hi); \
+ hi = _mm_xor_si128(hi, H2_X2_hi); \
+ hi = _mm_xor_si128(hi, H3_X3_hi); \
+\
+/* 4 middle H*X, using Karatsuba, i.e. \
+ x1*h0+x0*h1 =(x1+x0)*(h1+h0)-x1*h1-x0*h0 \
+ we already have all x1y1 & x0y0 (accumulated in hi & lo) \
+ (0 is low half and 1 is high half) \
+ */ \
+/* permute the high and low 64 bits in H1 & X1, \
+ so create (h0,h1) from (h1,h0) and (x0,x1) from (x1,x0), \
+ then compute (h0+h1,h1+h0) and (x0+x1,x1+x0), \
+ and finally multiply \
+ */ \
+ MAKE4(RED_MUL_MID); \
+\
+/* substracts x1*h1 and x0*h0 */ \
+ tmp0 = _mm_xor_si128(tmp0, lo); \
+ tmp0 = _mm_xor_si128(tmp0, hi); \
+ tmp0 = _mm_xor_si128(tmp1, tmp0); \
+ tmp0 = _mm_xor_si128(tmp2, tmp0); \
+ tmp0 = _mm_xor_si128(tmp3, tmp0);\
+\
+ /* reduction */ \
+ tmp0B = _mm_slli_si128(tmp0, 8); \
+ tmp0 = _mm_srli_si128(tmp0, 8); \
+ lo = _mm_xor_si128(tmp0B, lo); \
+ hi = _mm_xor_si128(tmp0, hi); \
+ tmp3 = lo; \
+ tmp2B = hi; \
+ tmp3B = _mm_srli_epi32(tmp3, 31); \
+ tmp8 = _mm_srli_epi32(tmp2B, 31); \
+ tmp3 = _mm_slli_epi32(tmp3, 1); \
+ tmp2B = _mm_slli_epi32(tmp2B, 1); \
+ tmp9 = _mm_srli_si128(tmp3B, 12); \
+ tmp8 = _mm_slli_si128(tmp8, 4); \
+ tmp3B = _mm_slli_si128(tmp3B, 4); \
+ tmp3 = _mm_or_si128(tmp3, tmp3B); \
+ tmp2B = _mm_or_si128(tmp2B, tmp8); \
+ tmp2B = _mm_or_si128(tmp2B, tmp9); \
+ tmp3B = _mm_slli_epi32(tmp3, 31); \
+ tmp8 = _mm_slli_epi32(tmp3, 30); \
+ tmp9 = _mm_slli_epi32(tmp3, 25); \
+ tmp3B = _mm_xor_si128(tmp3B, tmp8); \
+ tmp3B = _mm_xor_si128(tmp3B, tmp9); \
+ tmp8 = _mm_srli_si128(tmp3B, 4); \
+ tmp3B = _mm_slli_si128(tmp3B, 12); \
+ tmp3 = _mm_xor_si128(tmp3, tmp3B); \
+ tmp2 = _mm_srli_epi32(tmp3, 1); \
+ tmp0B = _mm_srli_epi32(tmp3, 2); \
+ tmp1B = _mm_srli_epi32(tmp3, 7); \
+ tmp2 = _mm_xor_si128(tmp2, tmp0B); \
+ tmp2 = _mm_xor_si128(tmp2, tmp1B); \
+ tmp2 = _mm_xor_si128(tmp2, tmp8); \
+ tmp3 = _mm_xor_si128(tmp3, tmp2); \
+ tmp2B = _mm_xor_si128(tmp2B, tmp3); \
+\
+ accv = tmp2B; \
+} while(0)
+
+#define XORx(a) \
+ temp##a = _mm_xor_si128(temp##a, \
+ _mm_loadu_si128((const __m128i *) (in + a * 16)))
+
+#define LOADx(a) \
+ __m128i in##a = _mm_loadu_si128((const __m128i *) (in + a * 16))
+
+/* full encrypt & checksum 8 blocks at once */
+#define aesni_encrypt8full(out_, n_, rkeys, in_, accum, hv_, h2v_, h3v_, h4v_, rev) \
+do { \
+ unsigned char *out = out_; \
+ uint32_t *n = n_; \
+ const unsigned char *in = in_; \
+ const __m128i hv = hv_; \
+ const __m128i h2v = h2v_; \
+ const __m128i h3v = h3v_; \
+ const __m128i h4v = h4v_; \
+ const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+ __m128i accv_; \
+ int roundctr; \
+ \
+ MAKE8(NVDECLx); \
+ MAKE8(TEMPDECLx); \
+ MAKE8(NVx); \
+ MAKE8(TEMPx); \
+ for (roundctr = 1; roundctr < 14; roundctr++) { \
+ MAKE8(AESENCx); \
+ } \
+ MAKE8(AESENCLASTx); \
+ MAKE8(XORx); \
+ MAKE8(STOREx); \
+ accv_ = _mm_load_si128((const __m128i *) accum); \
+ MULREDUCE4(rev, hv, h2v, h3v, h4v, temp3, temp2, temp1, temp0, accv_); \
+ MULREDUCE4(rev, hv, h2v, h3v, h4v, temp7, temp6, temp5, temp4, accv_); \
+ _mm_store_si128((__m128i *) accum, accv_); \
+} while(0)
+
+/* checksum 8 blocks at once */
+#define aesni_addmul8full(in_, accum, hv_, h2v_, h3v_, h4v_, rev) \
+do { \
+ const unsigned char *in = in_; \
+ const __m128i hv = hv_; \
+ const __m128i h2v = h2v_; \
+ const __m128i h3v = h3v_; \
+ const __m128i h4v = h4v_; \
+ __m128i accv_; \
+ \
+ MAKE8(LOADx); \
+ accv_ = _mm_load_si128((const __m128i *) accum); \
+ MULREDUCE4(rev, hv, h2v, h3v, h4v, in3, in2, in1, in0, accv_); \
+ MULREDUCE4(rev, hv, h2v, h3v, h4v, in7, in6, in5, in4, accv_); \
+ _mm_store_si128((__m128i *) accum, accv_); \
+} while(0)
+
+/* decrypt 8 blocks at once */
+#define aesni_decrypt8full(out_, n_, rkeys, in_) \
+do { \
+ unsigned char *out = out_; \
+ uint32_t *n = n_; \
+ const unsigned char *in = in_; \
+ const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+ int roundctr; \
+\
+ MAKE8(NVDECLx); \
+ MAKE8(TEMPDECLx); \
+ MAKE8(NVx); \
+ MAKE8(TEMPx); \
+ for (roundctr = 1; roundctr < 14; roundctr++) { \
+ MAKE8(AESENCx); \
+ } \
+ MAKE8(AESENCLASTx); \
+ MAKE8(XORx); \
+ MAKE8(STOREx); \
+} while(0)
+
+int
+crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
+ const unsigned char *k)
+{
+ context *ctx = (context *) ctx_;
+ __m128i *rkeys = ctx->rkeys;
+ __m128i zero = _mm_setzero_si128();
+ unsigned char *H = ctx->H;
+
+ COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx));
+ aesni_key256_expand(k, rkeys);
+ aesni_encrypt1(H, zero, rkeys);
+
+ return 0;
+}
+
+int
+crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
+ unsigned char *mac, unsigned long long *maclen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ const context *ctx = (const context *) ctx_;
+ const __m128i *rkeys = ctx->rkeys;
+ __m128i Hv, H2v, H3v, H4v, accv;
+ unsigned long long i, j;
+ unsigned long long adlen_rnd64 = adlen & ~63ULL;
+ unsigned long long mlen_rnd128 = mlen & ~127ULL;
+ CRYPTO_ALIGN(16) uint32_t n2[4];
+ CRYPTO_ALIGN(16) unsigned char H[16];
+ CRYPTO_ALIGN(16) unsigned char T[16];
+ CRYPTO_ALIGN(16) unsigned char accum[16];
+ CRYPTO_ALIGN(16) unsigned char fb[16];
+
+ (void) nsec;
+ memcpy(H, ctx->H, sizeof H);
+ if (mlen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ memcpy(&n2[0], npub, 3 * 4);
+ n2[3] = 0x01000000;
+ aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys);
+ {
+ uint64_t x;
+ x = _bswap64((uint64_t) (8 * adlen));
+ memcpy(&fb[0], &x, sizeof x);
+ x = _bswap64((uint64_t) (8 * mlen));
+ memcpy(&fb[8], &x, sizeof x);
+ }
+ /* we store H (and it's power) byte-reverted once and for all */
+ Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev);
+ _mm_store_si128((__m128i *) H, Hv);
+ H2v = mulv(Hv, Hv);
+ H3v = mulv(H2v, Hv);
+ H4v = mulv(H3v, Hv);
+
+ accv = _mm_setzero_si128();
+ /* unrolled by 4 GCM (by 8 doesn't improve using MULREDUCE4) */
+ for (i = 0; i < adlen_rnd64; i += 64) {
+ __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0));
+ __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16));
+ __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32));
+ __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48));
+ MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv);
+ }
+ _mm_store_si128((__m128i *) accum, accv);
+
+ /* GCM remainder loop */
+ for (i = adlen_rnd64; i < adlen; i += 16) {
+ unsigned int blocklen = 16;
+
+ if (i + (unsigned long long) blocklen > adlen) {
+ blocklen = (unsigned int) (adlen - i);
+ }
+ addmul(accum, ad + i, blocklen, H);
+ }
+
+/* this only does 8 full blocks, so no fancy bounds checking is necessary*/
+#define LOOPRND128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ \
+ for (i = 0; i < mlen_rnd128; i += lb) { \
+ aesni_encrypt8full(c + i, n2, rkeys, m + i, accum, Hv, H2v, H3v, H4v, rev); \
+ } \
+ } while(0)
+
+/* remainder loop, with the slower GCM update to accommodate partial blocks */
+#define LOOPRMD128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ \
+ for (i = mlen_rnd128; i < mlen; i += lb) { \
+ CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \
+ unsigned long long mj = lb; \
+ \
+ aesni_encrypt8(outni, n2, rkeys); \
+ if ((i + mj) >= mlen) { \
+ mj = mlen - i; \
+ } \
+ for (j = 0; j < mj; j++) { \
+ c[i + j] = m[i + j] ^ outni[j]; \
+ } \
+ for (j = 0; j < mj; j += 16) { \
+ unsigned int bl = 16; \
+ \
+ if (j + (unsigned long long) bl >= mj) { \
+ bl = (unsigned int) (mj - j); \
+ } \
+ addmul(accum, c + i + j, bl, H); \
+ } \
+ } \
+ } while(0)
+
+ n2[3] &= 0x00ffffff;
+ COUNTER_INC2(n2);
+ LOOPRND128;
+ LOOPRMD128;
+
+ addmul(accum, fb, 16, H);
+
+ for (i = 0; i < 16; ++i) {
+ mac[i] = T[i] ^ accum[15 - i];
+ }
+ if (maclen_p != NULL) {
+ *maclen_p = 16;
+ }
+ return 0;
+}
+
+int
+crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c,
+ c + mlen, NULL,
+ m, mlen,
+ ad, adlen,
+ nsec, npub, ctx_);
+ if (clen_p != NULL) {
+ *clen_p = mlen + crypto_aead_aes256gcm_ABYTES;
+ }
+ return ret;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ const context *ctx = (const context *) ctx_;
+ const __m128i *rkeys = ctx->rkeys;
+ __m128i Hv, H2v, H3v, H4v, accv;
+ unsigned long long i, j;
+ unsigned long long adlen_rnd64 = adlen & ~63ULL;
+ unsigned long long mlen;
+ unsigned long long mlen_rnd128;
+ CRYPTO_ALIGN(16) uint32_t n2[4];
+ CRYPTO_ALIGN(16) unsigned char H[16];
+ CRYPTO_ALIGN(16) unsigned char T[16];
+ CRYPTO_ALIGN(16) unsigned char accum[16];
+ CRYPTO_ALIGN(16) unsigned char fb[16];
+
+ (void) nsec;
+ if (clen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ mlen = clen;
+
+ memcpy(&n2[0], npub, 3 * 4);
+ n2[3] = 0x01000000;
+ aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys);
+
+ {
+ uint64_t x;
+ x = _bswap64((uint64_t)(8 * adlen));
+ memcpy(&fb[0], &x, sizeof x);
+ x = _bswap64((uint64_t)(8 * mlen));
+ memcpy(&fb[8], &x, sizeof x);
+ }
+
+ memcpy(H, ctx->H, sizeof H);
+ Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev);
+ _mm_store_si128((__m128i *) H, Hv);
+ H2v = mulv(Hv, Hv);
+ H3v = mulv(H2v, Hv);
+ H4v = mulv(H3v, Hv);
+
+ accv = _mm_setzero_si128();
+ for (i = 0; i < adlen_rnd64; i += 64) {
+ __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0));
+ __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16));
+ __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32));
+ __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48));
+ MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv);
+ }
+ _mm_store_si128((__m128i *) accum, accv);
+
+ for (i = adlen_rnd64; i < adlen; i += 16) {
+ unsigned int blocklen = 16;
+ if (i + (unsigned long long) blocklen > adlen) {
+ blocklen = (unsigned int) (adlen - i);
+ }
+ addmul(accum, ad + i, blocklen, H);
+ }
+
+ mlen_rnd128 = mlen & ~127ULL;
+
+#define LOOPACCUMDRND128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ for (i = 0; i < mlen_rnd128; i += lb) { \
+ aesni_addmul8full(c + i, accum, Hv, H2v, H3v, H4v, rev); \
+ } \
+ } while(0)
+
+#define LOOPDRND128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ \
+ for (i = 0; i < mlen_rnd128; i += lb) { \
+ aesni_decrypt8full(m + i, n2, rkeys, c + i); \
+ } \
+ } while(0)
+
+#define LOOPACCUMDRMD128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ \
+ for (i = mlen_rnd128; i < mlen; i += lb) { \
+ unsigned long long mj = lb; \
+ \
+ if ((i + mj) >= mlen) { \
+ mj = mlen - i; \
+ } \
+ for (j = 0; j < mj; j += 16) { \
+ unsigned int bl = 16; \
+ \
+ if (j + (unsigned long long) bl >= mj) { \
+ bl = (unsigned int) (mj - j); \
+ } \
+ addmul(accum, c + i + j, bl, H); \
+ } \
+ } \
+ } while(0)
+
+#define LOOPDRMD128 \
+ do { \
+ const int iter = 8; \
+ const int lb = iter * 16; \
+ \
+ for (i = mlen_rnd128; i < mlen; i += lb) { \
+ CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \
+ unsigned long long mj = lb; \
+ \
+ if ((i + mj) >= mlen) { \
+ mj = mlen - i; \
+ } \
+ aesni_encrypt8(outni, n2, rkeys); \
+ for (j = 0; j < mj; j++) { \
+ m[i + j] = c[i + j] ^ outni[j]; \
+ } \
+ } \
+ } while(0)
+
+ n2[3] &= 0x00ffffff;
+
+ COUNTER_INC2(n2);
+ LOOPACCUMDRND128;
+ LOOPACCUMDRMD128;
+ addmul(accum, fb, 16, H);
+ {
+ unsigned char d = 0;
+
+ for (i = 0; i < 16; i++) {
+ d |= (mac[i] ^ (T[i] ^ accum[15 - i]));
+ }
+ if (d != 0) {
+ if (m != NULL) {
+ memset(m, 0, mlen);
+ }
+ return -1;
+ }
+ if (m == NULL) {
+ return 0;
+ }
+ }
+ n2[3] = 0U;
+ COUNTER_INC2(n2);
+ LOOPDRND128;
+ LOOPDRMD128;
+
+ return 0;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ unsigned long long mlen = 0ULL;
+ int ret = -1;
+
+ if (clen >= crypto_aead_aes256gcm_ABYTES) {
+ ret = crypto_aead_aes256gcm_decrypt_detached_afternm
+ (m, nsec, c, clen - crypto_aead_aes256gcm_ABYTES,
+ c + clen - crypto_aead_aes256gcm_ABYTES,
+ ad, adlen, npub, ctx_);
+ }
+ if (mlen_p != NULL) {
+ if (ret == 0) {
+ mlen = clen - crypto_aead_aes256gcm_ABYTES;
+ }
+ *mlen_p = mlen;
+ }
+ return ret;
+}
+
+int
+crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
+
+ crypto_aead_aes256gcm_beforenm(&ctx, k);
+
+ return crypto_aead_aes256gcm_encrypt_detached_afternm
+ (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub,
+ (const crypto_aead_aes256gcm_state *) &ctx);
+}
+
+int
+crypto_aead_aes256gcm_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
+ int ret;
+
+ crypto_aead_aes256gcm_beforenm(&ctx, k);
+
+ ret = crypto_aead_aes256gcm_encrypt_afternm
+ (c, clen_p, m, mlen, ad, adlen, nsec, npub,
+ (const crypto_aead_aes256gcm_state *) &ctx);
+ sodium_memzero(ctx, sizeof ctx);
+
+ return ret;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
+
+ crypto_aead_aes256gcm_beforenm(&ctx, k);
+
+ return crypto_aead_aes256gcm_decrypt_detached_afternm
+ (m, nsec, c, clen, mac, ad, adlen, npub,
+ (const crypto_aead_aes256gcm_state *) &ctx);
+}
+
+int
+crypto_aead_aes256gcm_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx;
+ int ret;
+
+ crypto_aead_aes256gcm_beforenm(&ctx, k);
+
+ ret = crypto_aead_aes256gcm_decrypt_afternm
+ (m, mlen_p, nsec, c, clen, ad, adlen, npub,
+ (const crypto_aead_aes256gcm_state *) &ctx);
+ sodium_memzero(ctx, sizeof ctx);
+
+ return ret;
+}
+
+int
+crypto_aead_aes256gcm_is_available(void)
+{
+ return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni();
+}
+
+#else
+
+int
+crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *nsec, const unsigned char *npub,
+ const unsigned char *k)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p,
+ unsigned char *nsec, const unsigned char *c,
+ unsigned long long clen, const unsigned char *ad,
+ unsigned long long adlen, const unsigned char *npub,
+ const unsigned char *k)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
+ const unsigned char *k)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
+ unsigned char *mac, unsigned long long *maclen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *nsec, const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *ad, unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+crypto_aead_aes256gcm_is_available(void)
+{
+ return 0;
+}
+
+#endif
+
+size_t
+crypto_aead_aes256gcm_keybytes(void)
+{
+ return crypto_aead_aes256gcm_KEYBYTES;
+}
+
+size_t
+crypto_aead_aes256gcm_nsecbytes(void)
+{
+ return crypto_aead_aes256gcm_NSECBYTES;
+}
+
+size_t
+crypto_aead_aes256gcm_npubbytes(void)
+{
+ return crypto_aead_aes256gcm_NPUBBYTES;
+}
+
+size_t
+crypto_aead_aes256gcm_abytes(void)
+{
+ return crypto_aead_aes256gcm_ABYTES;
+}
+
+size_t
+crypto_aead_aes256gcm_statebytes(void)
+{
+ return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U;
+}
+
+size_t
+crypto_aead_aes256gcm_messagebytes_max(void)
+{
+ return crypto_aead_aes256gcm_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES])
+{
+ randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c b/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
new file mode 100644
index 0000000000..c79407a185
--- /dev/null
+++ b/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
@@ -0,0 +1,399 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_aead_chacha20poly1305.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_stream_chacha20.h"
+#include "crypto_verify_16.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#include "private/common.h"
+
+static const unsigned char _pad0[16] = { 0 };
+
+int
+crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char slen[8U];
+
+ (void) nsec;
+ crypto_stream_chacha20(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k);
+
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ STORE64_LE(slen, (uint64_t) mlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ crypto_onetimeauth_poly1305_final(&state, mac);
+ sodium_memzero(&state, sizeof state);
+
+ if (maclen_p != NULL) {
+ *maclen_p = crypto_aead_chacha20poly1305_ABYTES;
+ }
+ return 0;
+}
+
+int
+crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long clen = 0ULL;
+ int ret;
+
+ if (mlen > crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ ret = crypto_aead_chacha20poly1305_encrypt_detached(c,
+ c + mlen, NULL,
+ m, mlen,
+ ad, adlen,
+ nsec, npub, k);
+ if (clen_p != NULL) {
+ if (ret == 0) {
+ clen = mlen + crypto_aead_chacha20poly1305_ABYTES;
+ }
+ *clen_p = clen;
+ }
+ return ret;
+}
+
+int
+crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char slen[8U];
+
+ (void) nsec;
+ crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf);
+
+ crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k);
+
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ STORE64_LE(slen, (uint64_t) mlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ crypto_onetimeauth_poly1305_final(&state, mac);
+ sodium_memzero(&state, sizeof state);
+
+ if (maclen_p != NULL) {
+ *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES;
+ }
+ return 0;
+}
+
+int
+crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long clen = 0ULL;
+ int ret;
+
+ if (mlen > crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c,
+ c + mlen, NULL,
+ m, mlen,
+ ad, adlen,
+ nsec, npub, k);
+ if (clen_p != NULL) {
+ if (ret == 0) {
+ clen = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES;
+ }
+ *clen_p = clen;
+ }
+ return ret;
+}
+
+int
+crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char slen[8U];
+ unsigned char computed_mac[crypto_aead_chacha20poly1305_ABYTES];
+ unsigned long long mlen;
+ int ret;
+
+ (void) nsec;
+ crypto_stream_chacha20(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ mlen = clen;
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ STORE64_LE(slen, (uint64_t) mlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ crypto_onetimeauth_poly1305_final(&state, computed_mac);
+ sodium_memzero(&state, sizeof state);
+
+ COMPILER_ASSERT(sizeof computed_mac == 16U);
+ ret = crypto_verify_16(computed_mac, mac);
+ sodium_memzero(computed_mac, sizeof computed_mac);
+ if (m == NULL) {
+ return ret;
+ }
+ if (ret != 0) {
+ memset(m, 0, mlen);
+ return -1;
+ }
+ crypto_stream_chacha20_xor_ic(m, c, mlen, npub, 1U, k);
+
+ return 0;
+}
+
+int
+crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long mlen = 0ULL;
+ int ret = -1;
+
+ if (clen >= crypto_aead_chacha20poly1305_ABYTES) {
+ ret = crypto_aead_chacha20poly1305_decrypt_detached
+ (m, nsec,
+ c, clen - crypto_aead_chacha20poly1305_ABYTES,
+ c + clen - crypto_aead_chacha20poly1305_ABYTES,
+ ad, adlen, npub, k);
+ }
+ if (mlen_p != NULL) {
+ if (ret == 0) {
+ mlen = clen - crypto_aead_chacha20poly1305_ABYTES;
+ }
+ *mlen_p = mlen;
+ }
+ return ret;
+}
+
+int
+crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char slen[8U];
+ unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES];
+ unsigned long long mlen;
+ int ret;
+
+ (void) nsec;
+ crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+ sodium_memzero(block0, sizeof block0);
+
+ crypto_onetimeauth_poly1305_update(&state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf);
+
+ mlen = clen;
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ STORE64_LE(slen, (uint64_t) mlen);
+ crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen);
+
+ crypto_onetimeauth_poly1305_final(&state, computed_mac);
+ sodium_memzero(&state, sizeof state);
+
+ COMPILER_ASSERT(sizeof computed_mac == 16U);
+ ret = crypto_verify_16(computed_mac, mac);
+ sodium_memzero(computed_mac, sizeof computed_mac);
+ if (m == NULL) {
+ return ret;
+ }
+ if (ret != 0) {
+ memset(m, 0, mlen);
+ return -1;
+ }
+ crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k);
+
+ return 0;
+}
+
+int
+crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long mlen = 0ULL;
+ int ret = -1;
+
+ if (clen >= crypto_aead_chacha20poly1305_ietf_ABYTES) {
+ ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached
+ (m, nsec,
+ c, clen - crypto_aead_chacha20poly1305_ietf_ABYTES,
+ c + clen - crypto_aead_chacha20poly1305_ietf_ABYTES,
+ ad, adlen, npub, k);
+ }
+ if (mlen_p != NULL) {
+ if (ret == 0) {
+ mlen = clen - crypto_aead_chacha20poly1305_ietf_ABYTES;
+ }
+ *mlen_p = mlen;
+ }
+ return ret;
+}
+
+size_t
+crypto_aead_chacha20poly1305_ietf_keybytes(void)
+{
+ return crypto_aead_chacha20poly1305_ietf_KEYBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_ietf_npubbytes(void)
+{
+ return crypto_aead_chacha20poly1305_ietf_NPUBBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_ietf_nsecbytes(void)
+{
+ return crypto_aead_chacha20poly1305_ietf_NSECBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_ietf_abytes(void)
+{
+ return crypto_aead_chacha20poly1305_ietf_ABYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_ietf_messagebytes_max(void)
+{
+ return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES])
+{
+ randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES);
+}
+
+size_t
+crypto_aead_chacha20poly1305_keybytes(void)
+{
+ return crypto_aead_chacha20poly1305_KEYBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_npubbytes(void)
+{
+ return crypto_aead_chacha20poly1305_NPUBBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_nsecbytes(void)
+{
+ return crypto_aead_chacha20poly1305_NSECBYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_abytes(void)
+{
+ return crypto_aead_chacha20poly1305_ABYTES;
+}
+
+size_t
+crypto_aead_chacha20poly1305_messagebytes_max(void)
+{
+ return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES])
+{
+ randombytes_buf(k, crypto_aead_chacha20poly1305_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c
new file mode 100644
index 0000000000..c18cdf9458
--- /dev/null
+++ b/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c
@@ -0,0 +1,160 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_aead_xchacha20poly1305.h"
+#include "crypto_aead_chacha20poly1305.h"
+#include "crypto_core_hchacha20.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#include "private/common.h"
+
+int
+crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
+ unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 };
+ int ret;
+
+ crypto_core_hchacha20(k2, npub, k, NULL);
+ memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES,
+ crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4);
+ ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached
+ (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub2, k2);
+ sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
+
+ return ret;
+}
+
+int
+crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long clen = 0ULL;
+ int ret;
+
+ if (mlen > UINT64_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES) {
+ sodium_misuse();
+ }
+ ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached
+ (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k);
+ if (clen_p != NULL) {
+ if (ret == 0) {
+ clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES;
+ }
+ *clen_p = clen;
+ }
+ return ret;
+}
+
+int
+crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
+ unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 };
+ int ret;
+
+ crypto_core_hchacha20(k2, npub, k, NULL);
+ memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES,
+ crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4);
+ ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached
+ (m, nsec, c, clen, mac, ad, adlen, npub2, k2);
+ sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES);
+
+ return ret;
+
+}
+
+int
+crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+{
+ unsigned long long mlen = 0ULL;
+ int ret = -1;
+
+ if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) {
+ ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached
+ (m, nsec,
+ c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES,
+ c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES,
+ ad, adlen, npub, k);
+ }
+ if (mlen_p != NULL) {
+ if (ret == 0) {
+ mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES;
+ }
+ *mlen_p = mlen;
+ }
+ return ret;
+}
+
+size_t
+crypto_aead_xchacha20poly1305_ietf_keybytes(void)
+{
+ return crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
+}
+
+size_t
+crypto_aead_xchacha20poly1305_ietf_npubbytes(void)
+{
+ return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
+}
+
+size_t
+crypto_aead_xchacha20poly1305_ietf_nsecbytes(void)
+{
+ return crypto_aead_xchacha20poly1305_ietf_NSECBYTES;
+}
+
+size_t
+crypto_aead_xchacha20poly1305_ietf_abytes(void)
+{
+ return crypto_aead_xchacha20poly1305_ietf_ABYTES;
+}
+
+size_t
+crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void)
+{
+ return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES])
+{
+ randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_auth/crypto_auth.c b/libs/libsodium/src/crypto_auth/crypto_auth.c
new file mode 100644
index 0000000000..d061c8c1c5
--- /dev/null
+++ b/libs/libsodium/src/crypto_auth/crypto_auth.c
@@ -0,0 +1,41 @@
+
+#include "crypto_auth.h"
+#include "randombytes.h"
+
+size_t
+crypto_auth_bytes(void)
+{
+ return crypto_auth_BYTES;
+}
+
+size_t
+crypto_auth_keybytes(void)
+{
+ return crypto_auth_KEYBYTES;
+}
+
+const char *
+crypto_auth_primitive(void)
+{
+ return crypto_auth_PRIMITIVE;
+}
+
+int
+crypto_auth(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ return crypto_auth_hmacsha512256(out, in, inlen, k);
+}
+
+int
+crypto_auth_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen,const unsigned char *k)
+{
+ return crypto_auth_hmacsha512256_verify(h, in, inlen, k);
+}
+
+void
+crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES])
+{
+ randombytes_buf(k, crypto_auth_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c b/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c
new file mode 100644
index 0000000000..a951e932b8
--- /dev/null
+++ b/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c
@@ -0,0 +1,118 @@
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_auth_hmacsha256.h"
+#include "crypto_hash_sha256.h"
+#include "crypto_verify_32.h"
+#include "randombytes.h"
+#include "utils.h"
+
+size_t
+crypto_auth_hmacsha256_bytes(void)
+{
+ return crypto_auth_hmacsha256_BYTES;
+}
+
+size_t
+crypto_auth_hmacsha256_keybytes(void)
+{
+ return crypto_auth_hmacsha256_KEYBYTES;
+}
+
+size_t
+crypto_auth_hmacsha256_statebytes(void)
+{
+ return sizeof(crypto_auth_hmacsha256_state);
+}
+
+void
+crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES])
+{
+ randombytes_buf(k, crypto_auth_hmacsha256_KEYBYTES);
+}
+
+int
+crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
+ const unsigned char *key, size_t keylen)
+{
+ unsigned char pad[64];
+ unsigned char khash[32];
+ size_t i;
+
+ if (keylen > 64) {
+ crypto_hash_sha256_init(&state->ictx);
+ crypto_hash_sha256_update(&state->ictx, key, keylen);
+ crypto_hash_sha256_final(&state->ictx, khash);
+ key = khash;
+ keylen = 32;
+ }
+ crypto_hash_sha256_init(&state->ictx);
+ memset(pad, 0x36, 64);
+ for (i = 0; i < keylen; i++) {
+ pad[i] ^= key[i];
+ }
+ crypto_hash_sha256_update(&state->ictx, pad, 64);
+
+ crypto_hash_sha256_init(&state->octx);
+ memset(pad, 0x5c, 64);
+ for (i = 0; i < keylen; i++) {
+ pad[i] ^= key[i];
+ }
+ crypto_hash_sha256_update(&state->octx, pad, 64);
+
+ sodium_memzero((void *) pad, sizeof pad);
+ sodium_memzero((void *) khash, sizeof khash);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
+ const unsigned char *in, unsigned long long inlen)
+{
+ crypto_hash_sha256_update(&state->ictx, in, inlen);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
+ unsigned char *out)
+{
+ unsigned char ihash[32];
+
+ crypto_hash_sha256_final(&state->ictx, ihash);
+ crypto_hash_sha256_update(&state->octx, ihash, 32);
+ crypto_hash_sha256_final(&state->octx, out);
+
+ sodium_memzero((void *) ihash, sizeof ihash);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha256(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ crypto_auth_hmacsha256_state state;
+
+ crypto_auth_hmacsha256_init(&state, k, crypto_auth_hmacsha256_KEYBYTES);
+ crypto_auth_hmacsha256_update(&state, in, inlen);
+ crypto_auth_hmacsha256_final(&state, out);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha256_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ unsigned char correct[32];
+
+ crypto_auth_hmacsha256(correct, in, inlen, k);
+
+ return crypto_verify_32(h, correct) | (-(h == correct)) |
+ sodium_memcmp(correct, h, 32);
+}
diff --git a/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c b/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c
new file mode 100644
index 0000000000..018d7a4e87
--- /dev/null
+++ b/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c
@@ -0,0 +1,118 @@
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_auth_hmacsha512.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_64.h"
+#include "randombytes.h"
+#include "utils.h"
+
+size_t
+crypto_auth_hmacsha512_bytes(void)
+{
+ return crypto_auth_hmacsha512_BYTES;
+}
+
+size_t
+crypto_auth_hmacsha512_keybytes(void)
+{
+ return crypto_auth_hmacsha512_KEYBYTES;
+}
+
+size_t
+crypto_auth_hmacsha512_statebytes(void)
+{
+ return sizeof(crypto_auth_hmacsha512_state);
+}
+
+void
+crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES])
+{
+ randombytes_buf(k, crypto_auth_hmacsha512_KEYBYTES);
+}
+
+int
+crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
+ const unsigned char *key, size_t keylen)
+{
+ unsigned char pad[128];
+ unsigned char khash[64];
+ size_t i;
+
+ if (keylen > 128) {
+ crypto_hash_sha512_init(&state->ictx);
+ crypto_hash_sha512_update(&state->ictx, key, keylen);
+ crypto_hash_sha512_final(&state->ictx, khash);
+ key = khash;
+ keylen = 64;
+ }
+ crypto_hash_sha512_init(&state->ictx);
+ memset(pad, 0x36, 128);
+ for (i = 0; i < keylen; i++) {
+ pad[i] ^= key[i];
+ }
+ crypto_hash_sha512_update(&state->ictx, pad, 128);
+
+ crypto_hash_sha512_init(&state->octx);
+ memset(pad, 0x5c, 128);
+ for (i = 0; i < keylen; i++) {
+ pad[i] ^= key[i];
+ }
+ crypto_hash_sha512_update(&state->octx, pad, 128);
+
+ sodium_memzero((void *) pad, sizeof pad);
+ sodium_memzero((void *) khash, sizeof khash);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
+ const unsigned char *in, unsigned long long inlen)
+{
+ crypto_hash_sha512_update(&state->ictx, in, inlen);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
+ unsigned char *out)
+{
+ unsigned char ihash[64];
+
+ crypto_hash_sha512_final(&state->ictx, ihash);
+ crypto_hash_sha512_update(&state->octx, ihash, 64);
+ crypto_hash_sha512_final(&state->octx, out);
+
+ sodium_memzero((void *) ihash, sizeof ihash);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ crypto_auth_hmacsha512_state state;
+
+ crypto_auth_hmacsha512_init(&state, k, crypto_auth_hmacsha512_KEYBYTES);
+ crypto_auth_hmacsha512_update(&state, in, inlen);
+ crypto_auth_hmacsha512_final(&state, out);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ unsigned char correct[64];
+
+ crypto_auth_hmacsha512(correct, in, inlen, k);
+
+ return crypto_verify_64(h, correct) | (-(h == correct)) |
+ sodium_memcmp(correct, h, 64);
+}
diff --git a/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c b/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c
new file mode 100644
index 0000000000..432d6dbee5
--- /dev/null
+++ b/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c
@@ -0,0 +1,93 @@
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_auth_hmacsha512.h"
+#include "crypto_auth_hmacsha512256.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "randombytes.h"
+#include "utils.h"
+
+size_t
+crypto_auth_hmacsha512256_bytes(void)
+{
+ return crypto_auth_hmacsha512256_BYTES;
+}
+
+size_t
+crypto_auth_hmacsha512256_keybytes(void)
+{
+ return crypto_auth_hmacsha512256_KEYBYTES;
+}
+
+size_t
+crypto_auth_hmacsha512256_statebytes(void)
+{
+ return sizeof(crypto_auth_hmacsha512256_state);
+}
+
+void
+crypto_auth_hmacsha512256_keygen(
+ unsigned char k[crypto_auth_hmacsha512256_KEYBYTES])
+{
+ randombytes_buf(k, crypto_auth_hmacsha512256_KEYBYTES);
+}
+
+int
+crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
+ const unsigned char *key, size_t keylen)
+{
+ return crypto_auth_hmacsha512_init((crypto_auth_hmacsha512_state *) state,
+ key, keylen);
+}
+
+int
+crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
+ const unsigned char *in,
+ unsigned long long inlen)
+{
+ return crypto_auth_hmacsha512_update((crypto_auth_hmacsha512_state *) state,
+ in, inlen);
+}
+
+int
+crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
+ unsigned char *out)
+{
+ unsigned char out0[64];
+
+ crypto_auth_hmacsha512_final((crypto_auth_hmacsha512_state *) state, out0);
+ memcpy(out, out0, 32);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ crypto_auth_hmacsha512256_state state;
+
+ crypto_auth_hmacsha512256_init(&state, k,
+ crypto_auth_hmacsha512256_KEYBYTES);
+ crypto_auth_hmacsha512256_update(&state, in, inlen);
+ crypto_auth_hmacsha512256_final(&state, out);
+
+ return 0;
+}
+
+int
+crypto_auth_hmacsha512256_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+{
+ unsigned char correct[32];
+
+ crypto_auth_hmacsha512256(correct, in, inlen, k);
+
+ return crypto_verify_32(h, correct) | (-(h == correct)) |
+ sodium_memcmp(correct, h, 32);
+}
diff --git a/libs/libsodium/src/crypto_box/crypto_box.c b/libs/libsodium/src/crypto_box/crypto_box.c
new file mode 100644
index 0000000000..7e4f00bd15
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/crypto_box.c
@@ -0,0 +1,114 @@
+
+#include "crypto_box.h"
+
+size_t
+crypto_box_seedbytes(void)
+{
+ return crypto_box_SEEDBYTES;
+}
+
+size_t
+crypto_box_publickeybytes(void)
+{
+ return crypto_box_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_box_secretkeybytes(void)
+{
+ return crypto_box_SECRETKEYBYTES;
+}
+
+size_t
+crypto_box_beforenmbytes(void)
+{
+ return crypto_box_BEFORENMBYTES;
+}
+
+size_t
+crypto_box_noncebytes(void)
+{
+ return crypto_box_NONCEBYTES;
+}
+
+size_t
+crypto_box_zerobytes(void)
+{
+ return crypto_box_ZEROBYTES;
+}
+
+size_t
+crypto_box_boxzerobytes(void)
+{
+ return crypto_box_BOXZEROBYTES;
+}
+
+size_t
+crypto_box_macbytes(void)
+{
+ return crypto_box_MACBYTES;
+}
+
+size_t
+crypto_box_messagebytes_max(void)
+{
+ return crypto_box_MESSAGEBYTES_MAX;
+}
+
+const char *
+crypto_box_primitive(void)
+{
+ return crypto_box_PRIMITIVE;
+}
+
+int
+crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed)
+{
+ return crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk, sk, seed);
+}
+
+int
+crypto_box_keypair(unsigned char *pk, unsigned char *sk)
+{
+ return crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk);
+}
+
+int
+crypto_box_beforenm(unsigned char *k, const unsigned char *pk,
+ const unsigned char *sk)
+{
+ return crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk);
+}
+
+int
+crypto_box_afternm(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k);
+}
+
+int
+crypto_box_open_afternm(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k);
+}
+
+int
+crypto_box(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ return crypto_box_curve25519xsalsa20poly1305(c, m, mlen, n, pk, sk);
+}
+
+int
+crypto_box_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ return crypto_box_curve25519xsalsa20poly1305_open(m, c, clen, n, pk, sk);
+}
diff --git a/libs/libsodium/src/crypto_box/crypto_box_easy.c b/libs/libsodium/src/crypto_box/crypto_box_easy.c
new file mode 100644
index 0000000000..deb40b4083
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/crypto_box_easy.c
@@ -0,0 +1,115 @@
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "core.h"
+#include "crypto_box.h"
+#include "crypto_secretbox.h"
+#include "private/common.h"
+#include "utils.h"
+
+int
+crypto_box_detached_afternm(unsigned char *c, unsigned char *mac,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *n, const unsigned char *k)
+{
+ return crypto_secretbox_detached(c, mac, m, mlen, n, k);
+}
+
+int
+crypto_box_detached(unsigned char *c, unsigned char *mac,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *n, const unsigned char *pk,
+ const unsigned char *sk)
+{
+ unsigned char k[crypto_box_BEFORENMBYTES];
+ int ret;
+
+ COMPILER_ASSERT(crypto_box_BEFORENMBYTES >= crypto_secretbox_KEYBYTES);
+ if (crypto_box_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_detached_afternm(c, mac, m, mlen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+int
+crypto_box_easy_afternm(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ if (mlen > crypto_box_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_box_detached_afternm(c + crypto_box_MACBYTES, c, m, mlen, n,
+ k);
+}
+
+int
+crypto_box_easy(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ if (mlen > crypto_box_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_box_detached(c + crypto_box_MACBYTES, c, m, mlen, n,
+ pk, sk);
+}
+
+int
+crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_secretbox_open_detached(m, c, mac, clen, n, k);
+}
+
+int
+crypto_box_open_detached(unsigned char *m, const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ unsigned char k[crypto_box_BEFORENMBYTES];
+ int ret;
+
+ if (crypto_box_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_open_detached_afternm(m, c, mac, clen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+int
+crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ if (clen < crypto_box_MACBYTES) {
+ return -1;
+ }
+ return crypto_box_open_detached_afternm(m, c + crypto_box_MACBYTES, c,
+ clen - crypto_box_MACBYTES,
+ n, k);
+}
+
+int
+crypto_box_open_easy(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ if (clen < crypto_box_MACBYTES) {
+ return -1;
+ }
+ return crypto_box_open_detached(m, c + crypto_box_MACBYTES, c,
+ clen - crypto_box_MACBYTES,
+ n, pk, sk);
+}
diff --git a/libs/libsodium/src/crypto_box/crypto_box_seal.c b/libs/libsodium/src/crypto_box/crypto_box_seal.c
new file mode 100644
index 0000000000..7181334578
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/crypto_box_seal.c
@@ -0,0 +1,68 @@
+
+#include <string.h>
+
+#include "crypto_box.h"
+#include "crypto_generichash.h"
+#include "private/common.h"
+#include "utils.h"
+
+static int
+_crypto_box_seal_nonce(unsigned char *nonce,
+ const unsigned char *pk1, const unsigned char *pk2)
+{
+ crypto_generichash_state st;
+
+ crypto_generichash_init(&st, NULL, 0U, crypto_box_NONCEBYTES);
+ crypto_generichash_update(&st, pk1, crypto_box_PUBLICKEYBYTES);
+ crypto_generichash_update(&st, pk2, crypto_box_PUBLICKEYBYTES);
+ crypto_generichash_final(&st, nonce, crypto_box_NONCEBYTES);
+
+ return 0;
+}
+
+int
+crypto_box_seal(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *pk)
+{
+ unsigned char nonce[crypto_box_NONCEBYTES];
+ unsigned char epk[crypto_box_PUBLICKEYBYTES];
+ unsigned char esk[crypto_box_SECRETKEYBYTES];
+ int ret;
+
+ if (crypto_box_keypair(epk, esk) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ memcpy(c, epk, crypto_box_PUBLICKEYBYTES);
+ _crypto_box_seal_nonce(nonce, epk, pk);
+ ret = crypto_box_easy(c + crypto_box_PUBLICKEYBYTES, m, mlen,
+ nonce, pk, esk);
+ sodium_memzero(esk, sizeof esk);
+ sodium_memzero(epk, sizeof epk);
+ sodium_memzero(nonce, sizeof nonce);
+
+ return ret;
+}
+
+int
+crypto_box_seal_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *pk, const unsigned char *sk)
+{
+ unsigned char nonce[crypto_box_NONCEBYTES];
+
+ if (clen < crypto_box_SEALBYTES) {
+ return -1;
+ }
+ _crypto_box_seal_nonce(nonce, c, pk);
+
+ COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES);
+ return crypto_box_open_easy(m, c + crypto_box_PUBLICKEYBYTES,
+ clen - crypto_box_PUBLICKEYBYTES,
+ nonce, c, sk);
+}
+
+size_t
+crypto_box_sealbytes(void)
+{
+ return crypto_box_SEALBYTES;
+}
diff --git a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c
new file mode 100644
index 0000000000..5e2532eab7
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c
@@ -0,0 +1,204 @@
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_box_curve25519xchacha20poly1305.h"
+#include "crypto_core_hchacha20.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_scalarmult_curve25519.h"
+#include "crypto_secretbox_xchacha20poly1305.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk,
+ unsigned char *sk,
+ const unsigned char *seed)
+{
+ unsigned char hash[64];
+
+ crypto_hash_sha512(hash, seed, 32);
+ memcpy(sk, hash, 32);
+ sodium_memzero(hash, sizeof hash);
+
+ return crypto_scalarmult_curve25519_base(pk, sk);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk,
+ unsigned char *sk)
+{
+ randombytes_buf(sk, 32);
+
+ return crypto_scalarmult_curve25519_base(pk, sk);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k,
+ const unsigned char *pk,
+ const unsigned char *sk)
+{
+ static const unsigned char zero[16] = { 0 };
+ unsigned char s[32];
+
+ if (crypto_scalarmult_curve25519(s, sk, pk) != 0) {
+ return -1;
+ }
+ return crypto_core_hchacha20(k, zero, s, NULL);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_detached_afternm(
+ unsigned char *c, unsigned char *mac, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, const unsigned char *k)
+{
+ return crypto_secretbox_xchacha20poly1305_detached(c, mac, m, mlen, n, k);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_detached(
+ unsigned char *c, unsigned char *mac, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, const unsigned char *pk,
+ const unsigned char *sk)
+{
+ unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES];
+ int ret;
+
+ COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES >=
+ crypto_secretbox_xchacha20poly1305_KEYBYTES);
+ if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_curve25519xchacha20poly1305_detached_afternm(c, mac, m,
+ mlen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_box_curve25519xchacha20poly1305_detached_afternm(
+ c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, k);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_easy(
+ unsigned char *c, const unsigned char *m, unsigned long long mlen,
+ const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
+{
+ if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_box_curve25519xchacha20poly1305_detached(
+ c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, pk,
+ sk);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
+ unsigned char *m, const unsigned char *c, const unsigned char *mac,
+ unsigned long long clen, const unsigned char *n, const unsigned char *k)
+{
+ return crypto_secretbox_xchacha20poly1305_open_detached(m, c, mac, clen, n,
+ k);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_open_detached(
+ unsigned char *m, const unsigned char *c, const unsigned char *mac,
+ unsigned long long clen, const unsigned char *n, const unsigned char *pk,
+ const unsigned char *sk)
+{
+ unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES];
+ int ret;
+
+ if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
+ m, c, mac, clen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_open_easy_afternm(
+ unsigned char *m, const unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) {
+ return -1;
+ }
+ return crypto_box_curve25519xchacha20poly1305_open_detached_afternm(
+ m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c,
+ clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, k);
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_open_easy(
+ unsigned char *m, const unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
+{
+ if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) {
+ return -1;
+ }
+ return crypto_box_curve25519xchacha20poly1305_open_detached(
+ m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c,
+ clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, pk, sk);
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_seedbytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_SEEDBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_publickeybytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_secretkeybytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_beforenmbytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_noncebytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_NONCEBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_macbytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_MACBYTES;
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_messagebytes_max(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX;
+}
diff --git a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c
new file mode 100644
index 0000000000..9e73a265aa
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c
@@ -0,0 +1,79 @@
+
+#include <string.h>
+
+#include "crypto_box_curve25519xchacha20poly1305.h"
+#include "crypto_generichash.h"
+#include "private/common.h"
+#include "utils.h"
+
+static int
+_crypto_box_curve25519xchacha20poly1305_seal_nonce(unsigned char *nonce,
+ const unsigned char *pk1,
+ const unsigned char *pk2)
+{
+ crypto_generichash_state st;
+
+ crypto_generichash_init(&st, NULL, 0U,
+ crypto_box_curve25519xchacha20poly1305_NONCEBYTES);
+ crypto_generichash_update(&st, pk1,
+ crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
+ crypto_generichash_update(&st, pk2,
+ crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
+ crypto_generichash_final(&st, nonce,
+ crypto_box_curve25519xchacha20poly1305_NONCEBYTES);
+
+ return 0;
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk)
+{
+ unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES];
+ unsigned char epk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES];
+ unsigned char esk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES];
+ int ret;
+
+ if (crypto_box_curve25519xchacha20poly1305_keypair(epk, esk) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES);
+ _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, epk, pk);
+ ret = crypto_box_curve25519xchacha20poly1305_easy(
+ c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, m, mlen,
+ nonce, pk, esk);
+ sodium_memzero(esk, sizeof esk);
+ sodium_memzero(epk, sizeof epk);
+ sodium_memzero(nonce, sizeof nonce);
+
+ return ret;
+}
+
+int
+crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *pk,
+ const unsigned char *sk)
+{
+ unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES];
+
+ if (clen < crypto_box_curve25519xchacha20poly1305_SEALBYTES) {
+ return -1;
+ }
+ _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, c, pk);
+
+ COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES <
+ crypto_box_curve25519xchacha20poly1305_SEALBYTES);
+
+ return crypto_box_curve25519xchacha20poly1305_open_easy(
+ m, c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES,
+ clen - crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES,
+ nonce, c, sk);
+}
+
+size_t
+crypto_box_curve25519xchacha20poly1305_sealbytes(void)
+{
+ return crypto_box_curve25519xchacha20poly1305_SEALBYTES;
+}
diff --git a/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c
new file mode 100644
index 0000000000..4c1d62ed43
--- /dev/null
+++ b/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c
@@ -0,0 +1,156 @@
+#include <string.h>
+
+#include "crypto_box_curve25519xsalsa20poly1305.h"
+#include "crypto_core_hsalsa20.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_scalarmult_curve25519.h"
+#include "crypto_secretbox_xsalsa20poly1305.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk,
+ unsigned char *sk,
+ const unsigned char *seed)
+{
+ unsigned char hash[64];
+
+ crypto_hash_sha512(hash, seed, 32);
+ memcpy(sk, hash, 32);
+ sodium_memzero(hash, sizeof hash);
+
+ return crypto_scalarmult_curve25519_base(pk, sk);
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk,
+ unsigned char *sk)
+{
+ randombytes_buf(sk, 32);
+
+ return crypto_scalarmult_curve25519_base(pk, sk);
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k,
+ const unsigned char *pk,
+ const unsigned char *sk)
+{
+ static const unsigned char zero[16] = { 0 };
+ unsigned char s[32];
+
+ if (crypto_scalarmult_curve25519(s, sk, pk) != 0) {
+ return -1;
+ }
+ return crypto_core_hsalsa20(k, zero, s, NULL);
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k);
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k);
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+{
+ unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES];
+ int ret;
+
+ if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+int
+crypto_box_curve25519xsalsa20poly1305_open(
+ unsigned char *m, const unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
+{
+ unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES];
+ int ret;
+
+ if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) {
+ return -1;
+ }
+ ret = crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k);
+ sodium_memzero(k, sizeof k);
+
+ return ret;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_seedbytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_SEEDBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_publickeybytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_noncebytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_NONCEBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_zerobytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_ZEROBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_macbytes(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_MACBYTES;
+}
+
+size_t
+crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void)
+{
+ return crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX;
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c
new file mode 100644
index 0000000000..1bcf5022b1
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c
@@ -0,0 +1,79 @@
+
+#include "crypto_core_ed25519.h"
+#include "private/common.h"
+#include "private/ed25519_ref10.h"
+
+int
+crypto_core_ed25519_is_valid_point(const unsigned char *p)
+{
+ ge25519_p3 p_p3;
+
+ if (ge25519_is_canonical(p) == 0 ||
+ ge25519_has_small_order(p) != 0 ||
+ ge25519_frombytes(&p_p3, p) != 0 ||
+ ge25519_is_on_curve(&p_p3) == 0 ||
+ ge25519_is_on_main_subgroup(&p_p3) == 0) {
+ return 0;
+ }
+ return 1;
+}
+
+int
+crypto_core_ed25519_add(unsigned char *r,
+ const unsigned char *p, const unsigned char *q)
+{
+ ge25519_p3 p_p3, q_p3, r_p3;
+ ge25519_p1p1 r_p1p1;
+ ge25519_cached q_cached;
+
+ if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 ||
+ ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) {
+ return -1;
+ }
+ ge25519_p3_to_cached(&q_cached, &q_p3);
+ ge25519_add(&r_p1p1, &p_p3, &q_cached);
+ ge25519_p1p1_to_p3(&r_p3, &r_p1p1);
+ ge25519_p3_tobytes(r, &r_p3);
+
+ return 0;
+}
+
+int
+crypto_core_ed25519_sub(unsigned char *r,
+ const unsigned char *p, const unsigned char *q)
+{
+ ge25519_p3 p_p3, q_p3, r_p3;
+ ge25519_p1p1 r_p1p1;
+ ge25519_cached q_cached;
+
+ if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 ||
+ ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) {
+ return -1;
+ }
+ ge25519_p3_to_cached(&q_cached, &q_p3);
+ ge25519_sub(&r_p1p1, &p_p3, &q_cached);
+ ge25519_p1p1_to_p3(&r_p3, &r_p1p1);
+ ge25519_p3_tobytes(r, &r_p3);
+
+ return 0;
+}
+
+int
+crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r)
+{
+ ge25519_from_uniform(p, r);
+
+ return - ge25519_has_small_order(p);
+}
+
+size_t
+crypto_core_ed25519_bytes(void)
+{
+ return crypto_core_ed25519_BYTES;
+}
+
+size_t
+crypto_core_ed25519_uniformbytes(void)
+{
+ return crypto_core_ed25519_UNIFORMBYTES;
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c
new file mode 100644
index 0000000000..f7b8280685
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c
@@ -0,0 +1,2031 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_verify_32.h"
+#include "private/common.h"
+#include "private/ed25519_ref10.h"
+#include "utils.h"
+
+static inline uint64_t
+load_3(const unsigned char *in)
+{
+ uint64_t result;
+
+ result = (uint64_t) in[0];
+ result |= ((uint64_t) in[1]) << 8;
+ result |= ((uint64_t) in[2]) << 16;
+
+ return result;
+}
+
+static inline uint64_t
+load_4(const unsigned char *in)
+{
+ uint64_t result;
+
+ result = (uint64_t) in[0];
+ result |= ((uint64_t) in[1]) << 8;
+ result |= ((uint64_t) in[2]) << 16;
+ result |= ((uint64_t) in[3]) << 24;
+
+ return result;
+}
+
+/*
+ * Field arithmetic:
+ * Use 5*51 bit limbs on 64-bit systems with support for 128 bit arithmetic,
+ * and 10*25.5 bit limbs elsewhere.
+ *
+ * Functions used elsewhere that are candidates for inlining are defined
+ * via "private/curve25519_ref10.h".
+ */
+
+#ifdef HAVE_TI_MODE
+# include "fe_51/constants.h"
+# include "fe_51/fe.h"
+#else
+# include "fe_25_5/constants.h"
+# include "fe_25_5/fe.h"
+#endif
+
+void
+fe25519_invert(fe25519 out, const fe25519 z)
+{
+ fe25519 t0;
+ fe25519 t1;
+ fe25519 t2;
+ fe25519 t3;
+ int i;
+
+ fe25519_sq(t0, z);
+ fe25519_sq(t1, t0);
+ fe25519_sq(t1, t1);
+ fe25519_mul(t1, z, t1);
+ fe25519_mul(t0, t0, t1);
+ fe25519_sq(t2, t0);
+ fe25519_mul(t1, t1, t2);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 5; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 10; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t2, t2, t1);
+ fe25519_sq(t3, t2);
+ for (i = 1; i < 20; ++i) {
+ fe25519_sq(t3, t3);
+ }
+ fe25519_mul(t2, t3, t2);
+ fe25519_sq(t2, t2);
+ for (i = 1; i < 10; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 50; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t2, t2, t1);
+ fe25519_sq(t3, t2);
+ for (i = 1; i < 100; ++i) {
+ fe25519_sq(t3, t3);
+ }
+ fe25519_mul(t2, t3, t2);
+ fe25519_sq(t2, t2);
+ for (i = 1; i < 50; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t1, t1);
+ for (i = 1; i < 5; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(out, t1, t0);
+}
+
+static void
+fe25519_pow22523(fe25519 out, const fe25519 z)
+{
+ fe25519 t0;
+ fe25519 t1;
+ fe25519 t2;
+ int i;
+
+ fe25519_sq(t0, z);
+ fe25519_sq(t1, t0);
+ fe25519_sq(t1, t1);
+ fe25519_mul(t1, z, t1);
+ fe25519_mul(t0, t0, t1);
+ fe25519_sq(t0, t0);
+ fe25519_mul(t0, t1, t0);
+ fe25519_sq(t1, t0);
+ for (i = 1; i < 5; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(t0, t1, t0);
+ fe25519_sq(t1, t0);
+ for (i = 1; i < 10; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(t1, t1, t0);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 20; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t1, t1);
+ for (i = 1; i < 10; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(t0, t1, t0);
+ fe25519_sq(t1, t0);
+ for (i = 1; i < 50; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(t1, t1, t0);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 100; ++i) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t1, t1);
+ for (i = 1; i < 50; ++i) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(t0, t1, t0);
+ fe25519_sq(t0, t0);
+ fe25519_sq(t0, t0);
+ fe25519_mul(out, t0, z);
+}
+
+/*
+ r = p + q
+ */
+
+void
+ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q)
+{
+ fe25519 t0;
+
+ fe25519_add(r->X, p->Y, p->X);
+ fe25519_sub(r->Y, p->Y, p->X);
+ fe25519_mul(r->Z, r->X, q->YplusX);
+ fe25519_mul(r->Y, r->Y, q->YminusX);
+ fe25519_mul(r->T, q->T2d, p->T);
+ fe25519_mul(r->X, p->Z, q->Z);
+ fe25519_add(t0, r->X, r->X);
+ fe25519_sub(r->X, r->Z, r->Y);
+ fe25519_add(r->Y, r->Z, r->Y);
+ fe25519_add(r->Z, t0, r->T);
+ fe25519_sub(r->T, t0, r->T);
+}
+
+static void
+slide_vartime(signed char *r, const unsigned char *a)
+{
+ int i;
+ int b;
+ int k;
+ int ribs;
+ int cmp;
+
+ for (i = 0; i < 256; ++i) {
+ r[i] = 1 & (a[i >> 3] >> (i & 7));
+ }
+ for (i = 0; i < 256; ++i) {
+ if (! r[i]) {
+ continue;
+ }
+ for (b = 1; b <= 6 && i + b < 256; ++b) {
+ if (! r[i + b]) {
+ continue;
+ }
+ ribs = r[i + b] << b;
+ cmp = r[i] + ribs;
+ if (cmp <= 15) {
+ r[i] = cmp;
+ r[i + b] = 0;
+ } else {
+ cmp = r[i] - ribs;
+ if (cmp < -15) {
+ break;
+ }
+ r[i] = cmp;
+ for (k = i + b; k < 256; ++k) {
+ if (! r[k]) {
+ r[k] = 1;
+ break;
+ }
+ r[k] = 0;
+ }
+ }
+ }
+ }
+}
+
+int
+ge25519_frombytes(ge25519_p3 *h, const unsigned char *s)
+{
+ fe25519 u;
+ fe25519 v;
+ fe25519 v3;
+ fe25519 vxx;
+ fe25519 m_root_check, p_root_check;
+ fe25519 negx;
+ fe25519 x_sqrtm1;
+ int has_m_root, has_p_root;
+
+ fe25519_frombytes(h->Y, s);
+ fe25519_1(h->Z);
+ fe25519_sq(u, h->Y);
+ fe25519_mul(v, u, d);
+ fe25519_sub(u, u, h->Z); /* u = y^2-1 */
+ fe25519_add(v, v, h->Z); /* v = dy^2+1 */
+
+ fe25519_sq(v3, v);
+ fe25519_mul(v3, v3, v); /* v3 = v^3 */
+ fe25519_sq(h->X, v3);
+ fe25519_mul(h->X, h->X, v);
+ fe25519_mul(h->X, h->X, u); /* x = uv^7 */
+
+ fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
+ fe25519_mul(h->X, h->X, v3);
+ fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe25519_sq(vxx, h->X);
+ fe25519_mul(vxx, vxx, v);
+ fe25519_sub(m_root_check, vxx, u); /* vx^2-u */
+ fe25519_add(p_root_check, vxx, u); /* vx^2+u */
+ has_m_root = fe25519_iszero(m_root_check);
+ has_p_root = fe25519_iszero(p_root_check);
+ fe25519_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */
+ fe25519_cmov(h->X, x_sqrtm1, 1 - has_m_root);
+
+ fe25519_neg(negx, h->X);
+ fe25519_cmov(h->X, negx, fe25519_isnegative(h->X) ^ (s[31] >> 7));
+ fe25519_mul(h->T, h->X, h->Y);
+
+ return (has_m_root | has_p_root) - 1;
+}
+
+int
+ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s)
+{
+ fe25519 u;
+ fe25519 v;
+ fe25519 v3;
+ fe25519 vxx;
+ fe25519 m_root_check, p_root_check;
+
+ fe25519_frombytes(h->Y, s);
+ fe25519_1(h->Z);
+ fe25519_sq(u, h->Y);
+ fe25519_mul(v, u, d);
+ fe25519_sub(u, u, h->Z); /* u = y^2-1 */
+ fe25519_add(v, v, h->Z); /* v = dy^2+1 */
+
+ fe25519_sq(v3, v);
+ fe25519_mul(v3, v3, v); /* v3 = v^3 */
+ fe25519_sq(h->X, v3);
+ fe25519_mul(h->X, h->X, v);
+ fe25519_mul(h->X, h->X, u); /* x = uv^7 */
+
+ fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
+ fe25519_mul(h->X, h->X, v3);
+ fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe25519_sq(vxx, h->X);
+ fe25519_mul(vxx, vxx, v);
+ fe25519_sub(m_root_check, vxx, u); /* vx^2-u */
+ if (fe25519_iszero(m_root_check) == 0) {
+ fe25519_add(p_root_check, vxx, u); /* vx^2+u */
+ if (fe25519_iszero(p_root_check) == 0) {
+ return -1;
+ }
+ fe25519_mul(h->X, h->X, sqrtm1);
+ }
+
+ if (fe25519_isnegative(h->X) == (s[31] >> 7)) {
+ fe25519_neg(h->X, h->X);
+ }
+ fe25519_mul(h->T, h->X, h->Y);
+
+ return 0;
+}
+
+/*
+ r = p + q
+ */
+
+static void
+ge25519_madd(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q)
+{
+ fe25519 t0;
+
+ fe25519_add(r->X, p->Y, p->X);
+ fe25519_sub(r->Y, p->Y, p->X);
+ fe25519_mul(r->Z, r->X, q->yplusx);
+ fe25519_mul(r->Y, r->Y, q->yminusx);
+ fe25519_mul(r->T, q->xy2d, p->T);
+ fe25519_add(t0, p->Z, p->Z);
+ fe25519_sub(r->X, r->Z, r->Y);
+ fe25519_add(r->Y, r->Z, r->Y);
+ fe25519_add(r->Z, t0, r->T);
+ fe25519_sub(r->T, t0, r->T);
+}
+
+/*
+ r = p - q
+ */
+
+static void
+ge25519_msub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q)
+{
+ fe25519 t0;
+
+ fe25519_add(r->X, p->Y, p->X);
+ fe25519_sub(r->Y, p->Y, p->X);
+ fe25519_mul(r->Z, r->X, q->yminusx);
+ fe25519_mul(r->Y, r->Y, q->yplusx);
+ fe25519_mul(r->T, q->xy2d, p->T);
+ fe25519_add(t0, p->Z, p->Z);
+ fe25519_sub(r->X, r->Z, r->Y);
+ fe25519_add(r->Y, r->Z, r->Y);
+ fe25519_sub(r->Z, t0, r->T);
+ fe25519_add(r->T, t0, r->T);
+}
+
+/*
+ r = p
+ */
+
+void
+ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
+{
+ fe25519_mul(r->X, p->X, p->T);
+ fe25519_mul(r->Y, p->Y, p->Z);
+ fe25519_mul(r->Z, p->Z, p->T);
+}
+
+/*
+ r = p
+ */
+
+void
+ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
+{
+ fe25519_mul(r->X, p->X, p->T);
+ fe25519_mul(r->Y, p->Y, p->Z);
+ fe25519_mul(r->Z, p->Z, p->T);
+ fe25519_mul(r->T, p->X, p->Y);
+}
+
+static void
+ge25519_p2_0(ge25519_p2 *h)
+{
+ fe25519_0(h->X);
+ fe25519_1(h->Y);
+ fe25519_1(h->Z);
+}
+
+/*
+ r = 2 * p
+ */
+
+static void
+ge25519_p2_dbl(ge25519_p1p1 *r, const ge25519_p2 *p)
+{
+ fe25519 t0;
+
+ fe25519_sq(r->X, p->X);
+ fe25519_sq(r->Z, p->Y);
+ fe25519_sq2(r->T, p->Z);
+ fe25519_add(r->Y, p->X, p->Y);
+ fe25519_sq(t0, r->Y);
+ fe25519_add(r->Y, r->Z, r->X);
+ fe25519_sub(r->Z, r->Z, r->X);
+ fe25519_sub(r->X, t0, r->Y);
+ fe25519_sub(r->T, r->T, r->Z);
+}
+
+static void
+ge25519_p3_0(ge25519_p3 *h)
+{
+ fe25519_0(h->X);
+ fe25519_1(h->Y);
+ fe25519_1(h->Z);
+ fe25519_0(h->T);
+}
+
+static void
+ge25519_cached_0(ge25519_cached *h)
+{
+ fe25519_1(h->YplusX);
+ fe25519_1(h->YminusX);
+ fe25519_1(h->Z);
+ fe25519_0(h->T2d);
+}
+
+/*
+ r = p
+ */
+
+void
+ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p)
+{
+ fe25519_add(r->YplusX, p->Y, p->X);
+ fe25519_sub(r->YminusX, p->Y, p->X);
+ fe25519_copy(r->Z, p->Z);
+ fe25519_mul(r->T2d, p->T, d2);
+}
+
+static void
+ge25519_p3_to_precomp(ge25519_precomp *pi, const ge25519_p3 *p)
+{
+ fe25519 recip;
+ fe25519 x;
+ fe25519 y;
+ fe25519 xy;
+
+ fe25519_invert(recip, p->Z);
+ fe25519_mul(x, p->X, recip);
+ fe25519_mul(y, p->Y, recip);
+ fe25519_add(pi->yplusx, y, x);
+ fe25519_sub(pi->yminusx, y, x);
+ fe25519_mul(xy, x, y);
+ fe25519_mul(pi->xy2d, xy, d2);
+}
+
+/*
+ r = p
+ */
+
+static void
+ge25519_p3_to_p2(ge25519_p2 *r, const ge25519_p3 *p)
+{
+ fe25519_copy(r->X, p->X);
+ fe25519_copy(r->Y, p->Y);
+ fe25519_copy(r->Z, p->Z);
+}
+
+void
+ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h)
+{
+ fe25519 recip;
+ fe25519 x;
+ fe25519 y;
+
+ fe25519_invert(recip, h->Z);
+ fe25519_mul(x, h->X, recip);
+ fe25519_mul(y, h->Y, recip);
+ fe25519_tobytes(s, y);
+ s[31] ^= fe25519_isnegative(x) << 7;
+}
+
+/*
+ r = 2 * p
+ */
+
+static void
+ge25519_p3_dbl(ge25519_p1p1 *r, const ge25519_p3 *p)
+{
+ ge25519_p2 q;
+ ge25519_p3_to_p2(&q, p);
+ ge25519_p2_dbl(r, &q);
+}
+
+static void
+ge25519_precomp_0(ge25519_precomp *h)
+{
+ fe25519_1(h->yplusx);
+ fe25519_1(h->yminusx);
+ fe25519_0(h->xy2d);
+}
+
+static unsigned char
+equal(signed char b, signed char c)
+{
+ unsigned char ub = b;
+ unsigned char uc = c;
+ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
+ uint32_t y = x; /* 0: yes; 1..255: no */
+
+ y -= 1; /* 4294967295: yes; 0..254: no */
+ y >>= 31; /* 1: yes; 0: no */
+
+ return y;
+}
+
+static unsigned char
+negative(signed char b)
+{
+ /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
+ uint64_t x = b;
+
+ x >>= 63; /* 1: yes; 0: no */
+
+ return x;
+}
+
+static void
+ge25519_cmov(ge25519_precomp *t, const ge25519_precomp *u, unsigned char b)
+{
+ fe25519_cmov(t->yplusx, u->yplusx, b);
+ fe25519_cmov(t->yminusx, u->yminusx, b);
+ fe25519_cmov(t->xy2d, u->xy2d, b);
+}
+
+static void
+ge25519_cmov_cached(ge25519_cached *t, const ge25519_cached *u, unsigned char b)
+{
+ fe25519_cmov(t->YplusX, u->YplusX, b);
+ fe25519_cmov(t->YminusX, u->YminusX, b);
+ fe25519_cmov(t->Z, u->Z, b);
+ fe25519_cmov(t->T2d, u->T2d, b);
+}
+
+static void
+ge25519_select(ge25519_precomp *t, const ge25519_precomp precomp[8], const signed char b)
+{
+ ge25519_precomp minust;
+ const unsigned char bnegative = negative(b);
+ const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1));
+
+ ge25519_precomp_0(t);
+ ge25519_cmov(t, &precomp[0], equal(babs, 1));
+ ge25519_cmov(t, &precomp[1], equal(babs, 2));
+ ge25519_cmov(t, &precomp[2], equal(babs, 3));
+ ge25519_cmov(t, &precomp[3], equal(babs, 4));
+ ge25519_cmov(t, &precomp[4], equal(babs, 5));
+ ge25519_cmov(t, &precomp[5], equal(babs, 6));
+ ge25519_cmov(t, &precomp[6], equal(babs, 7));
+ ge25519_cmov(t, &precomp[7], equal(babs, 8));
+ fe25519_copy(minust.yplusx, t->yminusx);
+ fe25519_copy(minust.yminusx, t->yplusx);
+ fe25519_neg(minust.xy2d, t->xy2d);
+ ge25519_cmov(t, &minust, bnegative);
+}
+
+static void
+ge25519_select_base(ge25519_precomp *t, const int pos, const signed char b)
+{
+ static const ge25519_precomp base[32][8] = { /* base[i][j] = (j+1)*256^i*B */
+#ifdef HAVE_TI_MODE
+# include "fe_51/base.h"
+#else
+# include "fe_25_5/base.h"
+#endif
+ };
+ ge25519_select(t, base[pos], b);
+}
+
+static void
+ge25519_select_cached(ge25519_cached *t, const ge25519_cached cached[8], const signed char b)
+{
+ ge25519_cached minust;
+ const unsigned char bnegative = negative(b);
+ const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1));
+
+ ge25519_cached_0(t);
+ ge25519_cmov_cached(t, &cached[0], equal(babs, 1));
+ ge25519_cmov_cached(t, &cached[1], equal(babs, 2));
+ ge25519_cmov_cached(t, &cached[2], equal(babs, 3));
+ ge25519_cmov_cached(t, &cached[3], equal(babs, 4));
+ ge25519_cmov_cached(t, &cached[4], equal(babs, 5));
+ ge25519_cmov_cached(t, &cached[5], equal(babs, 6));
+ ge25519_cmov_cached(t, &cached[6], equal(babs, 7));
+ ge25519_cmov_cached(t, &cached[7], equal(babs, 8));
+ fe25519_copy(minust.YplusX, t->YminusX);
+ fe25519_copy(minust.YminusX, t->YplusX);
+ fe25519_copy(minust.Z, t->Z);
+ fe25519_neg(minust.T2d, t->T2d);
+ ge25519_cmov_cached(t, &minust, bnegative);
+}
+
+/*
+ r = p - q
+ */
+
+void
+ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q)
+{
+ fe25519 t0;
+
+ fe25519_add(r->X, p->Y, p->X);
+ fe25519_sub(r->Y, p->Y, p->X);
+ fe25519_mul(r->Z, r->X, q->YminusX);
+ fe25519_mul(r->Y, r->Y, q->YplusX);
+ fe25519_mul(r->T, q->T2d, p->T);
+ fe25519_mul(r->X, p->Z, q->Z);
+ fe25519_add(t0, r->X, r->X);
+ fe25519_sub(r->X, r->Z, r->Y);
+ fe25519_add(r->Y, r->Z, r->Y);
+ fe25519_sub(r->Z, t0, r->T);
+ fe25519_add(r->T, t0, r->T);
+}
+
+void
+ge25519_tobytes(unsigned char *s, const ge25519_p2 *h)
+{
+ fe25519 recip;
+ fe25519 x;
+ fe25519 y;
+
+ fe25519_invert(recip, h->Z);
+ fe25519_mul(x, h->X, recip);
+ fe25519_mul(y, h->Y, recip);
+ fe25519_tobytes(s, y);
+ s[31] ^= fe25519_isnegative(x) << 7;
+}
+
+/*
+ r = a * A + b * B
+ where a = a[0]+256*a[1]+...+256^31 a[31].
+ and b = b[0]+256*b[1]+...+256^31 b[31].
+ B is the Ed25519 base point (x,4/5) with x positive.
+
+ Only used for signatures verification.
+ */
+
+void
+ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a,
+ const ge25519_p3 *A, const unsigned char *b)
+{
+ static const ge25519_precomp Bi[8] = {
+#ifdef HAVE_TI_MODE
+# include "fe_51/base2.h"
+#else
+# include "fe_25_5/base2.h"
+#endif
+ };
+ signed char aslide[256];
+ signed char bslide[256];
+ ge25519_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
+ ge25519_p1p1 t;
+ ge25519_p3 u;
+ ge25519_p3 A2;
+ int i;
+
+ slide_vartime(aslide, a);
+ slide_vartime(bslide, b);
+
+ ge25519_p3_to_cached(&Ai[0], A);
+
+ ge25519_p3_dbl(&t, A);
+ ge25519_p1p1_to_p3(&A2, &t);
+
+ ge25519_add(&t, &A2, &Ai[0]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[1], &u);
+
+ ge25519_add(&t, &A2, &Ai[1]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[2], &u);
+
+ ge25519_add(&t, &A2, &Ai[2]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[3], &u);
+
+ ge25519_add(&t, &A2, &Ai[3]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[4], &u);
+
+ ge25519_add(&t, &A2, &Ai[4]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[5], &u);
+
+ ge25519_add(&t, &A2, &Ai[5]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[6], &u);
+
+ ge25519_add(&t, &A2, &Ai[6]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[7], &u);
+
+ ge25519_p2_0(r);
+
+ for (i = 255; i >= 0; --i) {
+ if (aslide[i] || bslide[i]) {
+ break;
+ }
+ }
+
+ for (; i >= 0; --i) {
+ ge25519_p2_dbl(&t, r);
+
+ if (aslide[i] > 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_add(&t, &u, &Ai[aslide[i] / 2]);
+ } else if (aslide[i] < 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
+ }
+
+ if (bslide[i] > 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_madd(&t, &u, &Bi[bslide[i] / 2]);
+ } else if (bslide[i] < 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
+ }
+
+ ge25519_p1p1_to_p2(r, &t);
+ }
+}
+
+/*
+ h = a * p
+ where a = a[0]+256*a[1]+...+256^31 a[31]
+
+ Preconditions:
+ a[31] <= 127
+
+ p is public
+ */
+
+void
+ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p)
+{
+ signed char e[64];
+ signed char carry;
+ ge25519_p1p1 r;
+ ge25519_p2 s;
+ ge25519_p1p1 t2, t3, t4, t5, t6, t7, t8;
+ ge25519_p3 p2, p3, p4, p5, p6, p7, p8;
+ ge25519_cached pi[8];
+ ge25519_cached t;
+ int i;
+
+ ge25519_p3_to_cached(&pi[1 - 1], p); /* p */
+
+ ge25519_p3_dbl(&t2, p);
+ ge25519_p1p1_to_p3(&p2, &t2);
+ ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */
+
+ ge25519_add(&t3, p, &pi[2 - 1]);
+ ge25519_p1p1_to_p3(&p3, &t3);
+ ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */
+
+ ge25519_p3_dbl(&t4, &p2);
+ ge25519_p1p1_to_p3(&p4, &t4);
+ ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */
+
+ ge25519_add(&t5, p, &pi[4 - 1]);
+ ge25519_p1p1_to_p3(&p5, &t5);
+ ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */
+
+ ge25519_p3_dbl(&t6, &p3);
+ ge25519_p1p1_to_p3(&p6, &t6);
+ ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */
+
+ ge25519_add(&t7, p, &pi[6 - 1]);
+ ge25519_p1p1_to_p3(&p7, &t7);
+ ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */
+
+ ge25519_p3_dbl(&t8, &p4);
+ ge25519_p1p1_to_p3(&p8, &t8);
+ ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */
+
+ for (i = 0; i < 32; ++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 15;
+ e[2 * i + 1] = (a[i] >> 4) & 15;
+ }
+ /* each e[i] is between 0 and 15 */
+ /* e[63] is between 0 and 7 */
+
+ carry = 0;
+ for (i = 0; i < 63; ++i) {
+ e[i] += carry;
+ carry = e[i] + 8;
+ carry >>= 4;
+ e[i] -= carry * ((signed char) 1 << 4);
+ }
+ e[63] += carry;
+ /* each e[i] is between -8 and 8 */
+
+ ge25519_p3_0(h);
+
+ for (i = 63; i != 0; i--) {
+ ge25519_select_cached(&t, pi, e[i]);
+ ge25519_add(&r, h, &t);
+
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+
+ ge25519_p1p1_to_p3(h, &r); /* *16 */
+ }
+ ge25519_select_cached(&t, pi, e[i]);
+ ge25519_add(&r, h, &t);
+
+ ge25519_p1p1_to_p3(h, &r);
+}
+
+/*
+ h = a * B (with precomputation)
+ where a = a[0]+256*a[1]+...+256^31 a[31]
+ B is the Ed25519 base point (x,4/5) with x positive
+ (as bytes: 0x5866666666666666666666666666666666666666666666666666666666666666)
+
+ Preconditions:
+ a[31] <= 127
+ */
+
+void
+ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a)
+{
+ signed char e[64];
+ signed char carry;
+ ge25519_p1p1 r;
+ ge25519_p2 s;
+ ge25519_precomp t;
+ int i;
+
+ for (i = 0; i < 32; ++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 15;
+ e[2 * i + 1] = (a[i] >> 4) & 15;
+ }
+ /* each e[i] is between 0 and 15 */
+ /* e[63] is between 0 and 7 */
+
+ carry = 0;
+ for (i = 0; i < 63; ++i) {
+ e[i] += carry;
+ carry = e[i] + 8;
+ carry >>= 4;
+ e[i] -= carry * ((signed char) 1 << 4);
+ }
+ e[63] += carry;
+ /* each e[i] is between -8 and 8 */
+
+ ge25519_p3_0(h);
+
+ for (i = 1; i < 64; i += 2) {
+ ge25519_select_base(&t, i / 2, e[i]);
+ ge25519_madd(&r, h, &t);
+ ge25519_p1p1_to_p3(h, &r);
+ }
+
+ ge25519_p3_dbl(&r, h);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p2(&s, &r);
+ ge25519_p2_dbl(&r, &s);
+ ge25519_p1p1_to_p3(h, &r);
+
+ for (i = 0; i < 64; i += 2) {
+ ge25519_select_base(&t, i / 2, e[i]);
+ ge25519_madd(&r, h, &t);
+ ge25519_p1p1_to_p3(h, &r);
+ }
+}
+
+/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */
+static void
+ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *A)
+{
+ static const signed char aslide[253] = {
+ 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+ };
+ ge25519_cached Ai[8];
+ ge25519_p1p1 t;
+ ge25519_p3 u;
+ ge25519_p3 A2;
+ int i;
+
+ ge25519_p3_to_cached(&Ai[0], A);
+ ge25519_p3_dbl(&t, A);
+ ge25519_p1p1_to_p3(&A2, &t);
+ ge25519_add(&t, &A2, &Ai[0]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[1], &u);
+ ge25519_add(&t, &A2, &Ai[1]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[2], &u);
+ ge25519_add(&t, &A2, &Ai[2]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[3], &u);
+ ge25519_add(&t, &A2, &Ai[3]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[4], &u);
+ ge25519_add(&t, &A2, &Ai[4]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[5], &u);
+ ge25519_add(&t, &A2, &Ai[5]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[6], &u);
+ ge25519_add(&t, &A2, &Ai[6]);
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_p3_to_cached(&Ai[7], &u);
+
+ ge25519_p3_0(r);
+
+ for (i = 252; i >= 0; --i) {
+ ge25519_p3_dbl(&t, r);
+
+ if (aslide[i] > 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_add(&t, &u, &Ai[aslide[i] / 2]);
+ } else if (aslide[i] < 0) {
+ ge25519_p1p1_to_p3(&u, &t);
+ ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
+ }
+
+ ge25519_p1p1_to_p3(r, &t);
+ }
+}
+
+int
+ge25519_is_on_curve(const ge25519_p3 *p)
+{
+ fe25519 x2;
+ fe25519 y2;
+ fe25519 z2;
+ fe25519 z4;
+ fe25519 t0;
+ fe25519 t1;
+
+ fe25519_sq(x2, p->X);
+ fe25519_sq(y2, p->Y);
+ fe25519_sq(z2, p->Z);
+ fe25519_sub(t0, y2, x2);
+ fe25519_mul(t0, t0, z2);
+
+ fe25519_mul(t1, x2, y2);
+ fe25519_mul(t1, t1, d);
+ fe25519_sq(z4, z2);
+ fe25519_add(t1, t1, z4);
+ fe25519_sub(t0, t0, t1);
+
+ return fe25519_iszero(t0);
+}
+
+int
+ge25519_is_on_main_subgroup(const ge25519_p3 *p)
+{
+ ge25519_p3 pl;
+
+ ge25519_mul_l(&pl, p);
+
+ return fe25519_iszero(pl.X);
+}
+
+int
+ge25519_is_canonical(const unsigned char *s)
+{
+ unsigned char c;
+ unsigned char d;
+ unsigned int i;
+
+ c = (s[31] & 0x7f) ^ 0x7f;
+ for (i = 30; i > 0; i--) {
+ c |= s[i] ^ 0xff;
+ }
+ c = (((unsigned int) c) - 1U) >> 8;
+ d = (0xed - 1U - (unsigned int) s[0]) >> 8;
+
+ return 1 - (c & d & 1);
+}
+
+int
+ge25519_has_small_order(const unsigned char s[32])
+{
+ CRYPTO_ALIGN(16)
+ static const unsigned char blacklist[][32] = {
+ /* 0 (order 4) */
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ /* 1 (order 1) */
+ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ /* 2707385501144840649318225287225658788936804267575313519463743609750303402022
+ (order 8) */
+ { 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4,
+ 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6,
+ 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 },
+ /* 55188659117513257062467267217118295137698188065244968500265048394206261417927
+ (order 8) */
+ { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b,
+ 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39,
+ 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a },
+ /* p-1 (order 2) */
+ { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ /* p (=0, order 4) */
+ { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ /* p+1 (=1, order 1) */
+ { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }
+ };
+ unsigned char c[7] = { 0 };
+ unsigned int k;
+ size_t i, j;
+
+ COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]);
+ for (j = 0; j < 31; j++) {
+ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) {
+ c[i] |= s[j] ^ blacklist[i][j];
+ }
+ }
+ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) {
+ c[i] |= (s[j] & 0x7f) ^ blacklist[i][j];
+ }
+ k = 0;
+ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) {
+ k |= (c[i] - 1);
+ }
+ return (int) ((k >> 8) & 1);
+}
+
+/*
+ Input:
+ a[0]+256*a[1]+...+256^31*a[31] = a
+ b[0]+256*b[1]+...+256^31*b[31] = b
+ c[0]+256*c[1]+...+256^31*c[31] = c
+ *
+ Output:
+ s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+ */
+
+void
+sc25519_muladd(unsigned char *s, const unsigned char *a,
+ const unsigned char *b, const unsigned char *c)
+{
+ int64_t a0 = 2097151 & load_3(a);
+ int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
+ int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
+ int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
+ int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
+ int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
+ int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
+ int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
+ int64_t a8 = 2097151 & load_3(a + 21);
+ int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
+ int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
+ int64_t a11 = (load_4(a + 28) >> 7);
+
+ int64_t b0 = 2097151 & load_3(b);
+ int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
+ int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
+ int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
+ int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
+ int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
+ int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
+ int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
+ int64_t b8 = 2097151 & load_3(b + 21);
+ int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
+ int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
+ int64_t b11 = (load_4(b + 28) >> 7);
+
+ int64_t c0 = 2097151 & load_3(c);
+ int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
+ int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
+ int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
+ int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
+ int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
+ int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
+ int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
+ int64_t c8 = 2097151 & load_3(c + 21);
+ int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
+ int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
+ int64_t c11 = (load_4(c + 28) >> 7);
+
+ int64_t s0;
+ int64_t s1;
+ int64_t s2;
+ int64_t s3;
+ int64_t s4;
+ int64_t s5;
+ int64_t s6;
+ int64_t s7;
+ int64_t s8;
+ int64_t s9;
+ int64_t s10;
+ int64_t s11;
+ int64_t s12;
+ int64_t s13;
+ int64_t s14;
+ int64_t s15;
+ int64_t s16;
+ int64_t s17;
+ int64_t s18;
+ int64_t s19;
+ int64_t s20;
+ int64_t s21;
+ int64_t s22;
+ int64_t s23;
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+ int64_t carry10;
+ int64_t carry11;
+ int64_t carry12;
+ int64_t carry13;
+ int64_t carry14;
+ int64_t carry15;
+ int64_t carry16;
+ int64_t carry17;
+ int64_t carry18;
+ int64_t carry19;
+ int64_t carry20;
+ int64_t carry21;
+ int64_t carry22;
+
+ s0 = c0 + a0 * b0;
+ s1 = c1 + a0 * b1 + a1 * b0;
+ s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
+ s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+ s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
+ s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
+ s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 +
+ a6 * b0;
+ s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
+ a6 * b1 + a7 * b0;
+ s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
+ a6 * b2 + a7 * b1 + a8 * b0;
+ s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
+ a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
+ s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
+ a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
+ s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
+ a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
+ s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 +
+ a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
+ s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 +
+ a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
+ s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 +
+ a9 * b5 + a10 * b4 + a11 * b3;
+ s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 +
+ a10 * b5 + a11 * b4;
+ s16 =
+ a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
+ s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
+ s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
+ s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
+ s20 = a9 * b11 + a10 * b10 + a11 * b9;
+ s21 = a10 * b11 + a11 * b10;
+ s22 = a11 * b11;
+ s23 = 0;
+
+ carry0 = (s0 + (int64_t) (1L << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry2 = (s2 + (int64_t) (1L << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry4 = (s4 + (int64_t) (1L << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+ carry12 = (s12 + (int64_t) (1L << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 * ((uint64_t) 1L << 21);
+ carry14 = (s14 + (int64_t) (1L << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 * ((uint64_t) 1L << 21);
+ carry16 = (s16 + (int64_t) (1L << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 * ((uint64_t) 1L << 21);
+ carry18 = (s18 + (int64_t) (1L << 20)) >> 21;
+ s19 += carry18;
+ s18 -= carry18 * ((uint64_t) 1L << 21);
+ carry20 = (s20 + (int64_t) (1L << 20)) >> 21;
+ s21 += carry20;
+ s20 -= carry20 * ((uint64_t) 1L << 21);
+ carry22 = (s22 + (int64_t) (1L << 20)) >> 21;
+ s23 += carry22;
+ s22 -= carry22 * ((uint64_t) 1L << 21);
+
+ carry1 = (s1 + (int64_t) (1L << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry3 = (s3 + (int64_t) (1L << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry5 = (s5 + (int64_t) (1L << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+ carry13 = (s13 + (int64_t) (1L << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 * ((uint64_t) 1L << 21);
+ carry15 = (s15 + (int64_t) (1L << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 * ((uint64_t) 1L << 21);
+ carry17 = (s17 + (int64_t) (1L << 20)) >> 21;
+ s18 += carry17;
+ s17 -= carry17 * ((uint64_t) 1L << 21);
+ carry19 = (s19 + (int64_t) (1L << 20)) >> 21;
+ s20 += carry19;
+ s19 -= carry19 * ((uint64_t) 1L << 21);
+ carry21 = (s21 + (int64_t) (1L << 20)) >> 21;
+ s22 += carry21;
+ s21 -= carry21 * ((uint64_t) 1L << 21);
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+
+ carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+ carry12 = (s12 + (int64_t) (1L << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 * ((uint64_t) 1L << 21);
+ carry14 = (s14 + (int64_t) (1L << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 * ((uint64_t) 1L << 21);
+ carry16 = (s16 + (int64_t) (1L << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 * ((uint64_t) 1L << 21);
+
+ carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+ carry13 = (s13 + (int64_t) (1L << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 * ((uint64_t) 1L << 21);
+ carry15 = (s15 + (int64_t) (1L << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 * ((uint64_t) 1L << 21);
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (int64_t) (1L << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry2 = (s2 + (int64_t) (1L << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry4 = (s4 + (int64_t) (1L << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+
+ carry1 = (s1 + (int64_t) (1L << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry3 = (s3 + (int64_t) (1L << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry5 = (s5 + (int64_t) (1L << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+ carry11 = s11 >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5));
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2));
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7));
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4));
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1));
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6));
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3));
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5));
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2));
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7));
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
+
+/*
+ Input:
+ s[0]+256*s[1]+...+256^63*s[63] = s
+ *
+ Output:
+ s[0]+256*s[1]+...+256^31*s[31] = s mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+ Overwrites s in place.
+ */
+
+void
+sc25519_reduce(unsigned char *s)
+{
+ int64_t s0 = 2097151 & load_3(s);
+ int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
+ int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
+ int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
+ int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
+ int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
+ int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
+ int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
+ int64_t s8 = 2097151 & load_3(s + 21);
+ int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
+ int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
+ int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
+ int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
+ int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
+ int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
+ int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
+ int64_t s16 = 2097151 & load_3(s + 42);
+ int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
+ int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
+ int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
+ int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
+ int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
+ int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
+ int64_t s23 = (load_4(s + 60) >> 3);
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+ int64_t carry10;
+ int64_t carry11;
+ int64_t carry12;
+ int64_t carry13;
+ int64_t carry14;
+ int64_t carry15;
+ int64_t carry16;
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+
+ carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+ carry12 = (s12 + (int64_t) (1L << 20)) >> 21;
+ s13 += carry12;
+ s12 -= carry12 * ((uint64_t) 1L << 21);
+ carry14 = (s14 + (int64_t) (1L << 20)) >> 21;
+ s15 += carry14;
+ s14 -= carry14 * ((uint64_t) 1L << 21);
+ carry16 = (s16 + (int64_t) (1L << 20)) >> 21;
+ s17 += carry16;
+ s16 -= carry16 * ((uint64_t) 1L << 21);
+
+ carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+ carry13 = (s13 + (int64_t) (1L << 20)) >> 21;
+ s14 += carry13;
+ s13 -= carry13 * ((uint64_t) 1L << 21);
+ carry15 = (s15 + (int64_t) (1L << 20)) >> 21;
+ s16 += carry15;
+ s15 -= carry15 * ((uint64_t) 1L << 21);
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (int64_t) (1L << 20)) >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry2 = (s2 + (int64_t) (1L << 20)) >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry4 = (s4 + (int64_t) (1L << 20)) >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+
+ carry1 = (s1 + (int64_t) (1L << 20)) >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry3 = (s3 + (int64_t) (1L << 20)) >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry5 = (s5 + (int64_t) (1L << 20)) >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+ carry11 = s11 >> 21;
+ s12 += carry11;
+ s11 -= carry11 * ((uint64_t) 1L << 21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+
+ carry0 = s0 >> 21;
+ s1 += carry0;
+ s0 -= carry0 * ((uint64_t) 1L << 21);
+ carry1 = s1 >> 21;
+ s2 += carry1;
+ s1 -= carry1 * ((uint64_t) 1L << 21);
+ carry2 = s2 >> 21;
+ s3 += carry2;
+ s2 -= carry2 * ((uint64_t) 1L << 21);
+ carry3 = s3 >> 21;
+ s4 += carry3;
+ s3 -= carry3 * ((uint64_t) 1L << 21);
+ carry4 = s4 >> 21;
+ s5 += carry4;
+ s4 -= carry4 * ((uint64_t) 1L << 21);
+ carry5 = s5 >> 21;
+ s6 += carry5;
+ s5 -= carry5 * ((uint64_t) 1L << 21);
+ carry6 = s6 >> 21;
+ s7 += carry6;
+ s6 -= carry6 * ((uint64_t) 1L << 21);
+ carry7 = s7 >> 21;
+ s8 += carry7;
+ s7 -= carry7 * ((uint64_t) 1L << 21);
+ carry8 = s8 >> 21;
+ s9 += carry8;
+ s8 -= carry8 * ((uint64_t) 1L << 21);
+ carry9 = s9 >> 21;
+ s10 += carry9;
+ s9 -= carry9 * ((uint64_t) 1L << 21);
+ carry10 = s10 >> 21;
+ s11 += carry10;
+ s10 -= carry10 * ((uint64_t) 1L << 21);
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5));
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2));
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7));
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4));
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1));
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6));
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3));
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5));
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2));
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7));
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
+
+int
+sc25519_is_canonical(const unsigned char *s)
+{
+ /* 2^252+27742317777372353535851937790883648493 */
+ static const unsigned char L[32] = {
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
+ 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
+ };
+ unsigned char c = 0;
+ unsigned char n = 1;
+ unsigned int i = 32;
+
+ do {
+ i--;
+ c |= ((s[i] - L[i]) >> 8) & n;
+ n &= ((s[i] ^ L[i]) - 1) >> 8;
+ } while (i != 0);
+
+ return (c != 0);
+}
+
+static void
+chi25519(fe25519 out, const fe25519 z)
+{
+ fe25519 t0, t1, t2, t3;
+ int i;
+
+ fe25519_sq(t0, z);
+ fe25519_mul(t1, t0, z);
+ fe25519_sq(t0, t1);
+ fe25519_sq(t2, t0);
+ fe25519_sq(t2, t2);
+ fe25519_mul(t2, t2, t0);
+ fe25519_mul(t1, t2, z);
+ fe25519_sq(t2, t1);
+
+ for (i = 1; i < 5; i++) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 10; i++) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t2, t2, t1);
+ fe25519_sq(t3, t2);
+ for (i = 1; i < 20; i++) {
+ fe25519_sq(t3, t3);
+ }
+ fe25519_mul(t2, t3, t2);
+ fe25519_sq(t2, t2);
+ for (i = 1; i < 10; i++) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t2, t1);
+ for (i = 1; i < 50; i++) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t2, t2, t1);
+ fe25519_sq(t3, t2);
+ for (i = 1; i < 100; i++) {
+ fe25519_sq(t3, t3);
+ }
+ fe25519_mul(t2, t3, t2);
+ fe25519_sq(t2, t2);
+ for (i = 1; i < 50; i++) {
+ fe25519_sq(t2, t2);
+ }
+ fe25519_mul(t1, t2, t1);
+ fe25519_sq(t1, t1);
+ for (i = 1; i < 4; i++) {
+ fe25519_sq(t1, t1);
+ }
+ fe25519_mul(out, t1, t0);
+}
+
+void
+ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
+{
+ fe25519 e;
+ fe25519 negx;
+ fe25519 rr2;
+ fe25519 x, x2, x3;
+ ge25519_p3 p3;
+ ge25519_p1p1 p1;
+ ge25519_p2 p2;
+ unsigned int e_is_minus_1;
+ unsigned char x_sign;
+
+ memcpy(s, r, 32);
+ x_sign = s[31] & 0x80;
+ s[31] &= 0x7f;
+
+ fe25519_frombytes(rr2, s);
+
+ /* elligator */
+ fe25519_sq2(rr2, rr2);
+ rr2[0]++;
+ fe25519_invert(rr2, rr2);
+ fe25519_mul(x, curve25519_A, rr2);
+ fe25519_neg(x, x);
+
+ fe25519_sq(x2, x);
+ fe25519_mul(x3, x, x2);
+ fe25519_add(e, x3, x);
+ fe25519_mul(x2, x2, curve25519_A);
+ fe25519_add(e, x2, e);
+
+ chi25519(e, e);
+
+ fe25519_tobytes(s, e);
+ e_is_minus_1 = s[1] & 1;
+ fe25519_neg(negx, x);
+ fe25519_cmov(x, negx, e_is_minus_1);
+ fe25519_0(x2);
+ fe25519_cmov(x2, curve25519_A, e_is_minus_1);
+ fe25519_sub(x, x, x2);
+
+ /* yed = (x-1)/(x+1) */
+ {
+ fe25519 one;
+ fe25519 x_plus_one;
+ fe25519 x_plus_one_inv;
+ fe25519 x_minus_one;
+ fe25519 yed;
+
+ fe25519_1(one);
+ fe25519_add(x_plus_one, x, one);
+ fe25519_sub(x_minus_one, x, one);
+ fe25519_invert(x_plus_one_inv, x_plus_one);
+ fe25519_mul(yed, x_minus_one, x_plus_one_inv);
+ fe25519_tobytes(s, yed);
+ }
+
+ /* recover x */
+ s[31] |= x_sign;
+ if (ge25519_frombytes(&p3, s) != 0) {
+ abort(); /* LCOV_EXCL_LINE */
+ }
+
+ /* multiply by the cofactor */
+ ge25519_p3_dbl(&p1, &p3);
+ ge25519_p1p1_to_p2(&p2, &p1);
+ ge25519_p2_dbl(&p1, &p2);
+ ge25519_p1p1_to_p2(&p2, &p1);
+ ge25519_p2_dbl(&p1, &p2);
+ ge25519_p1p1_to_p3(&p3, &p1);
+
+ ge25519_p3_tobytes(s, &p3);
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h
new file mode 100644
index 0000000000..e18530bbb1
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h
@@ -0,0 +1,1344 @@
+{ /* 0/31 */
+ {
+ { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 },
+ { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 },
+ { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }
+ },
+ {
+ { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 },
+ { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 },
+ { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 }
+ },
+ {
+ { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 },
+ { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 },
+ { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }
+ },
+ {
+ { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 },
+ { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 },
+ { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 }
+ },
+ {
+ { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 },
+ { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 },
+ { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }
+ },
+ {
+ { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 },
+ { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 },
+ { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 }
+ },
+ {
+ { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 },
+ { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 },
+ { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }
+ },
+ {
+ { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 },
+ { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 },
+ { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 }
+ }
+},
+{ /* 1/31 */
+ {
+ { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 },
+ { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 },
+ { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 }
+ },
+ {
+ { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 },
+ { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 },
+ { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 }
+ },
+ {
+ { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 },
+ { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 },
+ { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 }
+ },
+ {
+ { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 },
+ { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 },
+ { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 }
+ },
+ {
+ { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 },
+ { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 },
+ { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 }
+ },
+ {
+ { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 },
+ { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 },
+ { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 }
+ },
+ {
+ { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 },
+ { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 },
+ { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 }
+ },
+ {
+ { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 },
+ { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 },
+ { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 }
+ }
+},
+{ /* 2/31 */
+ {
+ { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 },
+ { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 },
+ { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 }
+ },
+ {
+ { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 },
+ { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 },
+ { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 }
+ },
+ {
+ { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 },
+ { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 },
+ { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 }
+ },
+ {
+ { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 },
+ { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 },
+ { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 }
+ },
+ {
+ { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 },
+ { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 },
+ { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 }
+ },
+ {
+ { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 },
+ { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 },
+ { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 }
+ },
+ {
+ { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 },
+ { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 },
+ { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 }
+ },
+ {
+ { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 },
+ { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 },
+ { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 }
+ }
+},
+{ /* 3/31 */
+ {
+ { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 },
+ { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 },
+ { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 }
+ },
+ {
+ { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 },
+ { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 },
+ { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 }
+ },
+ {
+ { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 },
+ { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 },
+ { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 }
+ },
+ {
+ { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 },
+ { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 },
+ { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 }
+ },
+ {
+ { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 },
+ { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 },
+ { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 }
+ },
+ {
+ { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 },
+ { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 },
+ { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 }
+ },
+ {
+ { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 },
+ { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 },
+ { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 }
+ },
+ {
+ { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 },
+ { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 },
+ { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 }
+ }
+},
+{ /* 4/31 */
+ {
+ { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 },
+ { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 },
+ { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 }
+ },
+ {
+ { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 },
+ { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 },
+ { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 }
+ },
+ {
+ { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 },
+ { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 },
+ { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 }
+ },
+ {
+ { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 },
+ { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 },
+ { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 }
+ },
+ {
+ { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 },
+ { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 },
+ { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 }
+ },
+ {
+ { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 },
+ { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 },
+ { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 }
+ },
+ {
+ { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 },
+ { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 },
+ { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 }
+ },
+ {
+ { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 },
+ { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 },
+ { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 }
+ }
+},
+{ /* 5/31 */
+ {
+ { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 },
+ { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 },
+ { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 }
+ },
+ {
+ { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 },
+ { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 },
+ { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 }
+ },
+ {
+ { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 },
+ { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 },
+ { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 }
+ },
+ {
+ { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 },
+ { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 },
+ { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 }
+ },
+ {
+ { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 },
+ { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 },
+ { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 }
+ },
+ {
+ { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 },
+ { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 },
+ { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 }
+ },
+ {
+ { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 },
+ { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 },
+ { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 }
+ },
+ {
+ { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 },
+ { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 },
+ { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 }
+ }
+},
+{ /* 6/31 */
+ {
+ { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 },
+ { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 },
+ { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 }
+ },
+ {
+ { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 },
+ { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 },
+ { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 }
+ },
+ {
+ { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 },
+ { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 },
+ { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 }
+ },
+ {
+ { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 },
+ { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 },
+ { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 }
+ },
+ {
+ { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 },
+ { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 },
+ { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 }
+ },
+ {
+ { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 },
+ { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 },
+ { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 }
+ },
+ {
+ { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 },
+ { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 },
+ { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 }
+ },
+ {
+ { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 },
+ { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 },
+ { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 }
+ }
+},
+{ /* 7/31 */
+ {
+ { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 },
+ { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 },
+ { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 }
+ },
+ {
+ { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 },
+ { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 },
+ { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 }
+ },
+ {
+ { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 },
+ { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 },
+ { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 }
+ },
+ {
+ { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 },
+ { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 },
+ { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 }
+ },
+ {
+ { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 },
+ { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 },
+ { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 }
+ },
+ {
+ { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 },
+ { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 },
+ { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 }
+ },
+ {
+ { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 },
+ { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 },
+ { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 }
+ },
+ {
+ { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 },
+ { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 },
+ { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 }
+ }
+},
+{ /* 8/31 */
+ {
+ { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 },
+ { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 },
+ { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 }
+ },
+ {
+ { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 },
+ { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 },
+ { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 }
+ },
+ {
+ { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 },
+ { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 },
+ { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 }
+ },
+ {
+ { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 },
+ { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 },
+ { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 }
+ },
+ {
+ { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 },
+ { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 },
+ { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 }
+ },
+ {
+ { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 },
+ { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 },
+ { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 }
+ },
+ {
+ { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 },
+ { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 },
+ { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 }
+ },
+ {
+ { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 },
+ { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 },
+ { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 }
+ }
+},
+{ /* 9/31 */
+ {
+ { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 },
+ { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 },
+ { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 }
+ },
+ {
+ { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 },
+ { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 },
+ { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 }
+ },
+ {
+ { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 },
+ { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 },
+ { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 }
+ },
+ {
+ { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 },
+ { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 },
+ { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 }
+ },
+ {
+ { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 },
+ { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 },
+ { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 }
+ },
+ {
+ { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 },
+ { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 },
+ { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 }
+ },
+ {
+ { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 },
+ { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 },
+ { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 }
+ },
+ {
+ { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 },
+ { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 },
+ { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 }
+ }
+},
+{ /* 10/31 */
+ {
+ { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 },
+ { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 },
+ { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 }
+ },
+ {
+ { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 },
+ { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 },
+ { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 }
+ },
+ {
+ { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 },
+ { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 },
+ { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 }
+ },
+ {
+ { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 },
+ { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 },
+ { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 }
+ },
+ {
+ { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 },
+ { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 },
+ { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 }
+ },
+ {
+ { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 },
+ { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 },
+ { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 }
+ },
+ {
+ { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 },
+ { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 },
+ { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 }
+ },
+ {
+ { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 },
+ { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 },
+ { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 }
+ }
+},
+{ /* 11/31 */
+ {
+ { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 },
+ { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 },
+ { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 }
+ },
+ {
+ { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 },
+ { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 },
+ { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 }
+ },
+ {
+ { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 },
+ { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 },
+ { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 }
+ },
+ {
+ { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 },
+ { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 },
+ { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 }
+ },
+ {
+ { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 },
+ { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 },
+ { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 }
+ },
+ {
+ { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 },
+ { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 },
+ { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 }
+ },
+ {
+ { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 },
+ { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 },
+ { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 }
+ },
+ {
+ { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 },
+ { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 },
+ { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 }
+ }
+},
+{ /* 12/31 */
+ {
+ { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 },
+ { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 },
+ { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 }
+ },
+ {
+ { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 },
+ { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 },
+ { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 }
+ },
+ {
+ { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 },
+ { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 },
+ { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 }
+ },
+ {
+ { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 },
+ { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 },
+ { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 }
+ },
+ {
+ { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 },
+ { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 },
+ { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 }
+ },
+ {
+ { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 },
+ { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 },
+ { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 }
+ },
+ {
+ { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 },
+ { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 },
+ { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 }
+ },
+ {
+ { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 },
+ { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 },
+ { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 }
+ }
+},
+{ /* 13/31 */
+ {
+ { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 },
+ { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 },
+ { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 }
+ },
+ {
+ { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 },
+ { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 },
+ { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 }
+ },
+ {
+ { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 },
+ { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 },
+ { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 }
+ },
+ {
+ { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 },
+ { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 },
+ { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 }
+ },
+ {
+ { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 },
+ { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 },
+ { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 }
+ },
+ {
+ { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 },
+ { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 },
+ { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 }
+ },
+ {
+ { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 },
+ { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 },
+ { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 }
+ },
+ {
+ { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 },
+ { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 },
+ { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 }
+ }
+},
+{ /* 14/31 */
+ {
+ { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 },
+ { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 },
+ { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 }
+ },
+ {
+ { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 },
+ { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 },
+ { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 }
+ },
+ {
+ { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 },
+ { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 },
+ { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 }
+ },
+ {
+ { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 },
+ { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 },
+ { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 }
+ },
+ {
+ { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 },
+ { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 },
+ { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 }
+ },
+ {
+ { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 },
+ { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 },
+ { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 }
+ },
+ {
+ { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 },
+ { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 },
+ { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 }
+ },
+ {
+ { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 },
+ { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 },
+ { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 }
+ }
+},
+{ /* 15/31 */
+ {
+ { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 },
+ { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 },
+ { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 }
+ },
+ {
+ { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 },
+ { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 },
+ { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 }
+ },
+ {
+ { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 },
+ { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 },
+ { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 }
+ },
+ {
+ { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 },
+ { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 },
+ { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 }
+ },
+ {
+ { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 },
+ { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 },
+ { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 }
+ },
+ {
+ { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 },
+ { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 },
+ { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 }
+ },
+ {
+ { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 },
+ { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 },
+ { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 }
+ },
+ {
+ { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 },
+ { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 },
+ { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 }
+ }
+},
+{ /* 16/31 */
+ {
+ { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 },
+ { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 },
+ { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 }
+ },
+ {
+ { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 },
+ { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 },
+ { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 }
+ },
+ {
+ { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 },
+ { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 },
+ { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 }
+ },
+ {
+ { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 },
+ { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 },
+ { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 }
+ },
+ {
+ { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 },
+ { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 },
+ { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 }
+ },
+ {
+ { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 },
+ { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 },
+ { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 }
+ },
+ {
+ { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 },
+ { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 },
+ { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 }
+ },
+ {
+ { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 },
+ { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 },
+ { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 }
+ }
+},
+{ /* 17/31 */
+ {
+ { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 },
+ { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 },
+ { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 }
+ },
+ {
+ { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 },
+ { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 },
+ { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 }
+ },
+ {
+ { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 },
+ { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 },
+ { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 }
+ },
+ {
+ { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 },
+ { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 },
+ { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 }
+ },
+ {
+ { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 },
+ { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 },
+ { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 }
+ },
+ {
+ { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 },
+ { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 },
+ { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 }
+ },
+ {
+ { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 },
+ { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 },
+ { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 }
+ },
+ {
+ { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 },
+ { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 },
+ { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 }
+ }
+},
+{ /* 18/31 */
+ {
+ { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 },
+ { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 },
+ { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 }
+ },
+ {
+ { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 },
+ { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 },
+ { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 }
+ },
+ {
+ { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 },
+ { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 },
+ { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 }
+ },
+ {
+ { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 },
+ { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 },
+ { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 }
+ },
+ {
+ { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 },
+ { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 },
+ { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 }
+ },
+ {
+ { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 },
+ { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 },
+ { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 }
+ },
+ {
+ { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 },
+ { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 },
+ { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 }
+ },
+ {
+ { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 },
+ { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 },
+ { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 }
+ }
+},
+{ /* 19/31 */
+ {
+ { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 },
+ { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 },
+ { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 }
+ },
+ {
+ { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 },
+ { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 },
+ { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 }
+ },
+ {
+ { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 },
+ { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 },
+ { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 }
+ },
+ {
+ { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 },
+ { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 },
+ { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 }
+ },
+ {
+ { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 },
+ { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 },
+ { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 }
+ },
+ {
+ { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 },
+ { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 },
+ { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 }
+ },
+ {
+ { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 },
+ { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 },
+ { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 }
+ },
+ {
+ { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 },
+ { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 },
+ { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 }
+ }
+},
+{ /* 20/31 */
+ {
+ { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 },
+ { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 },
+ { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 }
+ },
+ {
+ { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 },
+ { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 },
+ { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 }
+ },
+ {
+ { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 },
+ { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 },
+ { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 }
+ },
+ {
+ { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 },
+ { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 },
+ { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 }
+ },
+ {
+ { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 },
+ { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 },
+ { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 }
+ },
+ {
+ { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 },
+ { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 },
+ { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 }
+ },
+ {
+ { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 },
+ { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 },
+ { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 }
+ },
+ {
+ { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 },
+ { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 },
+ { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 }
+ }
+},
+{ /* 21/31 */
+ {
+ { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 },
+ { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 },
+ { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 }
+ },
+ {
+ { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 },
+ { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 },
+ { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 }
+ },
+ {
+ { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 },
+ { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 },
+ { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 }
+ },
+ {
+ { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 },
+ { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 },
+ { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 }
+ },
+ {
+ { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 },
+ { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 },
+ { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 }
+ },
+ {
+ { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 },
+ { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 },
+ { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 }
+ },
+ {
+ { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 },
+ { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 },
+ { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 }
+ },
+ {
+ { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 },
+ { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 },
+ { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 }
+ }
+},
+{ /* 22/31 */
+ {
+ { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 },
+ { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 },
+ { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 }
+ },
+ {
+ { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 },
+ { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 },
+ { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 }
+ },
+ {
+ { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 },
+ { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 },
+ { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 }
+ },
+ {
+ { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 },
+ { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 },
+ { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 }
+ },
+ {
+ { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 },
+ { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 },
+ { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 }
+ },
+ {
+ { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 },
+ { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 },
+ { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 }
+ },
+ {
+ { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 },
+ { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 },
+ { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 }
+ },
+ {
+ { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 },
+ { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 },
+ { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 }
+ }
+},
+{ /* 23/31 */
+ {
+ { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 },
+ { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 },
+ { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 }
+ },
+ {
+ { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 },
+ { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 },
+ { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 }
+ },
+ {
+ { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 },
+ { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 },
+ { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 }
+ },
+ {
+ { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 },
+ { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 },
+ { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 }
+ },
+ {
+ { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 },
+ { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 },
+ { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 }
+ },
+ {
+ { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 },
+ { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 },
+ { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 }
+ },
+ {
+ { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 },
+ { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 },
+ { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 }
+ },
+ {
+ { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 },
+ { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 },
+ { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 }
+ }
+},
+{ /* 24/31 */
+ {
+ { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 },
+ { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 },
+ { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 }
+ },
+ {
+ { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 },
+ { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 },
+ { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 }
+ },
+ {
+ { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 },
+ { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 },
+ { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 }
+ },
+ {
+ { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 },
+ { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 },
+ { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 }
+ },
+ {
+ { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 },
+ { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 },
+ { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 }
+ },
+ {
+ { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 },
+ { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 },
+ { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 }
+ },
+ {
+ { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 },
+ { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 },
+ { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 }
+ },
+ {
+ { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 },
+ { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 },
+ { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 }
+ }
+},
+{ /* 25/31 */
+ {
+ { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 },
+ { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 },
+ { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 }
+ },
+ {
+ { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 },
+ { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 },
+ { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 }
+ },
+ {
+ { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 },
+ { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 },
+ { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 }
+ },
+ {
+ { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 },
+ { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 },
+ { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 }
+ },
+ {
+ { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 },
+ { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 },
+ { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 }
+ },
+ {
+ { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 },
+ { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 },
+ { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 }
+ },
+ {
+ { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 },
+ { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 },
+ { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 }
+ },
+ {
+ { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 },
+ { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 },
+ { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 }
+ }
+},
+{ /* 26/31 */
+ {
+ { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 },
+ { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 },
+ { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 }
+ },
+ {
+ { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 },
+ { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 },
+ { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 }
+ },
+ {
+ { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 },
+ { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 },
+ { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 }
+ },
+ {
+ { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 },
+ { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 },
+ { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 }
+ },
+ {
+ { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 },
+ { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 },
+ { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 }
+ },
+ {
+ { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 },
+ { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 },
+ { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 }
+ },
+ {
+ { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 },
+ { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 },
+ { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 }
+ },
+ {
+ { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 },
+ { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 },
+ { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 }
+ }
+},
+{ /* 27/31 */
+ {
+ { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 },
+ { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 },
+ { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 }
+ },
+ {
+ { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 },
+ { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 },
+ { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 }
+ },
+ {
+ { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 },
+ { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 },
+ { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 }
+ },
+ {
+ { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 },
+ { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 },
+ { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 }
+ },
+ {
+ { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 },
+ { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 },
+ { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 }
+ },
+ {
+ { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 },
+ { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 },
+ { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 }
+ },
+ {
+ { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 },
+ { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 },
+ { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 }
+ },
+ {
+ { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 },
+ { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 },
+ { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 }
+ }
+},
+{ /* 28/31 */
+ {
+ { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 },
+ { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 },
+ { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 }
+ },
+ {
+ { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 },
+ { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 },
+ { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 }
+ },
+ {
+ { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 },
+ { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 },
+ { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 }
+ },
+ {
+ { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 },
+ { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 },
+ { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 }
+ },
+ {
+ { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 },
+ { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 },
+ { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 }
+ },
+ {
+ { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 },
+ { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 },
+ { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 }
+ },
+ {
+ { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 },
+ { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 },
+ { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 }
+ },
+ {
+ { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 },
+ { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 },
+ { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 }
+ }
+},
+{ /* 29/31 */
+ {
+ { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 },
+ { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 },
+ { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 }
+ },
+ {
+ { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 },
+ { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 },
+ { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 }
+ },
+ {
+ { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 },
+ { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 },
+ { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 }
+ },
+ {
+ { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 },
+ { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 },
+ { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 }
+ },
+ {
+ { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 },
+ { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 },
+ { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 }
+ },
+ {
+ { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 },
+ { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 },
+ { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 }
+ },
+ {
+ { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 },
+ { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 },
+ { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 }
+ },
+ {
+ { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 },
+ { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 },
+ { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 }
+ }
+},
+{ /* 30/31 */
+ {
+ { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 },
+ { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 },
+ { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 }
+ },
+ {
+ { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 },
+ { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 },
+ { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 }
+ },
+ {
+ { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 },
+ { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 },
+ { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 }
+ },
+ {
+ { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 },
+ { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 },
+ { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 }
+ },
+ {
+ { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 },
+ { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 },
+ { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 }
+ },
+ {
+ { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 },
+ { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 },
+ { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 }
+ },
+ {
+ { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 },
+ { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 },
+ { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 }
+ },
+ {
+ { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 },
+ { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 },
+ { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 }
+ }
+},
+{ /* 31/31 */
+ {
+ { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 },
+ { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 },
+ { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 }
+ },
+ {
+ { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 },
+ { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 },
+ { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 }
+ },
+ {
+ { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 },
+ { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 },
+ { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 }
+ },
+ {
+ { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 },
+ { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 },
+ { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 }
+ },
+ {
+ { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 },
+ { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 },
+ { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 }
+ },
+ {
+ { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 },
+ { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 },
+ { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 }
+ },
+ {
+ { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 },
+ { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 },
+ { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 }
+ },
+ {
+ { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 },
+ { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 },
+ { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 }
+ }
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h
new file mode 100644
index 0000000000..90a1457eab
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h
@@ -0,0 +1,40 @@
+{
+ { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 },
+ { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 },
+ { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 }
+},
+{
+ { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 },
+ { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 },
+ { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 }
+},
+{
+ { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 },
+ { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 },
+ { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 }
+},
+{
+ { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 },
+ { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 },
+ { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 }
+},
+{
+ { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 },
+ { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 },
+ { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 }
+},
+{
+ { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 },
+ { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 },
+ { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 }
+},
+{
+ { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 },
+ { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 },
+ { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 }
+},
+{
+ { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 },
+ { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 },
+ { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 }
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h
new file mode 100644
index 0000000000..3dc9156a31
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h
@@ -0,0 +1,20 @@
+/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */
+static const fe25519 d = {
+ -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
+};
+
+/* 2 * d =
+ * 16295367250680780974490674513165176452449235426866156013048779062215315747161
+ */
+static const fe25519 d2 = {
+ -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 };
+
+/* sqrt(-1) */
+static const fe25519 sqrtm1 = {
+ -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
+};
+
+/* A = 486662 */
+static const fe25519 curve25519_A = {
+ 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h
new file mode 100644
index 0000000000..f216669e4e
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h
@@ -0,0 +1,220 @@
+/*
+ Ignores top bit of h.
+ */
+
+void
+fe25519_frombytes(fe25519 h, const unsigned char *s)
+{
+ int64_t h0 = load_4(s);
+ int64_t h1 = load_3(s + 4) << 6;
+ int64_t h2 = load_3(s + 7) << 5;
+ int64_t h3 = load_3(s + 10) << 3;
+ int64_t h4 = load_3(s + 13) << 2;
+ int64_t h5 = load_4(s + 16);
+ int64_t h6 = load_3(s + 20) << 7;
+ int64_t h7 = load_3(s + 23) << 5;
+ int64_t h8 = load_3(s + 26) << 4;
+ int64_t h9 = (load_3(s + 29) & 8388607) << 2;
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ carry9 = (h9 + (int64_t)(1L << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 * ((uint64_t) 1L << 25);
+ carry1 = (h1 + (int64_t)(1L << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((uint64_t) 1L << 25);
+ carry3 = (h3 + (int64_t)(1L << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((uint64_t) 1L << 25);
+ carry5 = (h5 + (int64_t)(1L << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((uint64_t) 1L << 25);
+ carry7 = (h7 + (int64_t)(1L << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((uint64_t) 1L << 25);
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+ carry2 = (h2 + (int64_t)(1L << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((uint64_t) 1L << 26);
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+ carry6 = (h6 + (int64_t)(1L << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((uint64_t) 1L << 26);
+ carry8 = (h8 + (int64_t)(1L << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((uint64_t) 1L << 26);
+
+ h[0] = (int32_t) h0;
+ h[1] = (int32_t) h1;
+ h[2] = (int32_t) h2;
+ h[3] = (int32_t) h3;
+ h[4] = (int32_t) h4;
+ h[5] = (int32_t) h5;
+ h[6] = (int32_t) h6;
+ h[7] = (int32_t) h7;
+ h[8] = (int32_t) h8;
+ h[9] = (int32_t) h9;
+}
+
+/*
+ Preconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+
+ Write p=2^255-19; q=floor(h/p).
+ Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+
+ Proof:
+ Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+ Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
+
+ Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+ Then 0<y<1.
+
+ Write r=h-pq.
+ Have 0<=r<=p-1=2^255-20.
+ Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+
+ Write x=r+19(2^-255)r+y.
+ Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+
+ Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+ so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
+*/
+
+static void
+fe25519_reduce(fe25519 h, const fe25519 f)
+{
+ int32_t h0 = f[0];
+ int32_t h1 = f[1];
+ int32_t h2 = f[2];
+ int32_t h3 = f[3];
+ int32_t h4 = f[4];
+ int32_t h5 = f[5];
+ int32_t h6 = f[6];
+ int32_t h7 = f[7];
+ int32_t h8 = f[8];
+ int32_t h9 = f[9];
+
+ int32_t q;
+ int32_t carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9;
+
+ q = (19 * h9 + ((uint32_t) 1L << 24)) >> 25;
+ q = (h0 + q) >> 26;
+ q = (h1 + q) >> 25;
+ q = (h2 + q) >> 26;
+ q = (h3 + q) >> 25;
+ q = (h4 + q) >> 26;
+ q = (h5 + q) >> 25;
+ q = (h6 + q) >> 26;
+ q = (h7 + q) >> 25;
+ q = (h8 + q) >> 26;
+ q = (h9 + q) >> 25;
+
+ /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
+ h0 += 19 * q;
+ /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
+
+ carry0 = h0 >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint32_t) 1L << 26);
+ carry1 = h1 >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((uint32_t) 1L << 25);
+ carry2 = h2 >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((uint32_t) 1L << 26);
+ carry3 = h3 >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((uint32_t) 1L << 25);
+ carry4 = h4 >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint32_t) 1L << 26);
+ carry5 = h5 >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((uint32_t) 1L << 25);
+ carry6 = h6 >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((uint32_t) 1L << 26);
+ carry7 = h7 >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((uint32_t) 1L << 25);
+ carry8 = h8 >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((uint32_t) 1L << 26);
+ carry9 = h9 >> 25;
+ h9 -= carry9 * ((uint32_t) 1L << 25);
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/*
+ Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+ Have h0+...+2^230 h9 between 0 and 2^255-1;
+ evidently 2^255 h10-2^255 q = 0.
+
+ Goal: Output h0+...+2^230 h9.
+ */
+
+void
+fe25519_tobytes(unsigned char *s, const fe25519 h)
+{
+ fe25519 t;
+
+ fe25519_reduce(t, h);
+ s[0] = t[0] >> 0;
+ s[1] = t[0] >> 8;
+ s[2] = t[0] >> 16;
+ s[3] = (t[0] >> 24) | (t[1] * ((uint32_t) 1 << 2));
+ s[4] = t[1] >> 6;
+ s[5] = t[1] >> 14;
+ s[6] = (t[1] >> 22) | (t[2] * ((uint32_t) 1 << 3));
+ s[7] = t[2] >> 5;
+ s[8] = t[2] >> 13;
+ s[9] = (t[2] >> 21) | (t[3] * ((uint32_t) 1 << 5));
+ s[10] = t[3] >> 3;
+ s[11] = t[3] >> 11;
+ s[12] = (t[3] >> 19) | (t[4] * ((uint32_t) 1 << 6));
+ s[13] = t[4] >> 2;
+ s[14] = t[4] >> 10;
+ s[15] = t[4] >> 18;
+ s[16] = t[5] >> 0;
+ s[17] = t[5] >> 8;
+ s[18] = t[5] >> 16;
+ s[19] = (t[5] >> 24) | (t[6] * ((uint32_t) 1 << 1));
+ s[20] = t[6] >> 7;
+ s[21] = t[6] >> 15;
+ s[22] = (t[6] >> 23) | (t[7] * ((uint32_t) 1 << 3));
+ s[23] = t[7] >> 5;
+ s[24] = t[7] >> 13;
+ s[25] = (t[7] >> 21) | (t[8] * ((uint32_t) 1 << 4));
+ s[26] = t[8] >> 4;
+ s[27] = t[8] >> 12;
+ s[28] = (t[8] >> 20) | (t[9] * ((uint32_t) 1 << 6));
+ s[29] = t[9] >> 2;
+ s[30] = t[9] >> 10;
+ s[31] = t[9] >> 18;
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h
new file mode 100644
index 0000000000..6b3b833e7a
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h
@@ -0,0 +1,1344 @@
+{ /* 0/31 */
+ {
+ { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 },
+ { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 },
+ { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 }
+ },
+ {
+ { 1380971894829527, 790832306631236, 2067202295274102, 1995808275510000, 1566530869037010 },
+ { 463307831301544, 432984605774163, 1610641361907204, 750899048855000, 1894842303421586 },
+ { 748439484463711, 1033211726465151, 1396005112841647, 1611506220286469, 1972177495910992 }
+ },
+ {
+ { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 },
+ { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 },
+ { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 }
+ },
+ {
+ { 934282339813791, 1846903124198670, 1172395437954843, 1007037127761661, 1830588347719256 },
+ { 1694390458783935, 1735906047636159, 705069562067493, 648033061693059, 696214010414170 },
+ { 1121406372216585, 192876649532226, 190294192191717, 1994165897297032, 2245000007398739 }
+ },
+ {
+ { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 },
+ { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 },
+ { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 }
+ },
+ {
+ { 1388594989461809, 316767091099457, 394298842192982, 1230079486801005, 1440737038838979 },
+ { 7380825640100, 146210432690483, 304903576448906, 1198869323871120, 997689833219095 },
+ { 1181317918772081, 114573476638901, 262805072233344, 265712217171332, 294181933805782 }
+ },
+ {
+ { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 },
+ { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 },
+ { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 }
+ },
+ {
+ { 2068619540119183, 1966274918058806, 957728544705549, 729906502578991, 159834893065166 },
+ { 2073601412052185, 31021124762708, 264500969797082, 248034690651703, 1030252227928288 },
+ { 551790716293402, 1989538725166328, 801169423371717, 2052451893578887, 678432056995012 }
+ }
+},
+{ /* 1/31 */
+ {
+ { 1368953770187805, 790347636712921, 437508475667162, 2142576377050580, 1932081720066286 },
+ { 953638594433374, 1092333936795051, 1419774766716690, 805677984380077, 859228993502513 },
+ { 1200766035879111, 20142053207432, 1465634435977050, 1645256912097844, 295121984874596 }
+ },
+ {
+ { 1735718747031557, 1248237894295956, 1204753118328107, 976066523550493, 65943769534592 },
+ { 1060098822528990, 1586825862073490, 212301317240126, 1975302711403555, 666724059764335 },
+ { 1091990273418756, 1572899409348578, 80968014455247, 306009358661350, 1520450739132526 }
+ },
+ {
+ { 1480517209436112, 1511153322193952, 1244343858991172, 304788150493241, 369136856496443 },
+ { 2151330273626164, 762045184746182, 1688074332551515, 823046109005759, 907602769079491 },
+ { 2047386910586836, 168470092900250, 1552838872594810, 340951180073789, 360819374702533 }
+ },
+ {
+ { 1982622644432056, 2014393600336956, 128909208804214, 1617792623929191, 105294281913815 },
+ { 980234343912898, 1712256739246056, 588935272190264, 204298813091998, 841798321043288 },
+ { 197561292938973, 454817274782871, 1963754960082318, 2113372252160468, 971377527342673 }
+ },
+ {
+ { 164699448829328, 3127451757672, 1199504971548753, 1766155447043652, 1899238924683527 },
+ { 732262946680281, 1674412764227063, 2182456405662809, 1350894754474250, 558458873295247 },
+ { 2103305098582922, 1960809151316468, 715134605001343, 1454892949167181, 40827143824949 }
+ },
+ {
+ { 1239289043050212, 1744654158124578, 758702410031698, 1796762995074688, 1603056663766 },
+ { 2232056027107988, 987343914584615, 2115594492994461, 1819598072792159, 1119305654014850 },
+ { 320153677847348, 939613871605645, 641883205761567, 1930009789398224, 329165806634126 }
+ },
+ {
+ { 980930490474130, 1242488692177893, 1251446316964684, 1086618677993530, 1961430968465772 },
+ { 276821765317453, 1536835591188030, 1305212741412361, 61473904210175, 2051377036983058 },
+ { 833449923882501, 1750270368490475, 1123347002068295, 185477424765687, 278090826653186 }
+ },
+ {
+ { 794524995833413, 1849907304548286, 53348672473145, 1272368559505217, 1147304168324779 },
+ { 1504846112759364, 1203096289004681, 562139421471418, 274333017451844, 1284344053775441 },
+ { 483048732424432, 2116063063343382, 30120189902313, 292451576741007, 1156379271702225 }
+ }
+},
+{ /* 2/31 */
+ {
+ { 928372153029038, 2147692869914564, 1455665844462196, 1986737809425946, 185207050258089 },
+ { 137732961814206, 706670923917341, 1387038086865771, 1965643813686352, 1384777115696347 },
+ { 481144981981577, 2053319313589856, 2065402289827512, 617954271490316, 1106602634668125 }
+ },
+ {
+ { 696298019648792, 893299659040895, 1148636718636009, 26734077349617, 2203955659340681 },
+ { 657390353372855, 998499966885562, 991893336905797, 810470207106761, 343139804608786 },
+ { 791736669492960, 934767652997115, 824656780392914, 1759463253018643, 361530362383518 }
+ },
+ {
+ { 2022541353055597, 2094700262587466, 1551008075025686, 242785517418164, 695985404963562 },
+ { 1287487199965223, 2215311941380308, 1552928390931986, 1664859529680196, 1125004975265243 },
+ { 677434665154918, 989582503122485, 1817429540898386, 1052904935475344, 1143826298169798 }
+ },
+ {
+ { 367266328308408, 318431188922404, 695629353755355, 634085657580832, 24581612564426 },
+ { 773360688841258, 1815381330538070, 363773437667376, 539629987070205, 783280434248437 },
+ { 180820816194166, 168937968377394, 748416242794470, 1227281252254508, 1567587861004268 }
+ },
+ {
+ { 478775558583645, 2062896624554807, 699391259285399, 358099408427873, 1277310261461761 },
+ { 1984740906540026, 1079164179400229, 1056021349262661, 1659958556483663, 1088529069025527 },
+ { 580736401511151, 1842931091388998, 1177201471228238, 2075460256527244, 1301133425678027 }
+ },
+ {
+ { 1515728832059182, 1575261009617579, 1510246567196186, 191078022609704, 116661716289141 },
+ { 1295295738269652, 1714742313707026, 545583042462581, 2034411676262552, 1513248090013606 },
+ { 230710545179830, 30821514358353, 760704303452229, 390668103790604, 573437871383156 }
+ },
+ {
+ { 1169380107545646, 263167233745614, 2022901299054448, 819900753251120, 2023898464874585 },
+ { 2102254323485823, 1570832666216754, 34696906544624, 1993213739807337, 70638552271463 },
+ { 894132856735058, 548675863558441, 845349339503395, 1942269668326667, 1615682209874691 }
+ },
+ {
+ { 1287670217537834, 1222355136884920, 1846481788678694, 1150426571265110, 1613523400722047 },
+ { 793388516527298, 1315457083650035, 1972286999342417, 1901825953052455, 338269477222410 },
+ { 550201530671806, 778605267108140, 2063911101902983, 115500557286349, 2041641272971022 }
+ }
+},
+{ /* 3/31 */
+ {
+ { 717255318455100, 519313764361315, 2080406977303708, 541981206705521, 774328150311600 },
+ { 261715221532238, 1795354330069993, 1496878026850283, 499739720521052, 389031152673770 },
+ { 1997217696294013, 1717306351628065, 1684313917746180, 1644426076011410, 1857378133465451 }
+ },
+ {
+ { 1475434724792648, 76931896285979, 1116729029771667, 2002544139318042, 725547833803938 },
+ { 2022306639183567, 726296063571875, 315345054448644, 1058733329149221, 1448201136060677 },
+ { 1710065158525665, 1895094923036397, 123988286168546, 1145519900776355, 1607510767693874 }
+ },
+ {
+ { 561605375422540, 1071733543815037, 131496498800990, 1946868434569999, 828138133964203 },
+ { 1548495173745801, 442310529226540, 998072547000384, 553054358385281, 644824326376171 },
+ { 1445526537029440, 2225519789662536, 914628859347385, 1064754194555068, 1660295614401091 }
+ },
+ {
+ { 1199690223111956, 24028135822341, 66638289244341, 57626156285975, 565093967979607 },
+ { 876926774220824, 554618976488214, 1012056309841565, 839961821554611, 1414499340307677 },
+ { 703047626104145, 1266841406201770, 165556500219173, 486991595001879, 1011325891650656 }
+ },
+ {
+ { 1622861044480487, 1156394801573634, 1869132565415504, 327103985777730, 2095342781472284 },
+ { 334886927423922, 489511099221528, 129160865966726, 1720809113143481, 619700195649254 },
+ { 1646545795166119, 1758370782583567, 714746174550637, 1472693650165135, 898994790308209 }
+ },
+ {
+ { 333403773039279, 295772542452938, 1693106465353610, 912330357530760, 471235657950362 },
+ { 1811196219982022, 1068969825533602, 289602974833439, 1988956043611592, 863562343398367 },
+ { 906282429780072, 2108672665779781, 432396390473936, 150625823801893, 1708930497638539 }
+ },
+ {
+ { 925664675702328, 21416848568684, 1831436641861340, 601157008940113, 371818055044496 },
+ { 1479786007267725, 1738881859066675, 68646196476567, 2146507056100328, 1247662817535471 },
+ { 52035296774456, 939969390708103, 312023458773250, 59873523517659, 1231345905848899 }
+ },
+ {
+ { 643355106415761, 290186807495774, 2013561737429023, 319648069511546, 393736678496162 },
+ { 129358342392716, 1932811617704777, 1176749390799681, 398040349861790, 1170779668090425 },
+ { 2051980782668029, 121859921510665, 2048329875753063, 1235229850149665, 519062146124755 }
+ }
+},
+{ /* 4/31 */
+ {
+ { 1608170971973096, 415809060360428, 1350468408164766, 2038620059057678, 1026904485989112 },
+ { 1837656083115103, 1510134048812070, 906263674192061, 1821064197805734, 565375124676301 },
+ { 578027192365650, 2034800251375322, 2128954087207123, 478816193810521, 2196171989962750 }
+ },
+ {
+ { 1633188840273139, 852787172373708, 1548762607215796, 1266275218902681, 1107218203325133 },
+ { 462189358480054, 1784816734159228, 1611334301651368, 1303938263943540, 707589560319424 },
+ { 1038829280972848, 38176604650029, 753193246598573, 1136076426528122, 595709990562434 }
+ },
+ {
+ { 1408451820859834, 2194984964010833, 2198361797561729, 1061962440055713, 1645147963442934 },
+ { 4701053362120, 1647641066302348, 1047553002242085, 1923635013395977, 206970314902065 },
+ { 1750479161778571, 1362553355169293, 1891721260220598, 966109370862782, 1024913988299801 }
+ },
+ {
+ { 212699049131723, 1117950018299775, 1873945661751056, 1403802921984058, 130896082652698 },
+ { 636808533673210, 1262201711667560, 390951380330599, 1663420692697294, 561951321757406 },
+ { 520731594438141, 1446301499955692, 273753264629267, 1565101517999256, 1019411827004672 }
+ },
+ {
+ { 926527492029409, 1191853477411379, 734233225181171, 184038887541270, 1790426146325343 },
+ { 1464651961852572, 1483737295721717, 1519450561335517, 1161429831763785, 405914998179977 },
+ { 996126634382301, 796204125879525, 127517800546509, 344155944689303, 615279846169038 }
+ },
+ {
+ { 738724080975276, 2188666632415296, 1961313708559162, 1506545807547587, 1151301638969740 },
+ { 622917337413835, 1218989177089035, 1284857712846592, 970502061709359, 351025208117090 },
+ { 2067814584765580, 1677855129927492, 2086109782475197, 235286517313238, 1416314046739645 }
+ },
+ {
+ { 586844262630358, 307444381952195, 458399356043426, 602068024507062, 1028548203415243 },
+ { 678489922928203, 2016657584724032, 90977383049628, 1026831907234582, 615271492942522 },
+ { 301225714012278, 1094837270268560, 1202288391010439, 644352775178361, 1647055902137983 }
+ },
+ {
+ { 1210746697896478, 1416608304244708, 686487477217856, 1245131191434135, 1051238336855737 },
+ { 1135604073198207, 1683322080485474, 769147804376683, 2086688130589414, 900445683120379 },
+ { 1971518477615628, 401909519527336, 448627091057375, 1409486868273821, 1214789035034363 }
+ }
+},
+{ /* 5/31 */
+ {
+ { 1364039144731711, 1897497433586190, 2203097701135459, 145461396811251, 1349844460790699 },
+ { 1045230323257973, 818206601145807, 630513189076103, 1672046528998132, 807204017562437 },
+ { 439961968385997, 386362664488986, 1382706320807688, 309894000125359, 2207801346498567 }
+ },
+ {
+ { 1229004686397588, 920643968530863, 123975893911178, 681423993215777, 1400559197080973 },
+ { 2003766096898049, 170074059235165, 1141124258967971, 1485419893480973, 1573762821028725 },
+ { 729905708611432, 1270323270673202, 123353058984288, 426460209632942, 2195574535456672 }
+ },
+ {
+ { 1271140255321235, 2044363183174497, 52125387634689, 1445120246694705, 942541986339084 },
+ { 1761608437466135, 583360847526804, 1586706389685493, 2157056599579261, 1170692369685772 },
+ { 871476219910823, 1878769545097794, 2241832391238412, 548957640601001, 690047440233174 }
+ },
+ {
+ { 297194732135507, 1366347803776820, 1301185512245601, 561849853336294, 1533554921345731 },
+ { 999628998628371, 1132836708493400, 2084741674517453, 469343353015612, 678782988708035 },
+ { 2189427607417022, 699801937082607, 412764402319267, 1478091893643349, 2244675696854460 }
+ },
+ {
+ { 1712292055966563, 204413590624874, 1405738637332841, 408981300829763, 861082219276721 },
+ { 508561155940631, 966928475686665, 2236717801150132, 424543858577297, 2089272956986143 },
+ { 221245220129925, 1156020201681217, 491145634799213, 542422431960839, 828100817819207 }
+ },
+ {
+ { 153756971240384, 1299874139923977, 393099165260502, 1058234455773022, 996989038681183 },
+ { 559086812798481, 573177704212711, 1629737083816402, 1399819713462595, 1646954378266038 },
+ { 1887963056288059, 228507035730124, 1468368348640282, 930557653420194, 613513962454686 }
+ },
+ {
+ { 1224529808187553, 1577022856702685, 2206946542980843, 625883007765001, 279930793512158 },
+ { 1076287717051609, 1114455570543035, 187297059715481, 250446884292121, 1885187512550540 },
+ { 902497362940219, 76749815795675, 1657927525633846, 1420238379745202, 1340321636548352 }
+ },
+ {
+ { 1129576631190784, 1281994010027327, 996844254743018, 257876363489249, 1150850742055018 },
+ { 628740660038789, 1943038498527841, 467786347793886, 1093341428303375, 235413859513003 },
+ { 237425418909360, 469614029179605, 1512389769174935, 1241726368345357, 441602891065214 }
+ }
+},
+{ /* 6/31 */
+ {
+ { 1736417953058555, 726531315520508, 1833335034432527, 1629442561574747, 624418919286085 },
+ { 1960754663920689, 497040957888962, 1909832851283095, 1271432136996826, 2219780368020940 },
+ { 1537037379417136, 1358865369268262, 2130838645654099, 828733687040705, 1999987652890901 }
+ },
+ {
+ { 629042105241814, 1098854999137608, 887281544569320, 1423102019874777, 7911258951561 },
+ { 1811562332665373, 1501882019007673, 2213763501088999, 359573079719636, 36370565049116 },
+ { 218907117361280, 1209298913016966, 1944312619096112, 1130690631451061, 1342327389191701 }
+ },
+ {
+ { 1369976867854704, 1396479602419169, 1765656654398856, 2203659200586299, 998327836117241 },
+ { 2230701885562825, 1348173180338974, 2172856128624598, 1426538746123771, 444193481326151 },
+ { 784210426627951, 918204562375674, 1284546780452985, 1324534636134684, 1872449409642708 }
+ },
+ {
+ { 319638829540294, 596282656808406, 2037902696412608, 1557219121643918, 341938082688094 },
+ { 1901860206695915, 2004489122065736, 1625847061568236, 973529743399879, 2075287685312905 },
+ { 1371853944110545, 1042332820512553, 1949855697918254, 1791195775521505, 37487364849293 }
+ },
+ {
+ { 687200189577855, 1082536651125675, 644224940871546, 340923196057951, 343581346747396 },
+ { 2082717129583892, 27829425539422, 145655066671970, 1690527209845512, 1865260509673478 },
+ { 1059729620568824, 2163709103470266, 1440302280256872, 1769143160546397, 869830310425069 }
+ },
+ {
+ { 1609516219779025, 777277757338817, 2101121130363987, 550762194946473, 1905542338659364 },
+ { 2024821921041576, 426948675450149, 595133284085473, 471860860885970, 600321679413000 },
+ { 598474602406721, 1468128276358244, 1191923149557635, 1501376424093216, 1281662691293476 }
+ },
+ {
+ { 1721138489890707, 1264336102277790, 433064545421287, 1359988423149466, 1561871293409447 },
+ { 719520245587143, 393380711632345, 132350400863381, 1543271270810729, 1819543295798660 },
+ { 396397949784152, 1811354474471839, 1362679985304303, 2117033964846756, 498041172552279 }
+ },
+ {
+ { 1812471844975748, 1856491995543149, 126579494584102, 1036244859282620, 1975108050082550 },
+ { 650623932407995, 1137551288410575, 2125223403615539, 1725658013221271, 2134892965117796 },
+ { 522584000310195, 1241762481390450, 1743702789495384, 2227404127826575, 1686746002148897 }
+ }
+},
+{ /* 7/31 */
+ {
+ { 427904865186312, 1703211129693455, 1585368107547509, 1436984488744336, 761188534613978 },
+ { 318101947455002, 248138407995851, 1481904195303927, 309278454311197, 1258516760217879 },
+ { 1275068538599310, 513726919533379, 349926553492294, 688428871968420, 1702400196000666 }
+ },
+ {
+ { 1061864036265233, 961611260325381, 321859632700838, 1045600629959517, 1985130202504038 },
+ { 1558816436882417, 1962896332636523, 1337709822062152, 1501413830776938, 294436165831932 },
+ { 818359826554971, 1862173000996177, 626821592884859, 573655738872376, 1749691246745455 }
+ },
+ {
+ { 1988022651432119, 1082111498586040, 1834020786104821, 1454826876423687, 692929915223122 },
+ { 2146513703733331, 584788900394667, 464965657279958, 2183973639356127, 238371159456790 },
+ { 1129007025494441, 2197883144413266, 265142755578169, 971864464758890, 1983715884903702 }
+ },
+ {
+ { 1291366624493075, 381456718189114, 1711482489312444, 1815233647702022, 892279782992467 },
+ { 444548969917454, 1452286453853356, 2113731441506810, 645188273895859, 810317625309512 },
+ { 2242724082797924, 1373354730327868, 1006520110883049, 2147330369940688, 1151816104883620 }
+ },
+ {
+ { 1745720200383796, 1911723143175317, 2056329390702074, 355227174309849, 879232794371100 },
+ { 163723479936298, 115424889803150, 1156016391581227, 1894942220753364, 1970549419986329 },
+ { 681981452362484, 267208874112496, 1374683991933094, 638600984916117, 646178654558546 }
+ },
+ {
+ { 13378654854251, 106237307029567, 1944412051589651, 1841976767925457, 230702819835573 },
+ { 260683893467075, 854060306077237, 913639551980112, 4704576840123, 280254810808712 },
+ { 715374893080287, 1173334812210491, 1806524662079626, 1894596008000979, 398905715033393 }
+ },
+ {
+ { 500026409727661, 1596431288195371, 1420380351989370, 985211561521489, 392444930785633 },
+ { 2096421546958141, 1922523000950363, 789831022876840, 427295144688779, 320923973161730 },
+ { 1927770723575450, 1485792977512719, 1850996108474547, 551696031508956, 2126047405475647 }
+ },
+ {
+ { 2112099158080148, 742570803909715, 6484558077432, 1951119898618916, 93090382703416 },
+ { 383905201636970, 859946997631870, 855623867637644, 1017125780577795, 794250831877809 },
+ { 77571826285752, 999304298101753, 487841111777762, 1038031143212339, 339066367948762 }
+ }
+},
+{ /* 8/31 */
+ {
+ { 674994775520533, 266035846330789, 826951213393478, 1405007746162285, 1781791018620876 },
+ { 1001412661522686, 348196197067298, 1666614366723946, 888424995032760, 580747687801357 },
+ { 1939560076207777, 1409892634407635, 552574736069277, 383854338280405, 190706709864139 }
+ },
+ {
+ { 2177087163428741, 1439255351721944, 1208070840382793, 2230616362004769, 1396886392021913 },
+ { 676962063230039, 1880275537148808, 2046721011602706, 888463247083003, 1318301552024067 },
+ { 1466980508178206, 617045217998949, 652303580573628, 757303753529064, 207583137376902 }
+ },
+ {
+ { 1511056752906902, 105403126891277, 493434892772846, 1091943425335976, 1802717338077427 },
+ { 1853982405405128, 1878664056251147, 1528011020803992, 1019626468153565, 1128438412189035 },
+ { 1963939888391106, 293456433791664, 697897559513649, 985882796904380, 796244541237972 }
+ },
+ {
+ { 416770998629779, 389655552427054, 1314476859406756, 1749382513022778, 1161905598739491 },
+ { 1428358296490651, 1027115282420478, 304840698058337, 441410174026628, 1819358356278573 },
+ { 204943430200135, 1554861433819175, 216426658514651, 264149070665950, 2047097371738319 }
+ },
+ {
+ { 1934415182909034, 1393285083565062, 516409331772960, 1157690734993892, 121039666594268 },
+ { 662035583584445, 286736105093098, 1131773000510616, 818494214211439, 472943792054479 },
+ { 665784778135882, 1893179629898606, 808313193813106, 276797254706413, 1563426179676396 }
+ },
+ {
+ { 945205108984232, 526277562959295, 1324180513733566, 1666970227868664, 153547609289173 },
+ { 2031433403516252, 203996615228162, 170487168837083, 981513604791390, 843573964916831 },
+ { 1476570093962618, 838514669399805, 1857930577281364, 2017007352225784, 317085545220047 }
+ },
+ {
+ { 1461557121912842, 1600674043318359, 2157134900399597, 1670641601940616, 127765583803283 },
+ { 1293543509393474, 2143624609202546, 1058361566797508, 214097127393994, 946888515472729 },
+ { 357067959932916, 1290876214345711, 521245575443703, 1494975468601005, 800942377643885 }
+ },
+ {
+ { 566116659100033, 820247422481740, 994464017954148, 327157611686365, 92591318111744 },
+ { 617256647603209, 1652107761099439, 1857213046645471, 1085597175214970, 817432759830522 },
+ { 771808161440705, 1323510426395069, 680497615846440, 851580615547985, 1320806384849017 }
+ }
+},
+{ /* 9/31 */
+ {
+ { 1219260086131915, 647169006596815, 79601124759706, 2161724213426748, 404861897060198 },
+ { 1327968293887866, 1335500852943256, 1401587164534264, 558137311952440, 1551360549268902 },
+ { 417621685193956, 1429953819744454, 396157358457099, 1940470778873255, 214000046234152 }
+ },
+ {
+ { 1268047918491973, 2172375426948536, 1533916099229249, 1761293575457130, 1590622667026765 },
+ { 1627072914981959, 2211603081280073, 1912369601616504, 1191770436221309, 2187309757525860 },
+ { 1149147819689533, 378692712667677, 828475842424202, 2218619146419342, 70688125792186 }
+ },
+ {
+ { 1299739417079761, 1438616663452759, 1536729078504412, 2053896748919838, 1008421032591246 },
+ { 2040723824657366, 399555637875075, 632543375452995, 872649937008051, 1235394727030233 },
+ { 2211311599327900, 2139787259888175, 938706616835350, 12609661139114, 2081897930719789 }
+ },
+ {
+ { 1324994503390450, 336982330582631, 1183998925654177, 1091654665913274, 48727673971319 },
+ { 1845522914617879, 1222198248335542, 150841072760134, 1927029069940982, 1189913404498011 },
+ { 1079559557592645, 2215338383666441, 1903569501302605, 49033973033940, 305703433934152 }
+ },
+ {
+ { 94653405416909, 1386121349852999, 1062130477891762, 36553947479274, 833669648948846 },
+ { 1432015813136298, 440364795295369, 1395647062821501, 1976874522764578, 934452372723352 },
+ { 1296625309219774, 2068273464883862, 1858621048097805, 1492281814208508, 2235868981918946 }
+ },
+ {
+ { 1490330266465570, 1858795661361448, 1436241134969763, 294573218899647, 1208140011028933 },
+ { 1282462923712748, 741885683986255, 2027754642827561, 518989529541027, 1826610009555945 },
+ { 1525827120027511, 723686461809551, 1597702369236987, 244802101764964, 1502833890372311 }
+ },
+ {
+ { 113622036244513, 1233740067745854, 674109952278496, 2114345180342965, 166764512856263 },
+ { 2041668749310338, 2184405322203901, 1633400637611036, 2110682505536899, 2048144390084644 },
+ { 503058759232932, 760293024620937, 2027152777219493, 666858468148475, 1539184379870952 }
+ },
+ {
+ { 1916168475367211, 915626432541343, 883217071712575, 363427871374304, 1976029821251593 },
+ { 678039535434506, 570587290189340, 1605302676614120, 2147762562875701, 1706063797091704 },
+ { 1439489648586438, 2194580753290951, 832380563557396, 561521973970522, 584497280718389 }
+ }
+},
+{ /* 10/31 */
+ {
+ { 187989455492609, 681223515948275, 1933493571072456, 1872921007304880, 488162364135671 },
+ { 1413466089534451, 410844090765630, 1397263346404072, 408227143123410, 1594561803147811 },
+ { 2102170800973153, 719462588665004, 1479649438510153, 1097529543970028, 1302363283777685 }
+ },
+ {
+ { 942065717847195, 1069313679352961, 2007341951411051, 70973416446291, 1419433790163706 },
+ { 1146565545556377, 1661971299445212, 406681704748893, 564452436406089, 1109109865829139 },
+ { 2214421081775077, 1165671861210569, 1890453018796184, 3556249878661, 442116172656317 }
+ },
+ {
+ { 753830546620811, 1666955059895019, 1530775289309243, 1119987029104146, 2164156153857580 },
+ { 615171919212796, 1523849404854568, 854560460547503, 2067097370290715, 1765325848586042 },
+ { 1094538949313667, 1796592198908825, 870221004284388, 2025558921863561, 1699010892802384 }
+ },
+ {
+ { 1951351290725195, 1916457206844795, 198025184438026, 1909076887557595, 1938542290318919 },
+ { 1014323197538413, 869150639940606, 1756009942696599, 1334952557375672, 1544945379082874 },
+ { 764055910920305, 1603590757375439, 146805246592357, 1843313433854297, 954279890114939 }
+ },
+ {
+ { 80113526615750, 764536758732259, 1055139345100233, 469252651759390, 617897512431515 },
+ { 74497112547268, 740094153192149, 1745254631717581, 727713886503130, 1283034364416928 },
+ { 525892105991110, 1723776830270342, 1476444848991936, 573789489857760, 133864092632978 }
+ },
+ {
+ { 542611720192581, 1986812262899321, 1162535242465837, 481498966143464, 544600533583622 },
+ { 64123227344372, 1239927720647794, 1360722983445904, 222610813654661, 62429487187991 },
+ { 1793193323953132, 91096687857833, 70945970938921, 2158587638946380, 1537042406482111 }
+ },
+ {
+ { 1895854577604609, 1394895708949416, 1728548428495944, 1140864900240149, 563645333603061 },
+ { 141358280486863, 91435889572504, 1087208572552643, 1829599652522921, 1193307020643647 },
+ { 1611230858525381, 950720175540785, 499589887488610, 2001656988495019, 88977313255908 }
+ },
+ {
+ { 1189080501479658, 2184348804772597, 1040818725742319, 2018318290311834, 1712060030915354 },
+ { 873966876953756, 1090638350350440, 1708559325189137, 672344594801910, 1320437969700239 },
+ { 1508590048271766, 1131769479776094, 101550868699323, 428297785557897, 561791648661744 }
+ }
+},
+{ /* 11/31 */
+ {
+ { 756417570499462, 237882279232602, 2136263418594016, 1701968045454886, 703713185137472 },
+ { 1781187809325462, 1697624151492346, 1381393690939988, 175194132284669, 1483054666415238 },
+ { 2175517777364616, 708781536456029, 955668231122942, 1967557500069555, 2021208005604118 }
+ },
+ {
+ { 1115135966606887, 224217372950782, 915967306279222, 593866251291540, 561747094208006 },
+ { 1443163092879439, 391875531646162, 2180847134654632, 464538543018753, 1594098196837178 },
+ { 850858855888869, 319436476624586, 327807784938441, 740785849558761, 17128415486016 }
+ },
+ {
+ { 2132756334090067, 536247820155645, 48907151276867, 608473197600695, 1261689545022784 },
+ { 1525176236978354, 974205476721062, 293436255662638, 148269621098039, 137961998433963 },
+ { 1121075518299410, 2071745529082111, 1265567917414828, 1648196578317805, 496232102750820 }
+ },
+ {
+ { 122321229299801, 1022922077493685, 2001275453369484, 2017441881607947, 993205880778002 },
+ { 654925550560074, 1168810995576858, 575655959430926, 905758704861388, 496774564663534 },
+ { 1954109525779738, 2117022646152485, 338102630417180, 1194140505732026, 107881734943492 }
+ },
+ {
+ { 1714785840001267, 2036500018681589, 1876380234251966, 2056717182974196, 1645855254384642 },
+ { 106431476499341, 62482972120563, 1513446655109411, 807258751769522, 538491469114 },
+ { 2002850762893643, 1243624520538135, 1486040410574605, 2184752338181213, 378495998083531 }
+ },
+ {
+ { 922510868424903, 1089502620807680, 402544072617374, 1131446598479839, 1290278588136533 },
+ { 1867998812076769, 715425053580701, 39968586461416, 2173068014586163, 653822651801304 },
+ { 162892278589453, 182585796682149, 75093073137630, 497037941226502, 133871727117371 }
+ },
+ {
+ { 1914596576579670, 1608999621851578, 1987629837704609, 1519655314857977, 1819193753409464 },
+ { 1949315551096831, 1069003344994464, 1939165033499916, 1548227205730856, 1933767655861407 },
+ { 1730519386931635, 1393284965610134, 1597143735726030, 416032382447158, 1429665248828629 }
+ },
+ {
+ { 360275475604565, 547835731063078, 215360904187529, 596646739879007, 332709650425085 },
+ { 47602113726801, 1522314509708010, 437706261372925, 814035330438027, 335930650933545 },
+ { 1291597595523886, 1058020588994081, 402837842324045, 1363323695882781, 2105763393033193 }
+ }
+},
+{ /* 12/31 */
+ {
+ { 109521982566564, 1715257748585139, 1112231216891516, 2046641005101484, 134249157157013 },
+ { 2156991030936798, 2227544497153325, 1869050094431622, 754875860479115, 1754242344267058 },
+ { 1846089562873800, 98894784984326, 1412430299204844, 171351226625762, 1100604760929008 }
+ },
+ {
+ { 84172382130492, 499710970700046, 425749630620778, 1762872794206857, 612842602127960 },
+ { 868309334532756, 1703010512741873, 1952690008738057, 4325269926064, 2071083554962116 },
+ { 523094549451158, 401938899487815, 1407690589076010, 2022387426254453, 158660516411257 }
+ },
+ {
+ { 612867287630009, 448212612103814, 571629077419196, 1466796750919376, 1728478129663858 },
+ { 1723848973783452, 2208822520534681, 1718748322776940, 1974268454121942, 1194212502258141 },
+ { 1254114807944608, 977770684047110, 2010756238954993, 1783628927194099, 1525962994408256 }
+ },
+ {
+ { 232464058235826, 1948628555342434, 1835348780427694, 1031609499437291, 64472106918373 },
+ { 767338676040683, 754089548318405, 1523192045639075, 435746025122062, 512692508440385 },
+ { 1255955808701983, 1700487367990941, 1166401238800299, 1175121994891534, 1190934801395380 }
+ },
+ {
+ { 349144008168292, 1337012557669162, 1475912332999108, 1321618454900458, 47611291904320 },
+ { 877519947135419, 2172838026132651, 272304391224129, 1655143327559984, 886229406429814 },
+ { 375806028254706, 214463229793940, 572906353144089, 572168269875638, 697556386112979 }
+ },
+ {
+ { 1168827102357844, 823864273033637, 2071538752104697, 788062026895924, 599578340743362 },
+ { 1948116082078088, 2054898304487796, 2204939184983900, 210526805152138, 786593586607626 },
+ { 1915320147894736, 156481169009469, 655050471180417, 592917090415421, 2165897438660879 }
+ },
+ {
+ { 1726336468579724, 1119932070398949, 1929199510967666, 33918788322959, 1836837863503150 },
+ { 829996854845988, 217061778005138, 1686565909803640, 1346948817219846, 1723823550730181 },
+ { 384301494966394, 687038900403062, 2211195391021739, 254684538421383, 1245698430589680 }
+ },
+ {
+ { 1247567493562688, 1978182094455847, 183871474792955, 806570235643435, 288461518067916 },
+ { 1449077384734201, 38285445457996, 2136537659177832, 2146493000841573, 725161151123125 },
+ { 1201928866368855, 800415690605445, 1703146756828343, 997278587541744, 1858284414104014 }
+ }
+},
+{ /* 13/31 */
+ {
+ { 356468809648877, 782373916933152, 1718002439402870, 1392222252219254, 663171266061951 },
+ { 759628738230460, 1012693474275852, 353780233086498, 246080061387552, 2030378857679162 },
+ { 2040672435071076, 888593182036908, 1298443657189359, 1804780278521327, 354070726137060 }
+ },
+ {
+ { 1894938527423184, 1463213041477277, 474410505497651, 247294963033299, 877975941029128 },
+ { 207937160991127, 12966911039119, 820997788283092, 1010440472205286, 1701372890140810 },
+ { 218882774543183, 533427444716285, 1233243976733245, 435054256891319, 1509568989549904 }
+ },
+ {
+ { 1888838535711826, 1052177758340622, 1213553803324135, 169182009127332, 463374268115872 },
+ { 299137589460312, 1594371588983567, 868058494039073, 257771590636681, 1805012993142921 },
+ { 1806842755664364, 2098896946025095, 1356630998422878, 1458279806348064, 347755825962072 }
+ },
+ {
+ { 1402334161391744, 1560083671046299, 1008585416617747, 1147797150908892, 1420416683642459 },
+ { 665506704253369, 273770475169863, 799236974202630, 848328990077558, 1811448782807931 },
+ { 1468412523962641, 771866649897997, 1931766110147832, 799561180078482, 524837559150077 }
+ },
+ {
+ { 2223212657821850, 630416247363666, 2144451165500328, 816911130947791, 1024351058410032 },
+ { 1266603897524861, 156378408858100, 1275649024228779, 447738405888420, 253186462063095 },
+ { 2022215964509735, 136144366993649, 1800716593296582, 1193970603800203, 871675847064218 }
+ },
+ {
+ { 1862751661970328, 851596246739884, 1519315554814041, 1542798466547449, 1417975335901520 },
+ { 1228168094547481, 334133883362894, 587567568420081, 433612590281181, 603390400373205 },
+ { 121893973206505, 1843345804916664, 1703118377384911, 497810164760654, 101150811654673 }
+ },
+ {
+ { 458346255946468, 290909935619344, 1452768413850679, 550922875254215, 1537286854336538 },
+ { 584322311184395, 380661238802118, 114839394528060, 655082270500073, 2111856026034852 },
+ { 996965581008991, 2148998626477022, 1012273164934654, 1073876063914522, 1688031788934939 }
+ },
+ {
+ { 923487018849600, 2085106799623355, 528082801620136, 1606206360876188, 735907091712524 },
+ { 1697697887804317, 1335343703828273, 831288615207040, 949416685250051, 288760277392022 },
+ { 1419122478109648, 1325574567803701, 602393874111094, 2107893372601700, 1314159682671307 }
+ }
+},
+{ /* 14/31 */
+ {
+ { 2201150872731804, 2180241023425241, 97663456423163, 1633405770247824, 848945042443986 },
+ { 1173339555550611, 818605084277583, 47521504364289, 924108720564965, 735423405754506 },
+ { 830104860549448, 1886653193241086, 1600929509383773, 1475051275443631, 286679780900937 }
+ },
+ {
+ { 1577111294832995, 1030899169768747, 144900916293530, 1964672592979567, 568390100955250 },
+ { 278388655910247, 487143369099838, 927762205508727, 181017540174210, 1616886700741287 },
+ { 1191033906638969, 940823957346562, 1606870843663445, 861684761499847, 658674867251089 }
+ },
+ {
+ { 1875032594195546, 1427106132796197, 724736390962158, 901860512044740, 635268497268760 },
+ { 622869792298357, 1903919278950367, 1922588621661629, 1520574711600434, 1087100760174640 },
+ { 25465949416618, 1693639527318811, 1526153382657203, 125943137857169, 145276964043999 }
+ },
+ {
+ { 214739857969358, 920212862967915, 1939901550972269, 1211862791775221, 85097515720120 },
+ { 2006245852772938, 734762734836159, 254642929763427, 1406213292755966, 239303749517686 },
+ { 1619678837192149, 1919424032779215, 1357391272956794, 1525634040073113, 1310226789796241 }
+ },
+ {
+ { 1040763709762123, 1704449869235352, 605263070456329, 1998838089036355, 1312142911487502 },
+ { 1996723311435669, 1844342766567060, 985455700466044, 1165924681400960, 311508689870129 },
+ { 43173156290518, 2202883069785309, 1137787467085917, 1733636061944606, 1394992037553852 }
+ },
+ {
+ { 670078326344559, 555655025059356, 471959386282438, 2141455487356409, 849015953823125 },
+ { 2197214573372804, 794254097241315, 1030190060513737, 267632515541902, 2040478049202624 },
+ { 1812516004670529, 1609256702920783, 1706897079364493, 258549904773295, 996051247540686 }
+ },
+ {
+ { 1540374301420584, 1764656898914615, 1810104162020396, 923808779163088, 664390074196579 },
+ { 1323460699404750, 1262690757880991, 871777133477900, 1060078894988977, 1712236889662886 },
+ { 1696163952057966, 1391710137550823, 608793846867416, 1034391509472039, 1780770894075012 }
+ },
+ {
+ { 1367603834210841, 2131988646583224, 890353773628144, 1908908219165595, 270836895252891 },
+ { 597536315471731, 40375058742586, 1942256403956049, 1185484645495932, 312666282024145 },
+ { 1919411405316294, 1234508526402192, 1066863051997083, 1008444703737597, 1348810787701552 }
+ }
+},
+{ /* 15/31 */
+ {
+ { 2102881477513865, 1570274565945361, 1573617900503708, 18662635732583, 2232324307922098 },
+ { 1853931367696942, 8107973870707, 350214504129299, 775206934582587, 1752317649166792 },
+ { 1417148368003523, 721357181628282, 505725498207811, 373232277872983, 261634707184480 }
+ },
+ {
+ { 2186733281493267, 2250694917008620, 1014829812957440, 479998161452389, 83566193876474 },
+ { 1268116367301224, 560157088142809, 802626839600444, 2210189936605713, 1129993785579988 },
+ { 615183387352312, 917611676109240, 878893615973325, 978940963313282, 938686890583575 }
+ },
+ {
+ { 522024729211672, 1045059315315808, 1892245413707790, 1907891107684253, 2059998109500714 },
+ { 1799679152208884, 912132775900387, 25967768040979, 432130448590461, 274568990261996 },
+ { 98698809797682, 2144627600856209, 1907959298569602, 811491302610148, 1262481774981493 }
+ },
+ {
+ { 1791451399743152, 1713538728337276, 118349997257490, 1882306388849954, 158235232210248 },
+ { 1217809823321928, 2173947284933160, 1986927836272325, 1388114931125539, 12686131160169 },
+ { 1650875518872272, 1136263858253897, 1732115601395988, 734312880662190, 1252904681142109 }
+ },
+ {
+ { 372986456113865, 525430915458171, 2116279931702135, 501422713587815, 1907002872974925 },
+ { 803147181835288, 868941437997146, 316299302989663, 943495589630550, 571224287904572 },
+ { 227742695588364, 1776969298667369, 628602552821802, 457210915378118, 2041906378111140 }
+ },
+ {
+ { 815000523470260, 913085688728307, 1052060118271173, 1345536665214223, 541623413135555 },
+ { 1580216071604333, 1877997504342444, 857147161260913, 703522726778478, 2182763974211603 },
+ { 1870080310923419, 71988220958492, 1783225432016732, 615915287105016, 1035570475990230 }
+ },
+ {
+ { 730987750830150, 857613889540280, 1083813157271766, 1002817255970169, 1719228484436074 },
+ { 377616581647602, 1581980403078513, 804044118130621, 2034382823044191, 643844048472185 },
+ { 176957326463017, 1573744060478586, 528642225008045, 1816109618372371, 1515140189765006 }
+ },
+ {
+ { 1888911448245718, 1387110895611080, 1924503794066429, 1731539523700949, 2230378382645454 },
+ { 443392177002051, 233793396845137, 2199506622312416, 1011858706515937, 974676837063129 },
+ { 1846351103143623, 1949984838808427, 671247021915253, 1946756846184401, 1929296930380217 }
+ }
+},
+{ /* 16/31 */
+ {
+ { 849646212452002, 1410198775302919, 73767886183695, 1641663456615812, 762256272452411 },
+ { 692017667358279, 723305578826727, 1638042139863265, 748219305990306, 334589200523901 },
+ { 22893968530686, 2235758574399251, 1661465835630252, 925707319443452, 1203475116966621 }
+ },
+ {
+ { 801299035785166, 1733292596726131, 1664508947088596, 467749120991922, 1647498584535623 },
+ { 903105258014366, 427141894933047, 561187017169777, 1884330244401954, 1914145708422219 },
+ { 1344191060517578, 1960935031767890, 1518838929955259, 1781502350597190, 1564784025565682 }
+ },
+ {
+ { 673723351748086, 1979969272514923, 1175287312495508, 1187589090978666, 1881897672213940 },
+ { 1917185587363432, 1098342571752737, 5935801044414, 2000527662351839, 1538640296181569 },
+ { 2495540013192, 678856913479236, 224998292422872, 219635787698590, 1972465269000940 }
+ },
+ {
+ { 271413961212179, 1353052061471651, 344711291283483, 2014925838520662, 2006221033113941 },
+ { 194583029968109, 514316781467765, 829677956235672, 1676415686873082, 810104584395840 },
+ { 1980510813313589, 1948645276483975, 152063780665900, 129968026417582, 256984195613935 }
+ },
+ {
+ { 1860190562533102, 1936576191345085, 461100292705964, 1811043097042830, 957486749306835 },
+ { 796664815624365, 1543160838872951, 1500897791837765, 1667315977988401, 599303877030711 },
+ { 1151480509533204, 2136010406720455, 738796060240027, 319298003765044, 1150614464349587 }
+ },
+ {
+ { 1731069268103150, 735642447616087, 1364750481334268, 417232839982871, 927108269127661 },
+ { 1017222050227968, 1987716148359, 2234319589635701, 621282683093392, 2132553131763026 },
+ { 1567828528453324, 1017807205202360, 565295260895298, 829541698429100, 307243822276582 }
+ },
+ {
+ { 249079270936248, 1501514259790706, 947909724204848, 944551802437487, 552658763982480 },
+ { 2089966982947227, 1854140343916181, 2151980759220007, 2139781292261749, 158070445864917 },
+ { 1338766321464554, 1906702607371284, 1519569445519894, 115384726262267, 1393058953390992 }
+ },
+ {
+ { 1364621558265400, 1512388234908357, 1926731583198686, 2041482526432505, 920401122333774 },
+ { 1884844597333588, 601480070269079, 620203503079537, 1079527400117915, 1202076693132015 },
+ { 840922919763324, 727955812569642, 1303406629750194, 522898432152867, 294161410441865 }
+ }
+},
+{ /* 17/31 */
+ {
+ { 353760790835310, 1598361541848743, 1122905698202299, 1922533590158905, 419107700666580 },
+ { 359856369838236, 180914355488683, 861726472646627, 218807937262986, 575626773232501 },
+ { 755467689082474, 909202735047934, 730078068932500, 936309075711518, 2007798262842972 }
+ },
+ {
+ { 1609384177904073, 362745185608627, 1335318541768201, 800965770436248, 547877979267412 },
+ { 984339177776787, 815727786505884, 1645154585713747, 1659074964378553, 1686601651984156 },
+ { 1697863093781930, 599794399429786, 1104556219769607, 830560774794755, 12812858601017 }
+ },
+ {
+ { 1168737550514982, 897832437380552, 463140296333799, 302564600022547, 2008360505135501 },
+ { 1856930662813910, 678090852002597, 1920179140755167, 1259527833759868, 55540971895511 },
+ { 1158643631044921, 476554103621892, 178447851439725, 1305025542653569, 103433927680625 }
+ },
+ {
+ { 2176793111709008, 1576725716350391, 2009350167273523, 2012390194631546, 2125297410909580 },
+ { 825403285195098, 2144208587560784, 1925552004644643, 1915177840006985, 1015952128947864 },
+ { 1807108316634472, 1534392066433717, 347342975407218, 1153820745616376, 7375003497471 }
+ },
+ {
+ { 983061001799725, 431211889901241, 2201903782961093, 817393911064341, 2214616493042167 },
+ { 228567918409756, 865093958780220, 358083886450556, 159617889659320, 1360637926292598 },
+ { 234147501399755, 2229469128637390, 2175289352258889, 1397401514549353, 1885288963089922 }
+ },
+ {
+ { 1111762412951562, 252849572507389, 1048714233823341, 146111095601446, 1237505378776770 },
+ { 1113790697840279, 1051167139966244, 1045930658550944, 2011366241542643, 1686166824620755 },
+ { 1054097349305049, 1872495070333352, 182121071220717, 1064378906787311, 100273572924182 }
+ },
+ {
+ { 1306410853171605, 1627717417672447, 50983221088417, 1109249951172250, 870201789081392 },
+ { 104233794644221, 1548919791188248, 2224541913267306, 2054909377116478, 1043803389015153 },
+ { 216762189468802, 707284285441622, 190678557969733, 973969342604308, 1403009538434867 }
+ },
+ {
+ { 1279024291038477, 344776835218310, 273722096017199, 1834200436811442, 634517197663804 },
+ { 343805853118335, 1302216857414201, 566872543223541, 2051138939539004, 321428858384280 },
+ { 470067171324852, 1618629234173951, 2000092177515639, 7307679772789, 1117521120249968 }
+ }
+},
+{ /* 18/31 */
+ {
+ { 278151578291475, 1810282338562947, 1771599529530998, 1383659409671631, 685373414471841 },
+ { 577009397403102, 1791440261786291, 2177643735971638, 174546149911960, 1412505077782326 },
+ { 893719721537457, 1201282458018197, 1522349501711173, 58011597740583, 1130406465887139 }
+ },
+ {
+ { 412607348255453, 1280455764199780, 2233277987330768, 14180080401665, 331584698417165 },
+ { 262483770854550, 990511055108216, 526885552771698, 571664396646158, 354086190278723 },
+ { 1820352417585487, 24495617171480, 1547899057533253, 10041836186225, 480457105094042 }
+ },
+ {
+ { 2023310314989233, 637905337525881, 2106474638900687, 557820711084072, 1687858215057826 },
+ { 1144168702609745, 604444390410187, 1544541121756138, 1925315550126027, 626401428894002 },
+ { 1922168257351784, 2018674099908659, 1776454117494445, 956539191509034, 36031129147635 }
+ },
+ {
+ { 544644538748041, 1039872944430374, 876750409130610, 710657711326551, 1216952687484972 },
+ { 58242421545916, 2035812695641843, 2118491866122923, 1191684463816273, 46921517454099 },
+ { 272268252444639, 1374166457774292, 2230115177009552, 1053149803909880, 1354288411641016 }
+ },
+ {
+ { 1857910905368338, 1754729879288912, 885945464109877, 1516096106802166, 1602902393369811 },
+ { 1193437069800958, 901107149704790, 999672920611411, 477584824802207, 364239578697845 },
+ { 886299989548838, 1538292895758047, 1590564179491896, 1944527126709657, 837344427345298 }
+ },
+ {
+ { 754558365378305, 1712186480903618, 1703656826337531, 750310918489786, 518996040250900 },
+ { 1309847803895382, 1462151862813074, 211370866671570, 1544595152703681, 1027691798954090 },
+ { 803217563745370, 1884799722343599, 1357706345069218, 2244955901722095, 730869460037413 }
+ },
+ {
+ { 689299471295966, 1831210565161071, 1375187341585438, 1106284977546171, 1893781834054269 },
+ { 696351368613042, 1494385251239250, 738037133616932, 636385507851544, 927483222611406 },
+ { 1949114198209333, 1104419699537997, 783495707664463, 1747473107602770, 2002634765788641 }
+ },
+ {
+ { 1607325776830197, 530883941415333, 1451089452727895, 1581691157083423, 496100432831154 },
+ { 1068900648804224, 2006891997072550, 1134049269345549, 1638760646180091, 2055396084625778 },
+ { 2222475519314561, 1870703901472013, 1884051508440561, 1344072275216753, 1318025677799069 }
+ }
+},
+{ /* 19/31 */
+ {
+ { 155711679280656, 681100400509288, 389811735211209, 2135723811340709, 408733211204125 },
+ { 7813206966729, 194444201427550, 2071405409526507, 1065605076176312, 1645486789731291 },
+ { 16625790644959, 1647648827778410, 1579910185572704, 436452271048548, 121070048451050 }
+ },
+ {
+ { 1037263028552531, 568385780377829, 297953104144430, 1558584511931211, 2238221839292471 },
+ { 190565267697443, 672855706028058, 338796554369226, 337687268493904, 853246848691734 },
+ { 1763863028400139, 766498079432444, 1321118624818005, 69494294452268, 858786744165651 }
+ },
+ {
+ { 1292056768563024, 1456632109855638, 1100631247050184, 1386133165675321, 1232898350193752 },
+ { 366253102478259, 525676242508811, 1449610995265438, 1183300845322183, 185960306491545 },
+ { 28315355815982, 460422265558930, 1799675876678724, 1969256312504498, 1051823843138725 }
+ },
+ {
+ { 156914999361983, 1606148405719949, 1665208410108430, 317643278692271, 1383783705665320 },
+ { 54684536365732, 2210010038536222, 1194984798155308, 535239027773705, 1516355079301361 },
+ { 1484387703771650, 198537510937949, 2186282186359116, 617687444857508, 647477376402122 }
+ },
+ {
+ { 2147715541830533, 500032538445817, 646380016884826, 352227855331122, 1488268620408052 },
+ { 159386186465542, 1877626593362941, 618737197060512, 1026674284330807, 1158121760792685 },
+ { 1744544377739822, 1964054180355661, 1685781755873170, 2169740670377448, 1286112621104591 }
+ },
+ {
+ { 81977249784993, 1667943117713086, 1668983819634866, 1605016835177615, 1353960708075544 },
+ { 1602253788689063, 439542044889886, 2220348297664483, 657877410752869, 157451572512238 },
+ { 1029287186166717, 65860128430192, 525298368814832, 1491902500801986, 1461064796385400 }
+ },
+ {
+ { 408216988729246, 2121095722306989, 913562102267595, 1879708920318308, 241061448436731 },
+ { 1185483484383269, 1356339572588553, 584932367316448, 102132779946470, 1792922621116791 },
+ { 1966196870701923, 2230044620318636, 1425982460745905, 261167817826569, 46517743394330 }
+ },
+ {
+ { 107077591595359, 884959942172345, 27306869797400, 2224911448949390, 964352058245223 },
+ { 1730194207717538, 431790042319772, 1831515233279467, 1372080552768581, 1074513929381760 },
+ { 1450880638731607, 1019861580989005, 1229729455116861, 1174945729836143, 826083146840706 }
+ }
+},
+{ /* 20/31 */
+ {
+ { 1899935429242705, 1602068751520477, 940583196550370, 82431069053859, 1540863155745696 },
+ { 2136688454840028, 2099509000964294, 1690800495246475, 1217643678575476, 828720645084218 },
+ { 765548025667841, 462473984016099, 998061409979798, 546353034089527, 2212508972466858 }
+ },
+ {
+ { 46575283771160, 892570971573071, 1281983193144090, 1491520128287375, 75847005908304 },
+ { 1801436127943107, 1734436817907890, 1268728090345068, 167003097070711, 2233597765834956 },
+ { 1997562060465113, 1048700225534011, 7615603985628, 1855310849546841, 2242557647635213 }
+ },
+ {
+ { 1161017320376250, 492624580169043, 2169815802355237, 976496781732542, 1770879511019629 },
+ { 1357044908364776, 729130645262438, 1762469072918979, 1365633616878458, 181282906404941 },
+ { 1080413443139865, 1155205815510486, 1848782073549786, 622566975152580, 124965574467971 }
+ },
+ {
+ { 1184526762066993, 247622751762817, 692129017206356, 820018689412496, 2188697339828085 },
+ { 2020536369003019, 202261491735136, 1053169669150884, 2056531979272544, 778165514694311 },
+ { 237404399610207, 1308324858405118, 1229680749538400, 720131409105291, 1958958863624906 }
+ },
+ {
+ { 515583508038846, 17656978857189, 1717918437373989, 1568052070792483, 46975803123923 },
+ { 281527309158085, 36970532401524, 866906920877543, 2222282602952734, 1289598729589882 },
+ { 1278207464902042, 494742455008756, 1262082121427081, 1577236621659884, 1888786707293291 }
+ },
+ {
+ { 353042527954210, 1830056151907359, 1111731275799225, 174960955838824, 404312815582675 },
+ { 2064251142068628, 1666421603389706, 1419271365315441, 468767774902855, 191535130366583 },
+ { 1716987058588002, 1859366439773457, 1767194234188234, 64476199777924, 1117233614485261 }
+ },
+ {
+ { 984292135520292, 135138246951259, 2220652137473167, 1722843421165029, 190482558012909 },
+ { 298845952651262, 1166086588952562, 1179896526238434, 1347812759398693, 1412945390096208 },
+ { 1143239552672925, 906436640714209, 2177000572812152, 2075299936108548, 325186347798433 }
+ },
+ {
+ { 721024854374772, 684487861263316, 1373438744094159, 2193186935276995, 1387043709851261 },
+ { 418098668140962, 715065997721283, 1471916138376055, 2168570337288357, 937812682637044 },
+ { 1043584187226485, 2143395746619356, 2209558562919611, 482427979307092, 847556718384018 }
+ }
+},
+{ /* 21/31 */
+ {
+ { 1248731221520759, 1465200936117687, 540803492710140, 52978634680892, 261434490176109 },
+ { 1057329623869501, 620334067429122, 461700859268034, 2012481616501857, 297268569108938 },
+ { 1055352180870759, 1553151421852298, 1510903185371259, 1470458349428097, 1226259419062731 }
+ },
+ {
+ { 1492988790301668, 790326625573331, 1190107028409745, 1389394752159193, 1620408196604194 },
+ { 47000654413729, 1004754424173864, 1868044813557703, 173236934059409, 588771199737015 },
+ { 30498470091663, 1082245510489825, 576771653181956, 806509986132686, 1317634017056939 }
+ },
+ {
+ { 420308055751555, 1493354863316002, 165206721528088, 1884845694919786, 2065456951573059 },
+ { 1115636332012334, 1854340990964155, 83792697369514, 1972177451994021, 457455116057587 },
+ { 1698968457310898, 1435137169051090, 1083661677032510, 938363267483709, 340103887207182 }
+ },
+ {
+ { 1995325341336574, 911500251774648, 164010755403692, 855378419194762, 1573601397528842 },
+ { 241719380661528, 310028521317150, 1215881323380194, 1408214976493624, 2141142156467363 },
+ { 1315157046163473, 727368447885818, 1363466668108618, 1668921439990361, 1398483384337907 }
+ },
+ {
+ { 75029678299646, 1015388206460473, 1849729037055212, 1939814616452984, 444404230394954 },
+ { 2053597130993710, 2024431685856332, 2233550957004860, 2012407275509545, 872546993104440 },
+ { 1217269667678610, 599909351968693, 1390077048548598, 1471879360694802, 739586172317596 }
+ },
+ {
+ { 1718318639380794, 1560510726633958, 904462881159922, 1418028351780052, 94404349451937 },
+ { 2132502667405250, 214379346175414, 1502748313768060, 1960071701057800, 1353971822643138 },
+ { 319394212043702, 2127459436033571, 717646691535162, 663366796076914, 318459064945314 }
+ },
+ {
+ { 405989424923593, 1960452633787083, 667349034401665, 1492674260767112, 1451061489880787 },
+ { 947085906234007, 323284730494107, 1485778563977200, 728576821512394, 901584347702286 },
+ { 1575783124125742, 2126210792434375, 1569430791264065, 1402582372904727, 1891780248341114 }
+ },
+ {
+ { 838432205560695, 1997703511451664, 1018791879907867, 1662001808174331, 78328132957753 },
+ { 739152638255629, 2074935399403557, 505483666745895, 1611883356514088, 628654635394878 },
+ { 1822054032121349, 643057948186973, 7306757352712, 577249257962099, 284735863382083 }
+ }
+},
+{ /* 22/31 */
+ {
+ { 1366558556363930, 1448606567552086, 1478881020944768, 165803179355898, 1115718458123498 },
+ { 204146226972102, 1630511199034723, 2215235214174763, 174665910283542, 956127674017216 },
+ { 1562934578796716, 1070893489712745, 11324610642270, 958989751581897, 2172552325473805 }
+ },
+ {
+ { 1770564423056027, 735523631664565, 1326060113795289, 1509650369341127, 65892421582684 },
+ { 623682558650637, 1337866509471512, 990313350206649, 1314236615762469, 1164772974270275 },
+ { 223256821462517, 723690150104139, 1000261663630601, 933280913953265, 254872671543046 }
+ },
+ {
+ { 1969087237026041, 624795725447124, 1335555107635969, 2069986355593023, 1712100149341902 },
+ { 1236103475266979, 1837885883267218, 1026072585230455, 1025865513954973, 1801964901432134 },
+ { 1115241013365517, 1712251818829143, 2148864332502771, 2096001471438138, 2235017246626125 }
+ },
+ {
+ { 1299268198601632, 2047148477845621, 2165648650132450, 1612539282026145, 514197911628890 },
+ { 118352772338543, 1067608711804704, 1434796676193498, 1683240170548391, 230866769907437 },
+ { 1850689576796636, 1601590730430274, 1139674615958142, 1954384401440257, 76039205311 }
+ },
+ {
+ { 1723387471374172, 997301467038410, 533927635123657, 20928644693965, 1756575222802513 },
+ { 2146711623855116, 503278928021499, 625853062251406, 1109121378393107, 1033853809911861 },
+ { 571005965509422, 2005213373292546, 1016697270349626, 56607856974274, 914438579435146 }
+ },
+ {
+ { 1346698876211176, 2076651707527589, 1084761571110205, 265334478828406, 1068954492309671 },
+ { 1769967932677654, 1695893319756416, 1151863389675920, 1781042784397689, 400287774418285 },
+ { 1851867764003121, 403841933237558, 820549523771987, 761292590207581, 1743735048551143 }
+ },
+ {
+ { 410915148140008, 2107072311871739, 1004367461876503, 99684895396761, 1180818713503224 },
+ { 285945406881439, 648174397347453, 1098403762631981, 1366547441102991, 1505876883139217 },
+ { 672095903120153, 1675918957959872, 636236529315028, 1569297300327696, 2164144194785875 }
+ },
+ {
+ { 1902708175321798, 1035343530915438, 1178560808893263, 301095684058146, 1280977479761118 },
+ { 1615357281742403, 404257611616381, 2160201349780978, 1160947379188955, 1578038619549541 },
+ { 2013087639791217, 822734930507457, 1785668418619014, 1668650702946164, 389450875221715 }
+ }
+},
+{ /* 23/31 */
+ {
+ { 453918449698368, 106406819929001, 2072540975937135, 308588860670238, 1304394580755385 },
+ { 1295082798350326, 2091844511495996, 1851348972587817, 3375039684596, 789440738712837 },
+ { 2083069137186154, 848523102004566, 993982213589257, 1405313299916317, 1532824818698468 }
+ },
+ {
+ { 1495961298852430, 1397203457344779, 1774950217066942, 139302743555696, 66603584342787 },
+ { 1782411379088302, 1096724939964781, 27593390721418, 542241850291353, 1540337798439873 },
+ { 693543956581437, 171507720360750, 1557908942697227, 1074697073443438, 1104093109037196 }
+ },
+ {
+ { 345288228393419, 1099643569747172, 134881908403743, 1740551994106740, 248212179299770 },
+ { 231429562203065, 1526290236421172, 2021375064026423, 1520954495658041, 806337791525116 },
+ { 1079623667189886, 872403650198613, 766894200588288, 2163700860774109, 2023464507911816 }
+ },
+ {
+ { 854645372543796, 1936406001954827, 151460662541253, 825325739271555, 1554306377287556 },
+ { 1497138821904622, 1044820250515590, 1742593886423484, 1237204112746837, 849047450816987 },
+ { 667962773375330, 1897271816877105, 1399712621683474, 1143302161683099, 2081798441209593 }
+ },
+ {
+ { 127147851567005, 1936114012888110, 1704424366552046, 856674880716312, 716603621335359 },
+ { 1072409664800960, 2146937497077528, 1508780108920651, 935767602384853, 1112800433544068 },
+ { 333549023751292, 280219272863308, 2104176666454852, 1036466864875785, 536135186520207 }
+ },
+ {
+ { 373666279883137, 146457241530109, 304116267127857, 416088749147715, 1258577131183391 },
+ { 1186115062588401, 2251609796968486, 1098944457878953, 1153112761201374, 1791625503417267 },
+ { 1870078460219737, 2129630962183380, 852283639691142, 292865602592851, 401904317342226 }
+ },
+ {
+ { 1361070124828035, 815664541425524, 1026798897364671, 1951790935390647, 555874891834790 },
+ { 1546301003424277, 459094500062839, 1097668518375311, 1780297770129643, 720763293687608 },
+ { 1212405311403990, 1536693382542438, 61028431067459, 1863929423417129, 1223219538638038 }
+ },
+ {
+ { 1294303766540260, 1183557465955093, 882271357233093, 63854569425375, 2213283684565087 },
+ { 339050984211414, 601386726509773, 413735232134068, 966191255137228, 1839475899458159 },
+ { 235605972169408, 2174055643032978, 1538335001838863, 1281866796917192, 1815940222628465 }
+ }
+},
+{ /* 24/31 */
+ {
+ { 1632352921721536, 1833328609514701, 2092779091951987, 1923956201873226, 2210068022482919 },
+ { 35271216625062, 1712350667021807, 983664255668860, 98571260373038, 1232645608559836 },
+ { 1998172393429622, 1798947921427073, 784387737563581, 1589352214827263, 1589861734168180 }
+ },
+ {
+ { 1733739258725305, 31715717059538, 201969945218860, 992093044556990, 1194308773174556 },
+ { 846415389605137, 746163495539180, 829658752826080, 592067705956946, 957242537821393 },
+ { 1758148849754419, 619249044817679, 168089007997045, 1371497636330523, 1867101418880350 }
+ },
+ {
+ { 326633984209635, 261759506071016, 1700682323676193, 1577907266349064, 1217647663383016 },
+ { 1714182387328607, 1477856482074168, 574895689942184, 2159118410227270, 1555532449716575 },
+ { 853828206885131, 998498946036955, 1835887550391235, 207627336608048, 258363815956050 }
+ },
+ {
+ { 141141474651677, 1236728744905256, 643101419899887, 1646615130509173, 1208239602291765 },
+ { 1501663228068911, 1354879465566912, 1444432675498247, 897812463852601, 855062598754348 },
+ { 714380763546606, 1032824444965790, 1774073483745338, 1063840874947367, 1738680636537158 }
+ },
+ {
+ { 1640635546696252, 633168953192112, 2212651044092396, 30590958583852, 368515260889378 },
+ { 1171650314802029, 1567085444565577, 1453660792008405, 757914533009261, 1619511342778196 },
+ { 420958967093237, 971103481109486, 2169549185607107, 1301191633558497, 1661514101014240 }
+ },
+ {
+ { 907123651818302, 1332556122804146, 1824055253424487, 1367614217442959, 1982558335973172 },
+ { 1121533090144639, 1021251337022187, 110469995947421, 1511059774758394, 2110035908131662 },
+ { 303213233384524, 2061932261128138, 352862124777736, 40828818670255, 249879468482660 }
+ },
+ {
+ { 856559257852200, 508517664949010, 1378193767894916, 1723459126947129, 1962275756614521 },
+ { 1445691340537320, 40614383122127, 402104303144865, 485134269878232, 1659439323587426 },
+ { 20057458979482, 1183363722525800, 2140003847237215, 2053873950687614, 2112017736174909 }
+ },
+ {
+ { 2228654250927986, 1483591363415267, 1368661293910956, 1076511285177291, 526650682059608 },
+ { 709481497028540, 531682216165724, 316963769431931, 1814315888453765, 258560242424104 },
+ { 1053447823660455, 1955135194248683, 1010900954918985, 1182614026976701, 1240051576966610 }
+ }
+},
+{ /* 25/31 */
+ {
+ { 1957943897155497, 1788667368028035, 137692910029106, 1039519607062, 826404763313028 },
+ { 1848942433095597, 1582009882530495, 1849292741020143, 1068498323302788, 2001402229799484 },
+ { 1528282417624269, 2142492439828191, 2179662545816034, 362568973150328, 1591374675250271 }
+ },
+ {
+ { 160026679434388, 232341189218716, 2149181472355545, 598041771119831, 183859001910173 },
+ { 2013278155187349, 662660471354454, 793981225706267, 411706605985744, 804490933124791 },
+ { 2051892037280204, 488391251096321, 2230187337030708, 930221970662692, 679002758255210 }
+ },
+ {
+ { 1530723630438670, 875873929577927, 341560134269988, 449903119530753, 1055551308214179 },
+ { 1461835919309432, 1955256480136428, 180866187813063, 1551979252664528, 557743861963950 },
+ { 359179641731115, 1324915145732949, 902828372691474, 294254275669987, 1887036027752957 }
+ },
+ {
+ { 2043271609454323, 2038225437857464, 1317528426475850, 1398989128982787, 2027639881006861 },
+ { 2072902725256516, 312132452743412, 309930885642209, 996244312618453, 1590501300352303 },
+ { 1397254305160710, 695734355138021, 2233992044438756, 1776180593969996, 1085588199351115 }
+ },
+ {
+ { 440567051331029, 254894786356681, 493869224930222, 1556322069683366, 1567456540319218 },
+ { 1950722461391320, 1907845598854797, 1822757481635527, 2121567704750244, 73811931471221 },
+ { 387139307395758, 2058036430315676, 1220915649965325, 1794832055328951, 1230009312169328 }
+ },
+ {
+ { 1765973779329517, 659344059446977, 19821901606666, 1301928341311214, 1116266004075885 },
+ { 1127572801181483, 1224743760571696, 1276219889847274, 1529738721702581, 1589819666871853 },
+ { 2181229378964934, 2190885205260020, 1511536077659137, 1246504208580490, 668883326494241 }
+ },
+ {
+ { 437866655573314, 669026411194768, 81896997980338, 523874406393178, 245052060935236 },
+ { 1975438052228868, 1071801519999806, 594652299224319, 1877697652668809, 1489635366987285 },
+ { 958592545673770, 233048016518599, 851568750216589, 567703851596087, 1740300006094761 }
+ },
+ {
+ { 2014540178270324, 192672779514432, 213877182641530, 2194819933853411, 1716422829364835 },
+ { 1540769606609725, 2148289943846077, 1597804156127445, 1230603716683868, 815423458809453 },
+ { 1738560251245018, 1779576754536888, 1783765347671392, 1880170990446751, 1088225159617541 }
+ }
+},
+{ /* 26/31 */
+ {
+ { 659303913929492, 1956447718227573, 1830568515922666, 841069049744408, 1669607124206368 },
+ { 1143465490433355, 1532194726196059, 1093276745494697, 481041706116088, 2121405433561163 },
+ { 1686424298744462, 1451806974487153, 266296068846582, 1834686947542675, 1720762336132256 }
+ },
+ {
+ { 889217026388959, 1043290623284660, 856125087551909, 1669272323124636, 1603340330827879 },
+ { 1206396181488998, 333158148435054, 1402633492821422, 1120091191722026, 1945474114550509 },
+ { 766720088232571, 1512222781191002, 1189719893490790, 2091302129467914, 2141418006894941 }
+ },
+ {
+ { 419663647306612, 1998875112167987, 1426599870253707, 1154928355379510, 486538532138187 },
+ { 938160078005954, 1421776319053174, 1941643234741774, 180002183320818, 1414380336750546 },
+ { 398001940109652, 1577721237663248, 1012748649830402, 1540516006905144, 1011684812884559 }
+ },
+ {
+ { 1653276489969630, 6081825167624, 1921777941170836, 1604139841794531, 861211053640641 },
+ { 996661541407379, 1455877387952927, 744312806857277, 139213896196746, 1000282908547789 },
+ { 1450817495603008, 1476865707053229, 1030490562252053, 620966950353376, 1744760161539058 }
+ },
+ {
+ { 559728410002599, 37056661641185, 2038622963352006, 1637244893271723, 1026565352238948 },
+ { 962165956135846, 1116599660248791, 182090178006815, 1455605467021751, 196053588803284 },
+ { 796863823080135, 1897365583584155, 420466939481601, 2165972651724672, 932177357788289 }
+ },
+ {
+ { 877047233620632, 1375632631944375, 643773611882121, 660022738847877, 19353932331831 },
+ { 2216943882299338, 394841323190322, 2222656898319671, 558186553950529, 1077236877025190 },
+ { 801118384953213, 1914330175515892, 574541023311511, 1471123787903705, 1526158900256288 }
+ },
+ {
+ { 949617889087234, 2207116611267331, 912920039141287, 501158539198789, 62362560771472 },
+ { 1474518386765335, 1760793622169197, 1157399790472736, 1622864308058898, 165428294422792 },
+ { 1961673048027128, 102619413083113, 1051982726768458, 1603657989805485, 1941613251499678 }
+ },
+ {
+ { 1401939116319266, 335306339903072, 72046196085786, 862423201496006, 850518754531384 },
+ { 1234706593321979, 1083343891215917, 898273974314935, 1640859118399498, 157578398571149 },
+ { 1143483057726416, 1992614991758919, 674268662140796, 1773370048077526, 674318359920189 }
+ }
+},
+{ /* 27/31 */
+ {
+ { 1835401379538542, 173900035308392, 818247630716732, 1762100412152786, 1021506399448291 },
+ { 1506632088156630, 2127481795522179, 513812919490255, 140643715928370, 442476620300318 },
+ { 2056683376856736, 219094741662735, 2193541883188309, 1841182310235800, 556477468664293 }
+ },
+ {
+ { 1315019427910827, 1049075855992603, 2066573052986543, 266904467185534, 2040482348591520 },
+ { 94096246544434, 922482381166992, 24517828745563, 2139430508542503, 2097139044231004 },
+ { 537697207950515, 1399352016347350, 1563663552106345, 2148749520888918, 549922092988516 }
+ },
+ {
+ { 1747985413252434, 680511052635695, 1809559829982725, 594274250930054, 201673170745982 },
+ { 323583936109569, 1973572998577657, 1192219029966558, 79354804385273, 1374043025560347 },
+ { 213277331329947, 416202017849623, 1950535221091783, 1313441578103244, 2171386783823658 }
+ },
+ {
+ { 189088804229831, 993969372859110, 895870121536987, 1547301535298256, 1477373024911350 },
+ { 1620578418245010, 541035331188469, 2235785724453865, 2154865809088198, 1974627268751826 },
+ { 1346805451740245, 1350981335690626, 942744349501813, 2155094562545502, 1012483751693409 }
+ },
+ {
+ { 2107080134091762, 1132567062788208, 1824935377687210, 769194804343737, 1857941799971888 },
+ { 1074666112436467, 249279386739593, 1174337926625354, 1559013532006480, 1472287775519121 },
+ { 1872620123779532, 1892932666768992, 1921559078394978, 1270573311796160, 1438913646755037 }
+ },
+ {
+ { 837390187648199, 1012253300223599, 989780015893987, 1351393287739814, 328627746545550 },
+ { 1028328827183114, 1711043289969857, 1350832470374933, 1923164689604327, 1495656368846911 },
+ { 1900828492104143, 430212361082163, 687437570852799, 832514536673512, 1685641495940794 }
+ },
+ {
+ { 842632847936398, 605670026766216, 290836444839585, 163210774892356, 2213815011799645 },
+ { 1176336383453996, 1725477294339771, 12700622672454, 678015708818208, 162724078519879 },
+ { 1448049969043497, 1789411762943521, 385587766217753, 90201620913498, 832999441066823 }
+ },
+ {
+ { 516086333293313, 2240508292484616, 1351669528166508, 1223255565316488, 750235824427138 },
+ { 1263624896582495, 1102602401673328, 526302183714372, 2152015839128799, 1483839308490010 },
+ { 442991718646863, 1599275157036458, 1925389027579192, 899514691371390, 350263251085160 }
+ }
+},
+{ /* 28/31 */
+ {
+ { 1689713572022143, 593854559254373, 978095044791970, 1985127338729499, 1676069120347625 },
+ { 1557207018622683, 340631692799603, 1477725909476187, 614735951619419, 2033237123746766 },
+ { 968764929340557, 1225534776710944, 662967304013036, 1155521416178595, 791142883466590 }
+ },
+ {
+ { 1487081286167458, 993039441814934, 1792378982844640, 698652444999874, 2153908693179754 },
+ { 1123181311102823, 685575944875442, 507605465509927, 1412590462117473, 568017325228626 },
+ { 560258797465417, 2193971151466401, 1824086900849026, 579056363542056, 1690063960036441 }
+ },
+ {
+ { 1918407319222416, 353767553059963, 1930426334528099, 1564816146005724, 1861342381708096 },
+ { 2131325168777276, 1176636658428908, 1756922641512981, 1390243617176012, 1966325177038383 },
+ { 2063958120364491, 2140267332393533, 699896251574968, 273268351312140, 375580724713232 }
+ },
+ {
+ { 2024297515263178, 416959329722687, 1079014235017302, 171612225573183, 1031677520051053 },
+ { 2033900009388450, 1744902869870788, 2190580087917640, 1949474984254121, 231049754293748 },
+ { 343868674606581, 550155864008088, 1450580864229630, 481603765195050, 896972360018042 }
+ },
+ {
+ { 2151139328380127, 314745882084928, 59756825775204, 1676664391494651, 2048348075599360 },
+ { 1528930066340597, 1605003907059576, 1055061081337675, 1458319101947665, 1234195845213142 },
+ { 830430507734812, 1780282976102377, 1425386760709037, 362399353095425, 2168861579799910 }
+ },
+ {
+ { 1155762232730333, 980662895504006, 2053766700883521, 490966214077606, 510405877041357 },
+ { 1683750316716132, 652278688286128, 1221798761193539, 1897360681476669, 319658166027343 },
+ { 618808732869972, 72755186759744, 2060379135624181, 1730731526741822, 48862757828238 }
+ },
+ {
+ { 1463171970593505, 1143040711767452, 614590986558883, 1409210575145591, 1882816996436803 },
+ { 2230133264691131, 563950955091024, 2042915975426398, 827314356293472, 672028980152815 },
+ { 264204366029760, 1654686424479449, 2185050199932931, 2207056159091748, 506015669043634 }
+ },
+ {
+ { 1784446333136569, 1973746527984364, 334856327359575, 1156769775884610, 1023950124675478 },
+ { 2065270940578383, 31477096270353, 306421879113491, 181958643936686, 1907105536686083 },
+ { 1496516440779464, 1748485652986458, 872778352227340, 818358834654919, 97932669284220 }
+ }
+},
+{ /* 29/31 */
+ {
+ { 471636015770351, 672455402793577, 1804995246884103, 1842309243470804, 1501862504981682 },
+ { 1013216974933691, 538921919682598, 1915776722521558, 1742822441583877, 1886550687916656 },
+ { 2094270000643336, 303971879192276, 40801275554748, 649448917027930, 1818544418535447 }
+ },
+ {
+ { 2241737709499165, 549397817447461, 838180519319392, 1725686958520781, 1705639080897747 },
+ { 1216074541925116, 50120933933509, 1565829004133810, 721728156134580, 349206064666188 },
+ { 948617110470858, 346222547451945, 1126511960599975, 1759386906004538, 493053284802266 }
+ },
+ {
+ { 1454933046815146, 874696014266362, 1467170975468588, 1432316382418897, 2111710746366763 },
+ { 2105387117364450, 1996463405126433, 1303008614294500, 851908115948209, 1353742049788635 },
+ { 750300956351719, 1487736556065813, 15158817002104, 1511998221598392, 971739901354129 }
+ },
+ {
+ { 1874648163531693, 2124487685930551, 1810030029384882, 918400043048335, 586348627300650 },
+ { 1235084464747900, 1166111146432082, 1745394857881591, 1405516473883040, 4463504151617 },
+ { 1663810156463827, 327797390285791, 1341846161759410, 1964121122800605, 1747470312055380 }
+ },
+ {
+ { 660005247548233, 2071860029952887, 1358748199950107, 911703252219107, 1014379923023831 },
+ { 2206641276178231, 1690587809721504, 1600173622825126, 2156096097634421, 1106822408548216 },
+ { 1344788193552206, 1949552134239140, 1735915881729557, 675891104100469, 1834220014427292 }
+ },
+ {
+ { 1920949492387964, 158885288387530, 70308263664033, 626038464897817, 1468081726101009 },
+ { 622221042073383, 1210146474039168, 1742246422343683, 1403839361379025, 417189490895736 },
+ { 22727256592983, 168471543384997, 1324340989803650, 1839310709638189, 504999476432775 }
+ },
+ {
+ { 1313240518756327, 1721896294296942, 52263574587266, 2065069734239232, 804910473424630 },
+ { 1337466662091884, 1287645354669772, 2018019646776184, 652181229374245, 898011753211715 },
+ { 1969792547910734, 779969968247557, 2011350094423418, 1823964252907487, 1058949448296945 }
+ },
+ {
+ { 207343737062002, 1118176942430253, 758894594548164, 806764629546266, 1157700123092949 },
+ { 1273565321399022, 1638509681964574, 759235866488935, 666015124346707, 897983460943405 },
+ { 1717263794012298, 1059601762860786, 1837819172257618, 1054130665797229, 680893204263559 }
+ }
+},
+{ /* 30/31 */
+ {
+ { 2237039662793603, 2249022333361206, 2058613546633703, 149454094845279, 2215176649164582 },
+ { 79472182719605, 1851130257050174, 1825744808933107, 821667333481068, 781795293511946 },
+ { 755822026485370, 152464789723500, 1178207602290608, 410307889503239, 156581253571278 }
+ },
+ {
+ { 1418185496130297, 484520167728613, 1646737281442950, 1401487684670265, 1349185550126961 },
+ { 1495380034400429, 325049476417173, 46346894893933, 1553408840354856, 828980101835683 },
+ { 1280337889310282, 2070832742866672, 1640940617225222, 2098284908289951, 450929509534434 }
+ },
+ {
+ { 407703353998781, 126572141483652, 286039827513621, 1999255076709338, 2030511179441770 },
+ { 1254958221100483, 1153235960999843, 942907704968834, 637105404087392, 1149293270147267 },
+ { 894249020470196, 400291701616810, 406878712230981, 1599128793487393, 1145868722604026 }
+ },
+ {
+ { 1497955250203334, 110116344653260, 1128535642171976, 1900106496009660, 129792717460909 },
+ { 452487513298665, 1352120549024569, 1173495883910956, 1999111705922009, 367328130454226 },
+ { 1717539401269642, 1475188995688487, 891921989653942, 836824441505699, 1885988485608364 }
+ },
+ {
+ { 1241784121422547, 187337051947583, 1118481812236193, 428747751936362, 30358898927325 },
+ { 2022432361201842, 1088816090685051, 1977843398539868, 1854834215890724, 564238862029357 },
+ { 938868489100585, 1100285072929025, 1017806255688848, 1957262154788833, 152787950560442 }
+ },
+ {
+ { 867319417678923, 620471962942542, 226032203305716, 342001443957629, 1761675818237336 },
+ { 1295072362439987, 931227904689414, 1355731432641687, 922235735834035, 892227229410209 },
+ { 1680989767906154, 535362787031440, 2136691276706570, 1942228485381244, 1267350086882274 }
+ },
+ {
+ { 366018233770527, 432660629755596, 126409707644535, 1973842949591662, 645627343442376 },
+ { 535509430575217, 546885533737322, 1524675609547799, 2138095752851703, 1260738089896827 },
+ { 1159906385590467, 2198530004321610, 714559485023225, 81880727882151, 1484020820037082 }
+ },
+ {
+ { 1377485731340769, 2046328105512000, 1802058637158797, 62146136768173, 1356993908853901 },
+ { 2013612215646735, 1830770575920375, 536135310219832, 609272325580394, 270684344495013 },
+ { 1237542585982777, 2228682050256790, 1385281931622824, 593183794882890, 493654978552689 }
+ }
+},
+{ /* 31/31 */
+ {
+ { 47341488007760, 1891414891220257, 983894663308928, 176161768286818, 1126261115179708 },
+ { 1694030170963455, 502038567066200, 1691160065225467, 949628319562187, 275110186693066 },
+ { 1124515748676336, 1661673816593408, 1499640319059718, 1584929449166988, 558148594103306 }
+ },
+ {
+ { 1784525599998356, 1619698033617383, 2097300287550715, 258265458103756, 1905684794832758 },
+ { 1288941072872766, 931787902039402, 190731008859042, 2006859954667190, 1005931482221702 },
+ { 1465551264822703, 152905080555927, 680334307368453, 173227184634745, 666407097159852 }
+ },
+ {
+ { 2111017076203943, 1378760485794347, 1248583954016456, 1352289194864422, 1895180776543896 },
+ { 171348223915638, 662766099800389, 462338943760497, 466917763340314, 656911292869115 },
+ { 488623681976577, 866497561541722, 1708105560937768, 1673781214218839, 1506146329818807 }
+ },
+ {
+ { 160425464456957, 950394373239689, 430497123340934, 711676555398832, 320964687779005 },
+ { 988979367990485, 1359729327576302, 1301834257246029, 294141160829308, 29348272277475 },
+ { 1434382743317910, 100082049942065, 221102347892623, 186982837860588, 1305765053501834 }
+ },
+ {
+ { 2205916462268190, 499863829790820, 961960554686616, 158062762756985, 1841471168298305 },
+ { 1191737341426592, 1847042034978363, 1382213545049056, 1039952395710448, 788812858896859 },
+ { 1346965964571152, 1291881610839830, 2142916164336056, 786821641205979, 1571709146321039 }
+ },
+ {
+ { 787164375951248, 202869205373189, 1356590421032140, 1431233331032510, 786341368775957 },
+ { 492448143532951, 304105152670757, 1761767168301056, 233782684697790, 1981295323106089 },
+ { 665807507761866, 1343384868355425, 895831046139653, 439338948736892, 1986828765695105 }
+ },
+ {
+ { 756096210874553, 1721699973539149, 258765301727885, 1390588532210645, 1212530909934781 },
+ { 852891097972275, 1816988871354562, 1543772755726524, 1174710635522444, 202129090724628 },
+ { 1205281565824323, 22430498399418, 992947814485516, 1392458699738672, 688441466734558 }
+ },
+ {
+ { 1050627428414972, 1955849529137135, 2171162376368357, 91745868298214, 447733118757826 },
+ { 1287181461435438, 622722465530711, 880952150571872, 741035693459198, 311565274989772 },
+ { 1003649078149734, 545233927396469, 1849786171789880, 1318943684880434, 280345687170552 }
+ }
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h
new file mode 100644
index 0000000000..d088241657
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h
@@ -0,0 +1,40 @@
+{
+ { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 },
+ { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 },
+ { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 }
+},
+{
+ { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 },
+ { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 },
+ { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 }
+},
+{
+ { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 },
+ { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 },
+ { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 }
+},
+{
+ { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 },
+ { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 },
+ { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 }
+},
+{
+ { 1802695059465007, 1664899123557221, 593559490740857, 2160434469266659, 927570450755031 },
+ { 1725674970513508, 1933645953859181, 1542344539275782, 1767788773573747, 1297447965928905 },
+ { 1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624 }
+},
+{
+ { 1970894096313054, 528066325833207, 1619374932191227, 2207306624415883, 1169170329061080 },
+ { 2070390218572616, 1458919061857835, 624171843017421, 1055332792707765, 433987520732508 },
+ { 893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815 }
+},
+{
+ { 213454002618221, 939771523987438, 1159882208056014, 317388369627517, 621213314200687 },
+ { 1971678598905747, 338026507889165, 762398079972271, 655096486107477, 42299032696322 },
+ { 177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791 }
+},
+{
+ { 1913163449625248, 460779200291993, 2193883288642314, 1008900146920800, 1721983679009502 },
+ { 1070401523076875, 1272492007800961, 1910153608563310, 2075579521696771, 1191169788841221 },
+ { 692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901 }
+}
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h
new file mode 100644
index 0000000000..53b75c6b45
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h
@@ -0,0 +1,21 @@
+/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */
+static const fe25519 d = {
+ 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575
+};
+
+/* 2 * d =
+ * 16295367250680780974490674513165176452449235426866156013048779062215315747161
+ */
+static const fe25519 d2 = {
+ 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903
+};
+
+/* sqrt(-1) */
+static const fe25519 sqrtm1 = {
+ 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133
+};
+
+/* A = 486662 */
+static const fe25519 curve25519_A = {
+ 486662, 0, 0, 0, 0
+};
diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h
new file mode 100644
index 0000000000..de876264c8
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h
@@ -0,0 +1,116 @@
+/*
+ Ignores top bit of h.
+ */
+
+void
+fe25519_frombytes(fe25519 h, const unsigned char *s)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint64_t h0, h1, h2, h3, h4;
+
+ h0 = (LOAD64_LE(s ) ) & mask;
+ h1 = (LOAD64_LE(s + 6) >> 3) & mask;
+ h2 = (LOAD64_LE(s + 12) >> 6) & mask;
+ h3 = (LOAD64_LE(s + 19) >> 1) & mask;
+ h4 = (LOAD64_LE(s + 24) >> 12) & mask;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+}
+
+static void
+fe25519_reduce(fe25519 h, const fe25519 f)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint128_t t[5];
+
+ t[0] = f[0];
+ t[1] = f[1];
+ t[2] = f[2];
+ t[3] = f[3];
+ t[4] = f[4];
+
+ t[1] += t[0] >> 51;
+ t[0] &= mask;
+ t[2] += t[1] >> 51;
+ t[1] &= mask;
+ t[3] += t[2] >> 51;
+ t[2] &= mask;
+ t[4] += t[3] >> 51;
+ t[3] &= mask;
+ t[0] += 19 * (t[4] >> 51);
+ t[4] &= mask;
+
+ t[1] += t[0] >> 51;
+ t[0] &= mask;
+ t[2] += t[1] >> 51;
+ t[1] &= mask;
+ t[3] += t[2] >> 51;
+ t[2] &= mask;
+ t[4] += t[3] >> 51;
+ t[3] &= mask;
+ t[0] += 19 * (t[4] >> 51);
+ t[4] &= mask;
+
+ /* now t is between 0 and 2^255-1, properly carried. */
+ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
+
+ t[0] += 19ULL;
+
+ t[1] += t[0] >> 51;
+ t[0] &= mask;
+ t[2] += t[1] >> 51;
+ t[1] &= mask;
+ t[3] += t[2] >> 51;
+ t[2] &= mask;
+ t[4] += t[3] >> 51;
+ t[3] &= mask;
+ t[0] += 19ULL * (t[4] >> 51);
+ t[4] &= mask;
+
+ /* now between 19 and 2^255-1 in both cases, and offset by 19. */
+
+ t[0] += 0x8000000000000 - 19ULL;
+ t[1] += 0x8000000000000 - 1ULL;
+ t[2] += 0x8000000000000 - 1ULL;
+ t[3] += 0x8000000000000 - 1ULL;
+ t[4] += 0x8000000000000 - 1ULL;
+
+ /* now between 2^255 and 2^256-20, and offset by 2^255. */
+
+ t[1] += t[0] >> 51;
+ t[0] &= mask;
+ t[2] += t[1] >> 51;
+ t[1] &= mask;
+ t[3] += t[2] >> 51;
+ t[2] &= mask;
+ t[4] += t[3] >> 51;
+ t[3] &= mask;
+ t[4] &= mask;
+
+ h[0] = t[0];
+ h[1] = t[1];
+ h[2] = t[2];
+ h[3] = t[3];
+ h[4] = t[4];
+}
+
+void
+fe25519_tobytes(unsigned char *s, const fe25519 h)
+{
+ fe25519 t;
+ uint64_t t0, t1, t2, t3;
+
+ fe25519_reduce(t, h);
+ t0 = t[0] | (t[1] << 51);
+ t1 = (t[1] >> 13) | (t[2] << 38);
+ t2 = (t[2] >> 26) | (t[3] << 25);
+ t3 = (t[3] >> 39) | (t[4] << 12);
+ STORE64_LE(s + 0, t0);
+ STORE64_LE(s + 8, t1);
+ STORE64_LE(s + 16, t2);
+ STORE64_LE(s + 24, t3);
+}
diff --git a/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c b/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c
new file mode 100644
index 0000000000..39ab26a6da
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c
@@ -0,0 +1,93 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crypto_core_hchacha20.h"
+#include "private/common.h"
+
+#define QUARTERROUND(A, B, C, D) \
+ do { \
+ A += B; D = ROTL32(D ^ A, 16); \
+ C += D; B = ROTL32(B ^ C, 12); \
+ A += B; D = ROTL32(D ^ A, 8); \
+ C += D; B = ROTL32(B ^ C, 7); \
+ } while(0)
+
+int
+crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c)
+{
+ int i;
+ uint32_t x0, x1, x2, x3, x4, x5, x6, x7;
+ uint32_t x8, x9, x10, x11, x12, x13, x14, x15;
+
+ if (c == NULL) {
+ x0 = 0x61707865;
+ x1 = 0x3320646e;
+ x2 = 0x79622d32;
+ x3 = 0x6b206574;
+ } else {
+ x0 = LOAD32_LE(c + 0);
+ x1 = LOAD32_LE(c + 4);
+ x2 = LOAD32_LE(c + 8);
+ x3 = LOAD32_LE(c + 12);
+ }
+ x4 = LOAD32_LE(k + 0);
+ x5 = LOAD32_LE(k + 4);
+ x6 = LOAD32_LE(k + 8);
+ x7 = LOAD32_LE(k + 12);
+ x8 = LOAD32_LE(k + 16);
+ x9 = LOAD32_LE(k + 20);
+ x10 = LOAD32_LE(k + 24);
+ x11 = LOAD32_LE(k + 28);
+ x12 = LOAD32_LE(in + 0);
+ x13 = LOAD32_LE(in + 4);
+ x14 = LOAD32_LE(in + 8);
+ x15 = LOAD32_LE(in + 12);
+
+ for (i = 0; i < 10; i++) {
+ QUARTERROUND(x0, x4, x8, x12);
+ QUARTERROUND(x1, x5, x9, x13);
+ QUARTERROUND(x2, x6, x10, x14);
+ QUARTERROUND(x3, x7, x11, x15);
+ QUARTERROUND(x0, x5, x10, x15);
+ QUARTERROUND(x1, x6, x11, x12);
+ QUARTERROUND(x2, x7, x8, x13);
+ QUARTERROUND(x3, x4, x9, x14);
+ }
+
+ STORE32_LE(out + 0, x0);
+ STORE32_LE(out + 4, x1);
+ STORE32_LE(out + 8, x2);
+ STORE32_LE(out + 12, x3);
+ STORE32_LE(out + 16, x12);
+ STORE32_LE(out + 20, x13);
+ STORE32_LE(out + 24, x14);
+ STORE32_LE(out + 28, x15);
+
+ return 0;
+}
+
+size_t
+crypto_core_hchacha20_outputbytes(void)
+{
+ return crypto_core_hchacha20_OUTPUTBYTES;
+}
+
+size_t
+crypto_core_hchacha20_inputbytes(void)
+{
+ return crypto_core_hchacha20_INPUTBYTES;
+}
+
+size_t
+crypto_core_hchacha20_keybytes(void)
+{
+ return crypto_core_hchacha20_KEYBYTES;
+}
+
+size_t
+crypto_core_hchacha20_constbytes(void)
+{
+ return crypto_core_hchacha20_CONSTBYTES;
+}
diff --git a/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c b/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c
new file mode 100644
index 0000000000..37c4923af6
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c
@@ -0,0 +1,21 @@
+#include "crypto_core_hsalsa20.h"
+
+size_t
+crypto_core_hsalsa20_outputbytes(void) {
+ return crypto_core_hsalsa20_OUTPUTBYTES;
+}
+
+size_t
+crypto_core_hsalsa20_inputbytes(void) {
+ return crypto_core_hsalsa20_INPUTBYTES;
+}
+
+size_t
+crypto_core_hsalsa20_keybytes(void) {
+ return crypto_core_hsalsa20_KEYBYTES;
+}
+
+size_t
+crypto_core_hsalsa20_constbytes(void) {
+ return crypto_core_hsalsa20_CONSTBYTES;
+}
diff --git a/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c b/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c
new file mode 100644
index 0000000000..1d1220fee2
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c
@@ -0,0 +1,95 @@
+/*
+version 20080912
+D. J. Bernstein
+Public domain.
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crypto_core_hsalsa20.h"
+#include "private/common.h"
+
+#define ROUNDS 20
+#define U32C(v) (v##U)
+
+int
+crypto_core_hsalsa20(unsigned char *out,
+ const unsigned char *in,
+ const unsigned char *k,
+ const unsigned char *c)
+{
+ uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8,
+ x9, x10, x11, x12, x13, x14, x15;
+ int i;
+
+ if (c == NULL) {
+ x0 = U32C(0x61707865);
+ x5 = U32C(0x3320646e);
+ x10 = U32C(0x79622d32);
+ x15 = U32C(0x6b206574);
+ } else {
+ x0 = LOAD32_LE(c + 0);
+ x5 = LOAD32_LE(c + 4);
+ x10 = LOAD32_LE(c + 8);
+ x15 = LOAD32_LE(c + 12);
+ }
+ x1 = LOAD32_LE(k + 0);
+ x2 = LOAD32_LE(k + 4);
+ x3 = LOAD32_LE(k + 8);
+ x4 = LOAD32_LE(k + 12);
+ x11 = LOAD32_LE(k + 16);
+ x12 = LOAD32_LE(k + 20);
+ x13 = LOAD32_LE(k + 24);
+ x14 = LOAD32_LE(k + 28);
+ x6 = LOAD32_LE(in + 0);
+ x7 = LOAD32_LE(in + 4);
+ x8 = LOAD32_LE(in + 8);
+ x9 = LOAD32_LE(in + 12);
+
+ for (i = ROUNDS; i > 0; i -= 2) {
+ x4 ^= ROTL32(x0 + x12, 7);
+ x8 ^= ROTL32(x4 + x0, 9);
+ x12 ^= ROTL32(x8 + x4, 13);
+ x0 ^= ROTL32(x12 + x8, 18);
+ x9 ^= ROTL32(x5 + x1, 7);
+ x13 ^= ROTL32(x9 + x5, 9);
+ x1 ^= ROTL32(x13 + x9, 13);
+ x5 ^= ROTL32(x1 + x13, 18);
+ x14 ^= ROTL32(x10 + x6, 7);
+ x2 ^= ROTL32(x14 + x10, 9);
+ x6 ^= ROTL32(x2 + x14, 13);
+ x10 ^= ROTL32(x6 + x2, 18);
+ x3 ^= ROTL32(x15 + x11, 7);
+ x7 ^= ROTL32(x3 + x15, 9);
+ x11 ^= ROTL32(x7 + x3, 13);
+ x15 ^= ROTL32(x11 + x7, 18);
+ x1 ^= ROTL32(x0 + x3, 7);
+ x2 ^= ROTL32(x1 + x0, 9);
+ x3 ^= ROTL32(x2 + x1, 13);
+ x0 ^= ROTL32(x3 + x2, 18);
+ x6 ^= ROTL32(x5 + x4, 7);
+ x7 ^= ROTL32(x6 + x5, 9);
+ x4 ^= ROTL32(x7 + x6, 13);
+ x5 ^= ROTL32(x4 + x7, 18);
+ x11 ^= ROTL32(x10 + x9, 7);
+ x8 ^= ROTL32(x11 + x10, 9);
+ x9 ^= ROTL32(x8 + x11, 13);
+ x10 ^= ROTL32(x9 + x8, 18);
+ x12 ^= ROTL32(x15 + x14, 7);
+ x13 ^= ROTL32(x12 + x15, 9);
+ x14 ^= ROTL32(x13 + x12, 13);
+ x15 ^= ROTL32(x14 + x13, 18);
+ }
+
+ STORE32_LE(out + 0, x0);
+ STORE32_LE(out + 4, x5);
+ STORE32_LE(out + 8, x10);
+ STORE32_LE(out + 12, x15);
+ STORE32_LE(out + 16, x6);
+ STORE32_LE(out + 20, x7);
+ STORE32_LE(out + 24, x8);
+ STORE32_LE(out + 28, x9);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c
new file mode 100644
index 0000000000..a077d7f4db
--- /dev/null
+++ b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c
@@ -0,0 +1,195 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crypto_core_salsa20.h"
+#include "crypto_core_salsa2012.h"
+#include "crypto_core_salsa208.h"
+#include "private/common.h"
+
+static void
+crypto_core_salsa(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c,
+ const int rounds)
+{
+ uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14,
+ x15;
+ uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14,
+ j15;
+ int i;
+
+ j0 = x0 = 0x61707865;
+ j5 = x5 = 0x3320646e;
+ j10 = x10 = 0x79622d32;
+ j15 = x15 = 0x6b206574;
+ if (c != NULL) {
+ j0 = x0 = LOAD32_LE(c + 0);
+ j5 = x5 = LOAD32_LE(c + 4);
+ j10 = x10 = LOAD32_LE(c + 8);
+ j15 = x15 = LOAD32_LE(c + 12);
+ }
+ j1 = x1 = LOAD32_LE(k + 0);
+ j2 = x2 = LOAD32_LE(k + 4);
+ j3 = x3 = LOAD32_LE(k + 8);
+ j4 = x4 = LOAD32_LE(k + 12);
+ j11 = x11 = LOAD32_LE(k + 16);
+ j12 = x12 = LOAD32_LE(k + 20);
+ j13 = x13 = LOAD32_LE(k + 24);
+ j14 = x14 = LOAD32_LE(k + 28);
+
+ j6 = x6 = LOAD32_LE(in + 0);
+ j7 = x7 = LOAD32_LE(in + 4);
+ j8 = x8 = LOAD32_LE(in + 8);
+ j9 = x9 = LOAD32_LE(in + 12);
+
+ for (i = 0; i < rounds; i += 2) {
+ x4 ^= ROTL32(x0 + x12, 7);
+ x8 ^= ROTL32(x4 + x0, 9);
+ x12 ^= ROTL32(x8 + x4, 13);
+ x0 ^= ROTL32(x12 + x8, 18);
+ x9 ^= ROTL32(x5 + x1, 7);
+ x13 ^= ROTL32(x9 + x5, 9);
+ x1 ^= ROTL32(x13 + x9, 13);
+ x5 ^= ROTL32(x1 + x13, 18);
+ x14 ^= ROTL32(x10 + x6, 7);
+ x2 ^= ROTL32(x14 + x10, 9);
+ x6 ^= ROTL32(x2 + x14, 13);
+ x10 ^= ROTL32(x6 + x2, 18);
+ x3 ^= ROTL32(x15 + x11, 7);
+ x7 ^= ROTL32(x3 + x15, 9);
+ x11 ^= ROTL32(x7 + x3, 13);
+ x15 ^= ROTL32(x11 + x7, 18);
+ x1 ^= ROTL32(x0 + x3, 7);
+ x2 ^= ROTL32(x1 + x0, 9);
+ x3 ^= ROTL32(x2 + x1, 13);
+ x0 ^= ROTL32(x3 + x2, 18);
+ x6 ^= ROTL32(x5 + x4, 7);
+ x7 ^= ROTL32(x6 + x5, 9);
+ x4 ^= ROTL32(x7 + x6, 13);
+ x5 ^= ROTL32(x4 + x7, 18);
+ x11 ^= ROTL32(x10 + x9, 7);
+ x8 ^= ROTL32(x11 + x10, 9);
+ x9 ^= ROTL32(x8 + x11, 13);
+ x10 ^= ROTL32(x9 + x8, 18);
+ x12 ^= ROTL32(x15 + x14, 7);
+ x13 ^= ROTL32(x12 + x15, 9);
+ x14 ^= ROTL32(x13 + x12, 13);
+ x15 ^= ROTL32(x14 + x13, 18);
+ }
+ STORE32_LE(out + 0, x0 + j0);
+ STORE32_LE(out + 4, x1 + j1);
+ STORE32_LE(out + 8, x2 + j2);
+ STORE32_LE(out + 12, x3 + j3);
+ STORE32_LE(out + 16, x4 + j4);
+ STORE32_LE(out + 20, x5 + j5);
+ STORE32_LE(out + 24, x6 + j6);
+ STORE32_LE(out + 28, x7 + j7);
+ STORE32_LE(out + 32, x8 + j8);
+ STORE32_LE(out + 36, x9 + j9);
+ STORE32_LE(out + 40, x10 + j10);
+ STORE32_LE(out + 44, x11 + j11);
+ STORE32_LE(out + 48, x12 + j12);
+ STORE32_LE(out + 52, x13 + j13);
+ STORE32_LE(out + 56, x14 + j14);
+ STORE32_LE(out + 60, x15 + j15);
+}
+
+int
+crypto_core_salsa20(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c)
+{
+ crypto_core_salsa(out, in, k, c, 20);
+ return 0;
+}
+
+size_t
+crypto_core_salsa20_outputbytes(void)
+{
+ return crypto_core_salsa20_OUTPUTBYTES;
+}
+
+size_t
+crypto_core_salsa20_inputbytes(void)
+{
+ return crypto_core_salsa20_INPUTBYTES;
+}
+
+size_t
+crypto_core_salsa20_keybytes(void)
+{
+ return crypto_core_salsa20_KEYBYTES;
+}
+
+size_t
+crypto_core_salsa20_constbytes(void)
+{
+ return crypto_core_salsa20_CONSTBYTES;
+}
+
+#ifndef MINIMAL
+
+int
+crypto_core_salsa2012(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c)
+{
+ crypto_core_salsa(out, in, k, c, 12);
+ return 0;
+}
+
+size_t
+crypto_core_salsa2012_outputbytes(void)
+{
+ return crypto_core_salsa2012_OUTPUTBYTES;
+}
+
+size_t
+crypto_core_salsa2012_inputbytes(void)
+{
+ return crypto_core_salsa2012_INPUTBYTES;
+}
+
+size_t
+crypto_core_salsa2012_keybytes(void)
+{
+ return crypto_core_salsa2012_KEYBYTES;
+}
+
+size_t
+crypto_core_salsa2012_constbytes(void)
+{
+ return crypto_core_salsa2012_CONSTBYTES;
+}
+
+int
+crypto_core_salsa208(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c)
+{
+ crypto_core_salsa(out, in, k, c, 8);
+ return 0;
+}
+
+size_t
+crypto_core_salsa208_outputbytes(void)
+{
+ return crypto_core_salsa208_OUTPUTBYTES;
+}
+
+size_t
+crypto_core_salsa208_inputbytes(void)
+{
+ return crypto_core_salsa208_INPUTBYTES;
+}
+
+size_t
+crypto_core_salsa208_keybytes(void)
+{
+ return crypto_core_salsa208_KEYBYTES;
+}
+
+size_t
+crypto_core_salsa208_constbytes(void)
+{
+ return crypto_core_salsa208_CONSTBYTES;
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c b/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c
new file mode 100644
index 0000000000..781d4c584e
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c
@@ -0,0 +1,55 @@
+#include "crypto_generichash_blake2b.h"
+#include "randombytes.h"
+
+size_t
+crypto_generichash_blake2b_bytes_min(void) {
+ return crypto_generichash_blake2b_BYTES_MIN;
+}
+
+size_t
+crypto_generichash_blake2b_bytes_max(void) {
+ return crypto_generichash_blake2b_BYTES_MAX;
+}
+
+size_t
+crypto_generichash_blake2b_bytes(void) {
+ return crypto_generichash_blake2b_BYTES;
+}
+
+size_t
+crypto_generichash_blake2b_keybytes_min(void) {
+ return crypto_generichash_blake2b_KEYBYTES_MIN;
+}
+
+size_t
+crypto_generichash_blake2b_keybytes_max(void) {
+ return crypto_generichash_blake2b_KEYBYTES_MAX;
+}
+
+size_t
+crypto_generichash_blake2b_keybytes(void) {
+ return crypto_generichash_blake2b_KEYBYTES;
+}
+
+size_t
+crypto_generichash_blake2b_saltbytes(void) {
+ return crypto_generichash_blake2b_SALTBYTES;
+}
+
+size_t
+crypto_generichash_blake2b_personalbytes(void) {
+ return crypto_generichash_blake2b_PERSONALBYTES;
+}
+
+size_t
+crypto_generichash_blake2b_statebytes(void)
+{
+ return (sizeof(crypto_generichash_blake2b_state) + (size_t) 63U)
+ & ~(size_t) 63U;
+}
+
+void
+crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES])
+{
+ randombytes_buf(k, crypto_generichash_blake2b_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h
new file mode 100644
index 0000000000..c6c4fccbb7
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h
@@ -0,0 +1,109 @@
+/*
+ BLAKE2 reference source code package - reference C implementations
+
+ Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+ To the extent possible under law, the author(s) have dedicated all copyright
+ and related and neighboring rights to this software to the public domain
+ worldwide. This software is distributed without any warranty.
+
+ All code is triple-licensed under the
+ [CC0](http://creativecommons.org/publicdomain/zero/1.0), the
+ [OpenSSL Licence](https://www.openssl.org/source/license.html), or
+ the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0),
+ at your choosing.
+ */
+
+#ifndef blake2_H
+#define blake2_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "crypto_generichash_blake2b.h"
+#include "export.h"
+
+#define blake2b_init_param crypto_generichash_blake2b__init_param
+#define blake2b_init crypto_generichash_blake2b__init
+#define blake2b_init_salt_personal \
+ crypto_generichash_blake2b__init_salt_personal
+#define blake2b_init_key crypto_generichash_blake2b__init_key
+#define blake2b_init_key_salt_personal \
+ crypto_generichash_blake2b__init_key_salt_personal
+#define blake2b_update crypto_generichash_blake2b__update
+#define blake2b_final crypto_generichash_blake2b__final
+#define blake2b crypto_generichash_blake2b__blake2b
+#define blake2b_salt_personal crypto_generichash_blake2b__blake2b_salt_personal
+#define blake2b_pick_best_implementation \
+ crypto_generichash_blake2b__pick_best_implementation
+
+enum blake2b_constant {
+ BLAKE2B_BLOCKBYTES = 128,
+ BLAKE2B_OUTBYTES = 64,
+ BLAKE2B_KEYBYTES = 64,
+ BLAKE2B_SALTBYTES = 16,
+ BLAKE2B_PERSONALBYTES = 16
+};
+
+#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+typedef struct blake2b_param_ {
+ uint8_t digest_length; /* 1 */
+ uint8_t key_length; /* 2 */
+ uint8_t fanout; /* 3 */
+ uint8_t depth; /* 4 */
+ uint8_t leaf_length[4]; /* 8 */
+ uint8_t node_offset[8]; /* 16 */
+ uint8_t node_depth; /* 17 */
+ uint8_t inner_length; /* 18 */
+ uint8_t reserved[14]; /* 32 */
+ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
+ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
+} blake2b_param;
+
+typedef crypto_generichash_blake2b_state blake2b_state;
+
+#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+/* Streaming API */
+int blake2b_init(blake2b_state *S, const uint8_t outlen);
+int blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen,
+ const void *salt, const void *personal);
+int blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key,
+ const uint8_t keylen);
+int blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen,
+ const void *key, const uint8_t keylen,
+ const void *salt, const void *personal);
+int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
+int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen);
+int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen);
+
+/* Simple API */
+int blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen,
+ const uint64_t inlen, uint8_t keylen);
+int blake2b_salt_personal(uint8_t *out, const void *in, const void *key,
+ const uint8_t outlen, const uint64_t inlen,
+ uint8_t keylen, const void *salt,
+ const void *personal);
+
+typedef int (*blake2b_compress_fn)(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES]);
+int blake2b_pick_best_implementation(void);
+int blake2b_compress_ref(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES]);
+int blake2b_compress_ssse3(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES]);
+int blake2b_compress_sse41(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES]);
+int blake2b_compress_avx2(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES]);
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c
new file mode 100644
index 0000000000..7cb41fb6e7
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c
@@ -0,0 +1,49 @@
+
+#define BLAKE2_USE_SSSE3
+#define BLAKE2_USE_SSE41
+#define BLAKE2_USE_AVX2
+
+#include <stdint.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# pragma GCC target("avx2")
+# endif
+
+# include <emmintrin.h>
+# include <immintrin.h>
+# include <smmintrin.h>
+# include <tmmintrin.h>
+
+# include "blake2b-compress-avx2.h"
+
+CRYPTO_ALIGN(64)
+static const uint64_t blake2b_IV[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+int
+blake2b_compress_avx2(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES])
+{
+ __m256i a = LOADU(&S->h[0]);
+ __m256i b = LOADU(&S->h[4]);
+ BLAKE2B_COMPRESS_V1(a, b, block, S->t[0], S->t[1], S->f[0], S->f[1]);
+ STOREU(&S->h[0], a);
+ STOREU(&S->h[4], b);
+
+ return 0;
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h
new file mode 100644
index 0000000000..21acb2fa0c
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h
@@ -0,0 +1,140 @@
+
+#ifndef blake2b_compress_avx2_H
+#define blake2b_compress_avx2_H
+
+#define LOAD128(p) _mm_load_si128((__m128i *) (p))
+#define STORE128(p, r) _mm_store_si128((__m128i *) (p), r)
+
+#define LOADU128(p) _mm_loadu_si128((__m128i *) (p))
+#define STOREU128(p, r) _mm_storeu_si128((__m128i *) (p), r)
+
+#define LOAD(p) _mm256_load_si256((__m256i *) (p))
+#define STORE(p, r) _mm256_store_si256((__m256i *) (p), r)
+
+#define LOADU(p) _mm256_loadu_si256((__m256i *) (p))
+#define STOREU(p, r) _mm256_storeu_si256((__m256i *) (p), r)
+
+static inline uint64_t
+LOADU64(const void *p)
+{
+ uint64_t v;
+ memcpy(&v, p, sizeof v);
+ return v;
+}
+
+#define ROTATE16 \
+ _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, \
+ 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)
+
+#define ROTATE24 \
+ _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, \
+ 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)
+
+#define ADD(a, b) _mm256_add_epi64(a, b)
+#define SUB(a, b) _mm256_sub_epi64(a, b)
+
+#define XOR(a, b) _mm256_xor_si256(a, b)
+#define AND(a, b) _mm256_and_si256(a, b)
+#define OR(a, b) _mm256_or_si256(a, b)
+
+#define ROT32(x) _mm256_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1))
+#define ROT24(x) _mm256_shuffle_epi8((x), ROTATE24)
+#define ROT16(x) _mm256_shuffle_epi8((x), ROTATE16)
+#define ROT63(x) _mm256_or_si256(_mm256_srli_epi64((x), 63), ADD((x), (x)))
+
+#define BLAKE2B_G1_V1(a, b, c, d, m) \
+ do { \
+ a = ADD(a, m); \
+ a = ADD(a, b); \
+ d = XOR(d, a); \
+ d = ROT32(d); \
+ c = ADD(c, d); \
+ b = XOR(b, c); \
+ b = ROT24(b); \
+ } while (0)
+
+#define BLAKE2B_G2_V1(a, b, c, d, m) \
+ do { \
+ a = ADD(a, m); \
+ a = ADD(a, b); \
+ d = XOR(d, a); \
+ d = ROT16(d); \
+ c = ADD(c, d); \
+ b = XOR(b, c); \
+ b = ROT63(b); \
+ } while (0)
+
+#define BLAKE2B_DIAG_V1(a, b, c, d) \
+ do { \
+ d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(2, 1, 0, 3)); \
+ c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \
+ b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(0, 3, 2, 1)); \
+ } while (0)
+
+#define BLAKE2B_UNDIAG_V1(a, b, c, d) \
+ do { \
+ d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(0, 3, 2, 1)); \
+ c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \
+ b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(2, 1, 0, 3)); \
+ } while (0)
+
+#include "blake2b-load-avx2.h"
+
+#define BLAKE2B_ROUND_V1(a, b, c, d, r, m) \
+ do { \
+ __m256i b0; \
+ BLAKE2B_LOAD_MSG_##r##_1(b0); \
+ BLAKE2B_G1_V1(a, b, c, d, b0); \
+ BLAKE2B_LOAD_MSG_##r##_2(b0); \
+ BLAKE2B_G2_V1(a, b, c, d, b0); \
+ BLAKE2B_DIAG_V1(a, b, c, d); \
+ BLAKE2B_LOAD_MSG_##r##_3(b0); \
+ BLAKE2B_G1_V1(a, b, c, d, b0); \
+ BLAKE2B_LOAD_MSG_##r##_4(b0); \
+ BLAKE2B_G2_V1(a, b, c, d, b0); \
+ BLAKE2B_UNDIAG_V1(a, b, c, d); \
+ } while (0)
+
+#define BLAKE2B_ROUNDS_V1(a, b, c, d, m) \
+ do { \
+ BLAKE2B_ROUND_V1(a, b, c, d, 0, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 1, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 2, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 3, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 4, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 5, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 6, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 7, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 8, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 9, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 10, (m)); \
+ BLAKE2B_ROUND_V1(a, b, c, d, 11, (m)); \
+ } while (0)
+
+#define DECLARE_MESSAGE_WORDS(m) \
+ const __m256i m0 = _mm256_broadcastsi128_si256(LOADU128((m) + 0)); \
+ const __m256i m1 = _mm256_broadcastsi128_si256(LOADU128((m) + 16)); \
+ const __m256i m2 = _mm256_broadcastsi128_si256(LOADU128((m) + 32)); \
+ const __m256i m3 = _mm256_broadcastsi128_si256(LOADU128((m) + 48)); \
+ const __m256i m4 = _mm256_broadcastsi128_si256(LOADU128((m) + 64)); \
+ const __m256i m5 = _mm256_broadcastsi128_si256(LOADU128((m) + 80)); \
+ const __m256i m6 = _mm256_broadcastsi128_si256(LOADU128((m) + 96)); \
+ const __m256i m7 = _mm256_broadcastsi128_si256(LOADU128((m) + 112)); \
+ __m256i t0, t1;
+
+#define BLAKE2B_COMPRESS_V1(a, b, m, t0, t1, f0, f1) \
+ do { \
+ DECLARE_MESSAGE_WORDS(m) \
+ const __m256i iv0 = a; \
+ const __m256i iv1 = b; \
+ __m256i c = LOAD(&blake2b_IV[0]); \
+ __m256i d = \
+ XOR(LOAD(&blake2b_IV[4]), _mm256_set_epi64x(f1, f0, t1, t0)); \
+ BLAKE2B_ROUNDS_V1(a, b, c, d, m); \
+ a = XOR(a, c); \
+ b = XOR(b, d); \
+ a = XOR(a, iv0); \
+ b = XOR(b, iv1); \
+ } while (0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c
new file mode 100644
index 0000000000..614fa34af7
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c
@@ -0,0 +1,93 @@
+
+#include <stdint.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "private/common.h"
+
+CRYPTO_ALIGN(64)
+static const uint64_t blake2b_IV[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+static const uint8_t blake2b_sigma[12][16] = {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
+};
+
+int
+blake2b_compress_ref(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES])
+{
+ uint64_t m[16];
+ uint64_t v[16];
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ m[i] = LOAD64_LE(block + i * sizeof(m[i]));
+
+ for (i = 0; i < 8; ++i)
+ v[i] = S->h[i];
+
+ v[8] = blake2b_IV[0];
+ v[9] = blake2b_IV[1];
+ v[10] = blake2b_IV[2];
+ v[11] = blake2b_IV[3];
+ v[12] = S->t[0] ^ blake2b_IV[4];
+ v[13] = S->t[1] ^ blake2b_IV[5];
+ v[14] = S->f[0] ^ blake2b_IV[6];
+ v[15] = S->f[1] ^ blake2b_IV[7];
+#define G(r, i, a, b, c, d) \
+ do { \
+ a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
+ d = ROTR64(d ^ a, 32); \
+ c = c + d; \
+ b = ROTR64(b ^ c, 24); \
+ a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
+ d = ROTR64(d ^ a, 16); \
+ c = c + d; \
+ b = ROTR64(b ^ c, 63); \
+ } while (0)
+#define ROUND(r) \
+ do { \
+ G(r, 0, v[0], v[4], v[8], v[12]); \
+ G(r, 1, v[1], v[5], v[9], v[13]); \
+ G(r, 2, v[2], v[6], v[10], v[14]); \
+ G(r, 3, v[3], v[7], v[11], v[15]); \
+ G(r, 4, v[0], v[5], v[10], v[15]); \
+ G(r, 5, v[1], v[6], v[11], v[12]); \
+ G(r, 6, v[2], v[7], v[8], v[13]); \
+ G(r, 7, v[3], v[4], v[9], v[14]); \
+ } while (0)
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+ ROUND(10);
+ ROUND(11);
+
+ for (i = 0; i < 8; ++i) {
+ S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
+ }
+
+#undef G
+#undef ROUND
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c
new file mode 100644
index 0000000000..9e5c0c5081
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c
@@ -0,0 +1,87 @@
+
+#define BLAKE2_USE_SSSE3
+#define BLAKE2_USE_SSE41
+
+#include <stdint.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
+ defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# endif
+
+# include <emmintrin.h>
+# include <smmintrin.h>
+# include <tmmintrin.h>
+
+# include "blake2b-compress-sse41.h"
+
+CRYPTO_ALIGN(64)
+static const uint64_t blake2b_IV[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+int
+blake2b_compress_sse41(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES])
+{
+ __m128i row1l, row1h;
+ __m128i row2l, row2h;
+ __m128i row3l, row3h;
+ __m128i row4l, row4h;
+ __m128i b0, b1;
+ __m128i t0, t1;
+ const __m128i r16 =
+ _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9);
+ const __m128i r24 =
+ _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10);
+ const __m128i m0 = LOADU(block + 00);
+ const __m128i m1 = LOADU(block + 16);
+ const __m128i m2 = LOADU(block + 32);
+ const __m128i m3 = LOADU(block + 48);
+ const __m128i m4 = LOADU(block + 64);
+ const __m128i m5 = LOADU(block + 80);
+ const __m128i m6 = LOADU(block + 96);
+ const __m128i m7 = LOADU(block + 112);
+ row1l = LOADU(&S->h[0]);
+ row1h = LOADU(&S->h[2]);
+ row2l = LOADU(&S->h[4]);
+ row2h = LOADU(&S->h[6]);
+ row3l = LOADU(&blake2b_IV[0]);
+ row3h = LOADU(&blake2b_IV[2]);
+ row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0]));
+ row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0]));
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+ ROUND(10);
+ ROUND(11);
+ row1l = _mm_xor_si128(row3l, row1l);
+ row1h = _mm_xor_si128(row3h, row1h);
+ STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l));
+ STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h));
+ row2l = _mm_xor_si128(row4l, row2l);
+ row2h = _mm_xor_si128(row4h, row2h);
+ STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l));
+ STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h));
+ return 0;
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h
new file mode 100644
index 0000000000..ac78e5bb1e
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h
@@ -0,0 +1,103 @@
+
+#ifndef blake2b_compress_sse41_H
+#define blake2b_compress_sse41_H
+
+#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p))
+#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r)
+
+#define _mm_roti_epi64(x, c) \
+ (-(c) == 32) \
+ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
+ : (-(c) == 24) \
+ ? _mm_shuffle_epi8((x), r24) \
+ : (-(c) == 16) \
+ ? _mm_shuffle_epi8((x), r16) \
+ : (-(c) == 63) \
+ ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_add_epi64((x), (x))) \
+ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_slli_epi64((x), 64 - (-(c))))
+
+#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
+ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
+ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
+ \
+ row4l = _mm_xor_si128(row4l, row1l); \
+ row4h = _mm_xor_si128(row4h, row1h); \
+ \
+ row4l = _mm_roti_epi64(row4l, -32); \
+ row4h = _mm_roti_epi64(row4h, -32); \
+ \
+ row3l = _mm_add_epi64(row3l, row4l); \
+ row3h = _mm_add_epi64(row3h, row4h); \
+ \
+ row2l = _mm_xor_si128(row2l, row3l); \
+ row2h = _mm_xor_si128(row2h, row3h); \
+ \
+ row2l = _mm_roti_epi64(row2l, -24); \
+ row2h = _mm_roti_epi64(row2h, -24);
+
+#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
+ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
+ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
+ \
+ row4l = _mm_xor_si128(row4l, row1l); \
+ row4h = _mm_xor_si128(row4h, row1h); \
+ \
+ row4l = _mm_roti_epi64(row4l, -16); \
+ row4h = _mm_roti_epi64(row4h, -16); \
+ \
+ row3l = _mm_add_epi64(row3l, row4l); \
+ row3h = _mm_add_epi64(row3h, row4h); \
+ \
+ row2l = _mm_xor_si128(row2l, row3l); \
+ row2h = _mm_xor_si128(row2h, row3h); \
+ \
+ row2l = _mm_roti_epi64(row2l, -63); \
+ row2h = _mm_roti_epi64(row2h, -63);
+
+#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
+ t0 = _mm_alignr_epi8(row2h, row2l, 8); \
+ t1 = _mm_alignr_epi8(row2l, row2h, 8); \
+ row2l = t0; \
+ row2h = t1; \
+ \
+ t0 = row3l; \
+ row3l = row3h; \
+ row3h = t0; \
+ \
+ t0 = _mm_alignr_epi8(row4h, row4l, 8); \
+ t1 = _mm_alignr_epi8(row4l, row4h, 8); \
+ row4l = t1; \
+ row4h = t0;
+
+#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
+ t0 = _mm_alignr_epi8(row2l, row2h, 8); \
+ t1 = _mm_alignr_epi8(row2h, row2l, 8); \
+ row2l = t0; \
+ row2h = t1; \
+ \
+ t0 = row3l; \
+ row3l = row3h; \
+ row3h = t0; \
+ \
+ t0 = _mm_alignr_epi8(row4l, row4h, 8); \
+ t1 = _mm_alignr_epi8(row4h, row4l, 8); \
+ row4l = t1; \
+ row4h = t0;
+
+#include "blake2b-load-sse41.h"
+
+#define ROUND(r) \
+ LOAD_MSG_##r##_1(b0, b1); \
+ G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ LOAD_MSG_##r##_2(b0, b1); \
+ G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
+ LOAD_MSG_##r##_3(b0, b1); \
+ G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ LOAD_MSG_##r##_4(b0, b1); \
+ G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c
new file mode 100644
index 0000000000..a207a64d40
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c
@@ -0,0 +1,90 @@
+
+#include <stdint.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# endif
+
+# include <emmintrin.h>
+# include <tmmintrin.h>
+
+# include "blake2b-compress-ssse3.h"
+
+CRYPTO_ALIGN(64)
+static const uint64_t blake2b_IV[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+int
+blake2b_compress_ssse3(blake2b_state *S,
+ const uint8_t block[BLAKE2B_BLOCKBYTES])
+{
+ __m128i row1l, row1h;
+ __m128i row2l, row2h;
+ __m128i row3l, row3h;
+ __m128i row4l, row4h;
+ __m128i b0, b1;
+ __m128i t0, t1;
+ const __m128i r16 =
+ _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9);
+ const __m128i r24 =
+ _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10);
+ const uint64_t m0 = ((uint64_t *) block)[0];
+ const uint64_t m1 = ((uint64_t *) block)[1];
+ const uint64_t m2 = ((uint64_t *) block)[2];
+ const uint64_t m3 = ((uint64_t *) block)[3];
+ const uint64_t m4 = ((uint64_t *) block)[4];
+ const uint64_t m5 = ((uint64_t *) block)[5];
+ const uint64_t m6 = ((uint64_t *) block)[6];
+ const uint64_t m7 = ((uint64_t *) block)[7];
+ const uint64_t m8 = ((uint64_t *) block)[8];
+ const uint64_t m9 = ((uint64_t *) block)[9];
+ const uint64_t m10 = ((uint64_t *) block)[10];
+ const uint64_t m11 = ((uint64_t *) block)[11];
+ const uint64_t m12 = ((uint64_t *) block)[12];
+ const uint64_t m13 = ((uint64_t *) block)[13];
+ const uint64_t m14 = ((uint64_t *) block)[14];
+ const uint64_t m15 = ((uint64_t *) block)[15];
+
+ row1l = LOADU(&S->h[0]);
+ row1h = LOADU(&S->h[2]);
+ row2l = LOADU(&S->h[4]);
+ row2h = LOADU(&S->h[6]);
+ row3l = LOADU(&blake2b_IV[0]);
+ row3h = LOADU(&blake2b_IV[2]);
+ row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0]));
+ row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0]));
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+ ROUND(10);
+ ROUND(11);
+ row1l = _mm_xor_si128(row3l, row1l);
+ row1h = _mm_xor_si128(row3h, row1h);
+ STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l));
+ STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h));
+ row2l = _mm_xor_si128(row4l, row2l);
+ row2h = _mm_xor_si128(row4h, row2h);
+ STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l));
+ STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h));
+ return 0;
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h
new file mode 100644
index 0000000000..9a7164fe25
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h
@@ -0,0 +1,103 @@
+
+#ifndef blake2b_compress_ssse3_H
+#define blake2b_compress_ssse3_H
+
+#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p))
+#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r)
+
+#define _mm_roti_epi64(x, c) \
+ (-(c) == 32) \
+ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
+ : (-(c) == 24) \
+ ? _mm_shuffle_epi8((x), r24) \
+ : (-(c) == 16) \
+ ? _mm_shuffle_epi8((x), r16) \
+ : (-(c) == 63) \
+ ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_add_epi64((x), (x))) \
+ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_slli_epi64((x), 64 - (-(c))))
+
+#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
+ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
+ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
+ \
+ row4l = _mm_xor_si128(row4l, row1l); \
+ row4h = _mm_xor_si128(row4h, row1h); \
+ \
+ row4l = _mm_roti_epi64(row4l, -32); \
+ row4h = _mm_roti_epi64(row4h, -32); \
+ \
+ row3l = _mm_add_epi64(row3l, row4l); \
+ row3h = _mm_add_epi64(row3h, row4h); \
+ \
+ row2l = _mm_xor_si128(row2l, row3l); \
+ row2h = _mm_xor_si128(row2h, row3h); \
+ \
+ row2l = _mm_roti_epi64(row2l, -24); \
+ row2h = _mm_roti_epi64(row2h, -24);
+
+#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \
+ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
+ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
+ \
+ row4l = _mm_xor_si128(row4l, row1l); \
+ row4h = _mm_xor_si128(row4h, row1h); \
+ \
+ row4l = _mm_roti_epi64(row4l, -16); \
+ row4h = _mm_roti_epi64(row4h, -16); \
+ \
+ row3l = _mm_add_epi64(row3l, row4l); \
+ row3h = _mm_add_epi64(row3h, row4h); \
+ \
+ row2l = _mm_xor_si128(row2l, row3l); \
+ row2h = _mm_xor_si128(row2h, row3h); \
+ \
+ row2l = _mm_roti_epi64(row2l, -63); \
+ row2h = _mm_roti_epi64(row2h, -63);
+
+#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
+ t0 = _mm_alignr_epi8(row2h, row2l, 8); \
+ t1 = _mm_alignr_epi8(row2l, row2h, 8); \
+ row2l = t0; \
+ row2h = t1; \
+ \
+ t0 = row3l; \
+ row3l = row3h; \
+ row3h = t0; \
+ \
+ t0 = _mm_alignr_epi8(row4h, row4l, 8); \
+ t1 = _mm_alignr_epi8(row4l, row4h, 8); \
+ row4l = t1; \
+ row4h = t0;
+
+#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \
+ t0 = _mm_alignr_epi8(row2l, row2h, 8); \
+ t1 = _mm_alignr_epi8(row2h, row2l, 8); \
+ row2l = t0; \
+ row2h = t1; \
+ \
+ t0 = row3l; \
+ row3l = row3h; \
+ row3h = t0; \
+ \
+ t0 = _mm_alignr_epi8(row4l, row4h, 8); \
+ t1 = _mm_alignr_epi8(row4h, row4l, 8); \
+ row4l = t1; \
+ row4h = t0;
+
+#include "blake2b-load-sse2.h"
+
+#define ROUND(r) \
+ LOAD_MSG_##r##_1(b0, b1); \
+ G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ LOAD_MSG_##r##_2(b0, b1); \
+ G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
+ LOAD_MSG_##r##_3(b0, b1); \
+ G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ LOAD_MSG_##r##_4(b0, b1); \
+ G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \
+ UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h
new file mode 100644
index 0000000000..8c15f177c7
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h
@@ -0,0 +1,340 @@
+#ifndef blake2b_load_avx2_H
+#define blake2b_load_avx2_H
+
+#define BLAKE2B_LOAD_MSG_0_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m0, m1); \
+ t1 = _mm256_unpacklo_epi64(m2, m3); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_0_2(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m0, m1); \
+ t1 = _mm256_unpackhi_epi64(m2, m3); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_0_3(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m4, m5); \
+ t1 = _mm256_unpacklo_epi64(m6, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_0_4(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m4, m5); \
+ t1 = _mm256_unpackhi_epi64(m6, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_1_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m7, m2); \
+ t1 = _mm256_unpackhi_epi64(m4, m6); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_1_2(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m5, m4); \
+ t1 = _mm256_alignr_epi8(m3, m7, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_1_3(b0) \
+ do { \
+ t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ t1 = _mm256_unpackhi_epi64(m5, m2); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_1_4(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m6, m1); \
+ t1 = _mm256_unpackhi_epi64(m3, m1); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_2_1(b0) \
+ do { \
+ t0 = _mm256_alignr_epi8(m6, m5, 8); \
+ t1 = _mm256_unpackhi_epi64(m2, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_2_2(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m4, m0); \
+ t1 = _mm256_blend_epi32(m6, m1, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_2_3(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m1, m5, 0x33); \
+ t1 = _mm256_unpackhi_epi64(m3, m4); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_2_4(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m7, m3); \
+ t1 = _mm256_alignr_epi8(m2, m0, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_3_1(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m3, m1); \
+ t1 = _mm256_unpackhi_epi64(m6, m5); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_3_2(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m4, m0); \
+ t1 = _mm256_unpacklo_epi64(m6, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_3_3(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m2, m1, 0x33); \
+ t1 = _mm256_blend_epi32(m7, m2, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_3_4(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m3, m5); \
+ t1 = _mm256_unpacklo_epi64(m0, m4); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_4_1(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m4, m2); \
+ t1 = _mm256_unpacklo_epi64(m1, m5); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_4_2(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m3, m0, 0x33); \
+ t1 = _mm256_blend_epi32(m7, m2, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_4_3(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m5, m7, 0x33); \
+ t1 = _mm256_blend_epi32(m1, m3, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_4_4(b0) \
+ do { \
+ t0 = _mm256_alignr_epi8(m6, m0, 8); \
+ t1 = _mm256_blend_epi32(m6, m4, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_5_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m1, m3); \
+ t1 = _mm256_unpacklo_epi64(m0, m4); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_5_2(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m6, m5); \
+ t1 = _mm256_unpackhi_epi64(m5, m1); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_5_3(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m3, m2, 0x33); \
+ t1 = _mm256_unpackhi_epi64(m7, m0); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_5_4(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m6, m2); \
+ t1 = _mm256_blend_epi32(m4, m7, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_6_1(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m0, m6, 0x33); \
+ t1 = _mm256_unpacklo_epi64(m7, m2); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_6_2(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m2, m7); \
+ t1 = _mm256_alignr_epi8(m5, m6, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_6_3(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m0, m3); \
+ t1 = _mm256_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_6_4(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m3, m1); \
+ t1 = _mm256_blend_epi32(m5, m1, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_7_1(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m6, m3); \
+ t1 = _mm256_blend_epi32(m1, m6, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_7_2(b0) \
+ do { \
+ t0 = _mm256_alignr_epi8(m7, m5, 8); \
+ t1 = _mm256_unpackhi_epi64(m0, m4); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_7_3(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m2, m7); \
+ t1 = _mm256_unpacklo_epi64(m4, m1); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_7_4(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m0, m2); \
+ t1 = _mm256_unpacklo_epi64(m3, m5); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_8_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m3, m7); \
+ t1 = _mm256_alignr_epi8(m0, m5, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_8_2(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m7, m4); \
+ t1 = _mm256_alignr_epi8(m4, m1, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_8_3(b0) \
+ do { \
+ t0 = m6; \
+ t1 = _mm256_alignr_epi8(m5, m0, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_8_4(b0) \
+ do { \
+ t0 = _mm256_blend_epi32(m3, m1, 0x33); \
+ t1 = m2; \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_9_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m5, m4); \
+ t1 = _mm256_unpackhi_epi64(m3, m0); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_9_2(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m1, m2); \
+ t1 = _mm256_blend_epi32(m2, m3, 0x33); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_9_3(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m7, m4); \
+ t1 = _mm256_unpackhi_epi64(m1, m6); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_9_4(b0) \
+ do { \
+ t0 = _mm256_alignr_epi8(m7, m5, 8); \
+ t1 = _mm256_unpacklo_epi64(m6, m0); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_10_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m0, m1); \
+ t1 = _mm256_unpacklo_epi64(m2, m3); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_10_2(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m0, m1); \
+ t1 = _mm256_unpackhi_epi64(m2, m3); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_10_3(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m4, m5); \
+ t1 = _mm256_unpacklo_epi64(m6, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_10_4(b0) \
+ do { \
+ t0 = _mm256_unpackhi_epi64(m4, m5); \
+ t1 = _mm256_unpackhi_epi64(m6, m7); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_11_1(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m7, m2); \
+ t1 = _mm256_unpackhi_epi64(m4, m6); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_11_2(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m5, m4); \
+ t1 = _mm256_alignr_epi8(m3, m7, 8); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_11_3(b0) \
+ do { \
+ t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ t1 = _mm256_unpackhi_epi64(m5, m2); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#define BLAKE2B_LOAD_MSG_11_4(b0) \
+ do { \
+ t0 = _mm256_unpacklo_epi64(m6, m1); \
+ t1 = _mm256_unpackhi_epi64(m3, m1); \
+ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \
+ } while (0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h
new file mode 100644
index 0000000000..8e67421aca
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h
@@ -0,0 +1,164 @@
+/*
+ BLAKE2 reference source code package - optimized C implementations
+
+ Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+ To the extent possible under law, the author(s) have dedicated all copyright
+ and related and neighboring rights to this software to the public domain
+ worldwide. This software is distributed without any warranty.
+
+ You should have received a copy of the CC0 Public Domain Dedication along
+ with
+ this software. If not, see
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+
+#ifndef blake2b_load_sse2_H
+#define blake2b_load_sse2_H
+
+#define LOAD_MSG_0_1(b0, b1) \
+ b0 = _mm_set_epi64x(m2, m0); \
+ b1 = _mm_set_epi64x(m6, m4)
+#define LOAD_MSG_0_2(b0, b1) \
+ b0 = _mm_set_epi64x(m3, m1); \
+ b1 = _mm_set_epi64x(m7, m5)
+#define LOAD_MSG_0_3(b0, b1) \
+ b0 = _mm_set_epi64x(m10, m8); \
+ b1 = _mm_set_epi64x(m14, m12)
+#define LOAD_MSG_0_4(b0, b1) \
+ b0 = _mm_set_epi64x(m11, m9); \
+ b1 = _mm_set_epi64x(m15, m13)
+#define LOAD_MSG_1_1(b0, b1) \
+ b0 = _mm_set_epi64x(m4, m14); \
+ b1 = _mm_set_epi64x(m13, m9)
+#define LOAD_MSG_1_2(b0, b1) \
+ b0 = _mm_set_epi64x(m8, m10); \
+ b1 = _mm_set_epi64x(m6, m15)
+#define LOAD_MSG_1_3(b0, b1) \
+ b0 = _mm_set_epi64x(m0, m1); \
+ b1 = _mm_set_epi64x(m5, m11)
+#define LOAD_MSG_1_4(b0, b1) \
+ b0 = _mm_set_epi64x(m2, m12); \
+ b1 = _mm_set_epi64x(m3, m7)
+#define LOAD_MSG_2_1(b0, b1) \
+ b0 = _mm_set_epi64x(m12, m11); \
+ b1 = _mm_set_epi64x(m15, m5)
+#define LOAD_MSG_2_2(b0, b1) \
+ b0 = _mm_set_epi64x(m0, m8); \
+ b1 = _mm_set_epi64x(m13, m2)
+#define LOAD_MSG_2_3(b0, b1) \
+ b0 = _mm_set_epi64x(m3, m10); \
+ b1 = _mm_set_epi64x(m9, m7)
+#define LOAD_MSG_2_4(b0, b1) \
+ b0 = _mm_set_epi64x(m6, m14); \
+ b1 = _mm_set_epi64x(m4, m1)
+#define LOAD_MSG_3_1(b0, b1) \
+ b0 = _mm_set_epi64x(m3, m7); \
+ b1 = _mm_set_epi64x(m11, m13)
+#define LOAD_MSG_3_2(b0, b1) \
+ b0 = _mm_set_epi64x(m1, m9); \
+ b1 = _mm_set_epi64x(m14, m12)
+#define LOAD_MSG_3_3(b0, b1) \
+ b0 = _mm_set_epi64x(m5, m2); \
+ b1 = _mm_set_epi64x(m15, m4)
+#define LOAD_MSG_3_4(b0, b1) \
+ b0 = _mm_set_epi64x(m10, m6); \
+ b1 = _mm_set_epi64x(m8, m0)
+#define LOAD_MSG_4_1(b0, b1) \
+ b0 = _mm_set_epi64x(m5, m9); \
+ b1 = _mm_set_epi64x(m10, m2)
+#define LOAD_MSG_4_2(b0, b1) \
+ b0 = _mm_set_epi64x(m7, m0); \
+ b1 = _mm_set_epi64x(m15, m4)
+#define LOAD_MSG_4_3(b0, b1) \
+ b0 = _mm_set_epi64x(m11, m14); \
+ b1 = _mm_set_epi64x(m3, m6)
+#define LOAD_MSG_4_4(b0, b1) \
+ b0 = _mm_set_epi64x(m12, m1); \
+ b1 = _mm_set_epi64x(m13, m8)
+#define LOAD_MSG_5_1(b0, b1) \
+ b0 = _mm_set_epi64x(m6, m2); \
+ b1 = _mm_set_epi64x(m8, m0)
+#define LOAD_MSG_5_2(b0, b1) \
+ b0 = _mm_set_epi64x(m10, m12); \
+ b1 = _mm_set_epi64x(m3, m11)
+#define LOAD_MSG_5_3(b0, b1) \
+ b0 = _mm_set_epi64x(m7, m4); \
+ b1 = _mm_set_epi64x(m1, m15)
+#define LOAD_MSG_5_4(b0, b1) \
+ b0 = _mm_set_epi64x(m5, m13); \
+ b1 = _mm_set_epi64x(m9, m14)
+#define LOAD_MSG_6_1(b0, b1) \
+ b0 = _mm_set_epi64x(m1, m12); \
+ b1 = _mm_set_epi64x(m4, m14)
+#define LOAD_MSG_6_2(b0, b1) \
+ b0 = _mm_set_epi64x(m15, m5); \
+ b1 = _mm_set_epi64x(m10, m13)
+#define LOAD_MSG_6_3(b0, b1) \
+ b0 = _mm_set_epi64x(m6, m0); \
+ b1 = _mm_set_epi64x(m8, m9)
+#define LOAD_MSG_6_4(b0, b1) \
+ b0 = _mm_set_epi64x(m3, m7); \
+ b1 = _mm_set_epi64x(m11, m2)
+#define LOAD_MSG_7_1(b0, b1) \
+ b0 = _mm_set_epi64x(m7, m13); \
+ b1 = _mm_set_epi64x(m3, m12)
+#define LOAD_MSG_7_2(b0, b1) \
+ b0 = _mm_set_epi64x(m14, m11); \
+ b1 = _mm_set_epi64x(m9, m1)
+#define LOAD_MSG_7_3(b0, b1) \
+ b0 = _mm_set_epi64x(m15, m5); \
+ b1 = _mm_set_epi64x(m2, m8)
+#define LOAD_MSG_7_4(b0, b1) \
+ b0 = _mm_set_epi64x(m4, m0); \
+ b1 = _mm_set_epi64x(m10, m6)
+#define LOAD_MSG_8_1(b0, b1) \
+ b0 = _mm_set_epi64x(m14, m6); \
+ b1 = _mm_set_epi64x(m0, m11)
+#define LOAD_MSG_8_2(b0, b1) \
+ b0 = _mm_set_epi64x(m9, m15); \
+ b1 = _mm_set_epi64x(m8, m3)
+#define LOAD_MSG_8_3(b0, b1) \
+ b0 = _mm_set_epi64x(m13, m12); \
+ b1 = _mm_set_epi64x(m10, m1)
+#define LOAD_MSG_8_4(b0, b1) \
+ b0 = _mm_set_epi64x(m7, m2); \
+ b1 = _mm_set_epi64x(m5, m4)
+#define LOAD_MSG_9_1(b0, b1) \
+ b0 = _mm_set_epi64x(m8, m10); \
+ b1 = _mm_set_epi64x(m1, m7)
+#define LOAD_MSG_9_2(b0, b1) \
+ b0 = _mm_set_epi64x(m4, m2); \
+ b1 = _mm_set_epi64x(m5, m6)
+#define LOAD_MSG_9_3(b0, b1) \
+ b0 = _mm_set_epi64x(m9, m15); \
+ b1 = _mm_set_epi64x(m13, m3)
+#define LOAD_MSG_9_4(b0, b1) \
+ b0 = _mm_set_epi64x(m14, m11); \
+ b1 = _mm_set_epi64x(m0, m12)
+#define LOAD_MSG_10_1(b0, b1) \
+ b0 = _mm_set_epi64x(m2, m0); \
+ b1 = _mm_set_epi64x(m6, m4)
+#define LOAD_MSG_10_2(b0, b1) \
+ b0 = _mm_set_epi64x(m3, m1); \
+ b1 = _mm_set_epi64x(m7, m5)
+#define LOAD_MSG_10_3(b0, b1) \
+ b0 = _mm_set_epi64x(m10, m8); \
+ b1 = _mm_set_epi64x(m14, m12)
+#define LOAD_MSG_10_4(b0, b1) \
+ b0 = _mm_set_epi64x(m11, m9); \
+ b1 = _mm_set_epi64x(m15, m13)
+#define LOAD_MSG_11_1(b0, b1) \
+ b0 = _mm_set_epi64x(m4, m14); \
+ b1 = _mm_set_epi64x(m13, m9)
+#define LOAD_MSG_11_2(b0, b1) \
+ b0 = _mm_set_epi64x(m8, m10); \
+ b1 = _mm_set_epi64x(m6, m15)
+#define LOAD_MSG_11_3(b0, b1) \
+ b0 = _mm_set_epi64x(m0, m1); \
+ b1 = _mm_set_epi64x(m5, m11)
+#define LOAD_MSG_11_4(b0, b1) \
+ b0 = _mm_set_epi64x(m2, m12); \
+ b1 = _mm_set_epi64x(m3, m7)
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h
new file mode 100644
index 0000000000..31745fc139
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h
@@ -0,0 +1,307 @@
+/*
+ BLAKE2 reference source code package - optimized C implementations
+
+ Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+ To the extent possible under law, the author(s) have dedicated all copyright
+ and related and neighboring rights to this software to the public domain
+ worldwide. This software is distributed without any warranty.
+
+ You should have received a copy of the CC0 Public Domain Dedication along
+ with
+ this software. If not, see
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+
+#ifndef blake2b_load_sse41_H
+#define blake2b_load_sse41_H
+
+#define LOAD_MSG_0_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m0, m1); \
+ b1 = _mm_unpacklo_epi64(m2, m3); \
+ } while (0)
+
+#define LOAD_MSG_0_2(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m0, m1); \
+ b1 = _mm_unpackhi_epi64(m2, m3); \
+ } while (0)
+
+#define LOAD_MSG_0_3(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m4, m5); \
+ b1 = _mm_unpacklo_epi64(m6, m7); \
+ } while (0)
+
+#define LOAD_MSG_0_4(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m4, m5); \
+ b1 = _mm_unpackhi_epi64(m6, m7); \
+ } while (0)
+
+#define LOAD_MSG_1_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m7, m2); \
+ b1 = _mm_unpackhi_epi64(m4, m6); \
+ } while (0)
+
+#define LOAD_MSG_1_2(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m5, m4); \
+ b1 = _mm_alignr_epi8(m3, m7, 8); \
+ } while (0)
+
+#define LOAD_MSG_1_3(b0, b1) \
+ do { \
+ b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ b1 = _mm_unpackhi_epi64(m5, m2); \
+ } while (0)
+
+#define LOAD_MSG_1_4(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m6, m1); \
+ b1 = _mm_unpackhi_epi64(m3, m1); \
+ } while (0)
+
+#define LOAD_MSG_2_1(b0, b1) \
+ do { \
+ b0 = _mm_alignr_epi8(m6, m5, 8); \
+ b1 = _mm_unpackhi_epi64(m2, m7); \
+ } while (0)
+
+#define LOAD_MSG_2_2(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m4, m0); \
+ b1 = _mm_blend_epi16(m1, m6, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_2_3(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m5, m1, 0xF0); \
+ b1 = _mm_unpackhi_epi64(m3, m4); \
+ } while (0)
+
+#define LOAD_MSG_2_4(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m7, m3); \
+ b1 = _mm_alignr_epi8(m2, m0, 8); \
+ } while (0)
+
+#define LOAD_MSG_3_1(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m3, m1); \
+ b1 = _mm_unpackhi_epi64(m6, m5); \
+ } while (0)
+
+#define LOAD_MSG_3_2(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m4, m0); \
+ b1 = _mm_unpacklo_epi64(m6, m7); \
+ } while (0)
+
+#define LOAD_MSG_3_3(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m1, m2, 0xF0); \
+ b1 = _mm_blend_epi16(m2, m7, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_3_4(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m3, m5); \
+ b1 = _mm_unpacklo_epi64(m0, m4); \
+ } while (0)
+
+#define LOAD_MSG_4_1(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m4, m2); \
+ b1 = _mm_unpacklo_epi64(m1, m5); \
+ } while (0)
+
+#define LOAD_MSG_4_2(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m0, m3, 0xF0); \
+ b1 = _mm_blend_epi16(m2, m7, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_4_3(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m7, m5, 0xF0); \
+ b1 = _mm_blend_epi16(m3, m1, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_4_4(b0, b1) \
+ do { \
+ b0 = _mm_alignr_epi8(m6, m0, 8); \
+ b1 = _mm_blend_epi16(m4, m6, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_5_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m1, m3); \
+ b1 = _mm_unpacklo_epi64(m0, m4); \
+ } while (0)
+
+#define LOAD_MSG_5_2(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m6, m5); \
+ b1 = _mm_unpackhi_epi64(m5, m1); \
+ } while (0)
+
+#define LOAD_MSG_5_3(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m2, m3, 0xF0); \
+ b1 = _mm_unpackhi_epi64(m7, m0); \
+ } while (0)
+
+#define LOAD_MSG_5_4(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m6, m2); \
+ b1 = _mm_blend_epi16(m7, m4, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_6_1(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m6, m0, 0xF0); \
+ b1 = _mm_unpacklo_epi64(m7, m2); \
+ } while (0)
+
+#define LOAD_MSG_6_2(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m2, m7); \
+ b1 = _mm_alignr_epi8(m5, m6, 8); \
+ } while (0)
+
+#define LOAD_MSG_6_3(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m0, m3); \
+ b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \
+ } while (0)
+
+#define LOAD_MSG_6_4(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m3, m1); \
+ b1 = _mm_blend_epi16(m1, m5, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_7_1(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m6, m3); \
+ b1 = _mm_blend_epi16(m6, m1, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_7_2(b0, b1) \
+ do { \
+ b0 = _mm_alignr_epi8(m7, m5, 8); \
+ b1 = _mm_unpackhi_epi64(m0, m4); \
+ } while (0)
+
+#define LOAD_MSG_7_3(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m2, m7); \
+ b1 = _mm_unpacklo_epi64(m4, m1); \
+ } while (0)
+
+#define LOAD_MSG_7_4(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m0, m2); \
+ b1 = _mm_unpacklo_epi64(m3, m5); \
+ } while (0)
+
+#define LOAD_MSG_8_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m3, m7); \
+ b1 = _mm_alignr_epi8(m0, m5, 8); \
+ } while (0)
+
+#define LOAD_MSG_8_2(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m7, m4); \
+ b1 = _mm_alignr_epi8(m4, m1, 8); \
+ } while (0)
+
+#define LOAD_MSG_8_3(b0, b1) \
+ do { \
+ b0 = m6; \
+ b1 = _mm_alignr_epi8(m5, m0, 8); \
+ } while (0)
+
+#define LOAD_MSG_8_4(b0, b1) \
+ do { \
+ b0 = _mm_blend_epi16(m1, m3, 0xF0); \
+ b1 = m2; \
+ } while (0)
+
+#define LOAD_MSG_9_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m5, m4); \
+ b1 = _mm_unpackhi_epi64(m3, m0); \
+ } while (0)
+
+#define LOAD_MSG_9_2(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m1, m2); \
+ b1 = _mm_blend_epi16(m3, m2, 0xF0); \
+ } while (0)
+
+#define LOAD_MSG_9_3(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m7, m4); \
+ b1 = _mm_unpackhi_epi64(m1, m6); \
+ } while (0)
+
+#define LOAD_MSG_9_4(b0, b1) \
+ do { \
+ b0 = _mm_alignr_epi8(m7, m5, 8); \
+ b1 = _mm_unpacklo_epi64(m6, m0); \
+ } while (0)
+
+#define LOAD_MSG_10_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m0, m1); \
+ b1 = _mm_unpacklo_epi64(m2, m3); \
+ } while (0)
+
+#define LOAD_MSG_10_2(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m0, m1); \
+ b1 = _mm_unpackhi_epi64(m2, m3); \
+ } while (0)
+
+#define LOAD_MSG_10_3(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m4, m5); \
+ b1 = _mm_unpacklo_epi64(m6, m7); \
+ } while (0)
+
+#define LOAD_MSG_10_4(b0, b1) \
+ do { \
+ b0 = _mm_unpackhi_epi64(m4, m5); \
+ b1 = _mm_unpackhi_epi64(m6, m7); \
+ } while (0)
+
+#define LOAD_MSG_11_1(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m7, m2); \
+ b1 = _mm_unpackhi_epi64(m4, m6); \
+ } while (0)
+
+#define LOAD_MSG_11_2(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m5, m4); \
+ b1 = _mm_alignr_epi8(m3, m7, 8); \
+ } while (0)
+
+#define LOAD_MSG_11_3(b0, b1) \
+ do { \
+ b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ b1 = _mm_unpackhi_epi64(m5, m2); \
+ } while (0)
+
+#define LOAD_MSG_11_4(b0, b1) \
+ do { \
+ b0 = _mm_unpacklo_epi64(m6, m1); \
+ b1 = _mm_unpackhi_epi64(m3, m1); \
+ } while (0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c
new file mode 100644
index 0000000000..91435a1b16
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c
@@ -0,0 +1,436 @@
+/*
+ BLAKE2 reference source code package - C implementations
+
+ Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
+
+ To the extent possible under law, the author(s) have dedicated all copyright
+ and related and neighboring rights to this software to the public domain
+ worldwide. This software is distributed without any warranty.
+
+ You should have received a copy of the CC0 Public Domain Dedication along
+ with
+ this software. If not, see
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "core.h"
+#include "private/common.h"
+#include "runtime.h"
+#include "utils.h"
+
+static blake2b_compress_fn blake2b_compress = blake2b_compress_ref;
+
+static const uint64_t blake2b_IV[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+/* LCOV_EXCL_START */
+static inline int
+blake2b_set_lastnode(blake2b_state *S)
+{
+ S->f[1] = -1;
+ return 0;
+}
+/* LCOV_EXCL_STOP */
+
+static inline int
+blake2b_is_lastblock(const blake2b_state *S)
+{
+ return S->f[0] != 0;
+}
+
+static inline int
+blake2b_set_lastblock(blake2b_state *S)
+{
+ if (S->last_node)
+ blake2b_set_lastnode(S);
+
+ S->f[0] = -1;
+ return 0;
+}
+
+static inline int
+blake2b_increment_counter(blake2b_state *S, const uint64_t inc)
+{
+#ifdef HAVE_TI_MODE
+ uint128_t t = ((uint128_t) S->t[1] << 64) | S->t[0];
+ t += inc;
+ S->t[0] = (uint64_t)(t >> 0);
+ S->t[1] = (uint64_t)(t >> 64);
+#else
+ S->t[0] += inc;
+ S->t[1] += (S->t[0] < inc);
+#endif
+ return 0;
+}
+
+/* Parameter-related functions */
+static inline int
+blake2b_param_set_salt(blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES])
+{
+ memcpy(P->salt, salt, BLAKE2B_SALTBYTES);
+ return 0;
+}
+
+static inline int
+blake2b_param_set_personal(blake2b_param *P,
+ const uint8_t personal[BLAKE2B_PERSONALBYTES])
+{
+ memcpy(P->personal, personal, BLAKE2B_PERSONALBYTES);
+ return 0;
+}
+
+static inline int
+blake2b_init0(blake2b_state *S)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ S->h[i] = blake2b_IV[i];
+ }
+ memset(S->t, 0, offsetof(blake2b_state, last_node) + sizeof(S->last_node)
+ - offsetof(blake2b_state, t));
+ return 0;
+}
+
+/* init xors IV with input parameter block */
+int
+blake2b_init_param(blake2b_state *S, const blake2b_param *P)
+{
+ size_t i;
+ const uint8_t *p;
+
+ COMPILER_ASSERT(sizeof *P == 64);
+ blake2b_init0(S);
+ p = (const uint8_t *) (P);
+
+ /* IV XOR ParamBlock */
+ for (i = 0; i < 8; i++) {
+ S->h[i] ^= LOAD64_LE(p + sizeof(S->h[i]) * i);
+ }
+ return 0;
+}
+
+int
+blake2b_init(blake2b_state *S, const uint8_t outlen)
+{
+ blake2b_param P[1];
+
+ if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
+ sodium_misuse();
+ }
+ P->digest_length = outlen;
+ P->key_length = 0;
+ P->fanout = 1;
+ P->depth = 1;
+ STORE32_LE(P->leaf_length, 0);
+ STORE64_LE(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->reserved, 0, sizeof(P->reserved));
+ memset(P->salt, 0, sizeof(P->salt));
+ memset(P->personal, 0, sizeof(P->personal));
+ return blake2b_init_param(S, P);
+}
+
+int
+blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen,
+ const void *salt, const void *personal)
+{
+ blake2b_param P[1];
+
+ if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
+ sodium_misuse();
+ }
+ P->digest_length = outlen;
+ P->key_length = 0;
+ P->fanout = 1;
+ P->depth = 1;
+ STORE32_LE(P->leaf_length, 0);
+ STORE64_LE(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->reserved, 0, sizeof(P->reserved));
+ if (salt != NULL) {
+ blake2b_param_set_salt(P, (const uint8_t *) salt);
+ } else {
+ memset(P->salt, 0, sizeof(P->salt));
+ }
+ if (personal != NULL) {
+ blake2b_param_set_personal(P, (const uint8_t *) personal);
+ } else {
+ memset(P->personal, 0, sizeof(P->personal));
+ }
+ return blake2b_init_param(S, P);
+}
+
+int
+blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key,
+ const uint8_t keylen)
+{
+ blake2b_param P[1];
+
+ if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
+ sodium_misuse();
+ }
+ if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) {
+ sodium_misuse();
+ }
+ P->digest_length = outlen;
+ P->key_length = keylen;
+ P->fanout = 1;
+ P->depth = 1;
+ STORE32_LE(P->leaf_length, 0);
+ STORE64_LE(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->reserved, 0, sizeof(P->reserved));
+ memset(P->salt, 0, sizeof(P->salt));
+ memset(P->personal, 0, sizeof(P->personal));
+
+ if (blake2b_init_param(S, P) < 0) {
+ sodium_misuse();
+ }
+ {
+ uint8_t block[BLAKE2B_BLOCKBYTES];
+ memset(block, 0, BLAKE2B_BLOCKBYTES);
+ memcpy(block, key, keylen); /* keylen cannot be 0 */
+ blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
+ sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
+ }
+ return 0;
+}
+
+int
+blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen,
+ const void *key, const uint8_t keylen,
+ const void *salt, const void *personal)
+{
+ blake2b_param P[1];
+
+ if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
+ sodium_misuse();
+ }
+ if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) {
+ sodium_misuse();
+ }
+ P->digest_length = outlen;
+ P->key_length = keylen;
+ P->fanout = 1;
+ P->depth = 1;
+ STORE32_LE(P->leaf_length, 0);
+ STORE64_LE(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->reserved, 0, sizeof(P->reserved));
+ if (salt != NULL) {
+ blake2b_param_set_salt(P, (const uint8_t *) salt);
+ } else {
+ memset(P->salt, 0, sizeof(P->salt));
+ }
+ if (personal != NULL) {
+ blake2b_param_set_personal(P, (const uint8_t *) personal);
+ } else {
+ memset(P->personal, 0, sizeof(P->personal));
+ }
+
+ if (blake2b_init_param(S, P) < 0) {
+ sodium_misuse();
+ }
+ {
+ uint8_t block[BLAKE2B_BLOCKBYTES];
+ memset(block, 0, BLAKE2B_BLOCKBYTES);
+ memcpy(block, key, keylen); /* keylen cannot be 0 */
+ blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
+ sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */
+ }
+ return 0;
+}
+
+/* inlen now in bytes */
+int
+blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen)
+{
+ while (inlen > 0) {
+ size_t left = S->buflen;
+ size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
+
+ if (inlen > fill) {
+ memcpy(S->buf + left, in, fill); /* Fill buffer */
+ S->buflen += fill;
+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
+ blake2b_compress(S, S->buf); /* Compress */
+ memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES,
+ BLAKE2B_BLOCKBYTES); /* Shift buffer left */
+ S->buflen -= BLAKE2B_BLOCKBYTES;
+ in += fill;
+ inlen -= fill;
+ } else /* inlen <= fill */
+ {
+ memcpy(S->buf + left, in, inlen);
+ S->buflen += inlen; /* Be lazy, do not compress */
+ in += inlen;
+ inlen -= inlen;
+ }
+ }
+
+ return 0;
+}
+
+int
+blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen)
+{
+ unsigned char buffer[BLAKE2B_OUTBYTES];
+
+ if (!outlen || outlen > BLAKE2B_OUTBYTES) {
+ sodium_misuse();
+ }
+ if (blake2b_is_lastblock(S)) {
+ return -1;
+ }
+ if (S->buflen > BLAKE2B_BLOCKBYTES) {
+ blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
+ blake2b_compress(S, S->buf);
+ S->buflen -= BLAKE2B_BLOCKBYTES;
+ assert(S->buflen <= BLAKE2B_BLOCKBYTES);
+ memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen);
+ }
+
+ blake2b_increment_counter(S, S->buflen);
+ blake2b_set_lastblock(S);
+ memset(S->buf + S->buflen, 0,
+ 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
+ blake2b_compress(S, S->buf);
+
+ COMPILER_ASSERT(sizeof buffer == 64U);
+ STORE64_LE(buffer + 8 * 0, S->h[0]);
+ STORE64_LE(buffer + 8 * 1, S->h[1]);
+ STORE64_LE(buffer + 8 * 2, S->h[2]);
+ STORE64_LE(buffer + 8 * 3, S->h[3]);
+ STORE64_LE(buffer + 8 * 4, S->h[4]);
+ STORE64_LE(buffer + 8 * 5, S->h[5]);
+ STORE64_LE(buffer + 8 * 6, S->h[6]);
+ STORE64_LE(buffer + 8 * 7, S->h[7]);
+ memcpy(out, buffer, outlen); /* outlen <= BLAKE2B_OUTBYTES (64) */
+
+ sodium_memzero(S->h, sizeof S->h);
+ sodium_memzero(S->buf, sizeof S->buf);
+
+ return 0;
+}
+
+/* inlen, at least, should be uint64_t. Others can be size_t. */
+int
+blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen,
+ const uint64_t inlen, uint8_t keylen)
+{
+ blake2b_state S[1];
+
+ /* Verify parameters */
+ if (NULL == in && inlen > 0) {
+ sodium_misuse();
+ }
+ if (NULL == out) {
+ sodium_misuse();
+ }
+ if (!outlen || outlen > BLAKE2B_OUTBYTES) {
+ sodium_misuse();
+ }
+ if (NULL == key && keylen > 0) {
+ sodium_misuse();
+ }
+ if (keylen > BLAKE2B_KEYBYTES) {
+ sodium_misuse();
+ }
+ if (keylen > 0) {
+ if (blake2b_init_key(S, outlen, key, keylen) < 0) {
+ sodium_misuse();
+ }
+ } else {
+ if (blake2b_init(S, outlen) < 0) {
+ sodium_misuse();
+ }
+ }
+
+ blake2b_update(S, (const uint8_t *) in, inlen);
+ blake2b_final(S, out, outlen);
+ return 0;
+}
+
+int
+blake2b_salt_personal(uint8_t *out, const void *in, const void *key,
+ const uint8_t outlen, const uint64_t inlen,
+ uint8_t keylen, const void *salt, const void *personal)
+{
+ blake2b_state S[1];
+
+ /* Verify parameters */
+ if (NULL == in && inlen > 0) {
+ sodium_misuse();
+ }
+ if (NULL == out) {
+ sodium_misuse();
+ }
+ if (!outlen || outlen > BLAKE2B_OUTBYTES) {
+ sodium_misuse();
+ }
+ if (NULL == key && keylen > 0) {
+ sodium_misuse();
+ }
+ if (keylen > BLAKE2B_KEYBYTES) {
+ sodium_misuse();
+ }
+ if (keylen > 0) {
+ if (blake2b_init_key_salt_personal(S, outlen, key, keylen, salt,
+ personal) < 0) {
+ sodium_misuse();
+ }
+ } else {
+ if (blake2b_init_salt_personal(S, outlen, salt, personal) < 0) {
+ sodium_misuse();
+ }
+ }
+
+ blake2b_update(S, (const uint8_t *) in, inlen);
+ blake2b_final(S, out, outlen);
+ return 0;
+}
+
+int
+blake2b_pick_best_implementation(void)
+{
+/* LCOV_EXCL_START */
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
+ defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_avx2()) {
+ blake2b_compress = blake2b_compress_avx2;
+ return 0;
+ }
+#endif
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
+ defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_sse41()) {
+ blake2b_compress = blake2b_compress_sse41;
+ return 0;
+ }
+#endif
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+ if (sodium_runtime_has_ssse3()) {
+ blake2b_compress = blake2b_compress_ssse3;
+ return 0;
+ }
+#endif
+ blake2b_compress = blake2b_compress_ref;
+
+ return 0;
+ /* LCOV_EXCL_STOP */
+}
diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c
new file mode 100644
index 0000000000..4bd0855006
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c
@@ -0,0 +1,111 @@
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "blake2.h"
+#include "crypto_generichash_blake2b.h"
+#include "private/implementations.h"
+
+int
+crypto_generichash_blake2b(unsigned char *out, size_t outlen,
+ const unsigned char *in, unsigned long long inlen,
+ const unsigned char *key, size_t keylen)
+{
+ if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
+ keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) {
+ return -1;
+ }
+ assert(outlen <= UINT8_MAX);
+ assert(keylen <= UINT8_MAX);
+
+ return blake2b((uint8_t *) out, in, key, (uint8_t) outlen, (uint64_t) inlen,
+ (uint8_t) keylen);
+}
+
+int
+crypto_generichash_blake2b_salt_personal(
+ unsigned char *out, size_t outlen, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *key, size_t keylen,
+ const unsigned char *salt, const unsigned char *personal)
+{
+ if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
+ keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) {
+ return -1;
+ }
+ assert(outlen <= UINT8_MAX);
+ assert(keylen <= UINT8_MAX);
+
+ return blake2b_salt_personal((uint8_t *) out, in, key, (uint8_t) outlen,
+ (uint64_t) inlen, (uint8_t) keylen, salt,
+ personal);
+}
+
+int
+crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state,
+ const unsigned char *key, const size_t keylen,
+ const size_t outlen)
+{
+ if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
+ keylen > BLAKE2B_KEYBYTES) {
+ return -1;
+ }
+ assert(outlen <= UINT8_MAX);
+ assert(keylen <= UINT8_MAX);
+ if (key == NULL || keylen <= 0U) {
+ if (blake2b_init(state, (uint8_t) outlen) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ } else if (blake2b_init_key(state, (uint8_t) outlen, key,
+ (uint8_t) keylen) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+int
+crypto_generichash_blake2b_init_salt_personal(
+ crypto_generichash_blake2b_state *state, const unsigned char *key,
+ const size_t keylen, const size_t outlen, const unsigned char *salt,
+ const unsigned char *personal)
+{
+ if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES ||
+ keylen > BLAKE2B_KEYBYTES) {
+ return -1;
+ }
+ assert(outlen <= UINT8_MAX);
+ assert(keylen <= UINT8_MAX);
+ if (key == NULL || keylen <= 0U) {
+ if (blake2b_init_salt_personal(state, (uint8_t) outlen, salt,
+ personal) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ } else if (blake2b_init_key_salt_personal(state, (uint8_t) outlen, key,
+ (uint8_t) keylen, salt,
+ personal) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+int
+crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state,
+ const unsigned char *in,
+ unsigned long long inlen)
+{
+ return blake2b_update(state, (const uint8_t *) in, (uint64_t) inlen);
+}
+
+int
+crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state,
+ unsigned char *out, const size_t outlen)
+{
+ assert(outlen <= UINT8_MAX);
+ return blake2b_final(state, (uint8_t *) out, (uint8_t) outlen);
+}
+
+int
+_crypto_generichash_blake2b_pick_best_implementation(void)
+{
+ return blake2b_pick_best_implementation();
+}
diff --git a/libs/libsodium/src/crypto_generichash/crypto_generichash.c b/libs/libsodium/src/crypto_generichash/crypto_generichash.c
new file mode 100644
index 0000000000..a9a14e999a
--- /dev/null
+++ b/libs/libsodium/src/crypto_generichash/crypto_generichash.c
@@ -0,0 +1,91 @@
+
+#include "crypto_generichash.h"
+#include "randombytes.h"
+
+size_t
+crypto_generichash_bytes_min(void)
+{
+ return crypto_generichash_BYTES_MIN;
+}
+
+size_t
+crypto_generichash_bytes_max(void)
+{
+ return crypto_generichash_BYTES_MAX;
+}
+
+size_t
+crypto_generichash_bytes(void)
+{
+ return crypto_generichash_BYTES;
+}
+
+size_t
+crypto_generichash_keybytes_min(void)
+{
+ return crypto_generichash_KEYBYTES_MIN;
+}
+
+size_t
+crypto_generichash_keybytes_max(void)
+{
+ return crypto_generichash_KEYBYTES_MAX;
+}
+
+size_t
+crypto_generichash_keybytes(void)
+{
+ return crypto_generichash_KEYBYTES;
+}
+
+const char *
+crypto_generichash_primitive(void)
+{
+ return crypto_generichash_PRIMITIVE;
+}
+
+size_t
+crypto_generichash_statebytes(void)
+{
+ return (sizeof(crypto_generichash_state) + (size_t) 63U) & ~(size_t) 63U;
+}
+
+int
+crypto_generichash(unsigned char *out, size_t outlen, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *key,
+ size_t keylen)
+{
+ return crypto_generichash_blake2b(out, outlen, in, inlen, key, keylen);
+}
+
+int
+crypto_generichash_init(crypto_generichash_state *state,
+ const unsigned char *key,
+ const size_t keylen, const size_t outlen)
+{
+ return crypto_generichash_blake2b_init
+ ((crypto_generichash_blake2b_state *) state, key, keylen, outlen);
+}
+
+int
+crypto_generichash_update(crypto_generichash_state *state,
+ const unsigned char *in,
+ unsigned long long inlen)
+{
+ return crypto_generichash_blake2b_update
+ ((crypto_generichash_blake2b_state *) state, in, inlen);
+}
+
+int
+crypto_generichash_final(crypto_generichash_state *state,
+ unsigned char *out, const size_t outlen)
+{
+ return crypto_generichash_blake2b_final
+ ((crypto_generichash_blake2b_state *) state, out, outlen);
+}
+
+void
+crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES])
+{
+ randombytes_buf(k, crypto_generichash_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_hash/crypto_hash.c b/libs/libsodium/src/crypto_hash/crypto_hash.c
new file mode 100644
index 0000000000..855c560ba5
--- /dev/null
+++ b/libs/libsodium/src/crypto_hash/crypto_hash.c
@@ -0,0 +1,20 @@
+
+#include "crypto_hash.h"
+
+size_t
+crypto_hash_bytes(void)
+{
+ return crypto_hash_BYTES;
+}
+
+int
+crypto_hash(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen)
+{
+ return crypto_hash_sha512(out, in, inlen);
+}
+
+const char *
+crypto_hash_primitive(void) {
+ return crypto_hash_PRIMITIVE;
+}
diff --git a/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c
new file mode 100644
index 0000000000..264054f98b
--- /dev/null
+++ b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c
@@ -0,0 +1,254 @@
+
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include "crypto_hash_sha256.h"
+#include "private/common.h"
+#include "utils.h"
+
+static void
+be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 4; i++) {
+ STORE32_BE(dst + i * 4, src[i]);
+ }
+}
+
+static void
+be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 4; i++) {
+ dst[i] = LOAD32_BE(src + i * 4);
+ }
+}
+
+static const uint32_t Krnd[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
+#define Maj(x, y, z) ((x & (y | z)) | (y & z))
+#define SHR(x, n) (x >> n)
+#define ROTR(x, n) ROTR32(x, n)
+#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+#define RND(a, b, c, d, e, f, g, h, k) \
+ h += S1(e) + Ch(e, f, g) + k; \
+ d += h; \
+ h += S0(a) + Maj(a, b, c);
+
+#define RNDr(S, W, i, ii) \
+ RND(S[(64 - i) % 8], S[(65 - i) % 8], S[(66 - i) % 8], S[(67 - i) % 8], \
+ S[(68 - i) % 8], S[(69 - i) % 8], S[(70 - i) % 8], S[(71 - i) % 8], \
+ W[i + ii] + Krnd[i + ii])
+
+#define MSCH(W, ii, i) \
+ W[i + ii + 16] = \
+ s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
+
+static void
+SHA256_Transform(uint32_t state[8], const uint8_t block[64], uint32_t W[64],
+ uint32_t S[8])
+{
+ int i;
+
+ be32dec_vect(W, block, 64);
+ memcpy(S, state, 32);
+ for (i = 0; i < 64; i += 16) {
+ RNDr(S, W, 0, i);
+ RNDr(S, W, 1, i);
+ RNDr(S, W, 2, i);
+ RNDr(S, W, 3, i);
+ RNDr(S, W, 4, i);
+ RNDr(S, W, 5, i);
+ RNDr(S, W, 6, i);
+ RNDr(S, W, 7, i);
+ RNDr(S, W, 8, i);
+ RNDr(S, W, 9, i);
+ RNDr(S, W, 10, i);
+ RNDr(S, W, 11, i);
+ RNDr(S, W, 12, i);
+ RNDr(S, W, 13, i);
+ RNDr(S, W, 14, i);
+ RNDr(S, W, 15, i);
+ if (i == 48) {
+ break;
+ }
+ MSCH(W, 0, i);
+ MSCH(W, 1, i);
+ MSCH(W, 2, i);
+ MSCH(W, 3, i);
+ MSCH(W, 4, i);
+ MSCH(W, 5, i);
+ MSCH(W, 6, i);
+ MSCH(W, 7, i);
+ MSCH(W, 8, i);
+ MSCH(W, 9, i);
+ MSCH(W, 10, i);
+ MSCH(W, 11, i);
+ MSCH(W, 12, i);
+ MSCH(W, 13, i);
+ MSCH(W, 14, i);
+ MSCH(W, 15, i);
+ }
+ for (i = 0; i < 8; i++) {
+ state[i] += S[i];
+ }
+}
+
+static const uint8_t PAD[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static void
+SHA256_Pad(crypto_hash_sha256_state *state, uint32_t tmp32[64 + 8])
+{
+ unsigned int r;
+ unsigned int i;
+
+ r = (unsigned int) ((state->count >> 3) & 0x3f);
+ if (r < 56) {
+ for (i = 0; i < 56 - r; i++) {
+ state->buf[r + i] = PAD[i];
+ }
+ } else {
+ for (i = 0; i < 64 - r; i++) {
+ state->buf[r + i] = PAD[i];
+ }
+ SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]);
+ memset(&state->buf[0], 0, 56);
+ }
+ STORE64_BE(&state->buf[56], state->count);
+ SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]);
+}
+
+int
+crypto_hash_sha256_init(crypto_hash_sha256_state *state)
+{
+ static const uint32_t sha256_initial_state[8] = { 0x6a09e667, 0xbb67ae85,
+ 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c,
+ 0x1f83d9ab, 0x5be0cd19 };
+
+ state->count = (uint64_t) 0U;
+ memcpy(state->state, sha256_initial_state, sizeof sha256_initial_state);
+
+ return 0;
+}
+
+int
+crypto_hash_sha256_update(crypto_hash_sha256_state *state,
+ const unsigned char *in, unsigned long long inlen)
+{
+ uint32_t tmp32[64 + 8];
+ unsigned long long i;
+ unsigned long long r;
+
+ if (inlen <= 0U) {
+ return 0;
+ }
+ r = (unsigned long long) ((state->count >> 3) & 0x3f);
+
+ state->count += ((uint64_t) inlen) << 3;
+ if (inlen < 64 - r) {
+ for (i = 0; i < inlen; i++) {
+ state->buf[r + i] = in[i];
+ }
+ return 0;
+ }
+ for (i = 0; i < 64 - r; i++) {
+ state->buf[r + i] = in[i];
+ }
+ SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]);
+ in += 64 - r;
+ inlen -= 64 - r;
+
+ while (inlen >= 64) {
+ SHA256_Transform(state->state, in, &tmp32[0], &tmp32[64]);
+ in += 64;
+ inlen -= 64;
+ }
+ inlen &= 63;
+ for (i = 0; i < inlen; i++) {
+ state->buf[i] = in[i];
+ }
+ sodium_memzero((void *) tmp32, sizeof tmp32);
+
+ return 0;
+}
+
+int
+crypto_hash_sha256_final(crypto_hash_sha256_state *state, unsigned char *out)
+{
+ uint32_t tmp32[64 + 8];
+
+ SHA256_Pad(state, tmp32);
+ be32enc_vect(out, state->state, 32);
+ sodium_memzero((void *) tmp32, sizeof tmp32);
+ sodium_memzero((void *) state, sizeof *state);
+
+ return 0;
+}
+
+int
+crypto_hash_sha256(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen)
+{
+ crypto_hash_sha256_state state;
+
+ crypto_hash_sha256_init(&state);
+ crypto_hash_sha256_update(&state, in, inlen);
+ crypto_hash_sha256_final(&state, out);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c b/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c
new file mode 100644
index 0000000000..e729c811e6
--- /dev/null
+++ b/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c
@@ -0,0 +1,13 @@
+#include "crypto_hash_sha256.h"
+
+size_t
+crypto_hash_sha256_bytes(void)
+{
+ return crypto_hash_sha256_BYTES;
+}
+
+size_t
+crypto_hash_sha256_statebytes(void)
+{
+ return sizeof(crypto_hash_sha256_state);
+}
diff --git a/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c
new file mode 100644
index 0000000000..8e0f36fb6b
--- /dev/null
+++ b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c
@@ -0,0 +1,282 @@
+
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include "crypto_hash_sha512.h"
+#include "private/common.h"
+#include "utils.h"
+
+static void
+be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 8; i++) {
+ STORE64_BE(dst + i * 8, src[i]);
+ }
+}
+
+static void
+be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len / 8; i++) {
+ dst[i] = LOAD64_BE(src + i * 8);
+ }
+}
+
+static const uint64_t Krnd[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
+#define Maj(x, y, z) ((x & (y | z)) | (y & z))
+#define SHR(x, n) (x >> n)
+#define ROTR(x, n) ROTR64(x, n)
+#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
+#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
+#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
+#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
+
+#define RND(a, b, c, d, e, f, g, h, k) \
+ h += S1(e) + Ch(e, f, g) + k; \
+ d += h; \
+ h += S0(a) + Maj(a, b, c);
+
+#define RNDr(S, W, i, ii) \
+ RND(S[(80 - i) % 8], S[(81 - i) % 8], S[(82 - i) % 8], S[(83 - i) % 8], \
+ S[(84 - i) % 8], S[(85 - i) % 8], S[(86 - i) % 8], S[(87 - i) % 8], \
+ W[i + ii] + Krnd[i + ii])
+
+#define MSCH(W, ii, i) \
+ W[i + ii + 16] = \
+ s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
+
+static void
+SHA512_Transform(uint64_t *state, const uint8_t block[128], uint64_t W[80],
+ uint64_t S[8])
+{
+ int i;
+
+ be64dec_vect(W, block, 128);
+ memcpy(S, state, 64);
+ for (i = 0; i < 80; i += 16) {
+ RNDr(S, W, 0, i);
+ RNDr(S, W, 1, i);
+ RNDr(S, W, 2, i);
+ RNDr(S, W, 3, i);
+ RNDr(S, W, 4, i);
+ RNDr(S, W, 5, i);
+ RNDr(S, W, 6, i);
+ RNDr(S, W, 7, i);
+ RNDr(S, W, 8, i);
+ RNDr(S, W, 9, i);
+ RNDr(S, W, 10, i);
+ RNDr(S, W, 11, i);
+ RNDr(S, W, 12, i);
+ RNDr(S, W, 13, i);
+ RNDr(S, W, 14, i);
+ RNDr(S, W, 15, i);
+ if (i == 64) {
+ break;
+ }
+ MSCH(W, 0, i);
+ MSCH(W, 1, i);
+ MSCH(W, 2, i);
+ MSCH(W, 3, i);
+ MSCH(W, 4, i);
+ MSCH(W, 5, i);
+ MSCH(W, 6, i);
+ MSCH(W, 7, i);
+ MSCH(W, 8, i);
+ MSCH(W, 9, i);
+ MSCH(W, 10, i);
+ MSCH(W, 11, i);
+ MSCH(W, 12, i);
+ MSCH(W, 13, i);
+ MSCH(W, 14, i);
+ MSCH(W, 15, i);
+ }
+ for (i = 0; i < 8; i++) {
+ state[i] += S[i];
+ }
+}
+
+static const uint8_t PAD[128] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static void
+SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8])
+{
+ unsigned int r;
+ unsigned int i;
+
+ r = (unsigned int) ((state->count[1] >> 3) & 0x7f);
+ if (r < 112) {
+ for (i = 0; i < 112 - r; i++) {
+ state->buf[r + i] = PAD[i];
+ }
+ } else {
+ for (i = 0; i < 128 - r; i++) {
+ state->buf[r + i] = PAD[i];
+ }
+ SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
+ memset(&state->buf[0], 0, 112);
+ }
+ be64enc_vect(&state->buf[112], state->count, 16);
+ SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
+}
+
+int
+crypto_hash_sha512_init(crypto_hash_sha512_state *state)
+{
+ static const uint64_t sha512_initial_state[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+ };
+
+ state->count[0] = state->count[1] = (uint64_t) 0U;
+ memcpy(state->state, sha512_initial_state, sizeof sha512_initial_state);
+
+ return 0;
+}
+
+int
+crypto_hash_sha512_update(crypto_hash_sha512_state *state,
+ const unsigned char *in, unsigned long long inlen)
+{
+ uint64_t tmp64[80 + 8];
+ uint64_t bitlen[2];
+ unsigned long long i;
+ unsigned long long r;
+
+ if (inlen <= 0U) {
+ return 0;
+ }
+ r = (unsigned long long) ((state->count[1] >> 3) & 0x7f);
+
+ bitlen[1] = ((uint64_t) inlen) << 3;
+ bitlen[0] = ((uint64_t) inlen) >> 61;
+ /* LCOV_EXCL_START */
+ if ((state->count[1] += bitlen[1]) < bitlen[1]) {
+ state->count[0]++;
+ }
+ /* LCOV_EXCL_STOP */
+ state->count[0] += bitlen[0];
+ if (inlen < 128 - r) {
+ for (i = 0; i < inlen; i++) {
+ state->buf[r + i] = in[i];
+ }
+ return 0;
+ }
+ for (i = 0; i < 128 - r; i++) {
+ state->buf[r + i] = in[i];
+ }
+ SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
+ in += 128 - r;
+ inlen -= 128 - r;
+
+ while (inlen >= 128) {
+ SHA512_Transform(state->state, in, &tmp64[0], &tmp64[80]);
+ in += 128;
+ inlen -= 128;
+ }
+ inlen &= 127;
+ for (i = 0; i < inlen; i++) {
+ state->buf[i] = in[i];
+ }
+ sodium_memzero((void *) tmp64, sizeof tmp64);
+
+ return 0;
+}
+
+int
+crypto_hash_sha512_final(crypto_hash_sha512_state *state, unsigned char *out)
+{
+ uint64_t tmp64[80 + 8];
+
+ SHA512_Pad(state, tmp64);
+ be64enc_vect(out, state->state, 64);
+ sodium_memzero((void *) tmp64, sizeof tmp64);
+ sodium_memzero((void *) state, sizeof *state);
+
+ return 0;
+}
+
+int
+crypto_hash_sha512(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen)
+{
+ crypto_hash_sha512_state state;
+
+ crypto_hash_sha512_init(&state);
+ crypto_hash_sha512_update(&state, in, inlen);
+ crypto_hash_sha512_final(&state, out);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c b/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c
new file mode 100644
index 0000000000..ba842b8bd4
--- /dev/null
+++ b/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c
@@ -0,0 +1,13 @@
+#include "crypto_hash_sha512.h"
+
+size_t
+crypto_hash_sha512_bytes(void)
+{
+ return crypto_hash_sha512_BYTES;
+}
+
+size_t
+crypto_hash_sha512_statebytes(void)
+{
+ return sizeof(crypto_hash_sha512_state);
+}
diff --git a/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c b/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c
new file mode 100644
index 0000000000..2a690c9ac8
--- /dev/null
+++ b/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c
@@ -0,0 +1,52 @@
+#include <errno.h>
+
+#include "crypto_kdf_blake2b.h"
+#include "crypto_generichash_blake2b.h"
+#include "private/common.h"
+
+size_t
+crypto_kdf_blake2b_bytes_min(void)
+{
+ return crypto_kdf_blake2b_BYTES_MIN;
+}
+
+size_t
+crypto_kdf_blake2b_bytes_max(void)
+{
+ return crypto_kdf_blake2b_BYTES_MAX;
+}
+
+size_t
+crypto_kdf_blake2b_contextbytes(void)
+{
+ return crypto_kdf_blake2b_CONTEXTBYTES;
+}
+
+size_t
+crypto_kdf_blake2b_keybytes(void)
+{
+ return crypto_kdf_blake2b_KEYBYTES;
+}
+
+int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len,
+ uint64_t subkey_id,
+ const char ctx[crypto_kdf_blake2b_CONTEXTBYTES],
+ const unsigned char key[crypto_kdf_blake2b_KEYBYTES])
+{
+ unsigned char ctx_padded[crypto_generichash_blake2b_PERSONALBYTES];
+ unsigned char salt[crypto_generichash_blake2b_SALTBYTES];
+
+ memcpy(ctx_padded, ctx, crypto_kdf_blake2b_CONTEXTBYTES);
+ memset(ctx_padded + crypto_kdf_blake2b_CONTEXTBYTES, 0, sizeof ctx_padded - crypto_kdf_blake2b_CONTEXTBYTES);
+ STORE64_LE(salt, subkey_id);
+ memset(salt + 8, 0, (sizeof salt) - 8);
+ if (subkey_len < crypto_kdf_blake2b_BYTES_MIN ||
+ subkey_len > crypto_kdf_blake2b_BYTES_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+ return crypto_generichash_blake2b_salt_personal(subkey, subkey_len,
+ NULL, 0,
+ key, crypto_kdf_blake2b_KEYBYTES,
+ salt, ctx_padded);
+}
diff --git a/libs/libsodium/src/crypto_kdf/crypto_kdf.c b/libs/libsodium/src/crypto_kdf/crypto_kdf.c
new file mode 100644
index 0000000000..b215d99ae6
--- /dev/null
+++ b/libs/libsodium/src/crypto_kdf/crypto_kdf.c
@@ -0,0 +1,49 @@
+
+#include "crypto_kdf.h"
+#include "randombytes.h"
+
+const char *
+crypto_kdf_primitive(void)
+{
+ return crypto_kdf_PRIMITIVE;
+}
+
+size_t
+crypto_kdf_bytes_min(void)
+{
+ return crypto_kdf_BYTES_MIN;
+}
+
+size_t
+crypto_kdf_bytes_max(void)
+{
+ return crypto_kdf_BYTES_MAX;
+}
+
+size_t
+crypto_kdf_contextbytes(void)
+{
+ return crypto_kdf_CONTEXTBYTES;
+}
+
+size_t
+crypto_kdf_keybytes(void)
+{
+ return crypto_kdf_KEYBYTES;
+}
+
+int
+crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len,
+ uint64_t subkey_id,
+ const char ctx[crypto_kdf_CONTEXTBYTES],
+ const unsigned char key[crypto_kdf_KEYBYTES])
+{
+ return crypto_kdf_blake2b_derive_from_key(subkey, subkey_len,
+ subkey_id, ctx, key);
+}
+
+void
+crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES])
+{
+ randombytes_buf(k, crypto_kdf_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_kx/crypto_kx.c b/libs/libsodium/src/crypto_kx/crypto_kx.c
new file mode 100644
index 0000000000..877ab7ff4a
--- /dev/null
+++ b/libs/libsodium/src/crypto_kx/crypto_kx.c
@@ -0,0 +1,143 @@
+
+#include <stddef.h>
+
+#include "core.h"
+#include "crypto_generichash.h"
+#include "crypto_kx.h"
+#include "crypto_scalarmult.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char seed[crypto_kx_SEEDBYTES])
+{
+ crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
+ seed, crypto_kx_SEEDBYTES, NULL, 0);
+ return crypto_scalarmult_base(pk, sk);
+}
+
+int
+crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES])
+{
+ COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
+ COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
+
+ randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
+ return crypto_scalarmult_base(pk, sk);
+}
+
+int
+crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_BYTES];
+ unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult(q, client_sk, server_pk) != 0) {
+ return -1;
+ }
+ COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
+ crypto_generichash_init(&h, NULL, 0U, sizeof keys);
+ crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
+ rx[i] = keys[i];
+ tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+int
+crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_BYTES];
+ unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult(q, server_sk, client_pk) != 0) {
+ return -1;
+ }
+ COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
+ crypto_generichash_init(&h, NULL, 0U, sizeof keys);
+ crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
+ tx[i] = keys[i];
+ rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+size_t
+crypto_kx_publickeybytes(void)
+{
+ return crypto_kx_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_kx_secretkeybytes(void)
+{
+ return crypto_kx_SECRETKEYBYTES;
+}
+
+size_t
+crypto_kx_seedbytes(void)
+{
+ return crypto_kx_SEEDBYTES;
+}
+
+size_t
+crypto_kx_sessionkeybytes(void)
+{
+ return crypto_kx_SESSIONKEYBYTES;
+}
+
+const char *
+crypto_kx_primitive(void)
+{
+ return crypto_kx_PRIMITIVE;
+}
diff --git a/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c b/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c
new file mode 100644
index 0000000000..93567aae0b
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c
@@ -0,0 +1,71 @@
+
+#include "crypto_onetimeauth.h"
+#include "randombytes.h"
+
+size_t
+crypto_onetimeauth_statebytes(void)
+{
+ return sizeof(crypto_onetimeauth_state);
+}
+
+size_t
+crypto_onetimeauth_bytes(void)
+{
+ return crypto_onetimeauth_BYTES;
+}
+
+size_t
+crypto_onetimeauth_keybytes(void)
+{
+ return crypto_onetimeauth_KEYBYTES;
+}
+
+int
+crypto_onetimeauth(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ return crypto_onetimeauth_poly1305(out, in, inlen, k);
+}
+
+int
+crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ return crypto_onetimeauth_poly1305_verify(h, in, inlen, k);
+}
+
+int
+crypto_onetimeauth_init(crypto_onetimeauth_state *state,
+ const unsigned char *key)
+{
+ return crypto_onetimeauth_poly1305_init
+ ((crypto_onetimeauth_poly1305_state *) state, key);
+}
+
+int
+crypto_onetimeauth_update(crypto_onetimeauth_state *state,
+ const unsigned char *in,
+ unsigned long long inlen)
+{
+ return crypto_onetimeauth_poly1305_update
+ ((crypto_onetimeauth_poly1305_state *) state, in, inlen);
+}
+
+int
+crypto_onetimeauth_final(crypto_onetimeauth_state *state,
+ unsigned char *out)
+{
+ return crypto_onetimeauth_poly1305_final
+ ((crypto_onetimeauth_poly1305_state *) state, out);
+}
+
+const char *
+crypto_onetimeauth_primitive(void)
+{
+ return crypto_onetimeauth_PRIMITIVE;
+}
+
+void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES])
+{
+ randombytes_buf(k, crypto_onetimeauth_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c
new file mode 100644
index 0000000000..e798072f84
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c
@@ -0,0 +1,124 @@
+
+#include "poly1305_donna.h"
+#include "crypto_verify_16.h"
+#include "private/common.h"
+#include "utils.h"
+
+#ifdef HAVE_TI_MODE
+#include "poly1305_donna64.h"
+#else
+#include "poly1305_donna32.h"
+#endif
+#include "../onetimeauth_poly1305.h"
+
+static void
+poly1305_update(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long bytes)
+{
+ unsigned long long i;
+
+ /* handle leftover */
+ if (st->leftover) {
+ unsigned long long want = (poly1305_block_size - st->leftover);
+
+ if (want > bytes) {
+ want = bytes;
+ }
+ for (i = 0; i < want; i++) {
+ st->buffer[st->leftover + i] = m[i];
+ }
+ bytes -= want;
+ m += want;
+ st->leftover += want;
+ if (st->leftover < poly1305_block_size) {
+ return;
+ }
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ st->leftover = 0;
+ }
+
+ /* process full blocks */
+ if (bytes >= poly1305_block_size) {
+ unsigned long long want = (bytes & ~(poly1305_block_size - 1));
+
+ poly1305_blocks(st, m, want);
+ m += want;
+ bytes -= want;
+ }
+
+ /* store leftover */
+ if (bytes) {
+ for (i = 0; i < bytes; i++) {
+ st->buffer[st->leftover + i] = m[i];
+ }
+ st->leftover += bytes;
+ }
+}
+
+static int
+crypto_onetimeauth_poly1305_donna(unsigned char *out, const unsigned char *m,
+ unsigned long long inlen,
+ const unsigned char *key)
+{
+ CRYPTO_ALIGN(64) poly1305_state_internal_t state;
+
+ poly1305_init(&state, key);
+ poly1305_update(&state, m, inlen);
+ poly1305_finish(&state, out);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_donna_init(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *key)
+{
+ COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >=
+ sizeof(poly1305_state_internal_t));
+ poly1305_init((poly1305_state_internal_t *) (void *) state, key);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_donna_update(
+ crypto_onetimeauth_poly1305_state *state, const unsigned char *in,
+ unsigned long long inlen)
+{
+ poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_donna_final(
+ crypto_onetimeauth_poly1305_state *state, unsigned char *out)
+{
+ poly1305_finish((poly1305_state_internal_t *) (void *) state, out);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_donna_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+{
+ unsigned char correct[16];
+
+ crypto_onetimeauth_poly1305_donna(correct, in, inlen, k);
+
+ return crypto_verify_16(h, correct);
+}
+
+struct crypto_onetimeauth_poly1305_implementation
+ crypto_onetimeauth_poly1305_donna_implementation = {
+ SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_donna,
+ SODIUM_C99(.onetimeauth_verify =)
+ crypto_onetimeauth_poly1305_donna_verify,
+ SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_donna_init,
+ SODIUM_C99(.onetimeauth_update =)
+ crypto_onetimeauth_poly1305_donna_update,
+ SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_donna_final
+ };
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h
new file mode 100644
index 0000000000..d6474b3af4
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h
@@ -0,0 +1,12 @@
+#ifndef poly1305_donna_H
+#define poly1305_donna_H
+
+#include <stddef.h>
+
+#include "../onetimeauth_poly1305.h"
+#include "crypto_onetimeauth_poly1305.h"
+
+extern struct crypto_onetimeauth_poly1305_implementation
+ crypto_onetimeauth_poly1305_donna_implementation;
+
+#endif /* poly1305_donna_H */
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h
new file mode 100644
index 0000000000..bcf447cd7d
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h
@@ -0,0 +1,235 @@
+/*
+ poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication
+ and 64 bit addition
+*/
+
+#if defined(_MSC_VER)
+# define POLY1305_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+# define POLY1305_NOINLINE __attribute__((noinline))
+#else
+# define POLY1305_NOINLINE
+#endif
+
+#include "private/common.h"
+
+#define poly1305_block_size 16
+
+/* 17 + sizeof(unsigned long long) + 14*sizeof(unsigned long) */
+typedef struct poly1305_state_internal_t {
+ unsigned long r[5];
+ unsigned long h[5];
+ unsigned long pad[4];
+ unsigned long long leftover;
+ unsigned char buffer[poly1305_block_size];
+ unsigned char final;
+} poly1305_state_internal_t;
+
+static void
+poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32])
+{
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff - wiped after finalization */
+ st->r[0] = (LOAD32_LE(&key[0])) & 0x3ffffff;
+ st->r[1] = (LOAD32_LE(&key[3]) >> 2) & 0x3ffff03;
+ st->r[2] = (LOAD32_LE(&key[6]) >> 4) & 0x3ffc0ff;
+ st->r[3] = (LOAD32_LE(&key[9]) >> 6) & 0x3f03fff;
+ st->r[4] = (LOAD32_LE(&key[12]) >> 8) & 0x00fffff;
+
+ /* h = 0 */
+ st->h[0] = 0;
+ st->h[1] = 0;
+ st->h[2] = 0;
+ st->h[3] = 0;
+ st->h[4] = 0;
+
+ /* save pad for later */
+ st->pad[0] = LOAD32_LE(&key[16]);
+ st->pad[1] = LOAD32_LE(&key[20]);
+ st->pad[2] = LOAD32_LE(&key[24]);
+ st->pad[3] = LOAD32_LE(&key[28]);
+
+ st->leftover = 0;
+ st->final = 0;
+}
+
+static void
+poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long bytes)
+{
+ const unsigned long hibit = (st->final) ? 0UL : (1UL << 24); /* 1 << 128 */
+ unsigned long r0, r1, r2, r3, r4;
+ unsigned long s1, s2, s3, s4;
+ unsigned long h0, h1, h2, h3, h4;
+ unsigned long long d0, d1, d2, d3, d4;
+ unsigned long c;
+
+ r0 = st->r[0];
+ r1 = st->r[1];
+ r2 = st->r[2];
+ r3 = st->r[3];
+ r4 = st->r[4];
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ while (bytes >= poly1305_block_size) {
+ /* h += m[i] */
+ h0 += (LOAD32_LE(m + 0)) & 0x3ffffff;
+ h1 += (LOAD32_LE(m + 3) >> 2) & 0x3ffffff;
+ h2 += (LOAD32_LE(m + 6) >> 4) & 0x3ffffff;
+ h3 += (LOAD32_LE(m + 9) >> 6) & 0x3ffffff;
+ h4 += (LOAD32_LE(m + 12) >> 8) | hibit;
+
+ /* h *= r */
+ d0 = ((unsigned long long) h0 * r0) + ((unsigned long long) h1 * s4) +
+ ((unsigned long long) h2 * s3) + ((unsigned long long) h3 * s2) +
+ ((unsigned long long) h4 * s1);
+ d1 = ((unsigned long long) h0 * r1) + ((unsigned long long) h1 * r0) +
+ ((unsigned long long) h2 * s4) + ((unsigned long long) h3 * s3) +
+ ((unsigned long long) h4 * s2);
+ d2 = ((unsigned long long) h0 * r2) + ((unsigned long long) h1 * r1) +
+ ((unsigned long long) h2 * r0) + ((unsigned long long) h3 * s4) +
+ ((unsigned long long) h4 * s3);
+ d3 = ((unsigned long long) h0 * r3) + ((unsigned long long) h1 * r2) +
+ ((unsigned long long) h2 * r1) + ((unsigned long long) h3 * r0) +
+ ((unsigned long long) h4 * s4);
+ d4 = ((unsigned long long) h0 * r4) + ((unsigned long long) h1 * r3) +
+ ((unsigned long long) h2 * r2) + ((unsigned long long) h3 * r1) +
+ ((unsigned long long) h4 * r0);
+
+ /* (partial) h %= p */
+ c = (unsigned long) (d0 >> 26);
+ h0 = (unsigned long) d0 & 0x3ffffff;
+ d1 += c;
+ c = (unsigned long) (d1 >> 26);
+ h1 = (unsigned long) d1 & 0x3ffffff;
+ d2 += c;
+ c = (unsigned long) (d2 >> 26);
+ h2 = (unsigned long) d2 & 0x3ffffff;
+ d3 += c;
+ c = (unsigned long) (d3 >> 26);
+ h3 = (unsigned long) d3 & 0x3ffffff;
+ d4 += c;
+ c = (unsigned long) (d4 >> 26);
+ h4 = (unsigned long) d4 & 0x3ffffff;
+ h0 += c * 5;
+ c = (h0 >> 26);
+ h0 = h0 & 0x3ffffff;
+ h1 += c;
+
+ m += poly1305_block_size;
+ bytes -= poly1305_block_size;
+ }
+
+ st->h[0] = h0;
+ st->h[1] = h1;
+ st->h[2] = h2;
+ st->h[3] = h3;
+ st->h[4] = h4;
+}
+
+static POLY1305_NOINLINE void
+poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16])
+{
+ unsigned long h0, h1, h2, h3, h4, c;
+ unsigned long g0, g1, g2, g3, g4;
+ unsigned long long f;
+ unsigned long mask;
+
+ /* process the remaining block */
+ if (st->leftover) {
+ unsigned long long i = st->leftover;
+
+ st->buffer[i++] = 1;
+ for (; i < poly1305_block_size; i++) {
+ st->buffer[i] = 0;
+ }
+ st->final = 1;
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ }
+
+ /* fully carry h */
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+ h3 = st->h[3];
+ h4 = st->h[4];
+
+ c = h1 >> 26;
+ h1 = h1 & 0x3ffffff;
+ h2 += c;
+ c = h2 >> 26;
+ h2 = h2 & 0x3ffffff;
+ h3 += c;
+ c = h3 >> 26;
+ h3 = h3 & 0x3ffffff;
+ h4 += c;
+ c = h4 >> 26;
+ h4 = h4 & 0x3ffffff;
+ h0 += c * 5;
+ c = h0 >> 26;
+ h0 = h0 & 0x3ffffff;
+ h1 += c;
+
+ /* compute h + -p */
+ g0 = h0 + 5;
+ c = g0 >> 26;
+ g0 &= 0x3ffffff;
+ g1 = h1 + c;
+ c = g1 >> 26;
+ g1 &= 0x3ffffff;
+ g2 = h2 + c;
+ c = g2 >> 26;
+ g2 &= 0x3ffffff;
+ g3 = h3 + c;
+ c = g3 >> 26;
+ g3 &= 0x3ffffff;
+ g4 = h4 + c - (1UL << 26);
+
+ /* select h if h < p, or h + -p if h >= p */
+ mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
+ g0 &= mask;
+ g1 &= mask;
+ g2 &= mask;
+ g3 &= mask;
+ g4 &= mask;
+ mask = ~mask;
+
+ h0 = (h0 & mask) | g0;
+ h1 = (h1 & mask) | g1;
+ h2 = (h2 & mask) | g2;
+ h3 = (h3 & mask) | g3;
+ h4 = (h4 & mask) | g4;
+
+ /* h = h % (2^128) */
+ h0 = ((h0) | (h1 << 26)) & 0xffffffff;
+ h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
+ h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
+ h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
+
+ /* mac = (h + pad) % (2^128) */
+ f = (unsigned long long) h0 + st->pad[0];
+ h0 = (unsigned long) f;
+ f = (unsigned long long) h1 + st->pad[1] + (f >> 32);
+ h1 = (unsigned long) f;
+ f = (unsigned long long) h2 + st->pad[2] + (f >> 32);
+ h2 = (unsigned long) f;
+ f = (unsigned long long) h3 + st->pad[3] + (f >> 32);
+ h3 = (unsigned long) f;
+
+ STORE32_LE(mac + 0, (uint32_t) h0);
+ STORE32_LE(mac + 4, (uint32_t) h1);
+ STORE32_LE(mac + 8, (uint32_t) h2);
+ STORE32_LE(mac + 12, (uint32_t) h3);
+
+ /* zero out the state */
+ sodium_memzero((void *) st, sizeof *st);
+}
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h
new file mode 100644
index 0000000000..e0ed754779
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h
@@ -0,0 +1,220 @@
+/*
+ poly1305 implementation using 64 bit * 64 bit = 128 bit multiplication
+ and 128 bit addition
+*/
+
+#include "private/common.h"
+
+#define MUL(out, x, y) out = ((uint128_t) x * y)
+#define ADD(out, in) out += in
+#define ADDLO(out, in) out += in
+#define SHR(in, shift) (unsigned long long) (in >> (shift))
+#define LO(in) (unsigned long long) (in)
+
+#if defined(_MSC_VER)
+# define POLY1305_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+# define POLY1305_NOINLINE __attribute__((noinline))
+#else
+# define POLY1305_NOINLINE
+#endif
+
+#define poly1305_block_size 16
+
+/* 17 + sizeof(unsigned long long) + 8*sizeof(unsigned long long) */
+typedef struct poly1305_state_internal_t {
+ unsigned long long r[3];
+ unsigned long long h[3];
+ unsigned long long pad[2];
+ unsigned long long leftover;
+ unsigned char buffer[poly1305_block_size];
+ unsigned char final;
+} poly1305_state_internal_t;
+
+static void
+poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32])
+{
+ unsigned long long t0, t1;
+
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ t0 = LOAD64_LE(&key[0]);
+ t1 = LOAD64_LE(&key[8]);
+
+ /* wiped after finalization */
+ st->r[0] = (t0) &0xffc0fffffff;
+ st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
+ st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f;
+
+ /* h = 0 */
+ st->h[0] = 0;
+ st->h[1] = 0;
+ st->h[2] = 0;
+
+ /* save pad for later */
+ st->pad[0] = LOAD64_LE(&key[16]);
+ st->pad[1] = LOAD64_LE(&key[24]);
+
+ st->leftover = 0;
+ st->final = 0;
+}
+
+static void
+poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long bytes)
+{
+ const unsigned long long hibit =
+ (st->final) ? 0ULL : (1ULL << 40); /* 1 << 128 */
+ unsigned long long r0, r1, r2;
+ unsigned long long s1, s2;
+ unsigned long long h0, h1, h2;
+ unsigned long long c;
+ uint128_t d0, d1, d2, d;
+
+ r0 = st->r[0];
+ r1 = st->r[1];
+ r2 = st->r[2];
+
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+
+ s1 = r1 * (5 << 2);
+ s2 = r2 * (5 << 2);
+
+ while (bytes >= poly1305_block_size) {
+ unsigned long long t0, t1;
+
+ /* h += m[i] */
+ t0 = LOAD64_LE(&m[0]);
+ t1 = LOAD64_LE(&m[8]);
+
+ h0 += ((t0) &0xfffffffffff);
+ h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
+ h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit;
+
+ /* h *= r */
+ MUL(d0, h0, r0);
+ MUL(d, h1, s2);
+ ADD(d0, d);
+ MUL(d, h2, s1);
+ ADD(d0, d);
+ MUL(d1, h0, r1);
+ MUL(d, h1, r0);
+ ADD(d1, d);
+ MUL(d, h2, s2);
+ ADD(d1, d);
+ MUL(d2, h0, r2);
+ MUL(d, h1, r1);
+ ADD(d2, d);
+ MUL(d, h2, r0);
+ ADD(d2, d);
+
+ /* (partial) h %= p */
+ c = SHR(d0, 44);
+ h0 = LO(d0) & 0xfffffffffff;
+ ADDLO(d1, c);
+ c = SHR(d1, 44);
+ h1 = LO(d1) & 0xfffffffffff;
+ ADDLO(d2, c);
+ c = SHR(d2, 42);
+ h2 = LO(d2) & 0x3ffffffffff;
+ h0 += c * 5;
+ c = (h0 >> 44);
+ h0 = h0 & 0xfffffffffff;
+ h1 += c;
+
+ m += poly1305_block_size;
+ bytes -= poly1305_block_size;
+ }
+
+ st->h[0] = h0;
+ st->h[1] = h1;
+ st->h[2] = h2;
+}
+
+static POLY1305_NOINLINE void
+poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16])
+{
+ unsigned long long h0, h1, h2, c;
+ unsigned long long g0, g1, g2;
+ unsigned long long t0, t1;
+
+ /* process the remaining block */
+ if (st->leftover) {
+ unsigned long long i = st->leftover;
+
+ st->buffer[i] = 1;
+
+ for (i = i + 1; i < poly1305_block_size; i++) {
+ st->buffer[i] = 0;
+ }
+ st->final = 1;
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ }
+
+ /* fully carry h */
+ h0 = st->h[0];
+ h1 = st->h[1];
+ h2 = st->h[2];
+
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ h2 += c;
+ c = (h2 >> 42);
+ h2 &= 0x3ffffffffff;
+ h0 += c * 5;
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += c;
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ h2 += c;
+ c = (h2 >> 42);
+ h2 &= 0x3ffffffffff;
+ h0 += c * 5;
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += c;
+
+ /* compute h + -p */
+ g0 = h0 + 5;
+ c = (g0 >> 44);
+ g0 &= 0xfffffffffff;
+ g1 = h1 + c;
+ c = (g1 >> 44);
+ g1 &= 0xfffffffffff;
+ g2 = h2 + c - (1ULL << 42);
+
+ /* select h if h < p, or h + -p if h >= p */
+ c = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1;
+ g0 &= c;
+ g1 &= c;
+ g2 &= c;
+ c = ~c;
+ h0 = (h0 & c) | g0;
+ h1 = (h1 & c) | g1;
+ h2 = (h2 & c) | g2;
+
+ /* h = (h + pad) */
+ t0 = st->pad[0];
+ t1 = st->pad[1];
+
+ h0 += ((t0) &0xfffffffffff);
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ h2 += (((t1 >> 24)) & 0x3ffffffffff) + c;
+ h2 &= 0x3ffffffffff;
+
+ /* mac = h % (2^128) */
+ h0 = ((h0) | (h1 << 44));
+ h1 = ((h1 >> 20) | (h2 << 24));
+
+ STORE64_LE(&mac[0], h0);
+ STORE64_LE(&mac[8], h1);
+
+ /* zero out the state */
+ sodium_memzero((void *) st, sizeof *st);
+}
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c
new file mode 100644
index 0000000000..d5e2efa297
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c
@@ -0,0 +1,90 @@
+
+#include "onetimeauth_poly1305.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "private/common.h"
+#include "private/implementations.h"
+#include "randombytes.h"
+#include "runtime.h"
+
+#include "donna/poly1305_donna.h"
+#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H)
+# include "sse2/poly1305_sse2.h"
+#endif
+
+static const crypto_onetimeauth_poly1305_implementation *implementation =
+ &crypto_onetimeauth_poly1305_donna_implementation;
+
+int
+crypto_onetimeauth_poly1305(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ return implementation->onetimeauth(out, in, inlen, k);
+}
+
+int
+crypto_onetimeauth_poly1305_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+{
+ return implementation->onetimeauth_verify(h, in, inlen, k);
+}
+
+int
+crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *key)
+{
+ return implementation->onetimeauth_init(state, key);
+}
+
+int
+crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *in,
+ unsigned long long inlen)
+{
+ return implementation->onetimeauth_update(state, in, inlen);
+}
+
+int
+crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state,
+ unsigned char *out)
+{
+ return implementation->onetimeauth_final(state, out);
+}
+
+size_t
+crypto_onetimeauth_poly1305_bytes(void)
+{
+ return crypto_onetimeauth_poly1305_BYTES;
+}
+
+size_t
+crypto_onetimeauth_poly1305_keybytes(void)
+{
+ return crypto_onetimeauth_poly1305_KEYBYTES;
+}
+
+size_t
+crypto_onetimeauth_poly1305_statebytes(void)
+{
+ return sizeof(crypto_onetimeauth_poly1305_state);
+}
+
+void
+crypto_onetimeauth_poly1305_keygen(
+ unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES])
+{
+ randombytes_buf(k, crypto_onetimeauth_poly1305_KEYBYTES);
+}
+
+int
+_crypto_onetimeauth_poly1305_pick_best_implementation(void)
+{
+ implementation = &crypto_onetimeauth_poly1305_donna_implementation;
+#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H)
+ if (sodium_runtime_has_sse2()) {
+ implementation = &crypto_onetimeauth_poly1305_sse2_implementation;
+ }
+#endif
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h
new file mode 100644
index 0000000000..243eadd50b
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h
@@ -0,0 +1,21 @@
+
+#ifndef onetimeauth_poly1305_H
+#define onetimeauth_poly1305_H
+
+#include "crypto_onetimeauth_poly1305.h"
+
+typedef struct crypto_onetimeauth_poly1305_implementation {
+ int (*onetimeauth)(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+ int (*onetimeauth_verify)(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+ int (*onetimeauth_init)(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char * key);
+ int (*onetimeauth_update)(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char * in,
+ unsigned long long inlen);
+ int (*onetimeauth_final)(crypto_onetimeauth_poly1305_state *state,
+ unsigned char * out);
+} crypto_onetimeauth_poly1305_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c
new file mode 100644
index 0000000000..022f15249b
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c
@@ -0,0 +1,949 @@
+
+#include <stdint.h>
+#include <string.h>
+
+#include "../onetimeauth_poly1305.h"
+#include "crypto_verify_16.h"
+#include "poly1305_sse2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "utils.h"
+
+#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# endif
+
+# include <emmintrin.h>
+
+typedef __m128i xmmi;
+
+# if defined(_MSC_VER)
+# define POLY1305_NOINLINE __declspec(noinline)
+# elif defined(__GNUC__)
+# define POLY1305_NOINLINE __attribute__((noinline))
+# else
+# define POLY1305_NOINLINE
+# endif
+
+# define poly1305_block_size 32
+
+enum poly1305_state_flags_t {
+ poly1305_started = 1,
+ poly1305_final_shift8 = 4,
+ poly1305_final_shift16 = 8,
+ poly1305_final_r2_r = 16, /* use [r^2,r] for the final block */
+ poly1305_final_r_1 = 32 /* use [r,1] for the final block */
+};
+
+typedef struct poly1305_state_internal_t {
+ union {
+ uint64_t h[3];
+ uint32_t hh[10];
+ } H; /* 40 bytes */
+ uint32_t R[5]; /* 20 bytes */
+ uint32_t R2[5]; /* 20 bytes */
+ uint32_t R4[5]; /* 20 bytes */
+ uint64_t pad[2]; /* 16 bytes */
+ uint64_t flags; /* 8 bytes */
+ unsigned long long leftover; /* 8 bytes */
+ unsigned char buffer[poly1305_block_size]; /* 32 bytes */
+} poly1305_state_internal_t; /* 164 bytes total */
+
+/*
+ * _mm_loadl_epi64() is turned into a simple MOVQ. So, unaligned accesses are
+ * totally fine, even though this intrinsic requires a __m128i* input.
+ * This confuses dynamic analysis, so force alignment, only in debug mode.
+ */
+# ifdef DEBUG
+static xmmi
+_fakealign_mm_loadl_epi64(const void *m)
+{
+ xmmi tmp;
+ memcpy(&tmp, m, 8);
+
+ return _mm_loadl_epi64(&tmp);
+}
+# define _mm_loadl_epi64(X) _fakealign_mm_loadl_epi64(X)
+#endif
+
+/* copy 0-31 bytes */
+static inline void
+poly1305_block_copy31(unsigned char *dst, const unsigned char *src,
+ unsigned long long bytes)
+{
+ if (bytes & 16) {
+ _mm_store_si128((xmmi *) (void *) dst,
+ _mm_loadu_si128((const xmmi *) (const void *) src));
+ src += 16;
+ dst += 16;
+ }
+ if (bytes & 8) {
+ memcpy(dst, src, 8);
+ src += 8;
+ dst += 8;
+ }
+ if (bytes & 4) {
+ memcpy(dst, src, 4);
+ src += 4;
+ dst += 4;
+ }
+ if (bytes & 2) {
+ memcpy(dst, src, 2);
+ src += 2;
+ dst += 2;
+ }
+ if (bytes & 1) {
+ *dst = *src;
+ }
+}
+
+static POLY1305_NOINLINE void
+poly1305_init_ext(poly1305_state_internal_t *st, const unsigned char key[32],
+ unsigned long long bytes)
+{
+ uint32_t *R;
+ uint128_t d[3];
+ uint64_t r0, r1, r2;
+ uint64_t rt0, rt1, rt2, st2, c;
+ uint64_t t0, t1;
+ unsigned long long i;
+
+ if (!bytes) {
+ bytes = ~(unsigned long long) 0;
+ }
+ /* H = 0 */
+ _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) &st->H.hh[8], _mm_setzero_si128());
+
+ /* clamp key */
+ memcpy(&t0, key, 8);
+ memcpy(&t1, key + 8, 8);
+ r0 = t0 & 0xffc0fffffff;
+ t0 >>= 44;
+ t0 |= t1 << 20;
+ r1 = t0 & 0xfffffc0ffff;
+ t1 >>= 24;
+ r2 = t1 & 0x00ffffffc0f;
+
+ /* r^1 */
+ R = st->R;
+ R[0] = (uint32_t)(r0) &0x3ffffff;
+ R[1] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff;
+ R[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff;
+ R[3] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff;
+ R[4] = (uint32_t)((r2 >> 16));
+
+ /* save pad */
+ memcpy(&st->pad[0], key + 16, 8);
+ memcpy(&st->pad[1], key + 24, 8);
+
+ rt0 = r0;
+ rt1 = r1;
+ rt2 = r2;
+
+ /* r^2, r^4 */
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ R = st->R2;
+ if (bytes <= 16) {
+ break;
+ }
+ } else if (i == 1) {
+ R = st->R4;
+ if (bytes < 96) {
+ break;
+ }
+ }
+ st2 = rt2 * (5 << 2);
+
+ d[0] = ((uint128_t) rt0 * rt0) + ((uint128_t)(rt1 * 2) * st2);
+ d[1] = ((uint128_t) rt2 * st2) + ((uint128_t)(rt0 * 2) * rt1);
+ d[2] = ((uint128_t) rt1 * rt1) + ((uint128_t)(rt2 * 2) * rt0);
+
+ rt0 = (uint64_t) d[0] & 0xfffffffffff;
+ c = (uint64_t)(d[0] >> 44);
+ d[1] += c;
+
+ rt1 = (uint64_t) d[1] & 0xfffffffffff;
+ c = (uint64_t)(d[1] >> 44);
+ d[2] += c;
+
+ rt2 = (uint64_t) d[2] & 0x3ffffffffff;
+ c = (uint64_t)(d[2] >> 42);
+ rt0 += c * 5;
+ c = (rt0 >> 44);
+ rt0 = rt0 & 0xfffffffffff;
+ rt1 += c;
+ c = (rt1 >> 44);
+ rt1 = rt1 & 0xfffffffffff;
+ rt2 += c; /* even if rt2 overflows, it will still fit in rp4 safely, and
+ is safe to multiply with */
+
+ R[0] = (uint32_t)(rt0) &0x3ffffff;
+ R[1] = (uint32_t)((rt0 >> 26) | (rt1 << 18)) & 0x3ffffff;
+ R[2] = (uint32_t)((rt1 >> 8)) & 0x3ffffff;
+ R[3] = (uint32_t)((rt1 >> 34) | (rt2 << 10)) & 0x3ffffff;
+ R[4] = (uint32_t)((rt2 >> 16));
+ }
+ st->flags = 0;
+ st->leftover = 0U;
+}
+
+static POLY1305_NOINLINE void
+poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long bytes)
+{
+ CRYPTO_ALIGN(64)
+ xmmi HIBIT =
+ _mm_shuffle_epi32(_mm_cvtsi32_si128(1 << 24), _MM_SHUFFLE(1, 0, 1, 0));
+ const xmmi MMASK = _mm_shuffle_epi32(_mm_cvtsi32_si128((1 << 26) - 1),
+ _MM_SHUFFLE(1, 0, 1, 0));
+ const xmmi FIVE =
+ _mm_shuffle_epi32(_mm_cvtsi32_si128(5), _MM_SHUFFLE(1, 0, 1, 0));
+ xmmi H0, H1, H2, H3, H4;
+ xmmi T0, T1, T2, T3, T4, T5, T6, T7, T8;
+ xmmi M0, M1, M2, M3, M4;
+ xmmi M5, M6, M7, M8;
+ xmmi C1, C2;
+ xmmi R20, R21, R22, R23, R24, S21, S22, S23, S24;
+ xmmi R40, R41, R42, R43, R44, S41, S42, S43, S44;
+
+ if (st->flags & poly1305_final_shift8) {
+ HIBIT = _mm_srli_si128(HIBIT, 8);
+ }
+ if (st->flags & poly1305_final_shift16) {
+ HIBIT = _mm_setzero_si128();
+ }
+ if (!(st->flags & poly1305_started)) {
+ /* H = [Mx,My] */
+ T5 = _mm_unpacklo_epi64(
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)),
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 16)));
+ T6 = _mm_unpacklo_epi64(
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)),
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 24)));
+ H0 = _mm_and_si128(MMASK, T5);
+ H1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ H2 = _mm_and_si128(MMASK, T5);
+ H3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ H4 = _mm_srli_epi64(T6, 40);
+ H4 = _mm_or_si128(H4, HIBIT);
+ m += 32;
+ bytes -= 32;
+ st->flags |= poly1305_started;
+ } else {
+ T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[0]);
+ T1 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[4]);
+ T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[8]);
+ H0 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 0, 0));
+ H1 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 2, 2));
+ H2 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(1, 1, 0, 0));
+ H3 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(3, 3, 2, 2));
+ H4 = _mm_shuffle_epi32(T2, _MM_SHUFFLE(1, 1, 0, 0));
+ }
+ if (st->flags & (poly1305_final_r2_r | poly1305_final_r_1)) {
+ if (st->flags & poly1305_final_r2_r) {
+ /* use [r^2, r] */
+ T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]);
+ T3 = _mm_cvtsi32_si128(st->R[4]);
+ T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]);
+ T1 = _mm_cvtsi32_si128(st->R2[4]);
+ T4 = _mm_unpacklo_epi32(T0, T2);
+ T5 = _mm_unpackhi_epi32(T0, T2);
+ R24 = _mm_unpacklo_epi64(T1, T3);
+ } else {
+ /* use [r^1, 1] */
+ T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]);
+ T1 = _mm_cvtsi32_si128(st->R[4]);
+ T2 = _mm_cvtsi32_si128(1);
+ T4 = _mm_unpacklo_epi32(T0, T2);
+ T5 = _mm_unpackhi_epi32(T0, T2);
+ R24 = T1;
+ }
+ R20 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(1, 1, 0, 0));
+ R21 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(3, 3, 2, 2));
+ R22 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(1, 1, 0, 0));
+ R23 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(3, 3, 2, 2));
+ } else {
+ /* use [r^2, r^2] */
+ T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]);
+ T1 = _mm_cvtsi32_si128(st->R2[4]);
+ R20 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0));
+ R21 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1));
+ R22 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2));
+ R23 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3));
+ R24 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0));
+ }
+ S21 = _mm_mul_epu32(R21, FIVE);
+ S22 = _mm_mul_epu32(R22, FIVE);
+ S23 = _mm_mul_epu32(R23, FIVE);
+ S24 = _mm_mul_epu32(R24, FIVE);
+
+ if (bytes >= 64) {
+ T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R4[0]);
+ T1 = _mm_cvtsi32_si128(st->R4[4]);
+ R40 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0));
+ R41 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1));
+ R42 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2));
+ R43 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3));
+ R44 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0));
+ S41 = _mm_mul_epu32(R41, FIVE);
+ S42 = _mm_mul_epu32(R42, FIVE);
+ S43 = _mm_mul_epu32(R43, FIVE);
+ S44 = _mm_mul_epu32(R44, FIVE);
+
+ while (bytes >= 64) {
+ xmmi v00, v01, v02, v03, v04;
+ xmmi v10, v11, v12, v13, v14;
+ xmmi v20, v21, v22, v23, v24;
+ xmmi v30, v31, v32, v33, v34;
+ xmmi v40, v41, v42, v43, v44;
+ xmmi T14, T15;
+
+ /* H *= [r^4,r^4], preload [Mx,My] */
+ T15 = S42;
+ T0 = H4;
+ T0 = _mm_mul_epu32(T0, S41);
+ v01 = H3;
+ v01 = _mm_mul_epu32(v01, T15);
+ T14 = S43;
+ T1 = H4;
+ T1 = _mm_mul_epu32(T1, T15);
+ v11 = H3;
+ v11 = _mm_mul_epu32(v11, T14);
+ T2 = H4;
+ T2 = _mm_mul_epu32(T2, T14);
+ T0 = _mm_add_epi64(T0, v01);
+ T15 = S44;
+ v02 = H2;
+ v02 = _mm_mul_epu32(v02, T14);
+ T3 = H4;
+ T3 = _mm_mul_epu32(T3, T15);
+ T1 = _mm_add_epi64(T1, v11);
+ v03 = H1;
+ v03 = _mm_mul_epu32(v03, T15);
+ v12 = H2;
+ v12 = _mm_mul_epu32(v12, T15);
+ T0 = _mm_add_epi64(T0, v02);
+ T14 = R40;
+ v21 = H3;
+ v21 = _mm_mul_epu32(v21, T15);
+ v31 = H3;
+ v31 = _mm_mul_epu32(v31, T14);
+ T0 = _mm_add_epi64(T0, v03);
+ T4 = H4;
+ T4 = _mm_mul_epu32(T4, T14);
+ T1 = _mm_add_epi64(T1, v12);
+ v04 = H0;
+ v04 = _mm_mul_epu32(v04, T14);
+ T2 = _mm_add_epi64(T2, v21);
+ v13 = H1;
+ v13 = _mm_mul_epu32(v13, T14);
+ T3 = _mm_add_epi64(T3, v31);
+ T15 = R41;
+ v22 = H2;
+ v22 = _mm_mul_epu32(v22, T14);
+ v32 = H2;
+ v32 = _mm_mul_epu32(v32, T15);
+ T0 = _mm_add_epi64(T0, v04);
+ v41 = H3;
+ v41 = _mm_mul_epu32(v41, T15);
+ T1 = _mm_add_epi64(T1, v13);
+ v14 = H0;
+ v14 = _mm_mul_epu32(v14, T15);
+ T2 = _mm_add_epi64(T2, v22);
+ T14 = R42;
+ T5 = _mm_unpacklo_epi64(
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)),
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 16)));
+ v23 = H1;
+ v23 = _mm_mul_epu32(v23, T15);
+ T3 = _mm_add_epi64(T3, v32);
+ v33 = H1;
+ v33 = _mm_mul_epu32(v33, T14);
+ T4 = _mm_add_epi64(T4, v41);
+ v42 = H2;
+ v42 = _mm_mul_epu32(v42, T14);
+ T1 = _mm_add_epi64(T1, v14);
+ T15 = R43;
+ T6 = _mm_unpacklo_epi64(
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)),
+ _mm_loadl_epi64((const xmmi *) (const void *) (m + 24)));
+ v24 = H0;
+ v24 = _mm_mul_epu32(v24, T14);
+ T2 = _mm_add_epi64(T2, v23);
+ v34 = H0;
+ v34 = _mm_mul_epu32(v34, T15);
+ T3 = _mm_add_epi64(T3, v33);
+ M0 = _mm_and_si128(MMASK, T5);
+ v43 = H1;
+ v43 = _mm_mul_epu32(v43, T15);
+ T4 = _mm_add_epi64(T4, v42);
+ M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ v44 = H0;
+ v44 = _mm_mul_epu32(v44, R44);
+ T2 = _mm_add_epi64(T2, v24);
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ T3 = _mm_add_epi64(T3, v34);
+ M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T6, 14));
+ T4 = _mm_add_epi64(T4, v43);
+ M2 = _mm_and_si128(MMASK, T5);
+ T4 = _mm_add_epi64(T4, v44);
+ M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
+
+ /* H += [Mx',My'] */
+ T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 32));
+ T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 48));
+ T7 = _mm_unpacklo_epi32(T5, T6);
+ T8 = _mm_unpackhi_epi32(T5, T6);
+ M5 = _mm_unpacklo_epi32(T7, _mm_setzero_si128());
+ M6 = _mm_unpackhi_epi32(T7, _mm_setzero_si128());
+ M7 = _mm_unpacklo_epi32(T8, _mm_setzero_si128());
+ M8 = _mm_unpackhi_epi32(T8, _mm_setzero_si128());
+ M6 = _mm_slli_epi64(M6, 6);
+ M7 = _mm_slli_epi64(M7, 12);
+ M8 = _mm_slli_epi64(M8, 18);
+ T0 = _mm_add_epi64(T0, M5);
+ T1 = _mm_add_epi64(T1, M6);
+ T2 = _mm_add_epi64(T2, M7);
+ T3 = _mm_add_epi64(T3, M8);
+ T4 = _mm_add_epi64(T4, HIBIT);
+
+ /* H += [Mx,My]*[r^2,r^2] */
+ T15 = S22;
+ v00 = M4;
+ v00 = _mm_mul_epu32(v00, S21);
+ v01 = M3;
+ v01 = _mm_mul_epu32(v01, T15);
+ T14 = S23;
+ v10 = M4;
+ v10 = _mm_mul_epu32(v10, T15);
+ v11 = M3;
+ v11 = _mm_mul_epu32(v11, T14);
+ T0 = _mm_add_epi64(T0, v00);
+ v20 = M4;
+ v20 = _mm_mul_epu32(v20, T14);
+ T0 = _mm_add_epi64(T0, v01);
+ T15 = S24;
+ v02 = M2;
+ v02 = _mm_mul_epu32(v02, T14);
+ T1 = _mm_add_epi64(T1, v10);
+ v30 = M4;
+ v30 = _mm_mul_epu32(v30, T15);
+ T1 = _mm_add_epi64(T1, v11);
+ v03 = M1;
+ v03 = _mm_mul_epu32(v03, T15);
+ T2 = _mm_add_epi64(T2, v20);
+ v12 = M2;
+ v12 = _mm_mul_epu32(v12, T15);
+ T0 = _mm_add_epi64(T0, v02);
+ T14 = R20;
+ v21 = M3;
+ v21 = _mm_mul_epu32(v21, T15);
+ T3 = _mm_add_epi64(T3, v30);
+ v31 = M3;
+ v31 = _mm_mul_epu32(v31, T14);
+ T0 = _mm_add_epi64(T0, v03);
+ v40 = M4;
+ v40 = _mm_mul_epu32(v40, T14);
+ T1 = _mm_add_epi64(T1, v12);
+ v04 = M0;
+ v04 = _mm_mul_epu32(v04, T14);
+ T2 = _mm_add_epi64(T2, v21);
+ v13 = M1;
+ v13 = _mm_mul_epu32(v13, T14);
+ T3 = _mm_add_epi64(T3, v31);
+ T15 = R21;
+ v22 = M2;
+ v22 = _mm_mul_epu32(v22, T14);
+ T4 = _mm_add_epi64(T4, v40);
+ v32 = M2;
+ v32 = _mm_mul_epu32(v32, T15);
+ T0 = _mm_add_epi64(T0, v04);
+ v41 = M3;
+ v41 = _mm_mul_epu32(v41, T15);
+ T1 = _mm_add_epi64(T1, v13);
+ v14 = M0;
+ v14 = _mm_mul_epu32(v14, T15);
+ T2 = _mm_add_epi64(T2, v22);
+ T14 = R22;
+ v23 = M1;
+ v23 = _mm_mul_epu32(v23, T15);
+ T3 = _mm_add_epi64(T3, v32);
+ v33 = M1;
+ v33 = _mm_mul_epu32(v33, T14);
+ T4 = _mm_add_epi64(T4, v41);
+ v42 = M2;
+ v42 = _mm_mul_epu32(v42, T14);
+ T1 = _mm_add_epi64(T1, v14);
+ T15 = R23;
+ v24 = M0;
+ v24 = _mm_mul_epu32(v24, T14);
+ T2 = _mm_add_epi64(T2, v23);
+ v34 = M0;
+ v34 = _mm_mul_epu32(v34, T15);
+ T3 = _mm_add_epi64(T3, v33);
+ v43 = M1;
+ v43 = _mm_mul_epu32(v43, T15);
+ T4 = _mm_add_epi64(T4, v42);
+ v44 = M0;
+ v44 = _mm_mul_epu32(v44, R24);
+ T2 = _mm_add_epi64(T2, v24);
+ T3 = _mm_add_epi64(T3, v34);
+ T4 = _mm_add_epi64(T4, v43);
+ T4 = _mm_add_epi64(T4, v44);
+
+ /* reduce */
+ C1 = _mm_srli_epi64(T0, 26);
+ C2 = _mm_srli_epi64(T3, 26);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_and_si128(T3, MMASK);
+ T1 = _mm_add_epi64(T1, C1);
+ T4 = _mm_add_epi64(T4, C2);
+ C1 = _mm_srli_epi64(T1, 26);
+ C2 = _mm_srli_epi64(T4, 26);
+ T1 = _mm_and_si128(T1, MMASK);
+ T4 = _mm_and_si128(T4, MMASK);
+ T2 = _mm_add_epi64(T2, C1);
+ T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
+ C1 = _mm_srli_epi64(T2, 26);
+ C2 = _mm_srli_epi64(T0, 26);
+ T2 = _mm_and_si128(T2, MMASK);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_add_epi64(T3, C1);
+ T1 = _mm_add_epi64(T1, C2);
+ C1 = _mm_srli_epi64(T3, 26);
+ T3 = _mm_and_si128(T3, MMASK);
+ T4 = _mm_add_epi64(T4, C1);
+
+ /* Final: H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx',My']) */
+ H0 = T0;
+ H1 = T1;
+ H2 = T2;
+ H3 = T3;
+ H4 = T4;
+
+ m += 64;
+ bytes -= 64;
+ }
+ }
+
+ if (bytes >= 32) {
+ xmmi v01, v02, v03, v04;
+ xmmi v11, v12, v13, v14;
+ xmmi v21, v22, v23, v24;
+ xmmi v31, v32, v33, v34;
+ xmmi v41, v42, v43, v44;
+ xmmi T14, T15;
+
+ /* H *= [r^2,r^2] */
+ T15 = S22;
+ T0 = H4;
+ T0 = _mm_mul_epu32(T0, S21);
+ v01 = H3;
+ v01 = _mm_mul_epu32(v01, T15);
+ T14 = S23;
+ T1 = H4;
+ T1 = _mm_mul_epu32(T1, T15);
+ v11 = H3;
+ v11 = _mm_mul_epu32(v11, T14);
+ T2 = H4;
+ T2 = _mm_mul_epu32(T2, T14);
+ T0 = _mm_add_epi64(T0, v01);
+ T15 = S24;
+ v02 = H2;
+ v02 = _mm_mul_epu32(v02, T14);
+ T3 = H4;
+ T3 = _mm_mul_epu32(T3, T15);
+ T1 = _mm_add_epi64(T1, v11);
+ v03 = H1;
+ v03 = _mm_mul_epu32(v03, T15);
+ v12 = H2;
+ v12 = _mm_mul_epu32(v12, T15);
+ T0 = _mm_add_epi64(T0, v02);
+ T14 = R20;
+ v21 = H3;
+ v21 = _mm_mul_epu32(v21, T15);
+ v31 = H3;
+ v31 = _mm_mul_epu32(v31, T14);
+ T0 = _mm_add_epi64(T0, v03);
+ T4 = H4;
+ T4 = _mm_mul_epu32(T4, T14);
+ T1 = _mm_add_epi64(T1, v12);
+ v04 = H0;
+ v04 = _mm_mul_epu32(v04, T14);
+ T2 = _mm_add_epi64(T2, v21);
+ v13 = H1;
+ v13 = _mm_mul_epu32(v13, T14);
+ T3 = _mm_add_epi64(T3, v31);
+ T15 = R21;
+ v22 = H2;
+ v22 = _mm_mul_epu32(v22, T14);
+ v32 = H2;
+ v32 = _mm_mul_epu32(v32, T15);
+ T0 = _mm_add_epi64(T0, v04);
+ v41 = H3;
+ v41 = _mm_mul_epu32(v41, T15);
+ T1 = _mm_add_epi64(T1, v13);
+ v14 = H0;
+ v14 = _mm_mul_epu32(v14, T15);
+ T2 = _mm_add_epi64(T2, v22);
+ T14 = R22;
+ v23 = H1;
+ v23 = _mm_mul_epu32(v23, T15);
+ T3 = _mm_add_epi64(T3, v32);
+ v33 = H1;
+ v33 = _mm_mul_epu32(v33, T14);
+ T4 = _mm_add_epi64(T4, v41);
+ v42 = H2;
+ v42 = _mm_mul_epu32(v42, T14);
+ T1 = _mm_add_epi64(T1, v14);
+ T15 = R23;
+ v24 = H0;
+ v24 = _mm_mul_epu32(v24, T14);
+ T2 = _mm_add_epi64(T2, v23);
+ v34 = H0;
+ v34 = _mm_mul_epu32(v34, T15);
+ T3 = _mm_add_epi64(T3, v33);
+ v43 = H1;
+ v43 = _mm_mul_epu32(v43, T15);
+ T4 = _mm_add_epi64(T4, v42);
+ v44 = H0;
+ v44 = _mm_mul_epu32(v44, R24);
+ T2 = _mm_add_epi64(T2, v24);
+ T3 = _mm_add_epi64(T3, v34);
+ T4 = _mm_add_epi64(T4, v43);
+ T4 = _mm_add_epi64(T4, v44);
+
+ /* H += [Mx,My] */
+ if (m) {
+ T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 0));
+ T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 16));
+ T7 = _mm_unpacklo_epi32(T5, T6);
+ T8 = _mm_unpackhi_epi32(T5, T6);
+ M0 = _mm_unpacklo_epi32(T7, _mm_setzero_si128());
+ M1 = _mm_unpackhi_epi32(T7, _mm_setzero_si128());
+ M2 = _mm_unpacklo_epi32(T8, _mm_setzero_si128());
+ M3 = _mm_unpackhi_epi32(T8, _mm_setzero_si128());
+ M1 = _mm_slli_epi64(M1, 6);
+ M2 = _mm_slli_epi64(M2, 12);
+ M3 = _mm_slli_epi64(M3, 18);
+ T0 = _mm_add_epi64(T0, M0);
+ T1 = _mm_add_epi64(T1, M1);
+ T2 = _mm_add_epi64(T2, M2);
+ T3 = _mm_add_epi64(T3, M3);
+ T4 = _mm_add_epi64(T4, HIBIT);
+ }
+
+ /* reduce */
+ C1 = _mm_srli_epi64(T0, 26);
+ C2 = _mm_srli_epi64(T3, 26);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_and_si128(T3, MMASK);
+ T1 = _mm_add_epi64(T1, C1);
+ T4 = _mm_add_epi64(T4, C2);
+ C1 = _mm_srli_epi64(T1, 26);
+ C2 = _mm_srli_epi64(T4, 26);
+ T1 = _mm_and_si128(T1, MMASK);
+ T4 = _mm_and_si128(T4, MMASK);
+ T2 = _mm_add_epi64(T2, C1);
+ T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
+ C1 = _mm_srli_epi64(T2, 26);
+ C2 = _mm_srli_epi64(T0, 26);
+ T2 = _mm_and_si128(T2, MMASK);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_add_epi64(T3, C1);
+ T1 = _mm_add_epi64(T1, C2);
+ C1 = _mm_srli_epi64(T3, 26);
+ T3 = _mm_and_si128(T3, MMASK);
+ T4 = _mm_add_epi64(T4, C1);
+
+ /* H = (H*[r^2,r^2] + [Mx,My]) */
+ H0 = T0;
+ H1 = T1;
+ H2 = T2;
+ H3 = T3;
+ H4 = T4;
+ }
+
+ if (m) {
+ T0 = _mm_shuffle_epi32(H0, _MM_SHUFFLE(0, 0, 2, 0));
+ T1 = _mm_shuffle_epi32(H1, _MM_SHUFFLE(0, 0, 2, 0));
+ T2 = _mm_shuffle_epi32(H2, _MM_SHUFFLE(0, 0, 2, 0));
+ T3 = _mm_shuffle_epi32(H3, _MM_SHUFFLE(0, 0, 2, 0));
+ T4 = _mm_shuffle_epi32(H4, _MM_SHUFFLE(0, 0, 2, 0));
+ T0 = _mm_unpacklo_epi64(T0, T1);
+ T1 = _mm_unpacklo_epi64(T2, T3);
+ _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], T0);
+ _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], T1);
+ _mm_storel_epi64((xmmi *) (void *) &st->H.hh[8], T4);
+ } else {
+ uint32_t t0, t1, t2, t3, t4, b;
+ uint64_t h0, h1, h2, g0, g1, g2, c, nc;
+
+ /* H = H[0]+H[1] */
+ T0 = H0;
+ T1 = H1;
+ T2 = H2;
+ T3 = H3;
+ T4 = H4;
+
+ T0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8));
+ T1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8));
+ T2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8));
+ T3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8));
+ T4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8));
+
+ t0 = _mm_cvtsi128_si32(T0);
+ b = (t0 >> 26);
+ t0 &= 0x3ffffff;
+ t1 = _mm_cvtsi128_si32(T1) + b;
+ b = (t1 >> 26);
+ t1 &= 0x3ffffff;
+ t2 = _mm_cvtsi128_si32(T2) + b;
+ b = (t2 >> 26);
+ t2 &= 0x3ffffff;
+ t3 = _mm_cvtsi128_si32(T3) + b;
+ b = (t3 >> 26);
+ t3 &= 0x3ffffff;
+ t4 = _mm_cvtsi128_si32(T4) + b;
+
+ /* everything except t4 is in range, so this is all safe */
+ h0 = (((uint64_t) t0) | ((uint64_t) t1 << 26)) & 0xfffffffffffull;
+ h1 = (((uint64_t) t1 >> 18) | ((uint64_t) t2 << 8) |
+ ((uint64_t) t3 << 34)) &
+ 0xfffffffffffull;
+ h2 = (((uint64_t) t3 >> 10) | ((uint64_t) t4 << 16));
+
+ c = (h2 >> 42);
+ h2 &= 0x3ffffffffff;
+ h0 += c * 5;
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += c;
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ h2 += c;
+ c = (h2 >> 42);
+ h2 &= 0x3ffffffffff;
+ h0 += c * 5;
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += c;
+
+ g0 = h0 + 5;
+ c = (g0 >> 44);
+ g0 &= 0xfffffffffff;
+ g1 = h1 + c;
+ c = (g1 >> 44);
+ g1 &= 0xfffffffffff;
+ g2 = h2 + c - ((uint64_t) 1 << 42);
+
+ c = (g2 >> 63) - 1;
+ nc = ~c;
+ h0 = (h0 & nc) | (g0 & c);
+ h1 = (h1 & nc) | (g1 & c);
+ h2 = (h2 & nc) | (g2 & c);
+
+ st->H.h[0] = h0;
+ st->H.h[1] = h1;
+ st->H.h[2] = h2;
+ }
+}
+
+static void
+poly1305_update(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long bytes)
+{
+ unsigned long long i;
+
+ /* handle leftover */
+ if (st->leftover) {
+ unsigned long long want = (poly1305_block_size - st->leftover);
+
+ if (want > bytes) {
+ want = bytes;
+ }
+ for (i = 0; i < want; i++) {
+ st->buffer[st->leftover + i] = m[i];
+ }
+ bytes -= want;
+ m += want;
+ st->leftover += want;
+ if (st->leftover < poly1305_block_size) {
+ return;
+ }
+ poly1305_blocks(st, st->buffer, poly1305_block_size);
+ st->leftover = 0;
+ }
+
+ /* process full blocks */
+ if (bytes >= poly1305_block_size) {
+ unsigned long long want = (bytes & ~(poly1305_block_size - 1));
+
+ poly1305_blocks(st, m, want);
+ m += want;
+ bytes -= want;
+ }
+
+ /* store leftover */
+ if (bytes) {
+ for (i = 0; i < bytes; i++) {
+ st->buffer[st->leftover + i] = m[i];
+ }
+ st->leftover += bytes;
+ }
+}
+
+static POLY1305_NOINLINE void
+poly1305_finish_ext(poly1305_state_internal_t *st, const unsigned char *m,
+ unsigned long long leftover, unsigned char mac[16])
+{
+ uint64_t h0, h1, h2;
+
+ if (leftover) {
+ CRYPTO_ALIGN(16) unsigned char final[32] = { 0 };
+
+ poly1305_block_copy31(final, m, leftover);
+ if (leftover != 16) {
+ final[leftover] = 1;
+ }
+ st->flags |=
+ (leftover >= 16) ? poly1305_final_shift8 : poly1305_final_shift16;
+ poly1305_blocks(st, final, 32);
+ }
+
+ if (st->flags & poly1305_started) {
+ /* finalize, H *= [r^2,r], or H *= [r,1] */
+ if (!leftover || (leftover > 16)) {
+ st->flags |= poly1305_final_r2_r;
+ } else {
+ st->flags |= poly1305_final_r_1;
+ }
+ poly1305_blocks(st, NULL, 32);
+ }
+
+ h0 = st->H.h[0];
+ h1 = st->H.h[1];
+ h2 = st->H.h[2];
+
+ /* pad */
+ h0 = ((h0) | (h1 << 44));
+ h1 = ((h1 >> 20) | (h2 << 24));
+#ifdef HAVE_AMD64_ASM
+ __asm__ __volatile__(
+ "addq %2, %0 ;\n"
+ "adcq %3, %1 ;\n"
+ : "+r"(h0), "+r"(h1)
+ : "r"(st->pad[0]), "r"(st->pad[1])
+ : "flags", "cc");
+#else
+ {
+ uint128_t h;
+
+ memcpy(&h, &st->pad[0], 16);
+ h += ((uint128_t) h1 << 64) | h0;
+ h0 = (uint64_t) h;
+ h1 = (uint64_t)(h >> 64);
+ }
+#endif
+ _mm_storeu_si128((xmmi *) (void *) st + 0, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 1, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 2, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 3, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 4, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 5, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 6, _mm_setzero_si128());
+ _mm_storeu_si128((xmmi *) (void *) st + 7, _mm_setzero_si128());
+
+ memcpy(&mac[0], &h0, 8);
+ memcpy(&mac[8], &h1, 8);
+
+ sodium_memzero((void *) st, sizeof *st);
+}
+
+static void
+poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16])
+{
+ poly1305_finish_ext(st, st->buffer, st->leftover, mac);
+}
+
+static int
+crypto_onetimeauth_poly1305_sse2_init(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *key)
+{
+ COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >=
+ sizeof(poly1305_state_internal_t));
+ poly1305_init_ext((poly1305_state_internal_t *) (void *) state, key, 0U);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_sse2_update(
+ crypto_onetimeauth_poly1305_state *state, const unsigned char *in,
+ unsigned long long inlen)
+{
+ poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_sse2_final(crypto_onetimeauth_poly1305_state *state,
+ unsigned char *out)
+{
+ poly1305_finish((poly1305_state_internal_t *) (void *) state, out);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_sse2(unsigned char *out, const unsigned char *m,
+ unsigned long long inlen,
+ const unsigned char *key)
+{
+ CRYPTO_ALIGN(64) poly1305_state_internal_t st;
+ unsigned long long blocks;
+
+ poly1305_init_ext(&st, key, inlen);
+ blocks = inlen & ~31;
+ if (blocks > 0) {
+ poly1305_blocks(&st, m, blocks);
+ m += blocks;
+ inlen -= blocks;
+ }
+ poly1305_finish_ext(&st, m, inlen, out);
+
+ return 0;
+}
+
+static int
+crypto_onetimeauth_poly1305_sse2_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+{
+ unsigned char correct[16];
+
+ crypto_onetimeauth_poly1305_sse2(correct, in, inlen, k);
+
+ return crypto_verify_16(h, correct);
+}
+
+struct crypto_onetimeauth_poly1305_implementation
+ crypto_onetimeauth_poly1305_sse2_implementation = {
+ SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_sse2,
+ SODIUM_C99(.onetimeauth_verify =)
+ crypto_onetimeauth_poly1305_sse2_verify,
+ SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_sse2_init,
+ SODIUM_C99(.onetimeauth_update =)
+ crypto_onetimeauth_poly1305_sse2_update,
+ SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_sse2_final
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h
new file mode 100644
index 0000000000..9177cad487
--- /dev/null
+++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h
@@ -0,0 +1,12 @@
+#ifndef poly1305_sse2_H
+#define poly1305_sse2_H
+
+#include <stddef.h>
+
+#include "../onetimeauth_poly1305.h"
+#include "crypto_onetimeauth_poly1305.h"
+
+extern struct crypto_onetimeauth_poly1305_implementation
+ crypto_onetimeauth_poly1305_sse2_implementation;
+
+#endif /* poly1305_sse2_H */
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c
new file mode 100644
index 0000000000..b52b04d36d
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c
@@ -0,0 +1,549 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#include "crypto_generichash_blake2b.h"
+#include "private/common.h"
+#include "private/implementations.h"
+#include "runtime.h"
+#include "utils.h"
+
+#include "argon2-core.h"
+#include "blake2b-long.h"
+
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+#ifndef MAP_NOCORE
+# define MAP_NOCORE 0
+#endif
+#ifndef MAP_POPULATE
+# define MAP_POPULATE 0
+#endif
+
+static fill_segment_fn fill_segment = fill_segment_ref;
+
+static void
+load_block(block *dst, const void *input)
+{
+ unsigned i;
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
+ dst->v[i] = LOAD64_LE((const uint8_t *) input + i * sizeof(dst->v[i]));
+ }
+}
+
+static void
+store_block(void *output, const block *src)
+{
+ unsigned i;
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
+ STORE64_LE((uint8_t *) output + i * sizeof(src->v[i]), src->v[i]);
+ }
+}
+
+/***************Memory allocators*****************/
+/* Allocates memory to the given pointer
+ * @param memory pointer to the pointer to the memory
+ * @param m_cost number of blocks to allocate in the memory
+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
+ */
+static int allocate_memory(block_region **memory, uint32_t m_cost);
+
+static int
+allocate_memory(block_region **region, uint32_t m_cost)
+{
+ void * base;
+ block *memory;
+ size_t memory_size;
+
+ if (region == NULL) {
+ return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
+ }
+ memory_size = sizeof(block) * m_cost;
+ if (m_cost == 0 ||
+ memory_size / m_cost !=
+ sizeof(block)) { /*1. Check for multiplication overflow*/
+ return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
+ }
+ *region = (block_region *) malloc(
+ sizeof(block_region)); /*2. Try to allocate region*/
+ if (!*region) {
+ return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
+ }
+ (*region)->base = (*region)->memory = NULL;
+
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE,
+ -1, 0)) == MAP_FAILED) {
+ base = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+ memcpy(&memory, &base, sizeof memory);
+#elif defined(HAVE_POSIX_MEMALIGN)
+ if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) {
+ base = NULL;
+ }
+ memcpy(&memory, &base, sizeof memory);
+#else
+ memory = NULL;
+ if (memory_size + 63 < memory_size) {
+ base = NULL;
+ errno = ENOMEM;
+ } else if ((base = malloc(memory_size + 63)) != NULL) {
+ uint8_t *aligned = ((uint8_t *) base) + 63;
+ aligned -= (uintptr_t) aligned & 63;
+ memcpy(&memory, &aligned, sizeof memory);
+ }
+#endif
+ if (base == NULL) {
+ return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
+ }
+ (*region)->base = base;
+ (*region)->memory = memory;
+ (*region)->size = memory_size;
+
+ return ARGON2_OK;
+}
+
+/*********Memory functions*/
+
+/* Clears memory
+ * @param instance pointer to the current instance
+ * @param clear_memory indicates if we clear the memory with zeros.
+ */
+static void clear_memory(argon2_instance_t *instance, int clear);
+
+static void
+clear_memory(argon2_instance_t *instance, int clear)
+{
+ /* LCOV_EXCL_START */
+ if (clear) {
+ if (instance->region != NULL) {
+ sodium_memzero(instance->region->memory,
+ sizeof(block) * instance->memory_blocks);
+ }
+ if (instance->pseudo_rands != NULL) {
+ sodium_memzero(instance->pseudo_rands,
+ sizeof(uint64_t) * instance->segment_length);
+ }
+ }
+ /* LCOV_EXCL_STOP */
+}
+
+/* Deallocates memory
+ * @param memory pointer to the blocks
+ */
+static void free_memory(block_region *memory);
+
+static void
+free_memory(block_region *region)
+{
+ if (region && region->base) {
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if (munmap(region->base, region->size)) {
+ return; /* LCOV_EXCL_LINE */
+ }
+#else
+ free(region->base);
+#endif
+ }
+ free(region);
+}
+
+void
+free_instance(argon2_instance_t *instance, int flags)
+{
+ /* Clear memory */
+ clear_memory(instance, flags & ARGON2_FLAG_CLEAR_MEMORY);
+
+ /* Deallocate the memory */
+ free(instance->pseudo_rands);
+ instance->pseudo_rands = NULL;
+ free_memory(instance->region);
+ instance->region = NULL;
+}
+
+void
+finalize(const argon2_context *context, argon2_instance_t *instance)
+{
+ if (context != NULL && instance != NULL) {
+ block blockhash;
+ uint32_t l;
+
+ copy_block(&blockhash,
+ instance->region->memory + instance->lane_length - 1);
+
+ /* XOR the last blocks */
+ for (l = 1; l < instance->lanes; ++l) {
+ uint32_t last_block_in_lane =
+ l * instance->lane_length + (instance->lane_length - 1);
+ xor_block(&blockhash,
+ instance->region->memory + last_block_in_lane);
+ }
+
+ /* Hash the result */
+ {
+ uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
+ store_block(blockhash_bytes, &blockhash);
+ blake2b_long(context->out, context->outlen, blockhash_bytes,
+ ARGON2_BLOCK_SIZE);
+ sodium_memzero(blockhash.v,
+ ARGON2_BLOCK_SIZE); /* clear blockhash */
+ sodium_memzero(blockhash_bytes,
+ ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
+ }
+
+ free_instance(instance, context->flags);
+ }
+}
+
+void
+fill_memory_blocks(argon2_instance_t *instance, uint32_t pass)
+{
+ argon2_position_t position;
+ uint32_t l;
+ uint32_t s;
+
+ if (instance == NULL || instance->lanes == 0) {
+ return; /* LCOV_EXCL_LINE */
+ }
+
+ position.pass = pass;
+ for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
+ position.slice = (uint8_t) s;
+ for (l = 0; l < instance->lanes; ++l) {
+ position.lane = l;
+ position.index = 0;
+ fill_segment(instance, position);
+ }
+ }
+}
+
+int
+validate_inputs(const argon2_context *context)
+{
+ /* LCOV_EXCL_START */
+ if (NULL == context) {
+ return ARGON2_INCORRECT_PARAMETER;
+ }
+
+ if (NULL == context->out) {
+ return ARGON2_OUTPUT_PTR_NULL;
+ }
+
+ /* Validate output length */
+ if (ARGON2_MIN_OUTLEN > context->outlen) {
+ return ARGON2_OUTPUT_TOO_SHORT;
+ }
+
+ if (ARGON2_MAX_OUTLEN < context->outlen) {
+ return ARGON2_OUTPUT_TOO_LONG;
+ }
+
+ /* Validate password (required param) */
+ if (NULL == context->pwd) {
+ if (0 != context->pwdlen) {
+ return ARGON2_PWD_PTR_MISMATCH;
+ }
+ }
+
+ if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
+ return ARGON2_PWD_TOO_SHORT;
+ }
+
+ if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
+ return ARGON2_PWD_TOO_LONG;
+ }
+
+ /* Validate salt (required param) */
+ if (NULL == context->salt) {
+ if (0 != context->saltlen) {
+ return ARGON2_SALT_PTR_MISMATCH;
+ }
+ }
+
+ if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
+ return ARGON2_SALT_TOO_SHORT;
+ }
+
+ if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
+ return ARGON2_SALT_TOO_LONG;
+ }
+
+ /* Validate secret (optional param) */
+ if (NULL == context->secret) {
+ if (0 != context->secretlen) {
+ return ARGON2_SECRET_PTR_MISMATCH;
+ }
+ } else {
+ if (ARGON2_MIN_SECRET > context->secretlen) {
+ return ARGON2_SECRET_TOO_SHORT;
+ }
+
+ if (ARGON2_MAX_SECRET < context->secretlen) {
+ return ARGON2_SECRET_TOO_LONG;
+ }
+ }
+
+ /* Validate associated data (optional param) */
+ if (NULL == context->ad) {
+ if (0 != context->adlen) {
+ return ARGON2_AD_PTR_MISMATCH;
+ }
+ } else {
+ if (ARGON2_MIN_AD_LENGTH > context->adlen) {
+ return ARGON2_AD_TOO_SHORT;
+ }
+
+ if (ARGON2_MAX_AD_LENGTH < context->adlen) {
+ return ARGON2_AD_TOO_LONG;
+ }
+ }
+
+ /* Validate memory cost */
+ if (ARGON2_MIN_MEMORY > context->m_cost) {
+ return ARGON2_MEMORY_TOO_LITTLE;
+ }
+
+ if (ARGON2_MAX_MEMORY < context->m_cost) {
+ return ARGON2_MEMORY_TOO_MUCH;
+ }
+
+ if (context->m_cost < 8 * context->lanes) {
+ return ARGON2_MEMORY_TOO_LITTLE;
+ }
+
+ /* Validate time cost */
+ if (ARGON2_MIN_TIME > context->t_cost) {
+ return ARGON2_TIME_TOO_SMALL;
+ }
+
+ if (ARGON2_MAX_TIME < context->t_cost) {
+ return ARGON2_TIME_TOO_LARGE;
+ }
+
+ /* Validate lanes */
+ if (ARGON2_MIN_LANES > context->lanes) {
+ return ARGON2_LANES_TOO_FEW;
+ }
+
+ if (ARGON2_MAX_LANES < context->lanes) {
+ return ARGON2_LANES_TOO_MANY;
+ }
+
+ /* Validate threads */
+ if (ARGON2_MIN_THREADS > context->threads) {
+ return ARGON2_THREADS_TOO_FEW;
+ }
+
+ if (ARGON2_MAX_THREADS < context->threads) {
+ return ARGON2_THREADS_TOO_MANY;
+ }
+ /* LCOV_EXCL_STOP */
+
+ return ARGON2_OK;
+}
+
+void
+fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance)
+{
+ uint32_t l;
+ /* Make the first and second block in each lane as G(H0||i||0) or
+ G(H0||i||1) */
+ uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
+ for (l = 0; l < instance->lanes; ++l) {
+ STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
+ STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
+ ARGON2_PREHASH_SEED_LENGTH);
+ load_block(&instance->region->memory[l * instance->lane_length + 0],
+ blockhash_bytes);
+
+ STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
+ ARGON2_PREHASH_SEED_LENGTH);
+ load_block(&instance->region->memory[l * instance->lane_length + 1],
+ blockhash_bytes);
+ }
+ sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE);
+}
+
+void
+initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type)
+{
+ crypto_generichash_blake2b_state BlakeHash;
+ uint8_t value[4U /* sizeof(uint32_t) */];
+
+ if (NULL == context || NULL == blockhash) {
+ return; /* LCOV_EXCL_LINE */
+ }
+
+ crypto_generichash_blake2b_init(&BlakeHash, NULL, 0U,
+ ARGON2_PREHASH_DIGEST_LENGTH);
+
+ STORE32_LE(value, context->lanes);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, context->outlen);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, context->m_cost);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, context->t_cost);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, ARGON2_VERSION_NUMBER);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, (uint32_t) type);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ STORE32_LE(value, context->pwdlen);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ if (context->pwd != NULL) {
+ crypto_generichash_blake2b_update(
+ &BlakeHash, (const uint8_t *) context->pwd, context->pwdlen);
+
+ /* LCOV_EXCL_START */
+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
+ sodium_memzero(context->pwd, context->pwdlen);
+ context->pwdlen = 0;
+ }
+ /* LCOV_EXCL_STOP */
+ }
+
+ STORE32_LE(value, context->saltlen);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ if (context->salt != NULL) {
+ crypto_generichash_blake2b_update(
+ &BlakeHash, (const uint8_t *) context->salt, context->saltlen);
+ }
+
+ STORE32_LE(value, context->secretlen);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ /* LCOV_EXCL_START */
+ if (context->secret != NULL) {
+ crypto_generichash_blake2b_update(
+ &BlakeHash, (const uint8_t *) context->secret, context->secretlen);
+
+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
+ sodium_memzero(context->secret, context->secretlen);
+ context->secretlen = 0;
+ }
+ }
+ /* LCOV_EXCL_STOP */
+
+ STORE32_LE(value, context->adlen);
+ crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
+
+ /* LCOV_EXCL_START */
+ if (context->ad != NULL) {
+ crypto_generichash_blake2b_update(
+ &BlakeHash, (const uint8_t *) context->ad, context->adlen);
+ }
+ /* LCOV_EXCL_STOP */
+
+ crypto_generichash_blake2b_final(&BlakeHash, blockhash,
+ ARGON2_PREHASH_DIGEST_LENGTH);
+}
+
+int
+initialize(argon2_instance_t *instance, argon2_context *context)
+{
+ uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
+ int result = ARGON2_OK;
+
+ if (instance == NULL || context == NULL) {
+ return ARGON2_INCORRECT_PARAMETER;
+ }
+
+ /* 1. Memory allocation */
+
+ if ((instance->pseudo_rands = (uint64_t *)
+ malloc(sizeof(uint64_t) * instance->segment_length)) == NULL) {
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
+ }
+
+ result = allocate_memory(&(instance->region), instance->memory_blocks);
+ if (ARGON2_OK != result) {
+ free_instance(instance, context->flags);
+ return result;
+ }
+
+ /* 2. Initial hashing */
+ /* H_0 + 8 extra bytes to produce the first blocks */
+ /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
+ /* Hashing all inputs */
+ initial_hash(blockhash, context, instance->type);
+ /* Zeroing 8 extra bytes */
+ sodium_memzero(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
+ ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH);
+
+ /* 3. Creating first blocks, we always have at least two blocks in a slice
+ */
+ fill_first_blocks(blockhash, instance);
+ /* Clearing the hash */
+ sodium_memzero(blockhash, ARGON2_PREHASH_SEED_LENGTH);
+
+ return ARGON2_OK;
+}
+
+int
+argon2_pick_best_implementation(void)
+{
+/* LCOV_EXCL_START */
+#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_avx512f()) {
+ fill_segment = fill_segment_avx512f;
+ return 0;
+ }
+#endif
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
+ defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_avx2()) {
+ fill_segment = fill_segment_avx2;
+ return 0;
+ }
+#endif
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+ if (sodium_runtime_has_ssse3()) {
+ fill_segment = fill_segment_ssse3;
+ return 0;
+ }
+#endif
+ fill_segment = fill_segment_ref;
+
+ return 0;
+ /* LCOV_EXCL_STOP */
+}
+
+int
+_crypto_pwhash_argon2_pick_best_implementation(void)
+{
+ return argon2_pick_best_implementation();
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h
new file mode 100644
index 0000000000..caab103891
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h
@@ -0,0 +1,297 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#ifndef argon2_core_H
+#define argon2_core_H
+
+#include <string.h>
+
+#include "argon2.h"
+
+/*************************Argon2 internal
+ * constants**************************************************/
+
+enum argon2_ctx_constants {
+ /* Version of the algorithm */
+ ARGON2_VERSION_NUMBER = 0x13,
+
+ /* Memory block size in bytes */
+ ARGON2_BLOCK_SIZE = 1024,
+ ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
+ ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
+ ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
+ ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
+
+ /* Number of pseudo-random values generated by one call to Blake in Argon2i
+ to
+ generate reference block positions */
+ ARGON2_ADDRESSES_IN_BLOCK = 128,
+
+ /* Pre-hashing digest length and its extension*/
+ ARGON2_PREHASH_DIGEST_LENGTH = 64,
+ ARGON2_PREHASH_SEED_LENGTH = 72
+};
+
+/*************************Argon2 internal data
+ * types**************************************************/
+
+/*
+ * Structure for the (1KB) memory block implemented as 128 64-bit words.
+ * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
+ * bounds checking).
+ */
+typedef struct block_ {
+ uint64_t v[ARGON2_QWORDS_IN_BLOCK];
+} block;
+
+typedef struct block_region_ {
+ void * base;
+ block *memory;
+ size_t size;
+} block_region;
+
+/*****************Functions that work with the block******************/
+
+/* Initialize each byte of the block with @in */
+static inline void
+init_block_value(block *b, uint8_t in)
+{
+ memset(b->v, in, sizeof(b->v));
+}
+
+/* Copy block @src to block @dst */
+static inline void
+copy_block(block *dst, const block *src)
+{
+ memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
+}
+
+/* XOR @src onto @dst bytewise */
+static inline void
+xor_block(block *dst, const block *src)
+{
+ int i;
+ for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
+ dst->v[i] ^= src->v[i];
+ }
+}
+
+/*
+ * Argon2 instance: memory pointer, number of passes, amount of memory, type,
+ * and derived values.
+ * Used to evaluate the number and location of blocks to construct in each
+ * thread
+ */
+typedef struct Argon2_instance_t {
+ block_region *region; /* Memory region pointer */
+ uint64_t *pseudo_rands;
+ uint32_t passes; /* Number of passes */
+ uint32_t current_pass;
+ uint32_t memory_blocks; /* Number of blocks in memory */
+ uint32_t segment_length;
+ uint32_t lane_length;
+ uint32_t lanes;
+ uint32_t threads;
+ argon2_type type;
+ int print_internals; /* whether to print the memory blocks */
+} argon2_instance_t;
+
+/*
+ * Argon2 position: where we construct the block right now. Used to distribute
+ * work between threads.
+ */
+typedef struct Argon2_position_t {
+ uint32_t pass;
+ uint32_t lane;
+ uint8_t slice;
+ uint32_t index;
+} argon2_position_t;
+
+/*Struct that holds the inputs for thread handling FillSegment*/
+typedef struct Argon2_thread_data {
+ argon2_instance_t *instance_ptr;
+ argon2_position_t pos;
+} argon2_thread_data;
+
+/*************************Argon2 core
+ * functions**************************************************/
+
+/*
+ * Computes absolute position of reference block in the lane following a skewed
+ * distribution and using a pseudo-random value as input
+ * @param instance Pointer to the current instance
+ * @param position Pointer to the current position
+ * @param pseudo_rand 32-bit pseudo-random value used to determine the position
+ * @param same_lane Indicates if the block will be taken from the current lane.
+ * If so we can reference the current segment
+ * @pre All pointers must be valid
+ */
+static uint32_t index_alpha(const argon2_instance_t *instance,
+ const argon2_position_t *position, uint32_t pseudo_rand,
+ int same_lane)
+{
+ /*
+ * Pass 0:
+ * This lane : all already finished segments plus already constructed
+ * blocks in this segment
+ * Other lanes : all already finished segments
+ * Pass 1+:
+ * This lane : (SYNC_POINTS - 1) last segments plus already constructed
+ * blocks in this segment
+ * Other lanes : (SYNC_POINTS - 1) last segments
+ */
+ uint32_t reference_area_size;
+ uint64_t relative_position;
+ uint32_t start_position, absolute_position;
+
+ if (position->pass == 0) {
+ /* First pass */
+ if (position->slice == 0) {
+ /* First slice */
+ reference_area_size =
+ position->index - 1; /* all but the previous */
+ } else {
+ if (same_lane) {
+ /* The same lane => add current segment */
+ reference_area_size =
+ position->slice * instance->segment_length +
+ position->index - 1;
+ } else {
+ reference_area_size =
+ position->slice * instance->segment_length +
+ ((position->index == 0) ? (-1) : 0);
+ }
+ }
+ } else {
+ /* Second pass */
+ if (same_lane) {
+ reference_area_size = instance->lane_length -
+ instance->segment_length + position->index -
+ 1;
+ } else {
+ reference_area_size = instance->lane_length -
+ instance->segment_length +
+ ((position->index == 0) ? (-1) : 0);
+ }
+ }
+
+ /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
+ * relative position */
+ relative_position = pseudo_rand;
+ relative_position = relative_position * relative_position >> 32;
+ relative_position = reference_area_size - 1 -
+ (reference_area_size * relative_position >> 32);
+
+ /* 1.2.5 Computing starting position */
+ start_position = 0;
+
+ if (position->pass != 0) {
+ start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
+ ? 0
+ : (position->slice + 1) * instance->segment_length;
+ }
+
+ /* 1.2.6. Computing absolute position */
+ absolute_position = (start_position + relative_position) %
+ instance->lane_length; /* absolute position */
+ return absolute_position;
+}
+
+/*
+ * Function that validates all inputs against predefined restrictions and return
+ * an error code
+ * @param context Pointer to current Argon2 context
+ * @return ARGON2_OK if everything is all right, otherwise one of error codes
+ * (all defined in <argon2.h>
+ */
+int validate_inputs(const argon2_context *context);
+
+/*
+ * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
+ * password and secret if needed
+ * @param context Pointer to the Argon2 internal structure containing memory
+ * pointer, and parameters for time and space requirements.
+ * @param blockhash Buffer for pre-hashing digest
+ * @param type Argon2 type
+ * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
+ * allocated
+ */
+void initial_hash(uint8_t *blockhash, argon2_context *context,
+ argon2_type type);
+
+/*
+ * Function creates first 2 blocks per lane
+ * @param instance Pointer to the current instance
+ * @param blockhash Pointer to the pre-hashing digest
+ * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
+ */
+void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
+
+/*
+ * Function allocates memory, hashes the inputs with Blake, and creates first
+ * two blocks. Returns the pointer to the main memory with 2 blocks per lane
+ * initialized
+ * @param context Pointer to the Argon2 internal structure containing memory
+ * pointer, and parameters for time and space requirements.
+ * @param instance Current Argon2 instance
+ * @return Zero if successful, -1 if memory failed to allocate. @context->state
+ * will be modified if successful.
+ */
+int initialize(argon2_instance_t *instance, argon2_context *context);
+
+/*
+ * Deallocates memory. Used on error path.
+ */
+void free_instance(argon2_instance_t *instance, int flags);
+
+/*
+ * XORing the last block of each lane, hashing it, making the tag. Deallocates
+ * the memory.
+ * @param context Pointer to current Argon2 context (use only the out parameters
+ * from it)
+ * @param instance Pointer to current instance of Argon2
+ * @pre instance->state must point to necessary amount of memory
+ * @pre context->out must point to outlen bytes of memory
+ * @pre if context->free_cbk is not NULL, it should point to a function that
+ * deallocates memory
+ */
+void finalize(const argon2_context *context, argon2_instance_t *instance);
+
+/*
+ * Function that fills the segment using previous segments also from other
+ * threads
+ * @param instance Pointer to the current instance
+ * @param position Current position
+ * @pre all block pointers must be valid
+ */
+typedef void (*fill_segment_fn)(const argon2_instance_t *instance,
+ argon2_position_t position);
+int argon2_pick_best_implementation(void);
+void fill_segment_avx512f(const argon2_instance_t *instance,
+ argon2_position_t position);
+void fill_segment_avx2(const argon2_instance_t *instance,
+ argon2_position_t position);
+void fill_segment_ssse3(const argon2_instance_t *instance,
+ argon2_position_t position);
+void fill_segment_ref(const argon2_instance_t *instance,
+ argon2_position_t position);
+
+/*
+ * Function that fills the entire memory t_cost times based on the first two
+ * blocks in each lane
+ * @param instance Pointer to the current instance
+ * @return Zero if successful, -1 if memory failed to allocate
+ */
+void fill_memory_blocks(argon2_instance_t *instance, uint32_t pass);
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c
new file mode 100644
index 0000000000..a08acdda80
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c
@@ -0,0 +1,305 @@
+#include "argon2-encoding.h"
+#include "argon2-core.h"
+#include "utils.h"
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Example code for a decoder and encoder of "hash strings", with Argon2
+ * parameters.
+ *
+ * The code was originally written by Thomas Pornin <pornin@bolet.org>,
+ * to whom comments and remarks may be sent. It is released under what
+ * should amount to Public Domain or its closest equivalent; the
+ * following mantra is supposed to incarnate that fact with all the
+ * proper legal rituals:
+ *
+ * ---------------------------------------------------------------------
+ * This file is provided under the terms of Creative Commons CC0 1.0
+ * Public Domain Dedication. To the extent possible under law, the
+ * author (Thomas Pornin) has waived all copyright and related or
+ * neighboring rights to this file. This work is published from: Canada.
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2015 Thomas Pornin
+ */
+
+/* ==================================================================== */
+
+/*
+ * Decode decimal integer from 'str'; the value is written in '*v'.
+ * Returned value is a pointer to the next non-decimal character in the
+ * string. If there is no digit at all, or the value encoding is not
+ * minimal (extra leading zeros), or the value does not fit in an
+ * 'unsigned long', then NULL is returned.
+ */
+static const char *
+decode_decimal(const char *str, unsigned long *v)
+{
+ const char *orig;
+ unsigned long acc;
+
+ acc = 0;
+ for (orig = str;; str++) {
+ int c;
+
+ c = *str;
+ if (c < '0' || c > '9') {
+ break;
+ }
+ c -= '0';
+ if (acc > (ULONG_MAX / 10)) {
+ return NULL;
+ }
+ acc *= 10;
+ if ((unsigned long) c > (ULONG_MAX - acc)) {
+ return NULL;
+ }
+ acc += (unsigned long) c;
+ }
+ if (str == orig || (*orig == '0' && str != (orig + 1))) {
+ return NULL;
+ }
+ *v = acc;
+ return str;
+}
+
+/* ==================================================================== */
+/*
+ * Code specific to Argon2.
+ *
+ * The code below applies the following format:
+ *
+ * $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>
+ *
+ * where <T> is either 'i', <num> is a decimal integer (positive, fits in an
+ * 'unsigned long') and <bin> is Base64-encoded data (no '=' padding characters,
+ * no newline or whitespace).
+ *
+ * The last two binary chunks (encoded in Base64) are, in that order,
+ * the salt and the output. Both are required. The binary salt length and the
+ * output length must be in the allowed ranges defined in argon2.h.
+ *
+ * The ctx struct must contain buffers large enough to hold the salt and pwd
+ * when it is fed into decode_string.
+ */
+
+/*
+ * Decode an Argon2i hash string into the provided structure 'ctx'.
+ * Returned value is ARGON2_OK on success.
+ */
+int
+decode_string(argon2_context *ctx, const char *str, argon2_type type)
+{
+/* Prefix checking */
+#define CC(prefix) \
+ do { \
+ size_t cc_len = strlen(prefix); \
+ if (strncmp(str, prefix, cc_len) != 0) { \
+ return ARGON2_DECODING_FAIL; \
+ } \
+ str += cc_len; \
+ } while ((void) 0, 0)
+
+/* Optional prefix checking with supplied code */
+#define CC_opt(prefix, code) \
+ do { \
+ size_t cc_len = strlen(prefix); \
+ if (strncmp(str, prefix, cc_len) == 0) { \
+ str += cc_len; \
+ { \
+ code; \
+ } \
+ } \
+ } while ((void) 0, 0)
+
+/* Decoding prefix into decimal */
+#define DECIMAL(x) \
+ do { \
+ unsigned long dec_x; \
+ str = decode_decimal(str, &dec_x); \
+ if (str == NULL) { \
+ return ARGON2_DECODING_FAIL; \
+ } \
+ (x) = dec_x; \
+ } while ((void) 0, 0)
+
+/* Decoding prefix into uint32_t decimal */
+#define DECIMAL_U32(x) \
+ do { \
+ unsigned long dec_x; \
+ str = decode_decimal(str, &dec_x); \
+ if (str == NULL || dec_x > UINT32_MAX) { \
+ return ARGON2_DECODING_FAIL; \
+ } \
+ (x) = (uint32_t)dec_x; \
+ } while ((void)0, 0)
+
+/* Decoding base64 into a binary buffer */
+#define BIN(buf, max_len, len) \
+ do { \
+ size_t bin_len = (max_len); \
+ const char *str_end; \
+ if (sodium_base642bin((buf), (max_len), str, strlen(str), NULL, \
+ &bin_len, &str_end, \
+ sodium_base64_VARIANT_ORIGINAL_NO_PADDING) != 0 || \
+ bin_len > UINT32_MAX) { \
+ return ARGON2_DECODING_FAIL; \
+ } \
+ (len) = (uint32_t) bin_len; \
+ str = str_end; \
+ } while ((void) 0, 0)
+
+ size_t maxsaltlen = ctx->saltlen;
+ size_t maxoutlen = ctx->outlen;
+ int validation_result;
+ uint32_t version = 0;
+
+ ctx->saltlen = 0;
+ ctx->outlen = 0;
+
+ if (type == Argon2_id) {
+ CC("$argon2id");
+ } else if (type == Argon2_i) {
+ CC("$argon2i");
+ } else {
+ return ARGON2_INCORRECT_TYPE;
+ }
+ CC("$v=");
+ DECIMAL_U32(version);
+ if (version != ARGON2_VERSION_NUMBER) {
+ return ARGON2_INCORRECT_TYPE;
+ }
+ CC("$m=");
+ DECIMAL_U32(ctx->m_cost);
+ if (ctx->m_cost > UINT32_MAX) {
+ return ARGON2_INCORRECT_TYPE;
+ }
+ CC(",t=");
+ DECIMAL_U32(ctx->t_cost);
+ if (ctx->t_cost > UINT32_MAX) {
+ return ARGON2_INCORRECT_TYPE;
+ }
+ CC(",p=");
+ DECIMAL_U32(ctx->lanes);
+ if (ctx->lanes > UINT32_MAX) {
+ return ARGON2_INCORRECT_TYPE;
+ }
+ ctx->threads = ctx->lanes;
+
+ CC("$");
+ BIN(ctx->salt, maxsaltlen, ctx->saltlen);
+ CC("$");
+ BIN(ctx->out, maxoutlen, ctx->outlen);
+ validation_result = validate_inputs(ctx);
+ if (validation_result != ARGON2_OK) {
+ return validation_result;
+ }
+ if (*str == 0) {
+ return ARGON2_OK;
+ }
+ return ARGON2_DECODING_FAIL;
+
+#undef CC
+#undef CC_opt
+#undef DECIMAL
+#undef BIN
+}
+
+#define U32_STR_MAXSIZE 11U
+
+static void
+u32_to_string(char *str, uint32_t x)
+{
+ char tmp[U32_STR_MAXSIZE - 1U];
+ size_t i;
+
+ i = sizeof tmp;
+ do {
+ tmp[--i] = (x % (uint32_t) 10U) + '0';
+ x /= (uint32_t) 10U;
+ } while (x != 0U && i != 0U);
+ memcpy(str, &tmp[i], (sizeof tmp) - i);
+ str[(sizeof tmp) - i] = 0;
+}
+
+/*
+ * Encode an argon2i hash string into the provided buffer. 'dst_len'
+ * contains the size, in characters, of the 'dst' buffer; if 'dst_len'
+ * is less than the number of required characters (including the
+ * terminating 0), then this function returns 0.
+ *
+ * If pp->output_len is 0, then the hash string will be a salt string
+ * (no output). if pp->salt_len is also 0, then the string will be a
+ * parameter-only string (no salt and no output).
+ *
+ * On success, ARGON2_OK is returned.
+ */
+int
+encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type)
+{
+#define SS(str) \
+ do { \
+ size_t pp_len = strlen(str); \
+ if (pp_len >= dst_len) { \
+ return ARGON2_ENCODING_FAIL; \
+ } \
+ memcpy(dst, str, pp_len + 1); \
+ dst += pp_len; \
+ dst_len -= pp_len; \
+ } while ((void) 0, 0)
+
+#define SX(x) \
+ do { \
+ char tmp[U32_STR_MAXSIZE]; \
+ u32_to_string(tmp, x); \
+ SS(tmp); \
+ } while ((void) 0, 0)
+
+#define SB(buf, len) \
+ do { \
+ size_t sb_len; \
+ if (sodium_bin2base64(dst, dst_len, (buf), (len), \
+ sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == NULL) { \
+ return ARGON2_ENCODING_FAIL; \
+ } \
+ sb_len = strlen(dst); \
+ dst += sb_len; \
+ dst_len -= sb_len; \
+ } while ((void) 0, 0)
+
+ int validation_result;
+
+ switch (type) {
+ case Argon2_id:
+ SS("$argon2id$v="); break;
+ case Argon2_i:
+ SS("$argon2i$v="); break;
+ default:
+ return ARGON2_ENCODING_FAIL;
+ }
+ validation_result = validate_inputs(ctx);
+ if (validation_result != ARGON2_OK) {
+ return validation_result;
+ }
+ SX(ARGON2_VERSION_NUMBER);
+ SS("$m=");
+ SX(ctx->m_cost);
+ SS(",t=");
+ SX(ctx->t_cost);
+ SS(",p=");
+ SX(ctx->lanes);
+
+ SS("$");
+ SB(ctx->salt, ctx->saltlen);
+
+ SS("$");
+ SB(ctx->out, ctx->outlen);
+ return ARGON2_OK;
+
+#undef SS
+#undef SX
+#undef SB
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h
new file mode 100644
index 0000000000..e929b31dc3
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h
@@ -0,0 +1,33 @@
+#ifndef argon2_encoding_H
+#define argon2_encoding_H
+
+#include "argon2.h"
+
+/*
+ * encode an Argon2 hash string into the provided buffer. 'dst_len'
+ * contains the size, in characters, of the 'dst' buffer; if 'dst_len'
+ * is less than the number of required characters (including the
+ * terminating 0), then this function returns 0.
+ *
+ * if ctx->outlen is 0, then the hash string will be a salt string
+ * (no output). if ctx->saltlen is also 0, then the string will be a
+ * parameter-only string (no salt and no output).
+ *
+ * On success, ARGON2_OK is returned.
+ *
+ * No other parameters are checked
+ */
+int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
+ argon2_type type);
+
+/*
+ * Decodes an Argon2 hash string into the provided structure 'ctx'.
+ * The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out
+ * length values
+ * that are allowed; invalid input string causes an error
+ *
+ * Returned value is ARGON2_OK on success.
+ */
+int decode_string(argon2_context *ctx, const char *str, argon2_type type);
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c
new file mode 100644
index 0000000000..8acb42ca4d
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c
@@ -0,0 +1,239 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# pragma GCC target("avx2")
+# endif
+
+# ifdef _MSC_VER
+# include <intrin.h> /* for _mm_set_epi64x */
+# endif
+#include <emmintrin.h>
+#include <immintrin.h>
+#include <smmintrin.h>
+#include <tmmintrin.h>
+
+# include "blamka-round-avx2.h"
+
+static void
+fill_block(__m256i *state, const uint8_t *ref_block, uint8_t *next_block)
+{
+ __m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
+ block_XY[i] = state[i] = _mm256_xor_si256(
+ state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i])));
+ }
+
+ for (i = 0; i < 4; ++i) {
+ BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
+ state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 4; ++i) {
+ BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
+ state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
+ }
+
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
+ state[i] = _mm256_xor_si256(state[i], block_XY[i]);
+ _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]);
+ }
+}
+
+static void
+fill_block_with_xor(__m256i *state, const uint8_t *ref_block,
+ uint8_t *next_block)
+{
+ __m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
+ state[i] = _mm256_xor_si256(
+ state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i])));
+ block_XY[i] = _mm256_xor_si256(
+ state[i], _mm256_loadu_si256((__m256i const *) (&next_block[32 * i])));
+ }
+
+ for (i = 0; i < 4; ++i) {
+ BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
+ state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 4; ++i) {
+ BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
+ state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
+ }
+
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
+ state[i] = _mm256_xor_si256(state[i], block_XY[i]);
+ _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]);
+ }
+}
+
+static void
+generate_addresses(const argon2_instance_t *instance,
+ const argon2_position_t *position, uint64_t *pseudo_rands)
+{
+ block address_block, input_block, tmp_block;
+ uint32_t i;
+
+ init_block_value(&address_block, 0);
+ init_block_value(&input_block, 0);
+
+ if (instance != NULL && position != NULL) {
+ input_block.v[0] = position->pass;
+ input_block.v[1] = position->lane;
+ input_block.v[2] = position->slice;
+ input_block.v[3] = instance->memory_blocks;
+ input_block.v[4] = instance->passes;
+ input_block.v[5] = instance->type;
+
+ for (i = 0; i < instance->segment_length; ++i) {
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
+ /* Temporary zero-initialized blocks */
+ __m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
+ __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
+
+ memset(zero_block, 0, sizeof(zero_block));
+ memset(zero2_block, 0, sizeof(zero2_block));
+ init_block_value(&address_block, 0);
+ init_block_value(&tmp_block, 0);
+ /* Increasing index counter */
+ input_block.v[6]++;
+ /* First iteration of G */
+ fill_block_with_xor(zero_block, (uint8_t *) &input_block.v,
+ (uint8_t *) &tmp_block.v);
+ /* Second iteration of G */
+ fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v,
+ (uint8_t *) &address_block.v);
+ }
+
+ pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
+ }
+ }
+}
+
+void
+fill_segment_avx2(const argon2_instance_t *instance,
+ argon2_position_t position)
+{
+ block *ref_block = NULL, *curr_block = NULL;
+ uint64_t pseudo_rand, ref_index, ref_lane;
+ uint32_t prev_offset, curr_offset;
+ uint32_t starting_index, i;
+ __m256i state[ARGON2_HWORDS_IN_BLOCK];
+ int data_independent_addressing = 1;
+
+ /* Pseudo-random values that determine the reference block position */
+ uint64_t *pseudo_rands = NULL;
+
+ if (instance == NULL) {
+ return;
+ }
+
+ if (instance->type == Argon2_id &&
+ (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) {
+ data_independent_addressing = 0;
+ }
+
+ pseudo_rands = instance->pseudo_rands;
+
+ if (data_independent_addressing) {
+ generate_addresses(instance, &position, pseudo_rands);
+ }
+
+ starting_index = 0;
+
+ if ((0 == position.pass) && (0 == position.slice)) {
+ starting_index = 2; /* we have already generated the first two blocks */
+ }
+
+ /* Offset of the current block */
+ curr_offset = position.lane * instance->lane_length +
+ position.slice * instance->segment_length + starting_index;
+
+ if (0 == curr_offset % instance->lane_length) {
+ /* Last block in this lane */
+ prev_offset = curr_offset + instance->lane_length - 1;
+ } else {
+ /* Previous block */
+ prev_offset = curr_offset - 1;
+ }
+
+ memcpy(state, ((instance->region->memory + prev_offset)->v),
+ ARGON2_BLOCK_SIZE);
+
+ for (i = starting_index; i < instance->segment_length;
+ ++i, ++curr_offset, ++prev_offset) {
+ /*1.1 Rotating prev_offset if needed */
+ if (curr_offset % instance->lane_length == 1) {
+ prev_offset = curr_offset - 1;
+ }
+
+ /* 1.2 Computing the index of the reference block */
+ /* 1.2.1 Taking pseudo-random value from the previous block */
+ if (data_independent_addressing) {
+#pragma warning(push)
+#pragma warning(disable : 6385)
+ pseudo_rand = pseudo_rands[i];
+#pragma warning(pop)
+ } else {
+ pseudo_rand = instance->region->memory[prev_offset].v[0];
+ }
+
+ /* 1.2.2 Computing the lane of the reference block */
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
+
+ if ((position.pass == 0) && (position.slice == 0)) {
+ /* Can not reference other lanes yet */
+ ref_lane = position.lane;
+ }
+
+ /* 1.2.3 Computing the number of possible reference block within the
+ * lane.
+ */
+ position.index = i;
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
+ ref_lane == position.lane);
+
+ /* 2 Creating a new block */
+ ref_block = instance->region->memory +
+ instance->lane_length * ref_lane + ref_index;
+ curr_block = instance->region->memory + curr_offset;
+ if (position.pass != 0) {
+ fill_block_with_xor(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ } else {
+ fill_block(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ }
+ }
+}
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c
new file mode 100644
index 0000000000..1f1ec8b3b4
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c
@@ -0,0 +1,244 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \
+ defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# pragma GCC target("avx2")
+# pragma GCC target("avx512f")
+# endif
+
+# ifdef _MSC_VER
+# include <intrin.h> /* for _mm_set_epi64x */
+# endif
+#include <emmintrin.h>
+#include <immintrin.h>
+#include <smmintrin.h>
+#include <tmmintrin.h>
+
+# include "blamka-round-avx512f.h"
+
+static void
+fill_block(__m512i *state, const uint8_t *ref_block, uint8_t *next_block)
+{
+ __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
+ block_XY[i] = state[i] = _mm512_xor_si512(
+ state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i])));
+ }
+
+ for (i = 0; i < 2; ++i) {
+ BLAKE2_ROUND_1(
+ state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3],
+ state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 2; ++i) {
+ BLAKE2_ROUND_2(
+ state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i],
+ state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]);
+ }
+
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
+ state[i] = _mm512_xor_si512(state[i], block_XY[i]);
+ _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]);
+ }
+}
+
+static void
+fill_block_with_xor(__m512i *state, const uint8_t *ref_block,
+ uint8_t *next_block)
+{
+ __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
+ state[i] = _mm512_xor_si512(
+ state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i])));
+ block_XY[i] = _mm512_xor_si512(
+ state[i], _mm512_loadu_si512((__m512i const *) (&next_block[64 * i])));
+ }
+
+ for (i = 0; i < 2; ++i) {
+ BLAKE2_ROUND_1(
+ state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3],
+ state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 2; ++i) {
+ BLAKE2_ROUND_2(
+ state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i],
+ state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]);
+ }
+
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
+ state[i] = _mm512_xor_si512(state[i], block_XY[i]);
+ _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]);
+ }
+}
+
+static void
+generate_addresses(const argon2_instance_t *instance,
+ const argon2_position_t *position, uint64_t *pseudo_rands)
+{
+ block address_block, input_block, tmp_block;
+ uint32_t i;
+
+ init_block_value(&address_block, 0);
+ init_block_value(&input_block, 0);
+
+ if (instance != NULL && position != NULL) {
+ input_block.v[0] = position->pass;
+ input_block.v[1] = position->lane;
+ input_block.v[2] = position->slice;
+ input_block.v[3] = instance->memory_blocks;
+ input_block.v[4] = instance->passes;
+ input_block.v[5] = instance->type;
+
+ for (i = 0; i < instance->segment_length; ++i) {
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
+ /* Temporary zero-initialized blocks */
+ __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK];
+ __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK];
+
+ memset(zero_block, 0, sizeof(zero_block));
+ memset(zero2_block, 0, sizeof(zero2_block));
+ init_block_value(&address_block, 0);
+ init_block_value(&tmp_block, 0);
+ /* Increasing index counter */
+ input_block.v[6]++;
+ /* First iteration of G */
+ fill_block_with_xor(zero_block, (uint8_t *) &input_block.v,
+ (uint8_t *) &tmp_block.v);
+ /* Second iteration of G */
+ fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v,
+ (uint8_t *) &address_block.v);
+ }
+
+ pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
+ }
+ }
+}
+
+void
+fill_segment_avx512f(const argon2_instance_t *instance,
+ argon2_position_t position)
+{
+ block *ref_block = NULL, *curr_block = NULL;
+ uint64_t pseudo_rand, ref_index, ref_lane;
+ uint32_t prev_offset, curr_offset;
+ uint32_t starting_index, i;
+ __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK];
+ int data_independent_addressing = 1;
+
+ /* Pseudo-random values that determine the reference block position */
+ uint64_t *pseudo_rands = NULL;
+
+ if (instance == NULL) {
+ return;
+ }
+
+ if (instance->type == Argon2_id &&
+ (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) {
+ data_independent_addressing = 0;
+ }
+
+ pseudo_rands = instance->pseudo_rands;
+
+ if (data_independent_addressing) {
+ generate_addresses(instance, &position, pseudo_rands);
+ }
+
+ starting_index = 0;
+
+ if ((0 == position.pass) && (0 == position.slice)) {
+ starting_index = 2; /* we have already generated the first two blocks */
+ }
+
+ /* Offset of the current block */
+ curr_offset = position.lane * instance->lane_length +
+ position.slice * instance->segment_length + starting_index;
+
+ if (0 == curr_offset % instance->lane_length) {
+ /* Last block in this lane */
+ prev_offset = curr_offset + instance->lane_length - 1;
+ } else {
+ /* Previous block */
+ prev_offset = curr_offset - 1;
+ }
+
+ memcpy(state, ((instance->region->memory + prev_offset)->v),
+ ARGON2_BLOCK_SIZE);
+
+ for (i = starting_index; i < instance->segment_length;
+ ++i, ++curr_offset, ++prev_offset) {
+ /*1.1 Rotating prev_offset if needed */
+ if (curr_offset % instance->lane_length == 1) {
+ prev_offset = curr_offset - 1;
+ }
+
+ /* 1.2 Computing the index of the reference block */
+ /* 1.2.1 Taking pseudo-random value from the previous block */
+ if (data_independent_addressing) {
+#pragma warning(push)
+#pragma warning(disable : 6385)
+ pseudo_rand = pseudo_rands[i];
+#pragma warning(pop)
+ } else {
+ pseudo_rand = instance->region->memory[prev_offset].v[0];
+ }
+
+ /* 1.2.2 Computing the lane of the reference block */
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
+
+ if ((position.pass == 0) && (position.slice == 0)) {
+ /* Can not reference other lanes yet */
+ ref_lane = position.lane;
+ }
+
+ /* 1.2.3 Computing the number of possible reference block within the
+ * lane.
+ */
+ position.index = i;
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
+ ref_lane == position.lane);
+
+ /* 2 Creating a new block */
+ ref_block = instance->region->memory +
+ instance->lane_length * ref_lane + ref_index;
+ curr_block = instance->region->memory + curr_offset;
+ if (position.pass != 0) {
+ fill_block_with_xor(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ } else {
+ fill_block(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ }
+ }
+}
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c
new file mode 100644
index 0000000000..75e8d8f5ea
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c
@@ -0,0 +1,233 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2.h"
+#include "blamka-round-ref.h"
+#include "private/common.h"
+
+static void
+fill_block(const block *prev_block, const block *ref_block, block *next_block)
+{
+ block blockR, block_tmp;
+ unsigned i;
+
+ copy_block(&blockR, ref_block);
+ xor_block(&blockR, prev_block);
+ copy_block(&block_tmp, &blockR);
+ /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block
+ Apply Blake2 on columns of 64-bit words: (0,1,...,15), then
+ (16,17,..31)... finally (112,113,...127) */
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND_NOMSG(
+ blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
+ blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
+ blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
+ blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
+ blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
+ blockR.v[16 * i + 15]);
+ }
+
+ /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
+ (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
+ for (i = 0; i < 8; i++) {
+ BLAKE2_ROUND_NOMSG(
+ blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
+ blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
+ blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
+ blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
+ blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
+ blockR.v[2 * i + 113]);
+ }
+
+ copy_block(next_block, &block_tmp);
+ xor_block(next_block, &blockR);
+}
+
+static void
+fill_block_with_xor(const block *prev_block, const block *ref_block,
+ block *next_block)
+{
+ block blockR, block_tmp;
+ unsigned i;
+
+ copy_block(&blockR, ref_block);
+ xor_block(&blockR, prev_block);
+ copy_block(&block_tmp, &blockR);
+ xor_block(&block_tmp,
+ next_block); /* Saving the next block contents for XOR over */
+ /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block
+ * + next_block */
+ /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
+ (16,17,..31)... finally (112,113,...127) */
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND_NOMSG(
+ blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
+ blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
+ blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
+ blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
+ blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
+ blockR.v[16 * i + 15]);
+ }
+
+ /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
+ (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
+ for (i = 0; i < 8; i++) {
+ BLAKE2_ROUND_NOMSG(
+ blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
+ blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
+ blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
+ blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
+ blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
+ blockR.v[2 * i + 113]);
+ }
+
+ copy_block(next_block, &block_tmp);
+ xor_block(next_block, &blockR);
+}
+
+/*
+ * Generate pseudo-random values to reference blocks in the segment and puts
+ * them into the array
+ * @param instance Pointer to the current instance
+ * @param position Pointer to the current position
+ * @param pseudo_rands Pointer to the array of 64-bit values
+ * @pre pseudo_rands must point to @a instance->segment_length allocated values
+ */
+static void
+generate_addresses(const argon2_instance_t *instance,
+ const argon2_position_t *position, uint64_t *pseudo_rands)
+{
+ block zero_block, input_block, address_block, tmp_block;
+ uint32_t i;
+
+ init_block_value(&zero_block, 0);
+ init_block_value(&input_block, 0);
+
+ if (instance != NULL && position != NULL) {
+ input_block.v[0] = position->pass;
+ input_block.v[1] = position->lane;
+ input_block.v[2] = position->slice;
+ input_block.v[3] = instance->memory_blocks;
+ input_block.v[4] = instance->passes;
+ input_block.v[5] = instance->type;
+
+ for (i = 0; i < instance->segment_length; ++i) {
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
+ input_block.v[6]++;
+ init_block_value(&tmp_block, 0);
+ init_block_value(&address_block, 0);
+ fill_block_with_xor(&zero_block, &input_block, &tmp_block);
+ fill_block_with_xor(&zero_block, &tmp_block, &address_block);
+ }
+
+ pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
+ }
+ }
+}
+
+void
+fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position)
+{
+ block *ref_block = NULL, *curr_block = NULL;
+ /* Pseudo-random values that determine the reference block position */
+ uint64_t *pseudo_rands = NULL;
+ uint64_t pseudo_rand, ref_index, ref_lane;
+ uint32_t prev_offset, curr_offset;
+ uint32_t starting_index;
+ uint32_t i;
+ int data_independent_addressing = 1;
+
+ if (instance == NULL) {
+ return;
+ }
+
+ if (instance->type == Argon2_id &&
+ (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) {
+ data_independent_addressing = 0;
+ }
+
+ pseudo_rands = instance->pseudo_rands;
+
+ if (data_independent_addressing) {
+ generate_addresses(instance, &position, pseudo_rands);
+ }
+
+ starting_index = 0;
+
+ if ((0 == position.pass) && (0 == position.slice)) {
+ starting_index = 2; /* we have already generated the first two blocks */
+ }
+
+ /* Offset of the current block */
+ curr_offset = position.lane * instance->lane_length +
+ position.slice * instance->segment_length + starting_index;
+
+ if (0 == curr_offset % instance->lane_length) {
+ /* Last block in this lane */
+ prev_offset = curr_offset + instance->lane_length - 1;
+ } else {
+ /* Previous block */
+ prev_offset = curr_offset - 1;
+ }
+
+ for (i = starting_index; i < instance->segment_length;
+ ++i, ++curr_offset, ++prev_offset) {
+ /*1.1 Rotating prev_offset if needed */
+ if (curr_offset % instance->lane_length == 1) {
+ prev_offset = curr_offset - 1;
+ }
+
+ /* 1.2 Computing the index of the reference block */
+ /* 1.2.1 Taking pseudo-random value from the previous block */
+ if (data_independent_addressing) {
+#pragma warning(push)
+#pragma warning(disable : 6385)
+ pseudo_rand = pseudo_rands[i];
+#pragma warning(pop)
+ } else {
+ pseudo_rand = instance->region->memory[prev_offset].v[0];
+ }
+
+ /* 1.2.2 Computing the lane of the reference block */
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
+
+ if ((position.pass == 0) && (position.slice == 0)) {
+ /* Can not reference other lanes yet */
+ ref_lane = position.lane;
+ }
+
+ /* 1.2.3 Computing the number of possible reference block within the
+ * lane.
+ */
+ position.index = i;
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
+ ref_lane == position.lane);
+
+ /* 2 Creating a new block */
+ ref_block = instance->region->memory +
+ instance->lane_length * ref_lane + ref_index;
+ curr_block = instance->region->memory + curr_offset;
+ if (position.pass != 0) {
+ fill_block_with_xor(instance->region->memory + prev_offset,
+ ref_block, curr_block);
+ } else {
+ fill_block(instance->region->memory + prev_offset, ref_block,
+ curr_block);
+ }
+ }
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c
new file mode 100644
index 0000000000..796c445560
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c
@@ -0,0 +1,238 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# endif
+
+# ifdef _MSC_VER
+# include <intrin.h> /* for _mm_set_epi64x */
+# endif
+# include <emmintrin.h>
+# include <tmmintrin.h>
+
+# include "blamka-round-ssse3.h"
+
+static void
+fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block)
+{
+ __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
+ block_XY[i] = state[i] = _mm_xor_si128(
+ state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i])));
+ }
+
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
+ state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
+ state[8 * i + 6], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
+ state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
+ state[8 * 6 + i], state[8 * 7 + i]);
+ }
+
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
+ state[i] = _mm_xor_si128(state[i], block_XY[i]);
+ _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]);
+ }
+}
+
+static void
+fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
+ uint8_t *next_block)
+{
+ __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
+ uint32_t i;
+
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
+ state[i] = _mm_xor_si128(
+ state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i])));
+ block_XY[i] = _mm_xor_si128(
+ state[i], _mm_loadu_si128((__m128i const *) (&next_block[16 * i])));
+ }
+
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
+ state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
+ state[8 * i + 6], state[8 * i + 7]);
+ }
+
+ for (i = 0; i < 8; ++i) {
+ BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
+ state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
+ state[8 * 6 + i], state[8 * 7 + i]);
+ }
+
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
+ state[i] = _mm_xor_si128(state[i], block_XY[i]);
+ _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]);
+ }
+}
+
+static void
+generate_addresses(const argon2_instance_t *instance,
+ const argon2_position_t *position, uint64_t *pseudo_rands)
+{
+ block address_block, input_block, tmp_block;
+ uint32_t i;
+
+ init_block_value(&address_block, 0);
+ init_block_value(&input_block, 0);
+
+ if (instance != NULL && position != NULL) {
+ input_block.v[0] = position->pass;
+ input_block.v[1] = position->lane;
+ input_block.v[2] = position->slice;
+ input_block.v[3] = instance->memory_blocks;
+ input_block.v[4] = instance->passes;
+ input_block.v[5] = instance->type;
+
+ for (i = 0; i < instance->segment_length; ++i) {
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
+ /* Temporary zero-initialized blocks */
+ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
+ __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
+
+ memset(zero_block, 0, sizeof(zero_block));
+ memset(zero2_block, 0, sizeof(zero2_block));
+ init_block_value(&address_block, 0);
+ init_block_value(&tmp_block, 0);
+ /* Increasing index counter */
+ input_block.v[6]++;
+ /* First iteration of G */
+ fill_block_with_xor(zero_block, (uint8_t *) &input_block.v,
+ (uint8_t *) &tmp_block.v);
+ /* Second iteration of G */
+ fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v,
+ (uint8_t *) &address_block.v);
+ }
+
+ pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
+ }
+ }
+}
+
+void
+fill_segment_ssse3(const argon2_instance_t *instance,
+ argon2_position_t position)
+{
+ block *ref_block = NULL, *curr_block = NULL;
+ uint64_t pseudo_rand, ref_index, ref_lane;
+ uint32_t prev_offset, curr_offset;
+ uint32_t starting_index, i;
+ __m128i state[ARGON2_OWORDS_IN_BLOCK];
+ int data_independent_addressing = 1;
+
+ /* Pseudo-random values that determine the reference block position */
+ uint64_t *pseudo_rands = NULL;
+
+ if (instance == NULL) {
+ return;
+ }
+
+ if (instance->type == Argon2_id &&
+ (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) {
+ data_independent_addressing = 0;
+ }
+
+ pseudo_rands = instance->pseudo_rands;
+
+ if (data_independent_addressing) {
+ generate_addresses(instance, &position, pseudo_rands);
+ }
+
+ starting_index = 0;
+
+ if ((0 == position.pass) && (0 == position.slice)) {
+ starting_index = 2; /* we have already generated the first two blocks */
+ }
+
+ /* Offset of the current block */
+ curr_offset = position.lane * instance->lane_length +
+ position.slice * instance->segment_length + starting_index;
+
+ if (0 == curr_offset % instance->lane_length) {
+ /* Last block in this lane */
+ prev_offset = curr_offset + instance->lane_length - 1;
+ } else {
+ /* Previous block */
+ prev_offset = curr_offset - 1;
+ }
+
+ memcpy(state, ((instance->region->memory + prev_offset)->v),
+ ARGON2_BLOCK_SIZE);
+
+ for (i = starting_index; i < instance->segment_length;
+ ++i, ++curr_offset, ++prev_offset) {
+ /*1.1 Rotating prev_offset if needed */
+ if (curr_offset % instance->lane_length == 1) {
+ prev_offset = curr_offset - 1;
+ }
+
+ /* 1.2 Computing the index of the reference block */
+ /* 1.2.1 Taking pseudo-random value from the previous block */
+ if (data_independent_addressing) {
+#pragma warning(push)
+#pragma warning(disable : 6385)
+ pseudo_rand = pseudo_rands[i];
+#pragma warning(pop)
+ } else {
+ pseudo_rand = instance->region->memory[prev_offset].v[0];
+ }
+
+ /* 1.2.2 Computing the lane of the reference block */
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
+
+ if ((position.pass == 0) && (position.slice == 0)) {
+ /* Can not reference other lanes yet */
+ ref_lane = position.lane;
+ }
+
+ /* 1.2.3 Computing the number of possible reference block within the
+ * lane.
+ */
+ position.index = i;
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
+ ref_lane == position.lane);
+
+ /* 2 Creating a new block */
+ ref_block = instance->region->memory +
+ instance->lane_length * ref_lane + ref_index;
+ curr_block = instance->region->memory + curr_offset;
+ if (position.pass != 0) {
+ fill_block_with_xor(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ } else {
+ fill_block(state, (uint8_t *) ref_block->v,
+ (uint8_t *) curr_block->v);
+ }
+ }
+}
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c
new file mode 100644
index 0000000000..ac1628c991
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c
@@ -0,0 +1,277 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with
+ * this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+
+#include "argon2-core.h"
+#include "argon2-encoding.h"
+#include "argon2.h"
+
+int
+argon2_ctx(argon2_context *context, argon2_type type)
+{
+ /* 1. Validate all inputs */
+ int result = validate_inputs(context);
+ uint32_t memory_blocks, segment_length;
+ uint32_t pass;
+ argon2_instance_t instance;
+
+ if (ARGON2_OK != result) {
+ return result;
+ }
+
+ if (type != Argon2_id && type != Argon2_i) {
+ return ARGON2_INCORRECT_TYPE;
+ }
+
+ /* 2. Align memory size */
+ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
+ memory_blocks = context->m_cost;
+
+ if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
+ memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
+ }
+
+ segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
+ /* Ensure that all segments have equal length */
+ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
+
+ instance.region = NULL;
+ instance.passes = context->t_cost;
+ instance.current_pass = ~ 0U;
+ instance.memory_blocks = memory_blocks;
+ instance.segment_length = segment_length;
+ instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
+ instance.lanes = context->lanes;
+ instance.threads = context->threads;
+ instance.type = type;
+
+ /* 3. Initialization: Hashing inputs, allocating memory, filling first
+ * blocks
+ */
+ result = initialize(&instance, context);
+
+ if (ARGON2_OK != result) {
+ return result;
+ }
+
+ /* 4. Filling memory */
+ for (pass = 0; pass < instance.passes; pass++) {
+ fill_memory_blocks(&instance, pass);
+ }
+
+ /* 5. Finalization */
+ finalize(context, &instance);
+
+ return ARGON2_OK;
+}
+
+int
+argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd, const size_t pwdlen,
+ const void *salt, const size_t saltlen, void *hash,
+ const size_t hashlen, char *encoded, const size_t encodedlen,
+ argon2_type type)
+{
+ argon2_context context;
+ int result;
+ uint8_t *out;
+
+ if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
+ return ARGON2_PWD_TOO_LONG;
+ }
+
+ if (hashlen > ARGON2_MAX_OUTLEN) {
+ return ARGON2_OUTPUT_TOO_LONG;
+ }
+
+ if (saltlen > ARGON2_MAX_SALT_LENGTH) {
+ return ARGON2_SALT_TOO_LONG;
+ }
+
+ out = (uint8_t *) malloc(hashlen);
+ if (!out) {
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
+ }
+
+ context.out = (uint8_t *) out;
+ context.outlen = (uint32_t) hashlen;
+ context.pwd = (uint8_t *) pwd;
+ context.pwdlen = (uint32_t) pwdlen;
+ context.salt = (uint8_t *) salt;
+ context.saltlen = (uint32_t) saltlen;
+ context.secret = NULL;
+ context.secretlen = 0;
+ context.ad = NULL;
+ context.adlen = 0;
+ context.t_cost = t_cost;
+ context.m_cost = m_cost;
+ context.lanes = parallelism;
+ context.threads = parallelism;
+ context.flags = ARGON2_DEFAULT_FLAGS;
+
+ result = argon2_ctx(&context, type);
+
+ if (result != ARGON2_OK) {
+ sodium_memzero(out, hashlen);
+ free(out);
+ return result;
+ }
+
+ /* if raw hash requested, write it */
+ if (hash) {
+ memcpy(hash, out, hashlen);
+ }
+
+ /* if encoding requested, write it */
+ if (encoded && encodedlen) {
+ if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
+ sodium_memzero(out, hashlen);
+ sodium_memzero(encoded, encodedlen);
+ free(out);
+ return ARGON2_ENCODING_FAIL;
+ }
+ }
+
+ sodium_memzero(out, hashlen);
+ free(out);
+
+ return ARGON2_OK;
+}
+
+int
+argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, const size_t hashlen, char *encoded,
+ const size_t encodedlen)
+{
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+ NULL, hashlen, encoded, encodedlen, Argon2_i);
+}
+
+int
+argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt, const size_t saltlen,
+ void *hash, const size_t hashlen)
+{
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+ hash, hashlen, NULL, 0, Argon2_i);
+}
+
+int
+argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, const size_t hashlen, char *encoded,
+ const size_t encodedlen)
+{
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+ NULL, hashlen, encoded, encodedlen, Argon2_id);
+}
+
+int
+argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt, const size_t saltlen,
+ void *hash, const size_t hashlen)
+{
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+ hash, hashlen, NULL, 0, Argon2_id);
+}
+
+int
+argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
+ argon2_type type)
+{
+ argon2_context ctx;
+ uint8_t *out;
+ int decode_result;
+ int ret;
+ size_t encoded_len;
+
+ memset(&ctx, 0, sizeof ctx);
+
+ ctx.pwd = NULL;
+ ctx.pwdlen = 0;
+ ctx.secret = NULL;
+ ctx.secretlen = 0;
+
+ /* max values, to be updated in decode_string */
+ encoded_len = strlen(encoded);
+ if (encoded_len > UINT32_MAX) {
+ return ARGON2_DECODING_LENGTH_FAIL;
+ }
+ ctx.adlen = (uint32_t) encoded_len;
+ ctx.saltlen = (uint32_t) encoded_len;
+ ctx.outlen = (uint32_t) encoded_len;
+
+ ctx.ad = (uint8_t *) malloc(ctx.adlen);
+ ctx.salt = (uint8_t *) malloc(ctx.saltlen);
+ ctx.out = (uint8_t *) malloc(ctx.outlen);
+ if (!ctx.out || !ctx.salt || !ctx.ad) {
+ free(ctx.ad);
+ free(ctx.salt);
+ free(ctx.out);
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
+ }
+ out = (uint8_t *) malloc(ctx.outlen);
+ if (!out) {
+ free(ctx.ad);
+ free(ctx.salt);
+ free(ctx.out);
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
+ }
+
+ decode_result = decode_string(&ctx, encoded, type);
+ if (decode_result != ARGON2_OK) {
+ free(ctx.ad);
+ free(ctx.salt);
+ free(ctx.out);
+ free(out);
+ return decode_result;
+ }
+
+ ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen,
+ ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type);
+
+ free(ctx.ad);
+ free(ctx.salt);
+
+ if (ret != ARGON2_OK || sodium_memcmp(out, ctx.out, ctx.outlen) != 0) {
+ ret = ARGON2_VERIFY_MISMATCH;
+ }
+ free(out);
+ free(ctx.out);
+
+ return ret;
+}
+
+int
+argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen)
+{
+ return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
+}
+
+int
+argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen)
+{
+ return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h
new file mode 100644
index 0000000000..85ca4dd373
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h
@@ -0,0 +1,305 @@
+/*
+ * Argon2 source code package
+ *
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ *
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+#ifndef argon2_H
+#define argon2_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * Argon2 input parameter restrictions
+ */
+
+/* Minimum and maximum number of lanes (degree of parallelism) */
+#define ARGON2_MIN_LANES UINT32_C(1)
+#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
+
+/* Minimum and maximum number of threads */
+#define ARGON2_MIN_THREADS UINT32_C(1)
+#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
+
+/* Number of synchronization points between lanes per pass */
+#define ARGON2_SYNC_POINTS UINT32_C(4)
+
+/* Minimum and maximum digest size in bytes */
+#define ARGON2_MIN_OUTLEN UINT32_C(16)
+#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
+
+/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
+#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
+
+#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
+/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB)
+ */
+#define ARGON2_MAX_MEMORY_BITS \
+ ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
+#define ARGON2_MAX_MEMORY \
+ ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
+
+/* Minimum and maximum number of passes */
+#define ARGON2_MIN_TIME UINT32_C(1)
+#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
+
+/* Minimum and maximum password length in bytes */
+#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
+#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
+
+/* Minimum and maximum associated data length in bytes */
+#define ARGON2_MIN_AD_LENGTH UINT32_C(0)
+#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
+
+/* Minimum and maximum salt length in bytes */
+#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
+#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
+
+/* Minimum and maximum key length in bytes */
+#define ARGON2_MIN_SECRET UINT32_C(0)
+#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
+
+#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
+#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
+#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)
+#define ARGON2_DEFAULT_FLAGS (UINT32_C(0))
+
+/* Error codes */
+typedef enum Argon2_ErrorCodes {
+ ARGON2_OK = 0,
+
+ ARGON2_OUTPUT_PTR_NULL = -1,
+
+ ARGON2_OUTPUT_TOO_SHORT = -2,
+ ARGON2_OUTPUT_TOO_LONG = -3,
+
+ ARGON2_PWD_TOO_SHORT = -4,
+ ARGON2_PWD_TOO_LONG = -5,
+
+ ARGON2_SALT_TOO_SHORT = -6,
+ ARGON2_SALT_TOO_LONG = -7,
+
+ ARGON2_AD_TOO_SHORT = -8,
+ ARGON2_AD_TOO_LONG = -9,
+
+ ARGON2_SECRET_TOO_SHORT = -10,
+ ARGON2_SECRET_TOO_LONG = -11,
+
+ ARGON2_TIME_TOO_SMALL = -12,
+ ARGON2_TIME_TOO_LARGE = -13,
+
+ ARGON2_MEMORY_TOO_LITTLE = -14,
+ ARGON2_MEMORY_TOO_MUCH = -15,
+
+ ARGON2_LANES_TOO_FEW = -16,
+ ARGON2_LANES_TOO_MANY = -17,
+
+ ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
+ ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
+ ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
+ ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
+
+ ARGON2_MEMORY_ALLOCATION_ERROR = -22,
+
+ ARGON2_FREE_MEMORY_CBK_NULL = -23,
+ ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
+
+ ARGON2_INCORRECT_PARAMETER = -25,
+ ARGON2_INCORRECT_TYPE = -26,
+
+ ARGON2_OUT_PTR_MISMATCH = -27,
+
+ ARGON2_THREADS_TOO_FEW = -28,
+ ARGON2_THREADS_TOO_MANY = -29,
+
+ ARGON2_MISSING_ARGS = -30,
+
+ ARGON2_ENCODING_FAIL = -31,
+
+ ARGON2_DECODING_FAIL = -32,
+
+ ARGON2_THREAD_FAIL = -33,
+
+ ARGON2_DECODING_LENGTH_FAIL = -34,
+
+ ARGON2_VERIFY_MISMATCH = -35
+} argon2_error_codes;
+
+/* Argon2 external data structures */
+
+/*
+ * Context: structure to hold Argon2 inputs:
+ * output array and its length,
+ * password and its length,
+ * salt and its length,
+ * secret and its length,
+ * associated data and its length,
+ * number of passes, amount of used memory (in KBytes, can be rounded up a bit)
+ * number of parallel threads that will be run.
+ * All the parameters above affect the output hash value.
+ * Additionally, two function pointers can be provided to allocate and
+ * deallocate the memory (if NULL, memory will be allocated internally).
+ * Also, three flags indicate whether to erase password, secret as soon as they
+ * are pre-hashed (and thus not needed anymore), and the entire memory
+ *****
+ * Simplest situation: you have output array out[8], password is stored in
+ * pwd[32], salt is stored in salt[16], you do not have keys nor associated
+ *data.
+ * You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel
+ *lanes.
+ * You want to erase the password, but you're OK with last pass not being
+ *erased.
+ * You want to use the default memory allocator.
+ * Then you initialize:
+ * Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false).
+ */
+typedef struct Argon2_Context {
+ uint8_t *out; /* output array */
+ uint32_t outlen; /* digest length */
+
+ uint8_t *pwd; /* password array */
+ uint32_t pwdlen; /* password length */
+
+ uint8_t *salt; /* salt array */
+ uint32_t saltlen; /* salt length */
+
+ uint8_t *secret; /* key array */
+ uint32_t secretlen; /* key length */
+
+ uint8_t *ad; /* associated data array */
+ uint32_t adlen; /* associated data length */
+
+ uint32_t t_cost; /* number of passes */
+ uint32_t m_cost; /* amount of memory requested (KB) */
+ uint32_t lanes; /* number of lanes */
+ uint32_t threads; /* maximum number of threads */
+
+ uint32_t flags; /* array of bool options */
+} argon2_context;
+
+/* Argon2 primitive type */
+typedef enum Argon2_type { Argon2_i = 1, Argon2_id = 2 } argon2_type;
+
+/*
+ * Function that performs memory-hard hashing with certain degree of parallelism
+ * @param context Pointer to the Argon2 internal structure
+ * @return Error code if smth is wrong, ARGON2_OK otherwise
+ */
+int argon2_ctx(argon2_context *context, argon2_type type);
+
+/**
+ * Hashes a password with Argon2i, producing an encoded hash
+ * @param t_cost Number of iterations
+ * @param m_cost Sets memory usage to m_cost kibibytes
+ * @param parallelism Number of threads and compute lanes
+ * @param pwd Pointer to password
+ * @param pwdlen Password size in bytes
+ * @param salt Pointer to salt
+ * @param saltlen Salt size in bytes
+ * @param hashlen Desired length of the hash in bytes
+ * @param encoded Buffer where to write the encoded hash
+ * @param encodedlen Size of the buffer (thus max size of the encoded hash)
+ * @pre Different parallelism levels will give different results
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, const size_t hashlen,
+ char *encoded, const size_t encodedlen);
+
+/**
+ * Hashes a password with Argon2id, producing an encoded hash
+ * @param t_cost Number of iterations
+ * @param m_cost Sets memory usage to m_cost kibibytes
+ * @param parallelism Number of threads and compute lanes
+ * @param pwd Pointer to password
+ * @param pwdlen Password size in bytes
+ * @param salt Pointer to salt
+ * @param saltlen Salt size in bytes
+ * @param hashlen Desired length of the hash in bytes
+ * @param encoded Buffer where to write the encoded hash
+ * @param encodedlen Size of the buffer (thus max size of the encoded hash)
+ * @pre Different parallelism levels will give different results
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, const size_t hashlen,
+ char *encoded, const size_t encodedlen);
+
+/**
+ * Hashes a password with Argon2i, producing a raw hash
+ * @param t_cost Number of iterations
+ * @param m_cost Sets memory usage to m_cost kibibytes
+ * @param parallelism Number of threads and compute lanes
+ * @param pwd Pointer to password
+ * @param pwdlen Password size in bytes
+ * @param salt Pointer to salt
+ * @param saltlen Salt size in bytes
+ * @param hash Buffer where to write the raw hash
+ * @param hashlen Desired length of the hash in bytes
+ * @pre Different parallelism levels will give different results
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, void *hash, const size_t hashlen);
+
+/**
+ * Hashes a password with Argon2id, producing a raw hash
+ * @param t_cost Number of iterations
+ * @param m_cost Sets memory usage to m_cost kibibytes
+ * @param parallelism Number of threads and compute lanes
+ * @param pwd Pointer to password
+ * @param pwdlen Password size in bytes
+ * @param salt Pointer to salt
+ * @param saltlen Salt size in bytes
+ * @param hash Buffer where to write the raw hash
+ * @param hashlen Desired length of the hash in bytes
+ * @pre Different parallelism levels will give different results
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt,
+ const size_t saltlen, void *hash, const size_t hashlen);
+
+/* generic function underlying the above ones */
+int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
+ const uint32_t parallelism, const void *pwd,
+ const size_t pwdlen, const void *salt, const size_t saltlen,
+ void *hash, const size_t hashlen, char *encoded,
+ const size_t encodedlen, argon2_type type);
+
+/**
+ * Verifies a password against an encoded string
+ * Encoded string is restricted as in validate_inputs()
+ * @param encoded String encoding parameters, salt, hash
+ * @param pwd Pointer to password
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen);
+
+/**
+ * Verifies a password against an encoded string
+ * Encoded string is restricted as in validate_inputs()
+ * @param encoded String encoding parameters, salt, hash
+ * @param pwd Pointer to password
+ * @pre Returns ARGON2_OK if successful
+ */
+int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen);
+
+/* generic function underlying the above ones */
+int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
+ argon2_type type);
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c
new file mode 100644
index 0000000000..f0364aca87
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c
@@ -0,0 +1,79 @@
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_generichash_blake2b.h"
+#include "private/common.h"
+#include "utils.h"
+
+#include "blake2b-long.h"
+
+int
+blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen)
+{
+ uint8_t *out = (uint8_t *) pout;
+ crypto_generichash_blake2b_state blake_state;
+ uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 };
+ int ret = -1;
+
+ if (outlen > UINT32_MAX) {
+ goto fail; /* LCOV_EXCL_LINE */
+ }
+
+ /* Ensure little-endian byte order! */
+ STORE32_LE(outlen_bytes, (uint32_t) outlen);
+
+#define TRY(statement) \
+ do { \
+ ret = statement; \
+ if (ret < 0) { \
+ goto fail; \
+ } \
+ } while ((void) 0, 0)
+
+ if (outlen <= crypto_generichash_blake2b_BYTES_MAX) {
+ TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen));
+ TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
+ sizeof(outlen_bytes)));
+ TRY(crypto_generichash_blake2b_update(
+ &blake_state, (const unsigned char *) in, inlen));
+ TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen));
+ } else {
+ uint32_t toproduce;
+ uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX];
+ uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX];
+ TRY(crypto_generichash_blake2b_init(
+ &blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX));
+ TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
+ sizeof(outlen_bytes)));
+ TRY(crypto_generichash_blake2b_update(
+ &blake_state, (const unsigned char *) in, inlen));
+ TRY(crypto_generichash_blake2b_final(
+ &blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX));
+ memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
+ out += crypto_generichash_blake2b_BYTES_MAX / 2;
+ toproduce =
+ (uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2;
+
+ while (toproduce > crypto_generichash_blake2b_BYTES_MAX) {
+ memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
+ TRY(crypto_generichash_blake2b(
+ out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer,
+ crypto_generichash_blake2b_BYTES_MAX, NULL, 0U));
+ memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
+ out += crypto_generichash_blake2b_BYTES_MAX / 2;
+ toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2;
+ }
+
+ memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
+ TRY(crypto_generichash_blake2b(out_buffer, toproduce, in_buffer,
+ crypto_generichash_blake2b_BYTES_MAX,
+ NULL, 0U));
+ memcpy(out, out_buffer, toproduce);
+ }
+fail:
+ sodium_memzero(&blake_state, sizeof(blake_state));
+ return ret;
+#undef TRY
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h
new file mode 100644
index 0000000000..3d6d775521
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h
@@ -0,0 +1,8 @@
+#ifndef blake2b_long_H
+#define blake2b_long_H
+
+#include <stddef.h>
+
+int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen);
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h
new file mode 100644
index 0000000000..f3dfa0f506
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h
@@ -0,0 +1,150 @@
+#ifndef blamka_round_avx2_H
+#define blamka_round_avx2_H
+
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1))
+#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
+#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
+#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x)))
+
+#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ __m256i ml = _mm256_mul_epu32(A0, B0); \
+ ml = _mm256_add_epi64(ml, ml); \
+ A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \
+ D0 = _mm256_xor_si256(D0, A0); \
+ D0 = rotr32(D0); \
+ \
+ ml = _mm256_mul_epu32(C0, D0); \
+ ml = _mm256_add_epi64(ml, ml); \
+ C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \
+ \
+ B0 = _mm256_xor_si256(B0, C0); \
+ B0 = rotr24(B0); \
+ \
+ ml = _mm256_mul_epu32(A1, B1); \
+ ml = _mm256_add_epi64(ml, ml); \
+ A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \
+ D1 = _mm256_xor_si256(D1, A1); \
+ D1 = rotr32(D1); \
+ \
+ ml = _mm256_mul_epu32(C1, D1); \
+ ml = _mm256_add_epi64(ml, ml); \
+ C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \
+ \
+ B1 = _mm256_xor_si256(B1, C1); \
+ B1 = rotr24(B1); \
+ } while((void)0, 0);
+
+#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ __m256i ml = _mm256_mul_epu32(A0, B0); \
+ ml = _mm256_add_epi64(ml, ml); \
+ A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \
+ D0 = _mm256_xor_si256(D0, A0); \
+ D0 = rotr16(D0); \
+ \
+ ml = _mm256_mul_epu32(C0, D0); \
+ ml = _mm256_add_epi64(ml, ml); \
+ C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \
+ B0 = _mm256_xor_si256(B0, C0); \
+ B0 = rotr63(B0); \
+ \
+ ml = _mm256_mul_epu32(A1, B1); \
+ ml = _mm256_add_epi64(ml, ml); \
+ A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \
+ D1 = _mm256_xor_si256(D1, A1); \
+ D1 = rotr16(D1); \
+ \
+ ml = _mm256_mul_epu32(C1, D1); \
+ ml = _mm256_add_epi64(ml, ml); \
+ C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \
+ B1 = _mm256_xor_si256(B1, C1); \
+ B1 = rotr63(B1); \
+ } while((void)0, 0);
+
+#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
+ C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
+ \
+ B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
+ C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
+ D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
+ } while((void)0, 0);
+
+#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
+ __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
+ B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
+ B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
+ \
+ tmp1 = C0; \
+ C0 = C1; \
+ C1 = tmp1; \
+ \
+ tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \
+ tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \
+ D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
+ D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
+ } while(0);
+
+#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
+ C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
+ \
+ B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
+ C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
+ D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
+ } while((void)0, 0);
+
+#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
+ __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
+ B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
+ B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
+ \
+ tmp1 = C0; \
+ C0 = C1; \
+ C1 = tmp1; \
+ \
+ tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \
+ tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \
+ D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
+ D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
+ } while((void)0, 0);
+
+#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do{ \
+ G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ \
+ DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
+ \
+ G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ \
+ UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
+ } while((void)0, 0);
+
+#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do{ \
+ G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ \
+ DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ \
+ G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ \
+ UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ } while((void)0, 0);
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h
new file mode 100644
index 0000000000..9a822402d8
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h
@@ -0,0 +1,145 @@
+#ifndef blamka_round_avx512f_H
+#define blamka_round_avx512f_H
+
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#define ror64(x, n) _mm512_ror_epi64((x), (n))
+
+static inline __m512i
+muladd(__m512i x, __m512i y)
+{
+ __m512i z = _mm512_mul_epu32(x, y);
+
+ return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z));
+}
+
+#define G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ A0 = muladd(A0, B0); \
+ A1 = muladd(A1, B1); \
+ \
+ D0 = _mm512_xor_si512(D0, A0); \
+ D1 = _mm512_xor_si512(D1, A1); \
+ \
+ D0 = ror64(D0, 32); \
+ D1 = ror64(D1, 32); \
+ \
+ C0 = muladd(C0, D0); \
+ C1 = muladd(C1, D1); \
+ \
+ B0 = _mm512_xor_si512(B0, C0); \
+ B1 = _mm512_xor_si512(B1, C1); \
+ \
+ B0 = ror64(B0, 24); \
+ B1 = ror64(B1, 24); \
+ } while ((void)0, 0)
+
+#define G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ A0 = muladd(A0, B0); \
+ A1 = muladd(A1, B1); \
+ \
+ D0 = _mm512_xor_si512(D0, A0); \
+ D1 = _mm512_xor_si512(D1, A1); \
+ \
+ D0 = ror64(D0, 16); \
+ D1 = ror64(D1, 16); \
+ \
+ C0 = muladd(C0, D0); \
+ C1 = muladd(C1, D1); \
+ \
+ B0 = _mm512_xor_si512(B0, C0); \
+ B1 = _mm512_xor_si512(B1, C1); \
+ \
+ B0 = ror64(B0, 63); \
+ B1 = ror64(B1, 63); \
+ } while ((void)0, 0)
+
+#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
+ B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
+ \
+ C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
+ \
+ D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
+ D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
+ } while ((void)0, 0)
+
+#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
+ B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
+ \
+ C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
+ C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
+ \
+ D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
+ D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
+ } while ((void)0, 0)
+
+#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
+ G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
+ G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
+ } while ((void)0, 0)
+
+#define SWAP_HALVES(A0, A1) \
+ do { \
+ __m512i t0, t1; \
+ t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \
+ t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \
+ A0 = t0; \
+ A1 = t1; \
+ } while((void)0, 0)
+
+#define SWAP_QUARTERS(A0, A1) \
+ do { \
+ SWAP_HALVES(A0, A1); \
+ A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
+ A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
+ } while((void)0, 0)
+
+#define UNSWAP_QUARTERS(A0, A1) \
+ do { \
+ A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
+ A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
+ SWAP_HALVES(A0, A1); \
+ } while((void)0, 0)
+
+#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \
+ do { \
+ SWAP_HALVES(A0, B0); \
+ SWAP_HALVES(C0, D0); \
+ SWAP_HALVES(A1, B1); \
+ SWAP_HALVES(C1, D1); \
+ BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
+ SWAP_HALVES(A0, B0); \
+ SWAP_HALVES(C0, D0); \
+ SWAP_HALVES(A1, B1); \
+ SWAP_HALVES(C1, D1); \
+ } while ((void)0, 0)
+
+#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ SWAP_QUARTERS(A0, A1); \
+ SWAP_QUARTERS(B0, B1); \
+ SWAP_QUARTERS(C0, C1); \
+ SWAP_QUARTERS(D0, D1); \
+ BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
+ UNSWAP_QUARTERS(A0, A1); \
+ UNSWAP_QUARTERS(B0, B1); \
+ UNSWAP_QUARTERS(C0, C1); \
+ UNSWAP_QUARTERS(D0, D1); \
+ } while ((void)0, 0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h
new file mode 100644
index 0000000000..7a2c6eb20e
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h
@@ -0,0 +1,40 @@
+#ifndef blamka_round_ref_H
+#define blamka_round_ref_H
+
+#include "private/common.h"
+
+/*designed by the Lyra PHC team */
+static inline uint64_t
+fBlaMka(uint64_t x, uint64_t y)
+{
+ const uint64_t m = UINT64_C(0xFFFFFFFF);
+ const uint64_t xy = (x & m) * (y & m);
+ return x + y + 2 * xy;
+}
+
+#define G(a, b, c, d) \
+ do { \
+ a = fBlaMka(a, b); \
+ d = ROTR64(d ^ a, 32); \
+ c = fBlaMka(c, d); \
+ b = ROTR64(b ^ c, 24); \
+ a = fBlaMka(a, b); \
+ d = ROTR64(d ^ a, 16); \
+ c = fBlaMka(c, d); \
+ b = ROTR64(b ^ c, 63); \
+ } while ((void) 0, 0)
+
+#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
+ v12, v13, v14, v15) \
+ do { \
+ G(v0, v4, v8, v12); \
+ G(v1, v5, v9, v13); \
+ G(v2, v6, v10, v14); \
+ G(v3, v7, v11, v15); \
+ G(v0, v5, v10, v15); \
+ G(v1, v6, v11, v12); \
+ G(v2, v7, v8, v13); \
+ G(v3, v4, v9, v14); \
+ } while ((void) 0, 0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h
new file mode 100644
index 0000000000..98a47b93f8
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h
@@ -0,0 +1,120 @@
+#ifndef blamka_round_ssse3_H
+#define blamka_round_ssse3_H
+
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#define r16 \
+ (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
+#define r24 \
+ (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
+#define _mm_roti_epi64(x, c) \
+ (-(c) == 32) \
+ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
+ : (-(c) == 24) \
+ ? _mm_shuffle_epi8((x), r24) \
+ : (-(c) == 16) \
+ ? _mm_shuffle_epi8((x), r16) \
+ : (-(c) == 63) \
+ ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_add_epi64((x), (x))) \
+ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
+ _mm_slli_epi64((x), 64 - (-(c))))
+
+static inline __m128i
+fBlaMka(__m128i x, __m128i y)
+{
+ const __m128i z = _mm_mul_epu32(x, y);
+ return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
+}
+
+#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ A0 = fBlaMka(A0, B0); \
+ A1 = fBlaMka(A1, B1); \
+ \
+ D0 = _mm_xor_si128(D0, A0); \
+ D1 = _mm_xor_si128(D1, A1); \
+ \
+ D0 = _mm_roti_epi64(D0, -32); \
+ D1 = _mm_roti_epi64(D1, -32); \
+ \
+ C0 = fBlaMka(C0, D0); \
+ C1 = fBlaMka(C1, D1); \
+ \
+ B0 = _mm_xor_si128(B0, C0); \
+ B1 = _mm_xor_si128(B1, C1); \
+ \
+ B0 = _mm_roti_epi64(B0, -24); \
+ B1 = _mm_roti_epi64(B1, -24); \
+ } while ((void) 0, 0)
+
+#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ A0 = fBlaMka(A0, B0); \
+ A1 = fBlaMka(A1, B1); \
+ \
+ D0 = _mm_xor_si128(D0, A0); \
+ D1 = _mm_xor_si128(D1, A1); \
+ \
+ D0 = _mm_roti_epi64(D0, -16); \
+ D1 = _mm_roti_epi64(D1, -16); \
+ \
+ C0 = fBlaMka(C0, D0); \
+ C1 = fBlaMka(C1, D1); \
+ \
+ B0 = _mm_xor_si128(B0, C0); \
+ B1 = _mm_xor_si128(B1, C1); \
+ \
+ B0 = _mm_roti_epi64(B0, -63); \
+ B1 = _mm_roti_epi64(B1, -63); \
+ } while ((void) 0, 0)
+
+#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
+ __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
+ B0 = t0; \
+ B1 = t1; \
+ \
+ t0 = C0; \
+ C0 = C1; \
+ C1 = t0; \
+ \
+ t0 = _mm_alignr_epi8(D1, D0, 8); \
+ t1 = _mm_alignr_epi8(D0, D1, 8); \
+ D0 = t1; \
+ D1 = t0; \
+ } while ((void) 0, 0)
+
+#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
+ do { \
+ __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
+ __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
+ B0 = t0; \
+ B1 = t1; \
+ \
+ t0 = C0; \
+ C0 = C1; \
+ C1 = t0; \
+ \
+ t0 = _mm_alignr_epi8(D0, D1, 8); \
+ t1 = _mm_alignr_epi8(D1, D0, 8); \
+ D0 = t1; \
+ D1 = t0; \
+ } while ((void) 0, 0)
+
+#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
+ do { \
+ G1(A0, B0, C0, D0, A1, B1, C1, D1); \
+ G2(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ G1(A0, B0, C0, D0, A1, B1, C1, D1); \
+ G2(A0, B0, C0, D0, A1, B1, C1, D1); \
+ \
+ UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
+ } while ((void) 0, 0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c
new file mode 100644
index 0000000000..0515bd6135
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c
@@ -0,0 +1,290 @@
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2-encoding.h"
+#include "argon2.h"
+#include "crypto_pwhash.h"
+#include "crypto_pwhash_argon2i.h"
+#include "crypto_pwhash_argon2id.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#define STR_HASHBYTES 32U
+
+int
+crypto_pwhash_argon2i_alg_argon2i13(void)
+{
+ return crypto_pwhash_argon2i_ALG_ARGON2I13;
+}
+
+size_t
+crypto_pwhash_argon2i_bytes_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN);
+ return crypto_pwhash_argon2i_BYTES_MIN;
+}
+
+size_t
+crypto_pwhash_argon2i_bytes_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN);
+ return crypto_pwhash_argon2i_BYTES_MAX;
+}
+
+size_t
+crypto_pwhash_argon2i_passwd_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH);
+ return crypto_pwhash_argon2i_PASSWD_MIN;
+}
+
+size_t
+crypto_pwhash_argon2i_passwd_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH);
+ return crypto_pwhash_argon2i_PASSWD_MAX;
+}
+
+size_t
+crypto_pwhash_argon2i_saltbytes(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH);
+ COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH);
+ return crypto_pwhash_argon2i_SALTBYTES;
+}
+
+size_t
+crypto_pwhash_argon2i_strbytes(void)
+{
+ return crypto_pwhash_argon2i_STRBYTES;
+}
+
+const char*
+crypto_pwhash_argon2i_strprefix(void)
+{
+ return crypto_pwhash_argon2i_STRPREFIX;
+}
+
+size_t
+crypto_pwhash_argon2i_opslimit_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME);
+ return crypto_pwhash_argon2i_OPSLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_argon2i_opslimit_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME);
+ return crypto_pwhash_argon2i_OPSLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_argon2i_memlimit_min(void)
+{
+ COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY);
+ return crypto_pwhash_argon2i_MEMLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_argon2i_memlimit_max(void)
+{
+ COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY);
+ return crypto_pwhash_argon2i_MEMLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_argon2i_opslimit_interactive(void)
+{
+ return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_argon2i_memlimit_interactive(void)
+{
+ return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_argon2i_opslimit_moderate(void)
+{
+ return crypto_pwhash_argon2i_OPSLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_argon2i_memlimit_moderate(void)
+{
+ return crypto_pwhash_argon2i_MEMLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_argon2i_opslimit_sensitive(void)
+{
+ return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE;
+}
+
+size_t
+crypto_pwhash_argon2i_memlimit_sensitive(void)
+{
+ return crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE;
+}
+
+int
+crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen,
+ const char *const passwd, unsigned long long passwdlen,
+ const unsigned char *const salt,
+ unsigned long long opslimit, size_t memlimit, int alg)
+{
+ memset(out, 0, outlen);
+ if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
+ opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
+ memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
+ opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
+ memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ switch (alg) {
+ case crypto_pwhash_argon2i_ALG_ARGON2I13:
+ if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
+ (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
+ (size_t) crypto_pwhash_argon2i_SALTBYTES, out,
+ (size_t) outlen) != ARGON2_OK) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int
+crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
+ const char *const passwd,
+ unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+{
+ unsigned char salt[crypto_pwhash_argon2i_SALTBYTES];
+
+ memset(out, 0, crypto_pwhash_argon2i_STRBYTES);
+ if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
+ opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
+ memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
+ opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
+ memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ randombytes_buf(salt, sizeof salt);
+ if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
+ (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
+ sizeof salt, STR_HASHBYTES, out,
+ crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+int
+crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
+ const char *const passwd,
+ unsigned long long passwdlen)
+{
+ int verify_ret;
+
+ if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ /* LCOV_EXCL_START */
+ if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ /* LCOV_EXCL_STOP */
+
+ verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen);
+ if (verify_ret == ARGON2_OK) {
+ return 0;
+ }
+ if (verify_ret == ARGON2_VERIFY_MISMATCH) {
+ errno = EINVAL;
+ }
+ return -1;
+}
+
+static int
+_needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit,
+ argon2_type type)
+{
+ unsigned char *fodder;
+ argon2_context ctx;
+ size_t fodder_len;
+ int ret = -1;
+
+ fodder_len = strlen(str);
+ memlimit /= 1024U;
+ if (opslimit > UINT32_MAX || memlimit > UINT32_MAX ||
+ fodder_len >= crypto_pwhash_STRBYTES) {
+ errno = EINVAL;
+ return -1;
+ }
+ memset(&ctx, 0, sizeof ctx);
+ if ((fodder = (unsigned char *) calloc(fodder_len, 1U)) == NULL) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ ctx.out = ctx.pwd = ctx.salt = fodder;
+ ctx.outlen = ctx.pwdlen = ctx.saltlen = (uint32_t) fodder_len;
+ ctx.ad = ctx.secret = NULL;
+ ctx.adlen = ctx.secretlen = 0U;
+ if (decode_string(&ctx, str, type) != 0) {
+ errno = EINVAL;
+ ret = -1;
+ } else if (ctx.t_cost != (uint32_t) opslimit ||
+ ctx.m_cost != (uint32_t) memlimit) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ free(fodder);
+
+ return ret;
+}
+
+int
+crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+{
+ return _needs_rehash(str, opslimit, memlimit, Argon2_i);
+}
+
+int
+crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+{
+ return _needs_rehash(str, opslimit, memlimit, Argon2_id);
+}
diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c
new file mode 100644
index 0000000000..99d3e219bf
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c
@@ -0,0 +1,234 @@
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "argon2-core.h"
+#include "argon2.h"
+#include "crypto_pwhash_argon2id.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#define STR_HASHBYTES 32U
+
+int
+crypto_pwhash_argon2id_alg_argon2id13(void)
+{
+ return crypto_pwhash_argon2id_ALG_ARGON2ID13;
+}
+
+size_t
+crypto_pwhash_argon2id_bytes_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MIN >= ARGON2_MIN_OUTLEN);
+ return crypto_pwhash_argon2id_BYTES_MIN;
+}
+
+size_t
+crypto_pwhash_argon2id_bytes_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MAX <= ARGON2_MAX_OUTLEN);
+ return crypto_pwhash_argon2id_BYTES_MAX;
+}
+
+size_t
+crypto_pwhash_argon2id_passwd_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH);
+ return crypto_pwhash_argon2id_PASSWD_MIN;
+}
+
+size_t
+crypto_pwhash_argon2id_passwd_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH);
+ return crypto_pwhash_argon2id_PASSWD_MAX;
+}
+
+size_t
+crypto_pwhash_argon2id_saltbytes(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES >= ARGON2_MIN_SALT_LENGTH);
+ COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES <= ARGON2_MAX_SALT_LENGTH);
+ return crypto_pwhash_argon2id_SALTBYTES;
+}
+
+size_t
+crypto_pwhash_argon2id_strbytes(void)
+{
+ return crypto_pwhash_argon2id_STRBYTES;
+}
+
+const char*
+crypto_pwhash_argon2id_strprefix(void)
+{
+ return crypto_pwhash_argon2id_STRPREFIX;
+}
+
+size_t
+crypto_pwhash_argon2id_opslimit_min(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME);
+ return crypto_pwhash_argon2id_OPSLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_argon2id_opslimit_max(void)
+{
+ COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME);
+ return crypto_pwhash_argon2id_OPSLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_argon2id_memlimit_min(void)
+{
+ COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY);
+ return crypto_pwhash_argon2id_MEMLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_argon2id_memlimit_max(void)
+{
+ COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY);
+ return crypto_pwhash_argon2id_MEMLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_argon2id_opslimit_interactive(void)
+{
+ return crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_argon2id_memlimit_interactive(void)
+{
+ return crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_argon2id_opslimit_moderate(void)
+{
+ return crypto_pwhash_argon2id_OPSLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_argon2id_memlimit_moderate(void)
+{
+ return crypto_pwhash_argon2id_MEMLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_argon2id_opslimit_sensitive(void)
+{
+ return crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE;
+}
+
+size_t
+crypto_pwhash_argon2id_memlimit_sensitive(void)
+{
+ return crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE;
+}
+
+int
+crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen,
+ const char *const passwd, unsigned long long passwdlen,
+ const unsigned char *const salt,
+ unsigned long long opslimit, size_t memlimit, int alg)
+{
+ memset(out, 0, outlen);
+ if (outlen > crypto_pwhash_argon2id_BYTES_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (outlen < crypto_pwhash_argon2id_BYTES_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
+ opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
+ memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
+ opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN ||
+ memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ switch (alg) {
+ case crypto_pwhash_argon2id_ALG_ARGON2ID13:
+ if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
+ (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
+ (size_t) crypto_pwhash_argon2id_SALTBYTES, out,
+ (size_t) outlen) != ARGON2_OK) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int
+crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES],
+ const char *const passwd,
+ unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+{
+ unsigned char salt[crypto_pwhash_argon2id_SALTBYTES];
+
+ memset(out, 0, crypto_pwhash_argon2id_STRBYTES);
+ if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
+ opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
+ memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
+ opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN ||
+ memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ randombytes_buf(salt, sizeof salt);
+ if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
+ (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
+ sizeof salt, STR_HASHBYTES, out,
+ crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+int
+crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES],
+ const char *const passwd,
+ unsigned long long passwdlen)
+{
+ int verify_ret;
+
+ if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ /* LCOV_EXCL_START */
+ if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN) {
+ errno = EINVAL;
+ return -1;
+ }
+ /* LCOV_EXCL_STOP */
+
+ verify_ret = argon2id_verify(str, passwd, (size_t) passwdlen);
+ if (verify_ret == ARGON2_OK) {
+ return 0;
+ }
+ if (verify_ret == ARGON2_VERIFY_MISMATCH) {
+ errno = EINVAL;
+ }
+ return -1;
+}
diff --git a/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c
new file mode 100644
index 0000000000..8168f96216
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c
@@ -0,0 +1,211 @@
+
+#include <errno.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_pwhash.h"
+
+int
+crypto_pwhash_alg_argon2i13(void)
+{
+ return crypto_pwhash_ALG_ARGON2I13;
+}
+
+int
+crypto_pwhash_alg_argon2id13(void)
+{
+ return crypto_pwhash_ALG_ARGON2ID13;
+}
+
+int
+crypto_pwhash_alg_default(void)
+{
+ return crypto_pwhash_ALG_DEFAULT;
+}
+
+size_t
+crypto_pwhash_bytes_min(void)
+{
+ return crypto_pwhash_BYTES_MIN;
+}
+
+size_t
+crypto_pwhash_bytes_max(void)
+{
+ return crypto_pwhash_BYTES_MAX;
+}
+
+size_t
+crypto_pwhash_passwd_min(void)
+{
+ return crypto_pwhash_PASSWD_MIN;
+}
+
+size_t
+crypto_pwhash_passwd_max(void)
+{
+ return crypto_pwhash_PASSWD_MAX;
+}
+
+size_t
+crypto_pwhash_saltbytes(void)
+{
+ return crypto_pwhash_SALTBYTES;
+}
+
+size_t
+crypto_pwhash_strbytes(void)
+{
+ return crypto_pwhash_STRBYTES;
+}
+
+const char *
+crypto_pwhash_strprefix(void)
+{
+ return crypto_pwhash_STRPREFIX;
+}
+
+size_t
+crypto_pwhash_opslimit_min(void)
+{
+ return crypto_pwhash_OPSLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_opslimit_max(void)
+{
+ return crypto_pwhash_OPSLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_memlimit_min(void)
+{
+ return crypto_pwhash_MEMLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_memlimit_max(void)
+{
+ return crypto_pwhash_MEMLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_opslimit_interactive(void)
+{
+ return crypto_pwhash_OPSLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_memlimit_interactive(void)
+{
+ return crypto_pwhash_MEMLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_opslimit_moderate(void)
+{
+ return crypto_pwhash_OPSLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_memlimit_moderate(void)
+{
+ return crypto_pwhash_MEMLIMIT_MODERATE;
+}
+
+size_t
+crypto_pwhash_opslimit_sensitive(void)
+{
+ return crypto_pwhash_OPSLIMIT_SENSITIVE;
+}
+
+size_t
+crypto_pwhash_memlimit_sensitive(void)
+{
+ return crypto_pwhash_MEMLIMIT_SENSITIVE;
+}
+
+int
+crypto_pwhash(unsigned char * const out, unsigned long long outlen,
+ const char * const passwd, unsigned long long passwdlen,
+ const unsigned char * const salt,
+ unsigned long long opslimit, size_t memlimit, int alg)
+{
+ switch (alg) {
+ case crypto_pwhash_ALG_ARGON2I13:
+ return crypto_pwhash_argon2i(out, outlen, passwd, passwdlen, salt,
+ opslimit, memlimit, alg);
+ case crypto_pwhash_ALG_ARGON2ID13:
+ return crypto_pwhash_argon2id(out, outlen, passwd, passwdlen, salt,
+ opslimit, memlimit, alg);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int
+crypto_pwhash_str(char out[crypto_pwhash_STRBYTES],
+ const char * const passwd, unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+{
+ return crypto_pwhash_argon2id_str(out, passwd, passwdlen,
+ opslimit, memlimit);
+}
+
+int
+crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES],
+ const char * const passwd, unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit, int alg)
+{
+ switch (alg) {
+ case crypto_pwhash_ALG_ARGON2I13:
+ return crypto_pwhash_argon2i_str(out, passwd, passwdlen,
+ opslimit, memlimit);
+ case crypto_pwhash_ALG_ARGON2ID13:
+ return crypto_pwhash_argon2id_str(out, passwd, passwdlen,
+ opslimit, memlimit);
+ }
+ sodium_misuse();
+ /* NOTREACHED */
+}
+
+int
+crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen)
+{
+ if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX,
+ sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) {
+ return crypto_pwhash_argon2id_str_verify(str, passwd, passwdlen);
+ }
+ if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX,
+ sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) {
+ return crypto_pwhash_argon2i_str_verify(str, passwd, passwdlen);
+ }
+ errno = EINVAL;
+
+ return -1;
+}
+
+int
+crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+{
+ if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX,
+ sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) {
+ return crypto_pwhash_argon2id_str_needs_rehash(str, opslimit, memlimit);
+ }
+ if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX,
+ sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) {
+ return crypto_pwhash_argon2i_str_needs_rehash(str, opslimit, memlimit);
+ }
+ errno = EINVAL;
+
+ return -1;
+}
+
+const char *
+crypto_pwhash_primitive(void) {
+ return crypto_pwhash_PRIMITIVE;
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c
new file mode 100644
index 0000000000..e15e12b294
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c
@@ -0,0 +1,263 @@
+/*-
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_pwhash_scryptsalsa208sha256.h"
+#include "crypto_scrypt.h"
+#include "private/common.h"
+#include "runtime.h"
+#include "utils.h"
+
+static const char *const itoa64 =
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static uint8_t *
+encode64_uint32(uint8_t *dst, size_t dstlen, uint32_t src, uint32_t srcbits)
+{
+ uint32_t bit;
+
+ for (bit = 0; bit < srcbits; bit += 6) {
+ if (dstlen < 1) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ *dst++ = itoa64[src & 0x3f];
+ dstlen--;
+ src >>= 6;
+ }
+ return dst;
+}
+
+static uint8_t *
+encode64(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t srclen)
+{
+ size_t i;
+
+ for (i = 0; i < srclen;) {
+ uint8_t *dnext;
+ uint32_t value = 0, bits = 0;
+
+ do {
+ value |= (uint32_t) src[i++] << bits;
+ bits += 8;
+ } while (bits < 24 && i < srclen);
+
+ dnext = encode64_uint32(dst, dstlen, value, bits);
+ if (!dnext) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ dstlen -= dnext - dst;
+ dst = dnext;
+ }
+ return dst;
+}
+
+static int
+decode64_one(uint32_t *dst, uint8_t src)
+{
+ const char *ptr = strchr(itoa64, src);
+
+ if (ptr) {
+ *dst = (uint32_t)(ptr - itoa64);
+ return 0;
+ }
+ *dst = 0;
+
+ return -1;
+}
+
+static const uint8_t *
+decode64_uint32(uint32_t *dst, uint32_t dstbits, const uint8_t *src)
+{
+ uint32_t bit;
+ uint32_t value;
+
+ value = 0;
+ for (bit = 0; bit < dstbits; bit += 6) {
+ uint32_t one;
+ if (decode64_one(&one, *src)) {
+ *dst = 0;
+ return NULL;
+ }
+ src++;
+ value |= one << bit;
+ }
+ *dst = value;
+
+ return src;
+}
+
+const uint8_t *
+escrypt_parse_setting(const uint8_t *setting,
+ uint32_t *N_log2_p, uint32_t *r_p, uint32_t *p_p)
+{
+ const uint8_t *src;
+
+ if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') {
+ return NULL;
+ }
+ src = setting + 3;
+
+ if (decode64_one(N_log2_p, *src)) {
+ return NULL;
+ }
+ src++;
+
+ src = decode64_uint32(r_p, 30, src);
+ if (!src) {
+ return NULL;
+ }
+
+ src = decode64_uint32(p_p, 30, src);
+ if (!src) {
+ return NULL;
+ }
+ return src;
+}
+
+uint8_t *
+escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen,
+ const uint8_t *setting, uint8_t *buf, size_t buflen)
+{
+ uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES];
+ escrypt_kdf_t escrypt_kdf;
+ const uint8_t *src;
+ const uint8_t *salt;
+ uint8_t *dst;
+ size_t prefixlen;
+ size_t saltlen;
+ size_t need;
+ uint64_t N;
+ uint32_t N_log2;
+ uint32_t r;
+ uint32_t p;
+
+ src = escrypt_parse_setting(setting, &N_log2, &r, &p);
+ if (!src) {
+ return NULL;
+ }
+ N = (uint64_t) 1 << N_log2;
+ prefixlen = src - setting;
+
+ salt = src;
+ src = (uint8_t *) strrchr((char *) salt, '$');
+ if (src) {
+ saltlen = src - salt;
+ } else {
+ saltlen = strlen((char *) salt);
+ }
+ need = prefixlen + saltlen + 1 +
+ crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1;
+ if (need > buflen || need < saltlen) {
+ return NULL;
+ }
+#ifdef HAVE_EMMINTRIN_H
+ escrypt_kdf =
+ sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
+#else
+ escrypt_kdf = escrypt_kdf_nosse;
+#endif
+ if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen, N, r, p, hash,
+ sizeof(hash))) {
+ return NULL;
+ }
+ dst = buf;
+ memcpy(dst, setting, prefixlen + saltlen);
+ dst += prefixlen + saltlen;
+ *dst++ = '$';
+
+ dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
+ sodium_memzero(hash, sizeof hash);
+ if (!dst || dst >= buf + buflen) {
+ return NULL; /* Can't happen LCOV_EXCL_LINE */
+ }
+ *dst = 0; /* NUL termination */
+
+ return buf;
+}
+
+uint8_t *
+escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, const uint8_t *src,
+ size_t srclen, uint8_t *buf, size_t buflen)
+{
+ uint8_t *dst;
+ size_t prefixlen =
+ (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */);
+ size_t saltlen = BYTES2CHARS(srclen);
+ size_t need;
+
+ need = prefixlen + saltlen + 1;
+ if (need > buflen || need < saltlen || saltlen < srclen) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ if (N_log2 > 63 || ((uint64_t) r * (uint64_t) p >= (1U << 30))) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ dst = buf;
+ *dst++ = '$';
+ *dst++ = '7';
+ *dst++ = '$';
+
+ *dst++ = itoa64[N_log2];
+
+ dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
+ if (!dst) {
+ return NULL; /* Can't happen LCOV_EXCL_LINE */
+ }
+ dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
+ if (!dst) {
+ return NULL; /* Can't happen LCOV_EXCL_LINE */
+ }
+ dst = encode64(dst, buflen - (dst - buf), src, srclen);
+ if (!dst || dst >= buf + buflen) {
+ return NULL; /* Can't happen LCOV_EXCL_LINE */
+ }
+ *dst = 0; /* NUL termination */
+
+ return buf;
+}
+
+int
+crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t *passwd, size_t passwdlen,
+ const uint8_t *salt, size_t saltlen,
+ uint64_t N, uint32_t r, uint32_t p,
+ uint8_t *buf, size_t buflen)
+{
+ escrypt_kdf_t escrypt_kdf;
+ escrypt_local_t local;
+ int retval;
+
+ if (escrypt_init_local(&local)) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+#if defined(HAVE_EMMINTRIN_H)
+ escrypt_kdf =
+ sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
+#else
+ escrypt_kdf = escrypt_kdf_nosse;
+#endif
+ retval = escrypt_kdf(&local, passwd, passwdlen, salt, saltlen, N, r, p, buf,
+ buflen);
+ if (escrypt_free_local(&local)) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return retval;
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h
new file mode 100644
index 0000000000..83101967c3
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h
@@ -0,0 +1,98 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef crypto_scrypt_H
+#define crypto_scrypt_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#if SIZE_MAX > 0xffffffffULL
+#define ARCH_BITS 64
+#else
+#define ARCH_BITS 32
+#endif
+
+#define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14
+#define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57
+#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES 32
+#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES_ENCODED 43
+#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES 32
+#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED 43
+
+#define BYTES2CHARS(bytes) ((((bytes) *8) + 5) / 6)
+
+typedef struct {
+ void * base, *aligned;
+ size_t size;
+} escrypt_region_t;
+
+typedef union {
+ uint64_t d[8];
+ uint32_t w[16];
+} escrypt_block_t;
+
+typedef escrypt_region_t escrypt_local_t;
+
+extern int escrypt_init_local(escrypt_local_t *__local);
+
+extern int escrypt_free_local(escrypt_local_t *__local);
+
+extern void *alloc_region(escrypt_region_t *region, size_t size);
+extern int free_region(escrypt_region_t *region);
+
+typedef int (*escrypt_kdf_t)(escrypt_local_t *__local, const uint8_t *__passwd,
+ size_t __passwdlen, const uint8_t *__salt,
+ size_t __saltlen, uint64_t __N, uint32_t __r,
+ uint32_t __p, uint8_t *__buf, size_t __buflen);
+
+extern int escrypt_kdf_nosse(escrypt_local_t *__local, const uint8_t *__passwd,
+ size_t __passwdlen, const uint8_t *__salt,
+ size_t __saltlen, uint64_t __N, uint32_t __r,
+ uint32_t __p, uint8_t *__buf, size_t __buflen);
+
+extern int escrypt_kdf_sse(escrypt_local_t *__local, const uint8_t *__passwd,
+ size_t __passwdlen, const uint8_t *__salt,
+ size_t __saltlen, uint64_t __N, uint32_t __r,
+ uint32_t __p, uint8_t *__buf, size_t __buflen);
+
+extern uint8_t *escrypt_r(escrypt_local_t *__local, const uint8_t *__passwd,
+ size_t __passwdlen, const uint8_t *__setting,
+ uint8_t *__buf, size_t __buflen);
+
+extern uint8_t *escrypt_gensalt_r(uint32_t __N_log2, uint32_t __r, uint32_t __p,
+ const uint8_t *__src, size_t __srclen,
+ uint8_t *__buf, size_t __buflen);
+
+extern const uint8_t *escrypt_parse_setting(const uint8_t *setting,
+ uint32_t *N_log2_p, uint32_t *r_p,
+ uint32_t *p_p);
+
+#endif /* !_CRYPTO_SCRYPT_H_ */
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
new file mode 100644
index 0000000000..9e31352dc2
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
@@ -0,0 +1,375 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../crypto_scrypt.h"
+#include "../pbkdf2-sha256.h"
+#include "private/common.h"
+
+static inline void
+blkcpy_64(escrypt_block_t *dest, const escrypt_block_t *src)
+{
+ int i;
+
+#if (ARCH_BITS == 32)
+ for (i = 0; i < 16; ++i) {
+ dest->w[i] = src->w[i];
+ }
+#else
+ for (i = 0; i < 8; ++i) {
+ dest->d[i] = src->d[i];
+ }
+#endif
+}
+
+static inline void
+blkxor_64(escrypt_block_t *dest, const escrypt_block_t *src)
+{
+ int i;
+
+#if (ARCH_BITS == 32)
+ for (i = 0; i < 16; ++i) {
+ dest->w[i] ^= src->w[i];
+ }
+#else
+ for (i = 0; i < 8; ++i) {
+ dest->d[i] ^= src->d[i];
+ }
+#endif
+}
+
+static inline void
+blkcpy(escrypt_block_t *dest, const escrypt_block_t *src, size_t len)
+{
+ size_t i, L;
+
+#if (ARCH_BITS == 32)
+ L = (len >> 2);
+ for (i = 0; i < L; ++i) {
+ dest->w[i] = src->w[i];
+ }
+#else
+ L = (len >> 3);
+ for (i = 0; i < L; ++i) {
+ dest->d[i] = src->d[i];
+ }
+#endif
+}
+
+static inline void
+blkxor(escrypt_block_t *dest, const escrypt_block_t *src, size_t len)
+{
+ size_t i, L;
+
+#if (ARCH_BITS == 32)
+ L = (len >> 2);
+ for (i = 0; i < L; ++i) {
+ dest->w[i] ^= src->w[i];
+ }
+#else
+ L = (len >> 3);
+ for (i = 0; i < L; ++i) {
+ dest->d[i] ^= src->d[i];
+ }
+#endif
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint32_t B[16])
+{
+ escrypt_block_t X;
+ uint32_t *x = X.w;
+ size_t i;
+
+ blkcpy_64(&X, (escrypt_block_t *) B);
+ for (i = 0; i < 8; i += 2) {
+#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
+ /* Operate on columns. */
+ x[4] ^= R(x[0] + x[12], 7);
+ x[8] ^= R(x[4] + x[0], 9);
+ x[12] ^= R(x[8] + x[4], 13);
+ x[0] ^= R(x[12] + x[8], 18);
+
+ x[9] ^= R(x[5] + x[1], 7);
+ x[13] ^= R(x[9] + x[5], 9);
+ x[1] ^= R(x[13] + x[9], 13);
+ x[5] ^= R(x[1] + x[13], 18);
+
+ x[14] ^= R(x[10] + x[6], 7);
+ x[2] ^= R(x[14] + x[10], 9);
+ x[6] ^= R(x[2] + x[14], 13);
+ x[10] ^= R(x[6] + x[2], 18);
+
+ x[3] ^= R(x[15] + x[11], 7);
+ x[7] ^= R(x[3] + x[15], 9);
+ x[11] ^= R(x[7] + x[3], 13);
+ x[15] ^= R(x[11] + x[7], 18);
+
+ /* Operate on rows. */
+ x[1] ^= R(x[0] + x[3], 7);
+ x[2] ^= R(x[1] + x[0], 9);
+ x[3] ^= R(x[2] + x[1], 13);
+ x[0] ^= R(x[3] + x[2], 18);
+
+ x[6] ^= R(x[5] + x[4], 7);
+ x[7] ^= R(x[6] + x[5], 9);
+ x[4] ^= R(x[7] + x[6], 13);
+ x[5] ^= R(x[4] + x[7], 18);
+
+ x[11] ^= R(x[10] + x[9], 7);
+ x[8] ^= R(x[11] + x[10], 9);
+ x[9] ^= R(x[8] + x[11], 13);
+ x[10] ^= R(x[9] + x[8], 18);
+
+ x[12] ^= R(x[15] + x[14], 7);
+ x[13] ^= R(x[12] + x[15], 9);
+ x[14] ^= R(x[13] + x[12], 13);
+ x[15] ^= R(x[14] + x[13], 18);
+#undef R
+ }
+ for (i = 0; i < 16; i++)
+ B[i] += x[i];
+}
+
+/**
+ * blockmix_salsa8(Bin, Bout, X, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size. The
+ * temporary space X must be 64 bytes.
+ */
+static void
+blockmix_salsa8(const uint32_t *Bin, uint32_t *Bout, uint32_t *X, size_t r)
+{
+ size_t i;
+
+ /* 1: X <-- B_{2r - 1} */
+ blkcpy_64((escrypt_block_t *) X,
+ (escrypt_block_t *) &Bin[(2 * r - 1) * 16]);
+
+ /* 2: for i = 0 to 2r - 1 do */
+ for (i = 0; i < 2 * r; i += 2) {
+ /* 3: X <-- H(X \xor B_i) */
+ blkxor_64((escrypt_block_t *) X, (escrypt_block_t *) &Bin[i * 16]);
+ salsa20_8(X);
+
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ blkcpy_64((escrypt_block_t *) &Bout[i * 8], (escrypt_block_t *) X);
+
+ /* 3: X <-- H(X \xor B_i) */
+ blkxor_64((escrypt_block_t *) X, (escrypt_block_t *) &Bin[i * 16 + 16]);
+ salsa20_8(X);
+
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ blkcpy_64((escrypt_block_t *) &Bout[i * 8 + r * 16],
+ (escrypt_block_t *) X);
+ }
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static inline uint64_t
+integerify(const void *B, size_t r)
+{
+ const uint32_t *X = (const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64);
+
+ return (((uint64_t)(X[1]) << 32) + X[0]);
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length. The value N must be a
+ * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+static void
+smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY)
+{
+ uint32_t *X = XY;
+ uint32_t *Y = &XY[32 * r];
+ uint32_t *Z = &XY[64 * r];
+ uint64_t i;
+ uint64_t j;
+ size_t k;
+
+ /* 1: X <-- B */
+ for (k = 0; k < 32 * r; k++) {
+ X[k] = LOAD32_LE(&B[4 * k]);
+ }
+ /* 2: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i += 2) {
+ /* 3: V_i <-- X */
+ blkcpy((escrypt_block_t *) &V[i * (32 * r)], (escrypt_block_t *) X,
+ 128 * r);
+
+ /* 4: X <-- H(X) */
+ blockmix_salsa8(X, Y, Z, r);
+
+ /* 3: V_i <-- X */
+ blkcpy((escrypt_block_t *) &V[(i + 1) * (32 * r)],
+ (escrypt_block_t *) Y, 128 * r);
+
+ /* 4: X <-- H(X) */
+ blockmix_salsa8(Y, X, Z, r);
+ }
+
+ /* 6: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i += 2) {
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(X, r) & (N - 1);
+
+ /* 8: X <-- H(X \xor V_j) */
+ blkxor((escrypt_block_t *) X, (escrypt_block_t *) &V[j * (32 * r)],
+ 128 * r);
+ blockmix_salsa8(X, Y, Z, r);
+
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(Y, r) & (N - 1);
+
+ /* 8: X <-- H(X \xor V_j) */
+ blkxor((escrypt_block_t *) Y, (escrypt_block_t *) &V[j * (32 * r)],
+ 128 * r);
+ blockmix_salsa8(Y, X, Z, r);
+ }
+ /* 10: B' <-- X */
+ for (k = 0; k < 32 * r; k++) {
+ STORE32_LE(&B[4 * k], X[k]);
+ }
+}
+
+/**
+ * escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
+ * N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd,
+ size_t passwdlen, const uint8_t *salt, size_t saltlen,
+ uint64_t N, uint32_t _r, uint32_t _p, uint8_t *buf,
+ size_t buflen)
+{
+ size_t B_size, V_size, XY_size, need;
+ uint8_t * B;
+ uint32_t *V, *XY;
+ size_t r = _r, p = _p;
+ uint32_t i;
+
+/* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+ errno = EFBIG;
+ return -1;
+ }
+#endif
+ if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (N > UINT32_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (((N & (N - 1)) != 0) || (N < 2)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (r == 0 || p == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+ (r > SIZE_MAX / 256) ||
+#endif
+ (N > SIZE_MAX / 128 / r)) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Allocate memory. */
+ B_size = (size_t) 128 * r * p;
+ V_size = (size_t) 128 * r * (size_t) N;
+ need = B_size + V_size;
+ if (need < V_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+ XY_size = (size_t) 256 * r + 64;
+ need += XY_size;
+ if (need < XY_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+ if (local->size < need) {
+ if (free_region(local)) {
+ return -1;
+ }
+ if (!alloc_region(local, need)) {
+ return -1;
+ }
+ }
+ B = (uint8_t *) local->aligned;
+ V = (uint32_t *) ((uint8_t *) B + B_size);
+ XY = (uint32_t *) ((uint8_t *) V + V_size);
+
+ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
+
+ /* 2: for i = 0 to p - 1 do */
+ for (i = 0; i < p; i++) {
+ /* 3: B_i <-- MF(B_i, N) */
+ smix(&B[(size_t) 128 * i * r], r, N, V, XY);
+ }
+
+ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+ PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
+
+ /* Success! */
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c
new file mode 100644
index 0000000000..42cab61fe2
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include "core.h"
+#include "crypto_auth_hmacsha256.h"
+#include "crypto_pwhash_scryptsalsa208sha256.h"
+#include "pbkdf2-sha256.h"
+#include "private/common.h"
+#include "utils.h"
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void
+PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
+ size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen)
+{
+ crypto_auth_hmacsha256_state PShctx, hctx;
+ size_t i;
+ uint8_t ivec[4];
+ uint8_t U[32];
+ uint8_t T[32];
+ uint64_t j;
+ int k;
+ size_t clen;
+
+#if SIZE_MAX > 0x1fffffffe0ULL
+ COMPILER_ASSERT(crypto_pwhash_scryptsalsa208sha256_BYTES_MAX
+ <= 0x1fffffffe0ULL);
+ if (dkLen > 0x1fffffffe0ULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+ crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen);
+ crypto_auth_hmacsha256_update(&PShctx, salt, saltlen);
+
+ for (i = 0; i * 32 < dkLen; i++) {
+ STORE32_BE(ivec, (uint32_t)(i + 1));
+ memcpy(&hctx, &PShctx, sizeof(crypto_auth_hmacsha256_state));
+ crypto_auth_hmacsha256_update(&hctx, ivec, 4);
+ crypto_auth_hmacsha256_final(&hctx, U);
+
+ memcpy(T, U, 32);
+ /* LCOV_EXCL_START */
+ for (j = 2; j <= c; j++) {
+ crypto_auth_hmacsha256_init(&hctx, passwd, passwdlen);
+ crypto_auth_hmacsha256_update(&hctx, U, 32);
+ crypto_auth_hmacsha256_final(&hctx, U);
+
+ for (k = 0; k < 32; k++) {
+ T[k] ^= U[k];
+ }
+ }
+ /* LCOV_EXCL_STOP */
+
+ clen = dkLen - i * 32;
+ if (clen > 32) {
+ clen = 32;
+ }
+ memcpy(&buf[i * 32], T, clen);
+ }
+ sodium_memzero((void *) &PShctx, sizeof PShctx);
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h
new file mode 100644
index 0000000000..f9598c87aa
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright 2005,2007,2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef pbkdf2_sha256_H
+#define pbkdf2_sha256_H
+
+#include <stdint.h>
+
+#include <sys/types.h>
+
+#include "crypto_auth_hmacsha256.h"
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
+ uint8_t *, size_t);
+
+#endif /* !_SHA256_H_ */
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c
new file mode 100644
index 0000000000..d1afd91afe
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c
@@ -0,0 +1,285 @@
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_pwhash_scryptsalsa208sha256.h"
+#include "crypto_scrypt.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#define SETTING_SIZE(saltbytes) \
+ ((sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + \
+ BYTES2CHARS(saltbytes))
+
+static int
+pickparams(unsigned long long opslimit, const size_t memlimit,
+ uint32_t *const N_log2, uint32_t *const p, uint32_t *const r)
+{
+ unsigned long long maxN;
+ unsigned long long maxrp;
+
+ if (opslimit < 32768) {
+ opslimit = 32768;
+ }
+ *r = 8;
+ if (opslimit < memlimit / 32) {
+ *p = 1;
+ maxN = opslimit / (*r * 4);
+ for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
+ if ((uint64_t)(1) << *N_log2 > maxN / 2) {
+ break;
+ }
+ }
+ } else {
+ maxN = memlimit / ((size_t) *r * 128);
+ for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
+ if ((uint64_t)(1) << *N_log2 > maxN / 2) {
+ break;
+ }
+ }
+ maxrp = (opslimit / 4) / ((uint64_t)(1) << *N_log2);
+ /* LCOV_EXCL_START */
+ if (maxrp > 0x3fffffff) {
+ maxrp = 0x3fffffff;
+ }
+ /* LCOV_EXCL_STOP */
+ *p = (uint32_t)(maxrp) / *r;
+ }
+ return 0;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_bytes_min(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_BYTES_MIN;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_bytes_max(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_BYTES_MAX;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_passwd_min(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_passwd_max(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_saltbytes(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_strbytes(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_STRBYTES;
+}
+
+const char *
+crypto_pwhash_scryptsalsa208sha256_strprefix(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_STRPREFIX;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_opslimit_min(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_opslimit_max(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_memlimit_min(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_memlimit_max(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE;
+}
+
+size_t
+crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)
+{
+ return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE;
+}
+
+int
+crypto_pwhash_scryptsalsa208sha256(unsigned char *const out,
+ unsigned long long outlen,
+ const char *const passwd,
+ unsigned long long passwdlen,
+ const unsigned char *const salt,
+ unsigned long long opslimit, size_t memlimit)
+{
+ uint32_t N_log2;
+ uint32_t p;
+ uint32_t r;
+
+ memset(out, 0, outlen);
+ if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX ||
+ outlen > crypto_pwhash_scryptsalsa208sha256_BYTES_MAX) {
+ errno = EFBIG; /* LCOV_EXCL_LINE */
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (outlen < crypto_pwhash_scryptsalsa208sha256_BYTES_MIN ||
+ pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
+ errno = EINVAL; /* LCOV_EXCL_LINE */
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return crypto_pwhash_scryptsalsa208sha256_ll(
+ (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt,
+ crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t)(1) << N_log2,
+ r, p, out, (size_t) outlen);
+}
+
+int
+crypto_pwhash_scryptsalsa208sha256_str(
+ char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ const char *const passwd, unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+{
+ uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES];
+ char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U];
+ escrypt_local_t escrypt_local;
+ uint32_t N_log2;
+ uint32_t p;
+ uint32_t r;
+
+ memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES);
+ if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX) {
+ errno = EFBIG; /* LCOV_EXCL_LINE */
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (passwdlen < crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN ||
+ pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
+ errno = EINVAL; /* LCOV_EXCL_LINE */
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ randombytes_buf(salt, sizeof salt);
+ if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting,
+ sizeof setting) == NULL) {
+ errno = EINVAL; /* LCOV_EXCL_LINE */
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (escrypt_init_local(&escrypt_local) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
+ (const uint8_t *) setting, (uint8_t *) out,
+ crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) {
+ /* LCOV_EXCL_START */
+ escrypt_free_local(&escrypt_local);
+ errno = EINVAL;
+ return -1;
+ /* LCOV_EXCL_STOP */
+ }
+ escrypt_free_local(&escrypt_local);
+
+ COMPILER_ASSERT(
+ SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) ==
+ crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES);
+ COMPILER_ASSERT(
+ crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U +
+ crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U ==
+ crypto_pwhash_scryptsalsa208sha256_STRBYTES);
+
+ return 0;
+}
+
+int
+crypto_pwhash_scryptsalsa208sha256_str_verify(
+ const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ const char *const passwd, unsigned long long passwdlen)
+{
+ char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
+ escrypt_local_t escrypt_local;
+ int ret = -1;
+
+ if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
+ &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
+ return -1;
+ }
+ if (escrypt_init_local(&escrypt_local) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ memset(wanted, 0, sizeof wanted);
+ if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
+ (const uint8_t *) str, (uint8_t *) wanted,
+ sizeof wanted) == NULL) {
+ escrypt_free_local(&escrypt_local);
+ return -1;
+ }
+ escrypt_free_local(&escrypt_local);
+ ret = sodium_memcmp(wanted, str, sizeof wanted);
+ sodium_memzero(wanted, sizeof wanted);
+
+ return ret;
+}
+
+int
+crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(
+ const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+{
+ uint32_t N_log2, N_log2_;
+ uint32_t p, p_;
+ uint32_t r, r_;
+
+ if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
+ &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (escrypt_parse_setting((const uint8_t *) str,
+ &N_log2_, &r_, &p_) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (N_log2 != N_log2_ || r != r_ || p != p_) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c
new file mode 100644
index 0000000000..139a7df286
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright 2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdlib.h>
+
+#include "crypto_scrypt.h"
+#include "runtime.h"
+
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+#ifndef MAP_NOCORE
+# define MAP_NOCORE 0
+#endif
+#ifndef MAP_POPULATE
+# define MAP_POPULATE 0
+#endif
+
+void *
+alloc_region(escrypt_region_t *region, size_t size)
+{
+ uint8_t *base, *aligned;
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE,
+ -1, 0)) == MAP_FAILED) {
+ base = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+ aligned = base;
+#elif defined(HAVE_POSIX_MEMALIGN)
+ if ((errno = posix_memalign((void **) &base, 64, size)) != 0) {
+ base = NULL;
+ }
+ aligned = base;
+#else
+ base = aligned = NULL;
+ if (size + 63 < size)
+ errno = ENOMEM;
+ else if ((base = (uint8_t *) malloc(size + 63)) != NULL) {
+ aligned = base + 63;
+ aligned -= (uintptr_t) aligned & 63;
+ }
+#endif
+ region->base = base;
+ region->aligned = aligned;
+ region->size = base ? size : 0;
+
+ return aligned;
+}
+
+static inline void
+init_region(escrypt_region_t *region)
+{
+ region->base = region->aligned = NULL;
+ region->size = 0;
+}
+
+int
+free_region(escrypt_region_t *region)
+{
+ if (region->base) {
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if (munmap(region->base, region->size)) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+#else
+ free(region->base);
+#endif
+ }
+ init_region(region);
+
+ return 0;
+}
+
+int
+escrypt_init_local(escrypt_local_t *local)
+{
+ init_region(local);
+
+ return 0;
+}
+
+int
+escrypt_free_local(escrypt_local_t *local)
+{
+ return free_region(local);
+}
diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
new file mode 100644
index 0000000000..754a19fdb8
--- /dev/null
+++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
@@ -0,0 +1,400 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * Copyright 2012,2013 Alexander Peslyak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+
+#ifdef HAVE_EMMINTRIN_H
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# endif
+# include <emmintrin.h>
+# if defined(__XOP__) && defined(DISABLED)
+# include <x86intrin.h>
+# endif
+
+# include "../crypto_scrypt.h"
+# include "../pbkdf2-sha256.h"
+
+# if defined(__XOP__) && defined(DISABLED)
+# define ARX(out, in1, in2, s) \
+ out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s));
+# else
+# define ARX(out, in1, in2, s) \
+ { \
+ __m128i T = _mm_add_epi32(in1, in2); \
+ out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \
+ out = _mm_xor_si128(out, _mm_srli_epi32(T, 32 - s)); \
+ }
+# endif
+
+# define SALSA20_2ROUNDS \
+ /* Operate on "columns". */ \
+ ARX(X1, X0, X3, 7) \
+ ARX(X2, X1, X0, 9) \
+ ARX(X3, X2, X1, 13) \
+ ARX(X0, X3, X2, 18) \
+ \
+ /* Rearrange data. */ \
+ X1 = _mm_shuffle_epi32(X1, 0x93); \
+ X2 = _mm_shuffle_epi32(X2, 0x4E); \
+ X3 = _mm_shuffle_epi32(X3, 0x39); \
+ \
+ /* Operate on "rows". */ \
+ ARX(X3, X0, X1, 7) \
+ ARX(X2, X3, X0, 9) \
+ ARX(X1, X2, X3, 13) \
+ ARX(X0, X1, X2, 18) \
+ \
+ /* Rearrange data. */ \
+ X1 = _mm_shuffle_epi32(X1, 0x39); \
+ X2 = _mm_shuffle_epi32(X2, 0x4E); \
+ X3 = _mm_shuffle_epi32(X3, 0x93);
+
+/**
+ * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3).
+ */
+# define SALSA20_8_XOR(in, out) \
+ { \
+ __m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \
+ __m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \
+ __m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \
+ __m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \
+ SALSA20_2ROUNDS \
+ SALSA20_2ROUNDS \
+ SALSA20_2ROUNDS \
+ SALSA20_2ROUNDS(out)[0] = X0 = _mm_add_epi32(X0, Y0); \
+ (out)[1] = X1 = _mm_add_epi32(X1, Y1); \
+ (out)[2] = X2 = _mm_add_epi32(X2, Y2); \
+ (out)[3] = X3 = _mm_add_epi32(X3, Y3); \
+ }
+
+/**
+ * blockmix_salsa8(Bin, Bout, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size.
+ */
+static inline void
+blockmix_salsa8(const __m128i *Bin, __m128i *Bout, size_t r)
+{
+ __m128i X0, X1, X2, X3;
+ size_t i;
+
+ /* 1: X <-- B_{2r - 1} */
+ X0 = Bin[8 * r - 4];
+ X1 = Bin[8 * r - 3];
+ X2 = Bin[8 * r - 2];
+ X3 = Bin[8 * r - 1];
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ SALSA20_8_XOR(Bin, Bout)
+
+ /* 2: for i = 0 to 2r - 1 do */
+ r--;
+ for (i = 0; i < r;) {
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+ i++;
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4])
+ }
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+}
+
+# define XOR4(in) \
+ X0 = _mm_xor_si128(X0, (in)[0]); \
+ X1 = _mm_xor_si128(X1, (in)[1]); \
+ X2 = _mm_xor_si128(X2, (in)[2]); \
+ X3 = _mm_xor_si128(X3, (in)[3]);
+
+# define XOR4_2(in1, in2) \
+ X0 = _mm_xor_si128((in1)[0], (in2)[0]); \
+ X1 = _mm_xor_si128((in1)[1], (in2)[1]); \
+ X2 = _mm_xor_si128((in1)[2], (in2)[2]); \
+ X3 = _mm_xor_si128((in1)[3], (in2)[3]);
+
+static inline uint32_t
+blockmix_salsa8_xor(const __m128i *Bin1, const __m128i *Bin2, __m128i *Bout,
+ size_t r)
+{
+ __m128i X0, X1, X2, X3;
+ size_t i;
+
+ /* 1: X <-- B_{2r - 1} */
+ XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4])
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ XOR4(Bin1)
+ SALSA20_8_XOR(Bin2, Bout)
+
+ /* 2: for i = 0 to 2r - 1 do */
+ r--;
+ for (i = 0; i < r;) {
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ XOR4(&Bin1[i * 8 + 4])
+ SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+ i++;
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ XOR4(&Bin1[i * 8])
+ SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4])
+ }
+
+ /* 3: X <-- H(X \xor B_i) */
+ /* 4: Y_i <-- X */
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+ XOR4(&Bin1[i * 8 + 4])
+ SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
+
+ return _mm_cvtsi128_si32(X0);
+}
+
+# undef ARX
+# undef SALSA20_2ROUNDS
+# undef SALSA20_8_XOR
+# undef XOR4
+# undef XOR4_2
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ * Note that B's layout is permuted compared to the generic implementation.
+ */
+static inline uint32_t
+integerify(const void *B, size_t r)
+{
+ return *(const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64);
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length. The value N must be a
+ * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+static void
+smix(uint8_t *B, size_t r, uint32_t N, void *V, void *XY)
+{
+ size_t s = 128 * r;
+ __m128i * X = (__m128i *) V, *Y;
+ uint32_t *X32 = (uint32_t *) V;
+ uint32_t i, j;
+ size_t k;
+
+ /* 1: X <-- B */
+ /* 3: V_i <-- X */
+ for (k = 0; k < 2 * r; k++) {
+ for (i = 0; i < 16; i++) {
+ X32[k * 16 + i] = LOAD32_LE(&B[(k * 16 + (i * 5 % 16)) * 4]);
+ }
+ }
+
+ /* 2: for i = 0 to N - 1 do */
+ for (i = 1; i < N - 1; i += 2) {
+ /* 4: X <-- H(X) */
+ /* 3: V_i <-- X */
+ Y = (__m128i *) ((uintptr_t)(V) + i * s);
+ blockmix_salsa8(X, Y, r);
+
+ /* 4: X <-- H(X) */
+ /* 3: V_i <-- X */
+ X = (__m128i *) ((uintptr_t)(V) + (i + 1) * s);
+ blockmix_salsa8(Y, X, r);
+ }
+
+ /* 4: X <-- H(X) */
+ /* 3: V_i <-- X */
+ Y = (__m128i *) ((uintptr_t)(V) + i * s);
+ blockmix_salsa8(X, Y, r);
+
+ /* 4: X <-- H(X) */
+ /* 3: V_i <-- X */
+ X = (__m128i *) XY;
+ blockmix_salsa8(Y, X, r);
+
+ X32 = (uint32_t *) XY;
+ Y = (__m128i *) ((uintptr_t)(XY) + s);
+
+ /* 7: j <-- Integerify(X) mod N */
+ j = integerify(X, r) & (N - 1);
+
+ /* 6: for i = 0 to N - 1 do */
+ for (i = 0; i < N; i += 2) {
+ __m128i *V_j = (__m128i *) ((uintptr_t)(V) + j * s);
+
+ /* 8: X <-- H(X \xor V_j) */
+ /* 7: j <-- Integerify(X) mod N */
+ j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1);
+ V_j = (__m128i *) ((uintptr_t)(V) + j * s);
+
+ /* 8: X <-- H(X \xor V_j) */
+ /* 7: j <-- Integerify(X) mod N */
+ j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1);
+ }
+
+ /* 10: B' <-- X */
+ for (k = 0; k < 2 * r; k++) {
+ for (i = 0; i < 16; i++) {
+ STORE32_LE(&B[(k * 16 + (i * 5 % 16)) * 4], X32[k * 16 + i]);
+ }
+ }
+}
+
+/**
+ * escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
+ * N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen,
+ const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t _r,
+ uint32_t _p, uint8_t *buf, size_t buflen)
+{
+ size_t B_size, V_size, XY_size, need;
+ uint8_t * B;
+ uint32_t *V, *XY;
+ size_t r = _r, p = _p;
+ uint32_t i;
+
+/* Sanity-check parameters. */
+# if SIZE_MAX > UINT32_MAX
+/* LCOV_EXCL_START */
+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+ errno = EFBIG;
+ return -1;
+ }
+/* LCOV_EXCL_END */
+# endif
+ if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (N > UINT32_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
+ if (((N & (N - 1)) != 0) || (N < 2)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (r == 0 || p == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+/* LCOV_EXCL_START */
+ if ((r > SIZE_MAX / 128 / p) ||
+# if SIZE_MAX / 256 <= UINT32_MAX
+ (r > SIZE_MAX / 256) ||
+# endif
+ (N > SIZE_MAX / 128 / r)) {
+ errno = ENOMEM;
+ return -1;
+ }
+/* LCOV_EXCL_END */
+
+ /* Allocate memory. */
+ B_size = (size_t) 128 * r * p;
+ V_size = (size_t) 128 * r * N;
+ need = B_size + V_size;
+/* LCOV_EXCL_START */
+ if (need < V_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+/* LCOV_EXCL_END */
+ XY_size = (size_t) 256 * r + 64;
+ need += XY_size;
+/* LCOV_EXCL_START */
+ if (need < XY_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+/* LCOV_EXCL_END */
+ if (local->size < need) {
+ if (free_region(local)) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (!alloc_region(local, need)) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ }
+ B = (uint8_t *) local->aligned;
+ V = (uint32_t *) ((uint8_t *) B + B_size);
+ XY = (uint32_t *) ((uint8_t *) V + V_size);
+
+ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
+
+ /* 2: for i = 0 to p - 1 do */
+ for (i = 0; i < p; i++) {
+ /* 3: B_i <-- MF(B_i, N) */
+ smix(&B[(size_t) 128 * i * r], r, (uint32_t) N, V, XY);
+ }
+
+ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+ PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
+
+ /* Success! */
+ return 0;
+}
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c b/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c
new file mode 100644
index 0000000000..9afffce8a9
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c
@@ -0,0 +1,33 @@
+
+#include "crypto_scalarmult.h"
+
+const char *
+crypto_scalarmult_primitive(void)
+{
+ return crypto_scalarmult_PRIMITIVE;
+}
+
+int
+crypto_scalarmult_base(unsigned char *q, const unsigned char *n)
+{
+ return crypto_scalarmult_curve25519_base(q, n);
+}
+
+int
+crypto_scalarmult(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+{
+ return crypto_scalarmult_curve25519(q, n, p);
+}
+
+size_t
+crypto_scalarmult_bytes(void)
+{
+ return crypto_scalarmult_BYTES;
+}
+
+size_t
+crypto_scalarmult_scalarbytes(void)
+{
+ return crypto_scalarmult_SCALARBYTES;
+}
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c
new file mode 100644
index 0000000000..7b93a7247b
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c
@@ -0,0 +1,159 @@
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "../scalarmult_curve25519.h"
+#include "export.h"
+#include "private/ed25519_ref10.h"
+#include "utils.h"
+#include "x25519_ref10.h"
+
+/*
+ * Reject small order points early to mitigate the implications of
+ * unexpected optimizations that would affect the ref10 code.
+ * See https://eprint.iacr.org/2017/806.pdf for reference.
+ */
+static int
+has_small_order(const unsigned char s[32])
+{
+ CRYPTO_ALIGN(16)
+ static const unsigned char blacklist[][32] = {
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
+ { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
+ { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
+ { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
+ { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
+ };
+ unsigned char c[12] = { 0 };
+ unsigned int k;
+ size_t i, j;
+
+ COMPILER_ASSERT(12 == sizeof blacklist / sizeof blacklist[0]);
+ for (j = 0; j < 32; j++) {
+ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) {
+ c[i] |= s[j] ^ blacklist[i][j];
+ }
+ }
+ k = 0;
+ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) {
+ k |= (c[i] - 1);
+ }
+ return (int) ((k >> 8) & 1);
+}
+
+static int
+crypto_scalarmult_curve25519_ref10(unsigned char *q,
+ const unsigned char *n,
+ const unsigned char *p)
+{
+ unsigned char *t = q;
+ unsigned int i;
+ fe25519 x1;
+ fe25519 x2;
+ fe25519 z2;
+ fe25519 x3;
+ fe25519 z3;
+ fe25519 tmp0;
+ fe25519 tmp1;
+ int pos;
+ unsigned int swap;
+ unsigned int b;
+
+ if (has_small_order(p)) {
+ return -1;
+ }
+ for (i = 0; i < 32; i++) {
+ t[i] = n[i];
+ }
+ t[0] &= 248;
+ t[31] &= 127;
+ t[31] |= 64;
+ fe25519_frombytes(x1, p);
+ fe25519_1(x2);
+ fe25519_0(z2);
+ fe25519_copy(x3, x1);
+ fe25519_1(z3);
+
+ swap = 0;
+ for (pos = 254; pos >= 0; --pos) {
+ b = t[pos / 8] >> (pos & 7);
+ b &= 1;
+ swap ^= b;
+ fe25519_cswap(x2, x3, swap);
+ fe25519_cswap(z2, z3, swap);
+ swap = b;
+ fe25519_sub(tmp0, x3, z3);
+ fe25519_sub(tmp1, x2, z2);
+ fe25519_add(x2, x2, z2);
+ fe25519_add(z2, x3, z3);
+ fe25519_mul(z3, tmp0, x2);
+ fe25519_mul(z2, z2, tmp1);
+ fe25519_sq(tmp0, tmp1);
+ fe25519_sq(tmp1, x2);
+ fe25519_add(x3, z3, z2);
+ fe25519_sub(z2, z3, z2);
+ fe25519_mul(x2, tmp1, tmp0);
+ fe25519_sub(tmp1, tmp1, tmp0);
+ fe25519_sq(z2, z2);
+ fe25519_scalar_product(z3, tmp1, 121666);
+ fe25519_sq(x3, x3);
+ fe25519_add(tmp0, tmp0, z3);
+ fe25519_mul(z3, x1, z2);
+ fe25519_mul(z2, tmp1, tmp0);
+ }
+ fe25519_cswap(x2, x3, swap);
+ fe25519_cswap(z2, z3, swap);
+
+ fe25519_invert(z2, z2);
+ fe25519_mul(x2, x2, z2);
+ fe25519_tobytes(q, x2);
+
+ return 0;
+}
+
+static void
+edwards_to_montgomery(fe25519 montgomeryX, const fe25519 edwardsY, const fe25519 edwardsZ)
+{
+ fe25519 tempX;
+ fe25519 tempZ;
+
+ fe25519_add(tempX, edwardsZ, edwardsY);
+ fe25519_sub(tempZ, edwardsZ, edwardsY);
+ fe25519_invert(tempZ, tempZ);
+ fe25519_mul(montgomeryX, tempX, tempZ);
+}
+
+static int
+crypto_scalarmult_curve25519_ref10_base(unsigned char *q,
+ const unsigned char *n)
+{
+ unsigned char *t = q;
+ ge25519_p3 A;
+ fe25519 pk;
+ unsigned int i;
+
+ for (i = 0; i < 32; i++) {
+ t[i] = n[i];
+ }
+ t[0] &= 248;
+ t[31] &= 127;
+ t[31] |= 64;
+ ge25519_scalarmult_base(&A, t);
+ edwards_to_montgomery(pk, A.Y, A.Z);
+ fe25519_tobytes(q, pk);
+
+ return 0;
+}
+
+struct crypto_scalarmult_curve25519_implementation
+ crypto_scalarmult_curve25519_ref10_implementation = {
+ SODIUM_C99(.mult =) crypto_scalarmult_curve25519_ref10,
+ SODIUM_C99(.mult_base =) crypto_scalarmult_curve25519_ref10_base
+ };
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h
new file mode 100644
index 0000000000..ea52a62a69
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h
@@ -0,0 +1,10 @@
+#ifndef x25519_ref10_H
+#define x25519_ref10_H
+
+#include "crypto_scalarmult_curve25519.h"
+#include "../scalarmult_curve25519.h"
+
+extern struct crypto_scalarmult_curve25519_implementation
+ crypto_scalarmult_curve25519_ref10_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S
new file mode 100644
index 0000000000..67f1f0183e
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S
@@ -0,0 +1,25 @@
+#ifdef IN_SANDY2X
+
+/*
+ REDMASK51 is from amd64-51/consts.s.
+*/
+
+#include "consts_namespace.h"
+.data
+.p2align 4
+v0_0: .quad 0, 0
+v1_0: .quad 1, 0
+v2_1: .quad 2, 1
+v9_0: .quad 9, 0
+v9_9: .quad 9, 9
+v19_19: .quad 19, 19
+v38_1: .quad 38, 1
+v38_38: .quad 38, 38
+v121666_121666: .quad 121666, 121666
+m25: .quad 33554431, 33554431
+m26: .quad 67108863, 67108863
+subc0: .quad 0x07FFFFDA, 0x03FFFFFE
+subc2: .quad 0x07FFFFFE, 0x03FFFFFE
+REDMASK51: .quad 0x0007FFFFFFFFFFFF
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h
new file mode 100644
index 0000000000..9f81fa61c4
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h
@@ -0,0 +1,20 @@
+#ifndef consts_namespace_H
+#define consts_namespace_H
+
+#define v0_0 crypto_scalarmult_curve25519_sandy2x_v0_0
+#define v1_0 crypto_scalarmult_curve25519_sandy2x_v1_0
+#define v2_1 crypto_scalarmult_curve25519_sandy2x_v2_1
+#define v9_0 crypto_scalarmult_curve25519_sandy2x_v9_0
+#define v9_9 crypto_scalarmult_curve25519_sandy2x_v9_9
+#define v19_19 crypto_scalarmult_curve25519_sandy2x_v19_19
+#define v38_1 crypto_scalarmult_curve25519_sandy2x_v38_1
+#define v38_38 crypto_scalarmult_curve25519_sandy2x_v38_38
+#define v121666_121666 crypto_scalarmult_curve25519_sandy2x_v121666_121666
+#define m25 crypto_scalarmult_curve25519_sandy2x_m25
+#define m26 crypto_scalarmult_curve25519_sandy2x_m26
+#define subc0 crypto_scalarmult_curve25519_sandy2x_subc0
+#define subc2 crypto_scalarmult_curve25519_sandy2x_subc2
+#define REDMASK51 crypto_scalarmult_curve25519_sandy2x_REDMASK51
+
+#endif /* ifndef consts_namespace_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c
new file mode 100644
index 0000000000..98b7cf79e5
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c
@@ -0,0 +1,114 @@
+/*
+ This file is adapted from ref10/scalarmult.c:
+ The code for Mongomery ladder is replace by the ladder assembly function;
+ Inversion is done in the same way as amd64-51/.
+ (fe is first converted into fe51 after Mongomery ladder)
+*/
+
+#include <stddef.h>
+
+#ifdef HAVE_AVX_ASM
+
+#include "utils.h"
+#include "curve25519_sandy2x.h"
+#include "../scalarmult_curve25519.h"
+#include "fe.h"
+#include "fe51.h"
+#include "ladder.h"
+#include "ladder_base.h"
+
+#define x1 var[0]
+#define x2 var[1]
+#define z2 var[2]
+
+static int
+crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+{
+ unsigned char *t = q;
+ fe var[3];
+ fe51 x_51;
+ fe51 z_51;
+ unsigned int i;
+
+ for (i = 0; i < 32; i++) {
+ t[i] = n[i];
+ }
+ t[0] &= 248;
+ t[31] &= 127;
+ t[31] |= 64;
+
+ fe_frombytes(x1, p);
+
+ ladder(var, t);
+
+ z_51.v[0] = (z2[1] << 26) + z2[0];
+ z_51.v[1] = (z2[3] << 26) + z2[2];
+ z_51.v[2] = (z2[5] << 26) + z2[4];
+ z_51.v[3] = (z2[7] << 26) + z2[6];
+ z_51.v[4] = (z2[9] << 26) + z2[8];
+
+ x_51.v[0] = (x2[1] << 26) + x2[0];
+ x_51.v[1] = (x2[3] << 26) + x2[2];
+ x_51.v[2] = (x2[5] << 26) + x2[4];
+ x_51.v[3] = (x2[7] << 26) + x2[6];
+ x_51.v[4] = (x2[9] << 26) + x2[8];
+
+ fe51_invert(&z_51, &z_51);
+ fe51_mul(&x_51, &x_51, &z_51);
+ fe51_pack(q, &x_51);
+
+ return 0;
+}
+
+#undef x2
+#undef z2
+
+#define x2 var[0]
+#define z2 var[1]
+
+static int
+crypto_scalarmult_curve25519_sandy2x_base(unsigned char *q,
+ const unsigned char *n)
+{
+ unsigned char *t = q;
+ fe var[3];
+ fe51 x_51;
+ fe51 z_51;
+ unsigned int i;
+
+ for (i = 0;i < 32; i++) {
+ t[i] = n[i];
+ }
+ t[0] &= 248;
+ t[31] &= 127;
+ t[31] |= 64;
+
+ ladder_base(var, t);
+
+ z_51.v[0] = (z2[1] << 26) + z2[0];
+ z_51.v[1] = (z2[3] << 26) + z2[2];
+ z_51.v[2] = (z2[5] << 26) + z2[4];
+ z_51.v[3] = (z2[7] << 26) + z2[6];
+ z_51.v[4] = (z2[9] << 26) + z2[8];
+
+ x_51.v[0] = (x2[1] << 26) + x2[0];
+ x_51.v[1] = (x2[3] << 26) + x2[2];
+ x_51.v[2] = (x2[5] << 26) + x2[4];
+ x_51.v[3] = (x2[7] << 26) + x2[6];
+ x_51.v[4] = (x2[9] << 26) + x2[8];
+
+ fe51_invert(&z_51, &z_51);
+ fe51_mul(&x_51, &x_51, &z_51);
+ fe51_pack(q, &x_51);
+
+ return 0;
+}
+
+struct crypto_scalarmult_curve25519_implementation
+crypto_scalarmult_curve25519_sandy2x_implementation = {
+ SODIUM_C99(.mult = ) crypto_scalarmult_curve25519_sandy2x,
+ SODIUM_C99(.mult_base = ) crypto_scalarmult_curve25519_sandy2x_base
+};
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h
new file mode 100644
index 0000000000..f02d980187
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h
@@ -0,0 +1,9 @@
+#ifndef curve25519_sandy2x_H
+#define curve25519_sandy2x_H
+
+#include "crypto_scalarmult_curve25519.h"
+
+extern struct crypto_scalarmult_curve25519_implementation
+ crypto_scalarmult_curve25519_sandy2x_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h
new file mode 100644
index 0000000000..b1115f8691
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h
@@ -0,0 +1,26 @@
+/*
+ This file is adapted from ref10/fe.h:
+ All the redundant functions are removed.
+*/
+
+#ifndef fe_H
+#define fe_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef uint64_t fe[10];
+
+/*
+fe means field element.
+Here the field is \Z/(2^255-19).
+An element t, entries t[0]...t[9], represents the integer
+t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
+Bounds on each t[i] vary depending on context.
+*/
+
+#define fe_frombytes crypto_scalarmult_curve25519_sandy2x_fe_frombytes
+
+extern void fe_frombytes(fe, const unsigned char *);
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h
new file mode 100644
index 0000000000..8e3f199b24
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h
@@ -0,0 +1,35 @@
+/*
+ This file is adapted from amd64-51/fe25519.h:
+ 'fe25519' is renamed as 'fe51';
+ All the redundant functions are removed;
+ New function fe51_nsquare is introduced.
+*/
+
+#ifndef fe51_H
+#define fe51_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "fe51_namespace.h"
+
+typedef struct
+{
+ uint64_t v[5];
+}
+fe51;
+
+extern void fe51_pack(unsigned char *, const fe51 *);
+extern void fe51_mul(fe51 *, const fe51 *, const fe51 *);
+extern void fe51_nsquare(fe51 *, const fe51 *, int);
+extern void fe51_invert(fe51 *, const fe51 *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c
new file mode 100644
index 0000000000..ec9bb1a91f
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c
@@ -0,0 +1,58 @@
+/*
+ This file is adapted from amd64-51/fe25519_invert.c:
+ Loops of squares are replaced by nsquares for better performance.
+*/
+
+#include "fe51.h"
+
+#ifdef HAVE_AVX_ASM
+
+#define fe51_square(x, y) fe51_nsquare(x, y, 1)
+
+void
+fe51_invert(fe51 *r, const fe51 *x)
+{
+ fe51 z2;
+ fe51 z9;
+ fe51 z11;
+ fe51 z2_5_0;
+ fe51 z2_10_0;
+ fe51 z2_20_0;
+ fe51 z2_50_0;
+ fe51 z2_100_0;
+ fe51 t;
+
+ /* 2 */ fe51_square(&z2,x);
+ /* 4 */ fe51_square(&t,&z2);
+ /* 8 */ fe51_square(&t,&t);
+ /* 9 */ fe51_mul(&z9,&t,x);
+ /* 11 */ fe51_mul(&z11,&z9,&z2);
+ /* 22 */ fe51_square(&t,&z11);
+ /* 2^5 - 2^0 = 31 */ fe51_mul(&z2_5_0,&t,&z9);
+
+ /* 2^10 - 2^5 */ fe51_nsquare(&t,&z2_5_0, 5);
+ /* 2^10 - 2^0 */ fe51_mul(&z2_10_0,&t,&z2_5_0);
+
+ /* 2^20 - 2^10 */ fe51_nsquare(&t,&z2_10_0, 10);
+ /* 2^20 - 2^0 */ fe51_mul(&z2_20_0,&t,&z2_10_0);
+
+ /* 2^40 - 2^20 */ fe51_nsquare(&t,&z2_20_0, 20);
+ /* 2^40 - 2^0 */ fe51_mul(&t,&t,&z2_20_0);
+
+ /* 2^50 - 2^10 */ fe51_nsquare(&t,&t,10);
+ /* 2^50 - 2^0 */ fe51_mul(&z2_50_0,&t,&z2_10_0);
+
+ /* 2^100 - 2^50 */ fe51_nsquare(&t,&z2_50_0, 50);
+ /* 2^100 - 2^0 */ fe51_mul(&z2_100_0,&t,&z2_50_0);
+
+ /* 2^200 - 2^100 */ fe51_nsquare(&t,&z2_100_0, 100);
+ /* 2^200 - 2^0 */ fe51_mul(&t,&t,&z2_100_0);
+
+ /* 2^250 - 2^50 */ fe51_nsquare(&t,&t, 50);
+ /* 2^250 - 2^0 */ fe51_mul(&t,&t,&z2_50_0);
+
+ /* 2^255 - 2^5 */ fe51_nsquare(&t,&t,5);
+ /* 2^255 - 21 */ fe51_mul(r,&t,&z11);
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S
new file mode 100644
index 0000000000..83501b0395
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S
@@ -0,0 +1,197 @@
+#ifdef IN_SANDY2X
+
+/*
+ This file is basically amd64-51/fe25519_mul.s.
+*/
+#include "fe51_namespace.h"
+#include "consts_namespace.h"
+.text
+.p2align 5
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL fe51_mul
+ASM_HIDE_SYMBOL _fe51_mul
+#endif
+.globl fe51_mul
+.globl _fe51_mul
+#ifdef __ELF__
+.type fe51_mul, @function
+.type _fe51_mul, @function
+#endif
+fe51_mul:
+_fe51_mul:
+mov %rsp,%r11
+and $31,%r11
+add $96,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq %rdi,56(%rsp)
+mov %rdx,%rcx
+movq 24(%rsi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,64(%rsp)
+mulq 16(%rcx)
+mov %rax,%r8
+mov %rdx,%r9
+movq 32(%rsi),%rdx
+imulq $19,%rdx,%rax
+movq %rax,72(%rsp)
+mulq 8(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 0(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 0(%rsi),%rax
+mulq 8(%rcx)
+mov %rax,%r10
+mov %rdx,%r11
+movq 0(%rsi),%rax
+mulq 16(%rcx)
+mov %rax,%r12
+mov %rdx,%r13
+movq 0(%rsi),%rax
+mulq 24(%rcx)
+mov %rax,%r14
+mov %rdx,%r15
+movq 0(%rsi),%rax
+mulq 32(%rcx)
+mov %rax,%rbx
+mov %rdx,%rbp
+movq 8(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 8(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 8(%rsi),%rax
+mulq 16(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 8(%rsi),%rax
+mulq 24(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 8(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 16(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 16(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 16(%rsi),%rax
+mulq 16(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 16(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 24(%rcx)
+add %rax,%r8
+adc %rdx,%r9
+movq 16(%rsi),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 24(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq 24(%rsi),%rax
+mulq 8(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 64(%rsp),%rax
+mulq 24(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 64(%rsp),%rax
+mulq 32(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 32(%rsi),%rax
+mulq 0(%rcx)
+add %rax,%rbx
+adc %rdx,%rbp
+movq 72(%rsp),%rax
+mulq 16(%rcx)
+add %rax,%r10
+adc %rdx,%r11
+movq 72(%rsp),%rax
+mulq 24(%rcx)
+add %rax,%r12
+adc %rdx,%r13
+movq 72(%rsp),%rax
+mulq 32(%rcx)
+add %rax,%r14
+adc %rdx,%r15
+movq REDMASK51(%rip),%rsi
+shld $13,%r8,%r9
+and %rsi,%r8
+shld $13,%r10,%r11
+and %rsi,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rsi,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rsi,%r14
+add %r13,%r14
+shld $13,%rbx,%rbp
+and %rsi,%rbx
+add %r15,%rbx
+imulq $19,%rbp,%rdx
+add %rdx,%r8
+mov %r8,%rdx
+shr $51,%rdx
+add %r10,%rdx
+mov %rdx,%rcx
+shr $51,%rdx
+and %rsi,%r8
+add %r12,%rdx
+mov %rdx,%r9
+shr $51,%rdx
+and %rsi,%rcx
+add %r14,%rdx
+mov %rdx,%rax
+shr $51,%rdx
+and %rsi,%r9
+add %rbx,%rdx
+mov %rdx,%r10
+shr $51,%rdx
+and %rsi,%rax
+imulq $19,%rdx,%rdx
+add %rdx,%r8
+and %rsi,%r10
+movq %r8,0(%rdi)
+movq %rcx,8(%rdi)
+movq %r9,16(%rdi)
+movq %rax,24(%rdi)
+movq %r10,32(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+mov %rdi,%rax
+mov %rsi,%rdx
+ret
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h
new file mode 100644
index 0000000000..057f242ca1
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h
@@ -0,0 +1,16 @@
+#ifndef fe51_namespace_H
+#define fe51_namespace_H
+
+#define fe51 crypto_scalarmult_curve25519_sandy2x_fe51
+#define _fe51 _crypto_scalarmult_curve25519_sandy2x_fe51
+#define fe51_pack crypto_scalarmult_curve25519_sandy2x_fe51_pack
+#define _fe51_pack _crypto_scalarmult_curve25519_sandy2x_fe51_pack
+#define fe51_mul crypto_scalarmult_curve25519_sandy2x_fe51_mul
+#define _fe51_mul _crypto_scalarmult_curve25519_sandy2x_fe51_mul
+#define fe51_nsquare crypto_scalarmult_curve25519_sandy2x_fe51_nsquare
+#define _fe51_nsquare _crypto_scalarmult_curve25519_sandy2x_fe51_nsquare
+
+#define fe51_invert crypto_scalarmult_curve25519_sandy2x_fe51_invert
+
+#endif /* ifndef fe51_namespace_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S
new file mode 100644
index 0000000000..41c3054805
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S
@@ -0,0 +1,172 @@
+#ifdef IN_SANDY2X
+
+/*
+ This file is adapted from amd64-51/fe25519_square.s:
+ Adding loop to perform n squares.
+*/
+#include "fe51_namespace.h"
+#include "consts_namespace.h"
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL fe51_nsquare
+ASM_HIDE_SYMBOL _fe51_nsquare
+#endif
+.globl fe51_nsquare
+.globl _fe51_nsquare
+#ifdef __ELF__
+.type fe51_nsquare, @function
+.type _fe51_nsquare, @function
+#endif
+fe51_nsquare:
+_fe51_nsquare:
+
+mov %rsp,%r11
+and $31,%r11
+add $64,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq %r13,16(%rsp)
+movq %r14,24(%rsp)
+movq %r15,32(%rsp)
+movq %rbx,40(%rsp)
+movq %rbp,48(%rsp)
+movq 0(%rsi),%rcx
+movq 8(%rsi),%r8
+movq 16(%rsi),%r9
+movq 24(%rsi),%rax
+movq 32(%rsi),%rsi
+movq %r9,16(%rdi)
+movq %rax,24(%rdi)
+movq %rsi,32(%rdi)
+mov %rdx,%rsi
+
+.p2align 4
+._loop:
+sub $1,%rsi
+mov %rcx,%rax
+mul %rcx
+add %rcx,%rcx
+mov %rax,%r9
+mov %rdx,%r10
+mov %rcx,%rax
+mul %r8
+mov %rax,%r11
+mov %rdx,%r12
+mov %rcx,%rax
+mulq 16(%rdi)
+mov %rax,%r13
+mov %rdx,%r14
+mov %rcx,%rax
+mulq 24(%rdi)
+mov %rax,%r15
+mov %rdx,%rbx
+mov %rcx,%rax
+mulq 32(%rdi)
+mov %rax,%rcx
+mov %rdx,%rbp
+mov %r8,%rax
+mul %r8
+add %r8,%r8
+add %rax,%r13
+adc %rdx,%r14
+mov %r8,%rax
+mulq 16(%rdi)
+add %rax,%r15
+adc %rdx,%rbx
+mov %r8,%rax
+imulq $19, %r8,%r8
+mulq 24(%rdi)
+add %rax,%rcx
+adc %rdx,%rbp
+mov %r8,%rax
+mulq 32(%rdi)
+add %rax,%r9
+adc %rdx,%r10
+movq 16(%rdi),%rax
+mulq 16(%rdi)
+add %rax,%rcx
+adc %rdx,%rbp
+shld $13,%rcx,%rbp
+movq 16(%rdi),%rax
+imulq $38, %rax,%rax
+mulq 24(%rdi)
+add %rax,%r9
+adc %rdx,%r10
+shld $13,%r9,%r10
+movq 16(%rdi),%rax
+imulq $38, %rax,%rax
+mulq 32(%rdi)
+add %rax,%r11
+adc %rdx,%r12
+movq 24(%rdi),%rax
+imulq $19, %rax,%rax
+mulq 24(%rdi)
+add %rax,%r11
+adc %rdx,%r12
+shld $13,%r11,%r12
+movq 24(%rdi),%rax
+imulq $38, %rax,%rax
+mulq 32(%rdi)
+add %rax,%r13
+adc %rdx,%r14
+shld $13,%r13,%r14
+movq 32(%rdi),%rax
+imulq $19, %rax,%rax
+mulq 32(%rdi)
+add %rax,%r15
+adc %rdx,%rbx
+shld $13,%r15,%rbx
+movq REDMASK51(%rip),%rdx
+and %rdx,%rcx
+add %rbx,%rcx
+and %rdx,%r9
+and %rdx,%r11
+add %r10,%r11
+and %rdx,%r13
+add %r12,%r13
+and %rdx,%r15
+add %r14,%r15
+imulq $19, %rbp,%rbp
+lea (%r9,%rbp),%r9
+mov %r9,%rax
+shr $51,%r9
+add %r11,%r9
+and %rdx,%rax
+mov %r9,%r8
+shr $51,%r9
+add %r13,%r9
+and %rdx,%r8
+mov %r9,%r10
+shr $51,%r9
+add %r15,%r9
+and %rdx,%r10
+movq %r10,16(%rdi)
+mov %r9,%r10
+shr $51,%r9
+add %rcx,%r9
+and %rdx,%r10
+movq %r10,24(%rdi)
+mov %r9,%r10
+shr $51,%r9
+imulq $19, %r9,%r9
+lea (%rax,%r9),%rcx
+and %rdx,%r10
+movq %r10,32(%rdi)
+cmp $0,%rsi
+jne ._loop
+
+movq %rcx,0(%rdi)
+movq %r8,8(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+movq 16(%rsp),%r13
+movq 24(%rsp),%r14
+movq 32(%rsp),%r15
+movq 40(%rsp),%rbx
+movq 48(%rsp),%rbp
+add %r11,%rsp
+ret
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S
new file mode 100644
index 0000000000..500c858476
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S
@@ -0,0 +1,226 @@
+#ifdef IN_SANDY2X
+
+/*
+ This file is the result of merging
+ amd64-51/fe25519_pack.c and amd64-51/fe25519_freeze.s.
+*/
+#include "fe51_namespace.h"
+#include "consts_namespace.h"
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL fe51_pack
+ASM_HIDE_SYMBOL _fe51_pack
+#endif
+.globl fe51_pack
+.globl _fe51_pack
+#ifdef __ELF__
+.type fe51_pack, @function
+.type _fe51_pack, @function
+#endif
+fe51_pack:
+_fe51_pack:
+
+mov %rsp,%r11
+and $31,%r11
+add $32,%r11
+sub %r11,%rsp
+movq %r11,0(%rsp)
+movq %r12,8(%rsp)
+movq 0(%rsi),%rdx
+movq 8(%rsi),%rcx
+movq 16(%rsi),%r8
+movq 24(%rsi),%r9
+movq 32(%rsi),%rsi
+movq REDMASK51(%rip),%rax
+lea -18(%rax),%r10
+mov $3,%r11
+
+.p2align 4
+._reduceloop:
+mov %rdx,%r12
+shr $51,%r12
+and %rax,%rdx
+add %r12,%rcx
+mov %rcx,%r12
+shr $51,%r12
+and %rax,%rcx
+add %r12,%r8
+mov %r8,%r12
+shr $51,%r12
+and %rax,%r8
+add %r12,%r9
+mov %r9,%r12
+shr $51,%r12
+and %rax,%r9
+add %r12,%rsi
+mov %rsi,%r12
+shr $51,%r12
+and %rax,%rsi
+imulq $19, %r12,%r12
+add %r12,%rdx
+sub $1,%r11
+ja ._reduceloop
+
+mov $1,%r12
+cmp %r10,%rdx
+cmovl %r11,%r12
+cmp %rax,%rcx
+cmovne %r11,%r12
+cmp %rax,%r8
+cmovne %r11,%r12
+cmp %rax,%r9
+cmovne %r11,%r12
+cmp %rax,%rsi
+cmovne %r11,%r12
+neg %r12
+and %r12,%rax
+and %r12,%r10
+sub %r10,%rdx
+sub %rax,%rcx
+sub %rax,%r8
+sub %rax,%r9
+sub %rax,%rsi
+mov %rdx,%rax
+and $0xFF,%eax
+movb %al,0(%rdi)
+mov %rdx,%rax
+shr $8,%rax
+and $0xFF,%eax
+movb %al,1(%rdi)
+mov %rdx,%rax
+shr $16,%rax
+and $0xFF,%eax
+movb %al,2(%rdi)
+mov %rdx,%rax
+shr $24,%rax
+and $0xFF,%eax
+movb %al,3(%rdi)
+mov %rdx,%rax
+shr $32,%rax
+and $0xFF,%eax
+movb %al,4(%rdi)
+mov %rdx,%rax
+shr $40,%rax
+and $0xFF,%eax
+movb %al,5(%rdi)
+mov %rdx,%rdx
+shr $48,%rdx
+mov %rcx,%rax
+shl $3,%rax
+and $0xF8,%eax
+xor %rdx,%rax
+movb %al,6(%rdi)
+mov %rcx,%rdx
+shr $5,%rdx
+and $0xFF,%edx
+movb %dl,7(%rdi)
+mov %rcx,%rdx
+shr $13,%rdx
+and $0xFF,%edx
+movb %dl,8(%rdi)
+mov %rcx,%rdx
+shr $21,%rdx
+and $0xFF,%edx
+movb %dl,9(%rdi)
+mov %rcx,%rdx
+shr $29,%rdx
+and $0xFF,%edx
+movb %dl,10(%rdi)
+mov %rcx,%rdx
+shr $37,%rdx
+and $0xFF,%edx
+movb %dl,11(%rdi)
+mov %rcx,%rdx
+shr $45,%rdx
+mov %r8,%rcx
+shl $6,%rcx
+and $0xC0,%ecx
+xor %rdx,%rcx
+movb %cl,12(%rdi)
+mov %r8,%rdx
+shr $2,%rdx
+and $0xFF,%edx
+movb %dl,13(%rdi)
+mov %r8,%rdx
+shr $10,%rdx
+and $0xFF,%edx
+movb %dl,14(%rdi)
+mov %r8,%rdx
+shr $18,%rdx
+and $0xFF,%edx
+movb %dl,15(%rdi)
+mov %r8,%rdx
+shr $26,%rdx
+and $0xFF,%edx
+movb %dl,16(%rdi)
+mov %r8,%rdx
+shr $34,%rdx
+and $0xFF,%edx
+movb %dl,17(%rdi)
+mov %r8,%rdx
+shr $42,%rdx
+movb %dl,18(%rdi)
+mov %r8,%rdx
+shr $50,%rdx
+mov %r9,%rcx
+shl $1,%rcx
+and $0xFE,%ecx
+xor %rdx,%rcx
+movb %cl,19(%rdi)
+mov %r9,%rdx
+shr $7,%rdx
+and $0xFF,%edx
+movb %dl,20(%rdi)
+mov %r9,%rdx
+shr $15,%rdx
+and $0xFF,%edx
+movb %dl,21(%rdi)
+mov %r9,%rdx
+shr $23,%rdx
+and $0xFF,%edx
+movb %dl,22(%rdi)
+mov %r9,%rdx
+shr $31,%rdx
+and $0xFF,%edx
+movb %dl,23(%rdi)
+mov %r9,%rdx
+shr $39,%rdx
+and $0xFF,%edx
+movb %dl,24(%rdi)
+mov %r9,%rdx
+shr $47,%rdx
+mov %rsi,%rcx
+shl $4,%rcx
+and $0xF0,%ecx
+xor %rdx,%rcx
+movb %cl,25(%rdi)
+mov %rsi,%rdx
+shr $4,%rdx
+and $0xFF,%edx
+movb %dl,26(%rdi)
+mov %rsi,%rdx
+shr $12,%rdx
+and $0xFF,%edx
+movb %dl,27(%rdi)
+mov %rsi,%rdx
+shr $20,%rdx
+and $0xFF,%edx
+movb %dl,28(%rdi)
+mov %rsi,%rdx
+shr $28,%rdx
+and $0xFF,%edx
+movb %dl,29(%rdi)
+mov %rsi,%rdx
+shr $36,%rdx
+and $0xFF,%edx
+movb %dl,30(%rdi)
+mov %rsi,%rsi
+shr $44,%rsi
+movb %sil,31(%rdi)
+movq 0(%rsp),%r11
+movq 8(%rsp),%r12
+add %r11,%rsp
+ret
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c
new file mode 100644
index 0000000000..2fe081ee2a
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c
@@ -0,0 +1,78 @@
+/*
+ This file is basically ref10/fe_frombytes.h.
+*/
+
+#include "fe.h"
+
+#ifdef HAVE_AVX_ASM
+
+static uint64_t
+load_3(const unsigned char *in)
+{
+ uint64_t result;
+ result = (uint64_t) in[0];
+ result |= ((uint64_t) in[1]) << 8;
+ result |= ((uint64_t) in[2]) << 16;
+ return result;
+}
+
+static uint64_t
+load_4(const unsigned char *in)
+{
+ uint64_t result;
+ result = (uint64_t) in[0];
+ result |= ((uint64_t) in[1]) << 8;
+ result |= ((uint64_t) in[2]) << 16;
+ result |= ((uint64_t) in[3]) << 24;
+ return result;
+}
+
+void
+fe_frombytes(fe h, const unsigned char *s)
+{
+ uint64_t h0 = load_4(s);
+ uint64_t h1 = load_3(s + 4) << 6;
+ uint64_t h2 = load_3(s + 7) << 5;
+ uint64_t h3 = load_3(s + 10) << 3;
+ uint64_t h4 = load_3(s + 13) << 2;
+ uint64_t h5 = load_4(s + 16);
+ uint64_t h6 = load_3(s + 20) << 7;
+ uint64_t h7 = load_3(s + 23) << 5;
+ uint64_t h8 = load_3(s + 26) << 4;
+ uint64_t h9 = (load_3(s + 29) & 8388607) << 2;
+ uint64_t carry0;
+ uint64_t carry1;
+ uint64_t carry2;
+ uint64_t carry3;
+ uint64_t carry4;
+ uint64_t carry5;
+ uint64_t carry6;
+ uint64_t carry7;
+ uint64_t carry8;
+ uint64_t carry9;
+
+ carry9 = h9 >> 25; h0 += carry9 * 19; h9 &= 0x1FFFFFF;
+ carry1 = h1 >> 25; h2 += carry1; h1 &= 0x1FFFFFF;
+ carry3 = h3 >> 25; h4 += carry3; h3 &= 0x1FFFFFF;
+ carry5 = h5 >> 25; h6 += carry5; h5 &= 0x1FFFFFF;
+ carry7 = h7 >> 25; h8 += carry7; h7 &= 0x1FFFFFF;
+
+ carry0 = h0 >> 26; h1 += carry0; h0 &= 0x3FFFFFF;
+ carry2 = h2 >> 26; h3 += carry2; h2 &= 0x3FFFFFF;
+ carry4 = h4 >> 26; h5 += carry4; h4 &= 0x3FFFFFF;
+ carry6 = h6 >> 26; h7 += carry6; h6 &= 0x3FFFFFF;
+ carry8 = h8 >> 26; h9 += carry8; h8 &= 0x3FFFFFF;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S
new file mode 100644
index 0000000000..c5c06021d8
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S
@@ -0,0 +1,1440 @@
+#ifdef IN_SANDY2X
+
+#include "ladder_namespace.h"
+#include "consts_namespace.h"
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL ladder
+ASM_HIDE_SYMBOL _ladder
+#endif
+.globl ladder
+.globl _ladder
+#ifdef __ELF__
+.type ladder, @function
+.type _ladder, @function
+#endif
+ladder:
+_ladder:
+
+mov %rsp,%r11
+and $31,%r11
+add $1856,%r11
+sub %r11,%rsp
+movq %r11,1824(%rsp)
+movq %r12,1832(%rsp)
+movq %r13,1840(%rsp)
+movq %r14,1848(%rsp)
+vmovdqa v0_0(%rip),%xmm0
+vmovdqa v1_0(%rip),%xmm1
+vmovdqu 0(%rdi),%xmm2
+vmovdqa %xmm2,0(%rsp)
+vmovdqu 16(%rdi),%xmm2
+vmovdqa %xmm2,16(%rsp)
+vmovdqu 32(%rdi),%xmm2
+vmovdqa %xmm2,32(%rsp)
+vmovdqu 48(%rdi),%xmm2
+vmovdqa %xmm2,48(%rsp)
+vmovdqu 64(%rdi),%xmm2
+vmovdqa %xmm2,64(%rsp)
+vmovdqa %xmm1,80(%rsp)
+vmovdqa %xmm0,96(%rsp)
+vmovdqa %xmm0,112(%rsp)
+vmovdqa %xmm0,128(%rsp)
+vmovdqa %xmm0,144(%rsp)
+vmovdqa %xmm1,%xmm0
+vpxor %xmm1,%xmm1,%xmm1
+vpxor %xmm2,%xmm2,%xmm2
+vpxor %xmm3,%xmm3,%xmm3
+vpxor %xmm4,%xmm4,%xmm4
+vpxor %xmm5,%xmm5,%xmm5
+vpxor %xmm6,%xmm6,%xmm6
+vpxor %xmm7,%xmm7,%xmm7
+vpxor %xmm8,%xmm8,%xmm8
+vpxor %xmm9,%xmm9,%xmm9
+vmovdqu 0(%rdi),%xmm10
+vmovdqa %xmm10,160(%rsp)
+vmovdqu 16(%rdi),%xmm10
+vmovdqa %xmm10,176(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,192(%rsp)
+vmovdqu 32(%rdi),%xmm10
+vmovdqa %xmm10,208(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,224(%rsp)
+vmovdqu 48(%rdi),%xmm10
+vmovdqa %xmm10,240(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,256(%rsp)
+vmovdqu 64(%rdi),%xmm10
+vmovdqa %xmm10,272(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,288(%rsp)
+vmovdqu 8(%rdi),%xmm10
+vpmuludq v2_1(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,304(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,320(%rsp)
+vmovdqu 24(%rdi),%xmm10
+vpmuludq v2_1(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,336(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,352(%rsp)
+vmovdqu 40(%rdi),%xmm10
+vpmuludq v2_1(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,368(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,384(%rsp)
+vmovdqu 56(%rdi),%xmm10
+vpmuludq v2_1(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,400(%rsp)
+vpmuludq v19_19(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,416(%rsp)
+vmovdqu 0(%rdi),%xmm10
+vmovdqu 64(%rdi),%xmm11
+vblendps $12, %xmm11, %xmm10, %xmm10
+vpshufd $2,%xmm10,%xmm10
+vpmuludq v38_1(%rip),%xmm10,%xmm10
+vmovdqa %xmm10,432(%rsp)
+movq 0(%rsi),%rdx
+movq 8(%rsi),%rcx
+movq 16(%rsi),%r8
+movq 24(%rsi),%r9
+shrd $1,%rcx,%rdx
+shrd $1,%r8,%rcx
+shrd $1,%r9,%r8
+shr $1,%r9
+xorq 0(%rsi),%rdx
+xorq 8(%rsi),%rcx
+xorq 16(%rsi),%r8
+xorq 24(%rsi),%r9
+leaq 800(%rsp),%rsi
+mov $64,%rax
+
+.p2align 4
+._ladder_small_loop:
+mov %rdx,%r10
+mov %rcx,%r11
+mov %r8,%r12
+mov %r9,%r13
+shr $1,%rdx
+shr $1,%rcx
+shr $1,%r8
+shr $1,%r9
+and $1,%r10d
+and $1,%r11d
+and $1,%r12d
+and $1,%r13d
+neg %r10
+neg %r11
+neg %r12
+neg %r13
+movl %r10d,0(%rsi)
+movl %r11d,256(%rsi)
+movl %r12d,512(%rsi)
+movl %r13d,768(%rsi)
+add $4,%rsi
+sub $1,%rax
+jne ._ladder_small_loop
+mov $255,%rdx
+add $760,%rsi
+
+.p2align 4
+._ladder_loop:
+sub $1,%rdx
+vbroadcastss 0(%rsi),%xmm10
+sub $4,%rsi
+vmovdqa 0(%rsp),%xmm11
+vmovdqa 80(%rsp),%xmm12
+vpxor %xmm11,%xmm0,%xmm13
+vpand %xmm10,%xmm13,%xmm13
+vpxor %xmm13,%xmm0,%xmm0
+vpxor %xmm13,%xmm11,%xmm11
+vpxor %xmm12,%xmm1,%xmm13
+vpand %xmm10,%xmm13,%xmm13
+vpxor %xmm13,%xmm1,%xmm1
+vpxor %xmm13,%xmm12,%xmm12
+vmovdqa 16(%rsp),%xmm13
+vmovdqa 96(%rsp),%xmm14
+vpxor %xmm13,%xmm2,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm2,%xmm2
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm3,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm3,%xmm3
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,0(%rsp)
+vmovdqa %xmm14,16(%rsp)
+vmovdqa 32(%rsp),%xmm13
+vmovdqa 112(%rsp),%xmm14
+vpxor %xmm13,%xmm4,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm4,%xmm4
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm5,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm5,%xmm5
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,32(%rsp)
+vmovdqa %xmm14,80(%rsp)
+vmovdqa 48(%rsp),%xmm13
+vmovdqa 128(%rsp),%xmm14
+vpxor %xmm13,%xmm6,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm6,%xmm6
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm7,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm7,%xmm7
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,48(%rsp)
+vmovdqa %xmm14,96(%rsp)
+vmovdqa 64(%rsp),%xmm13
+vmovdqa 144(%rsp),%xmm14
+vpxor %xmm13,%xmm8,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm8,%xmm8
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm9,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm9,%xmm9
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,64(%rsp)
+vmovdqa %xmm14,112(%rsp)
+vpaddq subc0(%rip),%xmm11,%xmm10
+vpsubq %xmm12,%xmm10,%xmm10
+vpaddq %xmm12,%xmm11,%xmm11
+vpunpckhqdq %xmm10,%xmm11,%xmm12
+vpunpcklqdq %xmm10,%xmm11,%xmm10
+vpaddq %xmm1,%xmm0,%xmm11
+vpaddq subc0(%rip),%xmm0,%xmm0
+vpsubq %xmm1,%xmm0,%xmm0
+vpunpckhqdq %xmm11,%xmm0,%xmm1
+vpunpcklqdq %xmm11,%xmm0,%xmm0
+vpmuludq %xmm0,%xmm10,%xmm11
+vpmuludq %xmm1,%xmm10,%xmm13
+vmovdqa %xmm1,128(%rsp)
+vpaddq %xmm1,%xmm1,%xmm1
+vpmuludq %xmm0,%xmm12,%xmm14
+vmovdqa %xmm0,144(%rsp)
+vpaddq %xmm14,%xmm13,%xmm13
+vpmuludq %xmm1,%xmm12,%xmm0
+vmovdqa %xmm1,448(%rsp)
+vpaddq %xmm3,%xmm2,%xmm1
+vpaddq subc2(%rip),%xmm2,%xmm2
+vpsubq %xmm3,%xmm2,%xmm2
+vpunpckhqdq %xmm1,%xmm2,%xmm3
+vpunpcklqdq %xmm1,%xmm2,%xmm1
+vpmuludq %xmm1,%xmm10,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq %xmm3,%xmm10,%xmm2
+vmovdqa %xmm3,464(%rsp)
+vpaddq %xmm3,%xmm3,%xmm3
+vpmuludq %xmm1,%xmm12,%xmm14
+vmovdqa %xmm1,480(%rsp)
+vpaddq %xmm14,%xmm2,%xmm2
+vpmuludq %xmm3,%xmm12,%xmm1
+vmovdqa %xmm3,496(%rsp)
+vpaddq %xmm5,%xmm4,%xmm3
+vpaddq subc2(%rip),%xmm4,%xmm4
+vpsubq %xmm5,%xmm4,%xmm4
+vpunpckhqdq %xmm3,%xmm4,%xmm5
+vpunpcklqdq %xmm3,%xmm4,%xmm3
+vpmuludq %xmm3,%xmm10,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq %xmm5,%xmm10,%xmm4
+vmovdqa %xmm5,512(%rsp)
+vpaddq %xmm5,%xmm5,%xmm5
+vpmuludq %xmm3,%xmm12,%xmm14
+vmovdqa %xmm3,528(%rsp)
+vpaddq %xmm14,%xmm4,%xmm4
+vpaddq %xmm7,%xmm6,%xmm3
+vpaddq subc2(%rip),%xmm6,%xmm6
+vpsubq %xmm7,%xmm6,%xmm6
+vpunpckhqdq %xmm3,%xmm6,%xmm7
+vpunpcklqdq %xmm3,%xmm6,%xmm3
+vpmuludq %xmm3,%xmm10,%xmm6
+vpmuludq %xmm5,%xmm12,%xmm14
+vmovdqa %xmm5,544(%rsp)
+vpmuludq v19_19(%rip),%xmm5,%xmm5
+vmovdqa %xmm5,560(%rsp)
+vpaddq %xmm14,%xmm6,%xmm6
+vpmuludq %xmm7,%xmm10,%xmm5
+vmovdqa %xmm7,576(%rsp)
+vpaddq %xmm7,%xmm7,%xmm7
+vpmuludq %xmm3,%xmm12,%xmm14
+vmovdqa %xmm3,592(%rsp)
+vpaddq %xmm14,%xmm5,%xmm5
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vmovdqa %xmm3,608(%rsp)
+vpaddq %xmm9,%xmm8,%xmm3
+vpaddq subc2(%rip),%xmm8,%xmm8
+vpsubq %xmm9,%xmm8,%xmm8
+vpunpckhqdq %xmm3,%xmm8,%xmm9
+vpunpcklqdq %xmm3,%xmm8,%xmm3
+vmovdqa %xmm3,624(%rsp)
+vpmuludq %xmm7,%xmm12,%xmm8
+vmovdqa %xmm7,640(%rsp)
+vpmuludq v19_19(%rip),%xmm7,%xmm7
+vmovdqa %xmm7,656(%rsp)
+vpmuludq %xmm3,%xmm10,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq %xmm9,%xmm10,%xmm7
+vmovdqa %xmm9,672(%rsp)
+vpaddq %xmm9,%xmm9,%xmm9
+vpmuludq %xmm3,%xmm12,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vmovdqa %xmm3,688(%rsp)
+vpmuludq v19_19(%rip),%xmm12,%xmm12
+vpmuludq %xmm9,%xmm12,%xmm3
+vmovdqa %xmm9,704(%rsp)
+vpaddq %xmm3,%xmm11,%xmm11
+vmovdqa 0(%rsp),%xmm3
+vmovdqa 16(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 480(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 464(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 528(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 512(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 592(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 576(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 624(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 672(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 448(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 480(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 496(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 528(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 544(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 592(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 640(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 624(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 704(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm0,%xmm0
+vmovdqa 32(%rsp),%xmm3
+vmovdqa 80(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 480(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 464(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 528(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 512(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 592(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 576(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 624(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 672(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 448(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 480(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 496(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 528(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 544(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 592(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 640(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 624(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 704(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm1,%xmm1
+vmovdqa 48(%rsp),%xmm3
+vmovdqa 96(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 480(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 464(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 528(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 512(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 592(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 576(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 624(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 672(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 448(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 480(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 496(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 528(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 544(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 592(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 640(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 624(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 704(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm6,%xmm6
+vmovdqa 64(%rsp),%xmm3
+vmovdqa 112(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 480(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 464(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 528(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 512(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 592(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 576(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 624(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 672(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 448(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 480(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 496(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 528(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 544(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 592(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 640(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 624(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 704(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm8,%xmm8
+vpsrlq $25,%xmm4,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpand m25(%rip),%xmm4,%xmm4
+vpsrlq $26,%xmm11,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm6,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm13,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpand m25(%rip),%xmm13,%xmm13
+vpsrlq $25,%xmm5,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm0,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpand m26(%rip),%xmm0,%xmm0
+vpsrlq $26,%xmm8,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $25,%xmm2,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpand m25(%rip),%xmm2,%xmm2
+vpsrlq $25,%xmm7,%xmm3
+vpsllq $4,%xmm3,%xmm9
+vpaddq %xmm3,%xmm11,%xmm11
+vpsllq $1,%xmm3,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpaddq %xmm9,%xmm11,%xmm11
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $26,%xmm1,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $26,%xmm11,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $25,%xmm4,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpand m25(%rip),%xmm4,%xmm4
+vpunpcklqdq %xmm13,%xmm11,%xmm3
+vpunpckhqdq %xmm13,%xmm11,%xmm9
+vpaddq subc0(%rip),%xmm9,%xmm10
+vpsubq %xmm3,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm3,%xmm10,%xmm9
+vpunpcklqdq %xmm3,%xmm10,%xmm10
+vpmuludq %xmm10,%xmm10,%xmm3
+vpaddq %xmm10,%xmm10,%xmm10
+vpmuludq %xmm9,%xmm10,%xmm11
+vpunpcklqdq %xmm2,%xmm0,%xmm12
+vpunpckhqdq %xmm2,%xmm0,%xmm0
+vpaddq subc2(%rip),%xmm0,%xmm2
+vpsubq %xmm12,%xmm2,%xmm2
+vpaddq %xmm0,%xmm12,%xmm12
+vpunpckhqdq %xmm12,%xmm2,%xmm0
+vpunpcklqdq %xmm12,%xmm2,%xmm2
+vpmuludq %xmm2,%xmm10,%xmm12
+vpaddq %xmm9,%xmm9,%xmm13
+vpmuludq %xmm13,%xmm9,%xmm9
+vpaddq %xmm9,%xmm12,%xmm12
+vpmuludq %xmm0,%xmm10,%xmm9
+vpmuludq %xmm2,%xmm13,%xmm14
+vpaddq %xmm14,%xmm9,%xmm9
+vpunpcklqdq %xmm4,%xmm1,%xmm14
+vpunpckhqdq %xmm4,%xmm1,%xmm1
+vpaddq subc2(%rip),%xmm1,%xmm4
+vpsubq %xmm14,%xmm4,%xmm4
+vpaddq %xmm1,%xmm14,%xmm14
+vpunpckhqdq %xmm14,%xmm4,%xmm1
+vpunpcklqdq %xmm14,%xmm4,%xmm4
+vmovdqa %xmm1,0(%rsp)
+vpaddq %xmm1,%xmm1,%xmm1
+vmovdqa %xmm1,16(%rsp)
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vmovdqa %xmm1,32(%rsp)
+vpmuludq %xmm4,%xmm10,%xmm1
+vpmuludq %xmm2,%xmm2,%xmm14
+vpaddq %xmm14,%xmm1,%xmm1
+vpmuludq 0(%rsp),%xmm10,%xmm14
+vpmuludq %xmm4,%xmm13,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpunpcklqdq %xmm5,%xmm6,%xmm15
+vpunpckhqdq %xmm5,%xmm6,%xmm5
+vpaddq subc2(%rip),%xmm5,%xmm6
+vpsubq %xmm15,%xmm6,%xmm6
+vpaddq %xmm5,%xmm15,%xmm15
+vpunpckhqdq %xmm15,%xmm6,%xmm5
+vpunpcklqdq %xmm15,%xmm6,%xmm6
+vmovdqa %xmm6,48(%rsp)
+vpmuludq v19_19(%rip),%xmm6,%xmm6
+vmovdqa %xmm6,64(%rsp)
+vmovdqa %xmm5,80(%rsp)
+vpmuludq v38_38(%rip),%xmm5,%xmm5
+vmovdqa %xmm5,96(%rsp)
+vpmuludq 48(%rsp),%xmm10,%xmm5
+vpaddq %xmm0,%xmm0,%xmm6
+vpmuludq %xmm6,%xmm0,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpmuludq 80(%rsp),%xmm10,%xmm0
+vpmuludq %xmm4,%xmm6,%xmm15
+vpaddq %xmm15,%xmm0,%xmm0
+vpmuludq %xmm6,%xmm13,%xmm15
+vpaddq %xmm15,%xmm1,%xmm1
+vpmuludq %xmm6,%xmm2,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpunpcklqdq %xmm7,%xmm8,%xmm15
+vpunpckhqdq %xmm7,%xmm8,%xmm7
+vpaddq subc2(%rip),%xmm7,%xmm8
+vpsubq %xmm15,%xmm8,%xmm8
+vpaddq %xmm7,%xmm15,%xmm15
+vpunpckhqdq %xmm15,%xmm8,%xmm7
+vpunpcklqdq %xmm15,%xmm8,%xmm8
+vmovdqa %xmm8,112(%rsp)
+vpmuludq v19_19(%rip),%xmm8,%xmm8
+vmovdqa %xmm8,448(%rsp)
+vpmuludq 112(%rsp),%xmm10,%xmm8
+vpmuludq %xmm7,%xmm10,%xmm10
+vpmuludq v38_38(%rip),%xmm7,%xmm15
+vpmuludq %xmm15,%xmm7,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq %xmm15,%xmm13,%xmm7
+vpaddq %xmm7,%xmm3,%xmm3
+vpmuludq %xmm15,%xmm2,%xmm7
+vpaddq %xmm7,%xmm11,%xmm11
+vpmuludq 80(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm7,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq 16(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 48(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm0,%xmm0
+vpmuludq 112(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm10,%xmm10
+vpmuludq %xmm15,%xmm6,%xmm7
+vpaddq %xmm7,%xmm12,%xmm12
+vpmuludq %xmm15,%xmm4,%xmm7
+vpaddq %xmm7,%xmm9,%xmm9
+vpaddq %xmm2,%xmm2,%xmm2
+vpmuludq %xmm4,%xmm2,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 448(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm3,%xmm3
+vpmuludq 448(%rsp),%xmm6,%xmm7
+vpaddq %xmm7,%xmm11,%xmm11
+vpmuludq 0(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm0,%xmm0
+vpmuludq 48(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq 80(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 96(%rsp),%xmm4,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq %xmm4,%xmm4,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpaddq %xmm4,%xmm4,%xmm2
+vpmuludq 448(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vpmuludq 16(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq 48(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm14,%xmm14
+vpmuludq 96(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 448(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 16(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm8,%xmm8
+vpmuludq 48(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 80(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vpmuludq 112(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm0,%xmm0
+vmovdqa 48(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 448(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 80(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 448(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm14,%xmm14
+vpmuludq 64(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 64(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 96(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vmovdqa 48(%rsp),%xmm4
+vpmuludq 96(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 0(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vmovdqa 32(%rsp),%xmm2
+vpmuludq 0(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vmovdqa 64(%rsp),%xmm2
+vpmuludq 48(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vmovdqa 96(%rsp),%xmm2
+vpmuludq 80(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vmovdqa 448(%rsp),%xmm2
+vpmuludq 112(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpsrlq $26,%xmm3,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m26(%rip),%xmm3,%xmm3
+vpsrlq $25,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $25,%xmm11,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpand m25(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm5,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpand m26(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm12,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpand m26(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm0,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm9,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vpand m25(%rip),%xmm9,%xmm9
+vpsrlq $26,%xmm8,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $25,%xmm10,%xmm2
+vpsllq $4,%xmm2,%xmm4
+vpaddq %xmm2,%xmm3,%xmm3
+vpsllq $1,%xmm2,%xmm2
+vpaddq %xmm2,%xmm4,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $26,%xmm3,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m26(%rip),%xmm3,%xmm3
+vpunpckhqdq %xmm11,%xmm3,%xmm2
+vmovdqa %xmm2,0(%rsp)
+vpshufd $0,%xmm3,%xmm2
+vpshufd $0,%xmm11,%xmm3
+vpmuludq 160(%rsp),%xmm2,%xmm4
+vpmuludq 432(%rsp),%xmm3,%xmm6
+vpaddq %xmm6,%xmm4,%xmm4
+vpmuludq 176(%rsp),%xmm2,%xmm6
+vpmuludq 304(%rsp),%xmm3,%xmm7
+vpaddq %xmm7,%xmm6,%xmm6
+vpmuludq 208(%rsp),%xmm2,%xmm7
+vpmuludq 336(%rsp),%xmm3,%xmm11
+vpaddq %xmm11,%xmm7,%xmm7
+vpmuludq 240(%rsp),%xmm2,%xmm11
+vpmuludq 368(%rsp),%xmm3,%xmm13
+vpaddq %xmm13,%xmm11,%xmm11
+vpmuludq 272(%rsp),%xmm2,%xmm2
+vpmuludq 400(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpunpckhqdq %xmm9,%xmm12,%xmm3
+vmovdqa %xmm3,16(%rsp)
+vpshufd $0,%xmm12,%xmm3
+vpshufd $0,%xmm9,%xmm9
+vpmuludq 288(%rsp),%xmm3,%xmm12
+vpaddq %xmm12,%xmm4,%xmm4
+vpmuludq 416(%rsp),%xmm9,%xmm12
+vpaddq %xmm12,%xmm4,%xmm4
+vpmuludq 160(%rsp),%xmm3,%xmm12
+vpaddq %xmm12,%xmm6,%xmm6
+vpmuludq 432(%rsp),%xmm9,%xmm12
+vpaddq %xmm12,%xmm6,%xmm6
+vpmuludq 176(%rsp),%xmm3,%xmm12
+vpaddq %xmm12,%xmm7,%xmm7
+vpmuludq 304(%rsp),%xmm9,%xmm12
+vpaddq %xmm12,%xmm7,%xmm7
+vpmuludq 208(%rsp),%xmm3,%xmm12
+vpaddq %xmm12,%xmm11,%xmm11
+vpmuludq 336(%rsp),%xmm9,%xmm12
+vpaddq %xmm12,%xmm11,%xmm11
+vpmuludq 240(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 368(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpunpckhqdq %xmm14,%xmm1,%xmm3
+vmovdqa %xmm3,32(%rsp)
+vpshufd $0,%xmm1,%xmm1
+vpshufd $0,%xmm14,%xmm3
+vpmuludq 256(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm4,%xmm4
+vpmuludq 384(%rsp),%xmm3,%xmm9
+vpaddq %xmm9,%xmm4,%xmm4
+vpmuludq 288(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm6,%xmm6
+vpmuludq 416(%rsp),%xmm3,%xmm9
+vpaddq %xmm9,%xmm6,%xmm6
+vpmuludq 160(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm7,%xmm7
+vpmuludq 432(%rsp),%xmm3,%xmm9
+vpaddq %xmm9,%xmm7,%xmm7
+vpmuludq 176(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm11,%xmm11
+vpmuludq 304(%rsp),%xmm3,%xmm9
+vpaddq %xmm9,%xmm11,%xmm11
+vpmuludq 208(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm2,%xmm2
+vpmuludq 336(%rsp),%xmm3,%xmm1
+vpaddq %xmm1,%xmm2,%xmm2
+vpunpckhqdq %xmm0,%xmm5,%xmm1
+vmovdqa %xmm1,48(%rsp)
+vpshufd $0,%xmm5,%xmm1
+vpshufd $0,%xmm0,%xmm0
+vpmuludq 224(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 352(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 256(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 384(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 288(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 416(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 160(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 432(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 176(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm2,%xmm2
+vpmuludq 304(%rsp),%xmm0,%xmm0
+vpaddq %xmm0,%xmm2,%xmm2
+vpunpckhqdq %xmm10,%xmm8,%xmm0
+vmovdqa %xmm0,64(%rsp)
+vpshufd $0,%xmm8,%xmm0
+vpshufd $0,%xmm10,%xmm1
+vpmuludq 192(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 320(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 224(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 352(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 256(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 384(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 288(%rsp),%xmm0,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 416(%rsp),%xmm1,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 160(%rsp),%xmm0,%xmm0
+vpaddq %xmm0,%xmm2,%xmm2
+vpmuludq 432(%rsp),%xmm1,%xmm0
+vpaddq %xmm0,%xmm2,%xmm2
+vmovdqa %xmm4,80(%rsp)
+vmovdqa %xmm6,96(%rsp)
+vmovdqa %xmm7,112(%rsp)
+vmovdqa %xmm11,448(%rsp)
+vmovdqa %xmm2,496(%rsp)
+vmovdqa 144(%rsp),%xmm0
+vpmuludq %xmm0,%xmm0,%xmm1
+vpaddq %xmm0,%xmm0,%xmm0
+vmovdqa 128(%rsp),%xmm2
+vpmuludq %xmm2,%xmm0,%xmm3
+vmovdqa 480(%rsp),%xmm4
+vpmuludq %xmm4,%xmm0,%xmm5
+vmovdqa 464(%rsp),%xmm6
+vpmuludq %xmm6,%xmm0,%xmm7
+vmovdqa 528(%rsp),%xmm8
+vpmuludq %xmm8,%xmm0,%xmm9
+vpmuludq 512(%rsp),%xmm0,%xmm10
+vpmuludq 592(%rsp),%xmm0,%xmm11
+vpmuludq 576(%rsp),%xmm0,%xmm12
+vpmuludq 624(%rsp),%xmm0,%xmm13
+vmovdqa 672(%rsp),%xmm14
+vpmuludq %xmm14,%xmm0,%xmm0
+vpmuludq v38_38(%rip),%xmm14,%xmm15
+vpmuludq %xmm15,%xmm14,%xmm14
+vpaddq %xmm14,%xmm13,%xmm13
+vpaddq %xmm6,%xmm6,%xmm14
+vpmuludq %xmm14,%xmm6,%xmm6
+vpaddq %xmm6,%xmm11,%xmm11
+vpaddq %xmm2,%xmm2,%xmm6
+vpmuludq %xmm6,%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq %xmm15,%xmm6,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vpmuludq %xmm15,%xmm4,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpmuludq 544(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 592(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 640(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 624(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq %xmm4,%xmm6,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq %xmm14,%xmm6,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq %xmm8,%xmm6,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq %xmm15,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq %xmm15,%xmm8,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq %xmm4,%xmm4,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq %xmm14,%xmm4,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpaddq %xmm4,%xmm4,%xmm2
+vpmuludq %xmm8,%xmm2,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vpmuludq 688(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq 688(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vpmuludq 512(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vpmuludq 592(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm13,%xmm13
+vpmuludq 576(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq 656(%rsp),%xmm8,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpmuludq %xmm8,%xmm14,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq %xmm8,%xmm8,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpaddq %xmm8,%xmm8,%xmm2
+vpmuludq 688(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vpmuludq 544(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 592(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 656(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 544(%rsp),%xmm4
+vpmuludq 688(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm7,%xmm7
+vpmuludq 544(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm13,%xmm13
+vpmuludq 592(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm0,%xmm0
+vpmuludq 640(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vpmuludq 624(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vmovdqa 592(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 688(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 608(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 544(%rsp),%xmm4
+vpmuludq 608(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 544(%rsp),%xmm4
+vpmuludq 656(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vmovdqa 592(%rsp),%xmm4
+vpmuludq 656(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm7,%xmm7
+vmovdqa 640(%rsp),%xmm4
+vpmuludq 688(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 512(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vmovdqa 560(%rsp),%xmm2
+vpmuludq 512(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vmovdqa 608(%rsp),%xmm2
+vpmuludq 592(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vmovdqa 656(%rsp),%xmm2
+vpmuludq 576(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vmovdqa 688(%rsp),%xmm2
+vpmuludq 624(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $25,%xmm10,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm3,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm3,%xmm3
+vpsrlq $26,%xmm11,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm5,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpand m26(%rip),%xmm5,%xmm5
+vpsrlq $25,%xmm12,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpand m25(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm7,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $26,%xmm13,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpand m26(%rip),%xmm13,%xmm13
+vpsrlq $26,%xmm9,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $25,%xmm0,%xmm2
+vpsllq $4,%xmm2,%xmm4
+vpaddq %xmm2,%xmm1,%xmm1
+vpsllq $1,%xmm2,%xmm2
+vpaddq %xmm2,%xmm4,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm10,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpand m26(%rip),%xmm1,%xmm1
+vpunpckhqdq %xmm3,%xmm1,%xmm2
+vpunpcklqdq %xmm3,%xmm1,%xmm1
+vmovdqa %xmm1,464(%rsp)
+vpaddq subc0(%rip),%xmm2,%xmm3
+vpsubq %xmm1,%xmm3,%xmm3
+vpunpckhqdq %xmm3,%xmm2,%xmm1
+vpunpcklqdq %xmm3,%xmm2,%xmm2
+vmovdqa %xmm2,480(%rsp)
+vmovdqa %xmm1,512(%rsp)
+vpsllq $1,%xmm1,%xmm1
+vmovdqa %xmm1,528(%rsp)
+vpmuludq v121666_121666(%rip),%xmm3,%xmm3
+vmovdqa 80(%rsp),%xmm1
+vpunpcklqdq %xmm1,%xmm3,%xmm2
+vpunpckhqdq %xmm1,%xmm3,%xmm1
+vpunpckhqdq %xmm7,%xmm5,%xmm3
+vpunpcklqdq %xmm7,%xmm5,%xmm4
+vmovdqa %xmm4,544(%rsp)
+vpaddq subc2(%rip),%xmm3,%xmm5
+vpsubq %xmm4,%xmm5,%xmm5
+vpunpckhqdq %xmm5,%xmm3,%xmm4
+vpunpcklqdq %xmm5,%xmm3,%xmm3
+vmovdqa %xmm3,560(%rsp)
+vmovdqa %xmm4,576(%rsp)
+vpsllq $1,%xmm4,%xmm4
+vmovdqa %xmm4,592(%rsp)
+vpmuludq v121666_121666(%rip),%xmm5,%xmm5
+vmovdqa 96(%rsp),%xmm3
+vpunpcklqdq %xmm3,%xmm5,%xmm4
+vpunpckhqdq %xmm3,%xmm5,%xmm3
+vpunpckhqdq %xmm10,%xmm9,%xmm5
+vpunpcklqdq %xmm10,%xmm9,%xmm6
+vmovdqa %xmm6,608(%rsp)
+vpaddq subc2(%rip),%xmm5,%xmm7
+vpsubq %xmm6,%xmm7,%xmm7
+vpunpckhqdq %xmm7,%xmm5,%xmm6
+vpunpcklqdq %xmm7,%xmm5,%xmm5
+vmovdqa %xmm5,624(%rsp)
+vmovdqa %xmm6,640(%rsp)
+vpsllq $1,%xmm6,%xmm6
+vmovdqa %xmm6,656(%rsp)
+vpmuludq v121666_121666(%rip),%xmm7,%xmm7
+vmovdqa 112(%rsp),%xmm5
+vpunpcklqdq %xmm5,%xmm7,%xmm6
+vpunpckhqdq %xmm5,%xmm7,%xmm5
+vpunpckhqdq %xmm12,%xmm11,%xmm7
+vpunpcklqdq %xmm12,%xmm11,%xmm8
+vmovdqa %xmm8,672(%rsp)
+vpaddq subc2(%rip),%xmm7,%xmm9
+vpsubq %xmm8,%xmm9,%xmm9
+vpunpckhqdq %xmm9,%xmm7,%xmm8
+vpunpcklqdq %xmm9,%xmm7,%xmm7
+vmovdqa %xmm7,688(%rsp)
+vmovdqa %xmm8,704(%rsp)
+vpsllq $1,%xmm8,%xmm8
+vmovdqa %xmm8,720(%rsp)
+vpmuludq v121666_121666(%rip),%xmm9,%xmm9
+vmovdqa 448(%rsp),%xmm7
+vpunpcklqdq %xmm7,%xmm9,%xmm8
+vpunpckhqdq %xmm7,%xmm9,%xmm7
+vpunpckhqdq %xmm0,%xmm13,%xmm9
+vpunpcklqdq %xmm0,%xmm13,%xmm0
+vmovdqa %xmm0,448(%rsp)
+vpaddq subc2(%rip),%xmm9,%xmm10
+vpsubq %xmm0,%xmm10,%xmm10
+vpunpckhqdq %xmm10,%xmm9,%xmm0
+vpunpcklqdq %xmm10,%xmm9,%xmm9
+vmovdqa %xmm9,736(%rsp)
+vmovdqa %xmm0,752(%rsp)
+vpsllq $1,%xmm0,%xmm0
+vmovdqa %xmm0,768(%rsp)
+vpmuludq v121666_121666(%rip),%xmm10,%xmm10
+vmovdqa 496(%rsp),%xmm0
+vpunpcklqdq %xmm0,%xmm10,%xmm9
+vpunpckhqdq %xmm0,%xmm10,%xmm0
+vpsrlq $26,%xmm2,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpand m26(%rip),%xmm2,%xmm2
+vpsrlq $25,%xmm5,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $25,%xmm1,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpand m25(%rip),%xmm1,%xmm1
+vpsrlq $26,%xmm8,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm4,%xmm10
+vpaddq %xmm10,%xmm3,%xmm3
+vpand m26(%rip),%xmm4,%xmm4
+vpsrlq $25,%xmm7,%xmm10
+vpaddq %xmm10,%xmm9,%xmm9
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $25,%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpand m25(%rip),%xmm3,%xmm3
+vpsrlq $26,%xmm9,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $26,%xmm6,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm0,%xmm10
+vpsllq $4,%xmm10,%xmm11
+vpaddq %xmm10,%xmm2,%xmm2
+vpsllq $1,%xmm10,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpaddq %xmm11,%xmm2,%xmm2
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm5,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm2,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpand m26(%rip),%xmm2,%xmm2
+vpunpckhqdq %xmm1,%xmm2,%xmm10
+vmovdqa %xmm10,80(%rsp)
+vpunpcklqdq %xmm1,%xmm2,%xmm1
+vpunpckhqdq %xmm3,%xmm4,%xmm2
+vmovdqa %xmm2,96(%rsp)
+vpunpcklqdq %xmm3,%xmm4,%xmm2
+vpunpckhqdq %xmm5,%xmm6,%xmm3
+vmovdqa %xmm3,112(%rsp)
+vpunpcklqdq %xmm5,%xmm6,%xmm3
+vpunpckhqdq %xmm7,%xmm8,%xmm4
+vmovdqa %xmm4,128(%rsp)
+vpunpcklqdq %xmm7,%xmm8,%xmm4
+vpunpckhqdq %xmm0,%xmm9,%xmm5
+vmovdqa %xmm5,144(%rsp)
+vpunpcklqdq %xmm0,%xmm9,%xmm0
+vmovdqa 464(%rsp),%xmm5
+vpaddq %xmm5,%xmm1,%xmm1
+vpunpcklqdq %xmm1,%xmm5,%xmm6
+vpunpckhqdq %xmm1,%xmm5,%xmm1
+vpmuludq 512(%rsp),%xmm6,%xmm5
+vpmuludq 480(%rsp),%xmm1,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 560(%rsp),%xmm6,%xmm7
+vpmuludq 528(%rsp),%xmm1,%xmm8
+vpaddq %xmm8,%xmm7,%xmm7
+vpmuludq 576(%rsp),%xmm6,%xmm8
+vpmuludq 560(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm8,%xmm8
+vpmuludq 624(%rsp),%xmm6,%xmm9
+vpmuludq 592(%rsp),%xmm1,%xmm10
+vpaddq %xmm10,%xmm9,%xmm9
+vpmuludq 640(%rsp),%xmm6,%xmm10
+vpmuludq 624(%rsp),%xmm1,%xmm11
+vpaddq %xmm11,%xmm10,%xmm10
+vpmuludq 688(%rsp),%xmm6,%xmm11
+vpmuludq 656(%rsp),%xmm1,%xmm12
+vpaddq %xmm12,%xmm11,%xmm11
+vpmuludq 704(%rsp),%xmm6,%xmm12
+vpmuludq 688(%rsp),%xmm1,%xmm13
+vpaddq %xmm13,%xmm12,%xmm12
+vpmuludq 736(%rsp),%xmm6,%xmm13
+vpmuludq 720(%rsp),%xmm1,%xmm14
+vpaddq %xmm14,%xmm13,%xmm13
+vpmuludq 752(%rsp),%xmm6,%xmm14
+vpmuludq 736(%rsp),%xmm1,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpmuludq 480(%rsp),%xmm6,%xmm6
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 768(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vmovdqa 544(%rsp),%xmm1
+vpaddq %xmm1,%xmm2,%xmm2
+vpunpcklqdq %xmm2,%xmm1,%xmm15
+vpunpckhqdq %xmm2,%xmm1,%xmm1
+vpmuludq 480(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 512(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 560(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 576(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 624(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 640(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 688(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 704(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm15,%xmm15
+vpmuludq 736(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 752(%rsp),%xmm15,%xmm15
+vpaddq %xmm15,%xmm5,%xmm5
+vpmuludq 480(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 528(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 560(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 592(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 624(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 656(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 688(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 720(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 736(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 768(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vmovdqa 608(%rsp),%xmm1
+vpaddq %xmm1,%xmm3,%xmm3
+vpunpcklqdq %xmm3,%xmm1,%xmm2
+vpunpckhqdq %xmm3,%xmm1,%xmm1
+vpmuludq 480(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpmuludq 512(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm10,%xmm10
+vpmuludq 560(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 576(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm12,%xmm12
+vpmuludq 624(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 640(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 688(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 704(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 736(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 752(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 480(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 528(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 560(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 592(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 624(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 656(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 688(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 720(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 736(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 768(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vmovdqa 672(%rsp),%xmm1
+vpaddq %xmm1,%xmm4,%xmm4
+vpunpcklqdq %xmm4,%xmm1,%xmm2
+vpunpckhqdq %xmm4,%xmm1,%xmm1
+vpmuludq 480(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 512(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm12,%xmm12
+vpmuludq 560(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 576(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 624(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 640(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 688(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 704(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 736(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpmuludq 752(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 480(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 528(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 560(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 592(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 624(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 656(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 688(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 720(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 736(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 768(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vmovdqa 448(%rsp),%xmm1
+vpaddq %xmm1,%xmm0,%xmm0
+vpunpcklqdq %xmm0,%xmm1,%xmm2
+vpunpckhqdq %xmm0,%xmm1,%xmm0
+vpmuludq 480(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm13,%xmm13
+vpmuludq 512(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 560(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpmuludq 576(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm5,%xmm5
+vpmuludq 624(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vpmuludq 640(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm8,%xmm8
+vpmuludq 688(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vpmuludq 704(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm10,%xmm10
+vpmuludq 736(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vpmuludq 752(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 480(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm0,%xmm0
+vpmuludq 528(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpmuludq 560(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm5,%xmm5
+vpmuludq 592(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vpmuludq 624(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm8,%xmm8
+vpmuludq 656(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vpmuludq 688(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm10,%xmm10
+vpmuludq 720(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vpmuludq 736(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm12,%xmm12
+vpmuludq 768(%rsp),%xmm0,%xmm0
+vpaddq %xmm0,%xmm13,%xmm13
+vpsrlq $26,%xmm6,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm10,%xmm0
+vpaddq %xmm0,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm5,%xmm0
+vpaddq %xmm0,%xmm7,%xmm7
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm11,%xmm0
+vpaddq %xmm0,%xmm12,%xmm12
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm7,%xmm0
+vpaddq %xmm0,%xmm8,%xmm8
+vpand m26(%rip),%xmm7,%xmm7
+vpsrlq $25,%xmm12,%xmm0
+vpaddq %xmm0,%xmm13,%xmm13
+vpand m25(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm8,%xmm0
+vpaddq %xmm0,%xmm9,%xmm9
+vpand m25(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm13,%xmm0
+vpaddq %xmm0,%xmm14,%xmm14
+vpand m26(%rip),%xmm13,%xmm13
+vpsrlq $26,%xmm9,%xmm0
+vpaddq %xmm0,%xmm10,%xmm10
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $25,%xmm14,%xmm0
+vpsllq $4,%xmm0,%xmm1
+vpaddq %xmm0,%xmm6,%xmm6
+vpsllq $1,%xmm0,%xmm0
+vpaddq %xmm0,%xmm1,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $25,%xmm10,%xmm0
+vpaddq %xmm0,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $26,%xmm6,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpunpckhqdq %xmm5,%xmm6,%xmm1
+vpunpcklqdq %xmm5,%xmm6,%xmm0
+vpunpckhqdq %xmm8,%xmm7,%xmm3
+vpunpcklqdq %xmm8,%xmm7,%xmm2
+vpunpckhqdq %xmm10,%xmm9,%xmm5
+vpunpcklqdq %xmm10,%xmm9,%xmm4
+vpunpckhqdq %xmm12,%xmm11,%xmm7
+vpunpcklqdq %xmm12,%xmm11,%xmm6
+vpunpckhqdq %xmm14,%xmm13,%xmm9
+vpunpcklqdq %xmm14,%xmm13,%xmm8
+cmp $0,%rdx
+jne ._ladder_loop
+vmovdqu %xmm1,160(%rdi)
+vmovdqu %xmm0,80(%rdi)
+vmovdqu %xmm3,176(%rdi)
+vmovdqu %xmm2,96(%rdi)
+vmovdqu %xmm5,192(%rdi)
+vmovdqu %xmm4,112(%rdi)
+vmovdqu %xmm7,208(%rdi)
+vmovdqu %xmm6,128(%rdi)
+vmovdqu %xmm9,224(%rdi)
+vmovdqu %xmm8,144(%rdi)
+movq 1824(%rsp),%r11
+movq 1832(%rsp),%r12
+movq 1840(%rsp),%r13
+movq 1848(%rsp),%r14
+add %r11,%rsp
+ret
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h
new file mode 100644
index 0000000000..ccf4ecaecd
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h
@@ -0,0 +1,18 @@
+#ifndef ladder_H
+#define ladder_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fe.h"
+#include "ladder_namespace.h"
+
+extern void ladder(fe *, const unsigned char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef ladder_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S
new file mode 100644
index 0000000000..f290d2565e
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S
@@ -0,0 +1,1295 @@
+#ifdef IN_SANDY2X
+
+#include "ladder_base_namespace.h"
+#include "consts_namespace.h"
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL ladder_base
+ASM_HIDE_SYMBOL _ladder_base
+#endif
+.globl ladder_base
+.globl _ladder_base
+#ifdef __ELF__
+.type ladder_base, @function
+.type _ladder_base, @function
+#endif
+ladder_base:
+_ladder_base:
+
+mov %rsp,%r11
+and $31,%r11
+add $1568,%r11
+sub %r11,%rsp
+movq %r11,1536(%rsp)
+movq %r12,1544(%rsp)
+movq %r13,1552(%rsp)
+vmovdqa v0_0(%rip),%xmm0
+vmovdqa v1_0(%rip),%xmm1
+vmovdqa v9_0(%rip),%xmm2
+vmovdqa %xmm2,0(%rsp)
+vmovdqa %xmm0,16(%rsp)
+vmovdqa %xmm0,32(%rsp)
+vmovdqa %xmm0,48(%rsp)
+vmovdqa %xmm0,64(%rsp)
+vmovdqa %xmm1,80(%rsp)
+vmovdqa %xmm0,96(%rsp)
+vmovdqa %xmm0,112(%rsp)
+vmovdqa %xmm0,128(%rsp)
+vmovdqa %xmm0,144(%rsp)
+vmovdqa %xmm1,%xmm0
+vpxor %xmm1,%xmm1,%xmm1
+vpxor %xmm2,%xmm2,%xmm2
+vpxor %xmm3,%xmm3,%xmm3
+vpxor %xmm4,%xmm4,%xmm4
+vpxor %xmm5,%xmm5,%xmm5
+vpxor %xmm6,%xmm6,%xmm6
+vpxor %xmm7,%xmm7,%xmm7
+vpxor %xmm8,%xmm8,%xmm8
+vpxor %xmm9,%xmm9,%xmm9
+movq 0(%rsi),%rdx
+movq 8(%rsi),%rcx
+movq 16(%rsi),%r8
+movq 24(%rsi),%r9
+shrd $1,%rcx,%rdx
+shrd $1,%r8,%rcx
+shrd $1,%r9,%r8
+shr $1,%r9
+xorq 0(%rsi),%rdx
+xorq 8(%rsi),%rcx
+xorq 16(%rsi),%r8
+xorq 24(%rsi),%r9
+leaq 512(%rsp),%rsi
+mov $64,%rax
+
+.p2align 4
+._ladder_base_small_loop:
+mov %rdx,%r10
+mov %rcx,%r11
+mov %r8,%r12
+mov %r9,%r13
+shr $1,%rdx
+shr $1,%rcx
+shr $1,%r8
+shr $1,%r9
+and $1,%r10d
+and $1,%r11d
+and $1,%r12d
+and $1,%r13d
+neg %r10
+neg %r11
+neg %r12
+neg %r13
+movl %r10d,0(%rsi)
+movl %r11d,256(%rsi)
+movl %r12d,512(%rsi)
+movl %r13d,768(%rsi)
+add $4,%rsi
+sub $1,%rax
+jne ._ladder_base_small_loop
+mov $255,%rdx
+add $760,%rsi
+
+.p2align 4
+._ladder_base_loop:
+sub $1,%rdx
+vbroadcastss 0(%rsi),%xmm10
+sub $4,%rsi
+vmovdqa 0(%rsp),%xmm11
+vmovdqa 80(%rsp),%xmm12
+vpxor %xmm11,%xmm0,%xmm13
+vpand %xmm10,%xmm13,%xmm13
+vpxor %xmm13,%xmm0,%xmm0
+vpxor %xmm13,%xmm11,%xmm11
+vpxor %xmm12,%xmm1,%xmm13
+vpand %xmm10,%xmm13,%xmm13
+vpxor %xmm13,%xmm1,%xmm1
+vpxor %xmm13,%xmm12,%xmm12
+vmovdqa 16(%rsp),%xmm13
+vmovdqa 96(%rsp),%xmm14
+vpxor %xmm13,%xmm2,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm2,%xmm2
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm3,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm3,%xmm3
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,0(%rsp)
+vmovdqa %xmm14,16(%rsp)
+vmovdqa 32(%rsp),%xmm13
+vmovdqa 112(%rsp),%xmm14
+vpxor %xmm13,%xmm4,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm4,%xmm4
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm5,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm5,%xmm5
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,32(%rsp)
+vmovdqa %xmm14,80(%rsp)
+vmovdqa 48(%rsp),%xmm13
+vmovdqa 128(%rsp),%xmm14
+vpxor %xmm13,%xmm6,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm6,%xmm6
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm7,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm7,%xmm7
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,48(%rsp)
+vmovdqa %xmm14,96(%rsp)
+vmovdqa 64(%rsp),%xmm13
+vmovdqa 144(%rsp),%xmm14
+vpxor %xmm13,%xmm8,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm8,%xmm8
+vpxor %xmm15,%xmm13,%xmm13
+vpxor %xmm14,%xmm9,%xmm15
+vpand %xmm10,%xmm15,%xmm15
+vpxor %xmm15,%xmm9,%xmm9
+vpxor %xmm15,%xmm14,%xmm14
+vmovdqa %xmm13,64(%rsp)
+vmovdqa %xmm14,112(%rsp)
+vpaddq subc0(%rip),%xmm11,%xmm10
+vpsubq %xmm12,%xmm10,%xmm10
+vpaddq %xmm12,%xmm11,%xmm11
+vpunpckhqdq %xmm10,%xmm11,%xmm12
+vpunpcklqdq %xmm10,%xmm11,%xmm10
+vpaddq %xmm1,%xmm0,%xmm11
+vpaddq subc0(%rip),%xmm0,%xmm0
+vpsubq %xmm1,%xmm0,%xmm0
+vpunpckhqdq %xmm11,%xmm0,%xmm1
+vpunpcklqdq %xmm11,%xmm0,%xmm0
+vpmuludq %xmm0,%xmm10,%xmm11
+vpmuludq %xmm1,%xmm10,%xmm13
+vmovdqa %xmm1,128(%rsp)
+vpaddq %xmm1,%xmm1,%xmm1
+vpmuludq %xmm0,%xmm12,%xmm14
+vmovdqa %xmm0,144(%rsp)
+vpaddq %xmm14,%xmm13,%xmm13
+vpmuludq %xmm1,%xmm12,%xmm0
+vmovdqa %xmm1,160(%rsp)
+vpaddq %xmm3,%xmm2,%xmm1
+vpaddq subc2(%rip),%xmm2,%xmm2
+vpsubq %xmm3,%xmm2,%xmm2
+vpunpckhqdq %xmm1,%xmm2,%xmm3
+vpunpcklqdq %xmm1,%xmm2,%xmm1
+vpmuludq %xmm1,%xmm10,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq %xmm3,%xmm10,%xmm2
+vmovdqa %xmm3,176(%rsp)
+vpaddq %xmm3,%xmm3,%xmm3
+vpmuludq %xmm1,%xmm12,%xmm14
+vmovdqa %xmm1,192(%rsp)
+vpaddq %xmm14,%xmm2,%xmm2
+vpmuludq %xmm3,%xmm12,%xmm1
+vmovdqa %xmm3,208(%rsp)
+vpaddq %xmm5,%xmm4,%xmm3
+vpaddq subc2(%rip),%xmm4,%xmm4
+vpsubq %xmm5,%xmm4,%xmm4
+vpunpckhqdq %xmm3,%xmm4,%xmm5
+vpunpcklqdq %xmm3,%xmm4,%xmm3
+vpmuludq %xmm3,%xmm10,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq %xmm5,%xmm10,%xmm4
+vmovdqa %xmm5,224(%rsp)
+vpaddq %xmm5,%xmm5,%xmm5
+vpmuludq %xmm3,%xmm12,%xmm14
+vmovdqa %xmm3,240(%rsp)
+vpaddq %xmm14,%xmm4,%xmm4
+vpaddq %xmm7,%xmm6,%xmm3
+vpaddq subc2(%rip),%xmm6,%xmm6
+vpsubq %xmm7,%xmm6,%xmm6
+vpunpckhqdq %xmm3,%xmm6,%xmm7
+vpunpcklqdq %xmm3,%xmm6,%xmm3
+vpmuludq %xmm3,%xmm10,%xmm6
+vpmuludq %xmm5,%xmm12,%xmm14
+vmovdqa %xmm5,256(%rsp)
+vpmuludq v19_19(%rip),%xmm5,%xmm5
+vmovdqa %xmm5,272(%rsp)
+vpaddq %xmm14,%xmm6,%xmm6
+vpmuludq %xmm7,%xmm10,%xmm5
+vmovdqa %xmm7,288(%rsp)
+vpaddq %xmm7,%xmm7,%xmm7
+vpmuludq %xmm3,%xmm12,%xmm14
+vmovdqa %xmm3,304(%rsp)
+vpaddq %xmm14,%xmm5,%xmm5
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vmovdqa %xmm3,320(%rsp)
+vpaddq %xmm9,%xmm8,%xmm3
+vpaddq subc2(%rip),%xmm8,%xmm8
+vpsubq %xmm9,%xmm8,%xmm8
+vpunpckhqdq %xmm3,%xmm8,%xmm9
+vpunpcklqdq %xmm3,%xmm8,%xmm3
+vmovdqa %xmm3,336(%rsp)
+vpmuludq %xmm7,%xmm12,%xmm8
+vmovdqa %xmm7,352(%rsp)
+vpmuludq v19_19(%rip),%xmm7,%xmm7
+vmovdqa %xmm7,368(%rsp)
+vpmuludq %xmm3,%xmm10,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq %xmm9,%xmm10,%xmm7
+vmovdqa %xmm9,384(%rsp)
+vpaddq %xmm9,%xmm9,%xmm9
+vpmuludq %xmm3,%xmm12,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vmovdqa %xmm3,400(%rsp)
+vpmuludq v19_19(%rip),%xmm12,%xmm12
+vpmuludq %xmm9,%xmm12,%xmm3
+vmovdqa %xmm9,416(%rsp)
+vpaddq %xmm3,%xmm11,%xmm11
+vmovdqa 0(%rsp),%xmm3
+vmovdqa 16(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 192(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 176(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 240(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 224(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 304(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 288(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 336(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 384(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 160(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 192(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 208(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 240(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 256(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 304(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 352(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 336(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 416(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm0,%xmm0
+vmovdqa 32(%rsp),%xmm3
+vmovdqa 80(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 192(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 176(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 240(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 224(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 304(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 288(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 336(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 384(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 160(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 192(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 208(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 240(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 256(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 304(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 352(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 336(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 416(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm1,%xmm1
+vmovdqa 48(%rsp),%xmm3
+vmovdqa 96(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpmuludq 192(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 176(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 240(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 224(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 304(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 288(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 336(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 384(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 160(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 192(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 208(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 240(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 256(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 304(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 352(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 336(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 416(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm6,%xmm6
+vmovdqa 64(%rsp),%xmm3
+vmovdqa 112(%rsp),%xmm9
+vpaddq subc2(%rip),%xmm3,%xmm10
+vpsubq %xmm9,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm10,%xmm3,%xmm9
+vpunpcklqdq %xmm10,%xmm3,%xmm3
+vpmuludq 144(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpmuludq 128(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm3,%xmm3
+vpmuludq 192(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpmuludq 176(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm13,%xmm13
+vpmuludq 240(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpmuludq 224(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm2,%xmm2
+vpmuludq 304(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpmuludq 288(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpmuludq 336(%rsp),%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpmuludq 384(%rsp),%xmm3,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 144(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq v19_19(%rip),%xmm9,%xmm9
+vpmuludq 160(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 192(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 208(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpmuludq 240(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpmuludq 256(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpmuludq 304(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpmuludq 352(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 336(%rsp),%xmm9,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 416(%rsp),%xmm9,%xmm9
+vpaddq %xmm9,%xmm8,%xmm8
+vpsrlq $25,%xmm4,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpand m25(%rip),%xmm4,%xmm4
+vpsrlq $26,%xmm11,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm6,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm13,%xmm3
+vpaddq %xmm3,%xmm0,%xmm0
+vpand m25(%rip),%xmm13,%xmm13
+vpsrlq $25,%xmm5,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm0,%xmm3
+vpaddq %xmm3,%xmm2,%xmm2
+vpand m26(%rip),%xmm0,%xmm0
+vpsrlq $26,%xmm8,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $25,%xmm2,%xmm3
+vpaddq %xmm3,%xmm1,%xmm1
+vpand m25(%rip),%xmm2,%xmm2
+vpsrlq $25,%xmm7,%xmm3
+vpsllq $4,%xmm3,%xmm9
+vpaddq %xmm3,%xmm11,%xmm11
+vpsllq $1,%xmm3,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpaddq %xmm9,%xmm11,%xmm11
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $26,%xmm1,%xmm3
+vpaddq %xmm3,%xmm4,%xmm4
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $26,%xmm11,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $25,%xmm4,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpand m25(%rip),%xmm4,%xmm4
+vpunpcklqdq %xmm13,%xmm11,%xmm3
+vpunpckhqdq %xmm13,%xmm11,%xmm9
+vpaddq subc0(%rip),%xmm9,%xmm10
+vpsubq %xmm3,%xmm10,%xmm10
+vpaddq %xmm9,%xmm3,%xmm3
+vpunpckhqdq %xmm3,%xmm10,%xmm9
+vpunpcklqdq %xmm3,%xmm10,%xmm10
+vpmuludq %xmm10,%xmm10,%xmm3
+vpaddq %xmm10,%xmm10,%xmm10
+vpmuludq %xmm9,%xmm10,%xmm11
+vpunpcklqdq %xmm2,%xmm0,%xmm12
+vpunpckhqdq %xmm2,%xmm0,%xmm0
+vpaddq subc2(%rip),%xmm0,%xmm2
+vpsubq %xmm12,%xmm2,%xmm2
+vpaddq %xmm0,%xmm12,%xmm12
+vpunpckhqdq %xmm12,%xmm2,%xmm0
+vpunpcklqdq %xmm12,%xmm2,%xmm2
+vpmuludq %xmm2,%xmm10,%xmm12
+vpaddq %xmm9,%xmm9,%xmm13
+vpmuludq %xmm13,%xmm9,%xmm9
+vpaddq %xmm9,%xmm12,%xmm12
+vpmuludq %xmm0,%xmm10,%xmm9
+vpmuludq %xmm2,%xmm13,%xmm14
+vpaddq %xmm14,%xmm9,%xmm9
+vpunpcklqdq %xmm4,%xmm1,%xmm14
+vpunpckhqdq %xmm4,%xmm1,%xmm1
+vpaddq subc2(%rip),%xmm1,%xmm4
+vpsubq %xmm14,%xmm4,%xmm4
+vpaddq %xmm1,%xmm14,%xmm14
+vpunpckhqdq %xmm14,%xmm4,%xmm1
+vpunpcklqdq %xmm14,%xmm4,%xmm4
+vmovdqa %xmm1,0(%rsp)
+vpaddq %xmm1,%xmm1,%xmm1
+vmovdqa %xmm1,16(%rsp)
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vmovdqa %xmm1,32(%rsp)
+vpmuludq %xmm4,%xmm10,%xmm1
+vpmuludq %xmm2,%xmm2,%xmm14
+vpaddq %xmm14,%xmm1,%xmm1
+vpmuludq 0(%rsp),%xmm10,%xmm14
+vpmuludq %xmm4,%xmm13,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpunpcklqdq %xmm5,%xmm6,%xmm15
+vpunpckhqdq %xmm5,%xmm6,%xmm5
+vpaddq subc2(%rip),%xmm5,%xmm6
+vpsubq %xmm15,%xmm6,%xmm6
+vpaddq %xmm5,%xmm15,%xmm15
+vpunpckhqdq %xmm15,%xmm6,%xmm5
+vpunpcklqdq %xmm15,%xmm6,%xmm6
+vmovdqa %xmm6,48(%rsp)
+vpmuludq v19_19(%rip),%xmm6,%xmm6
+vmovdqa %xmm6,64(%rsp)
+vmovdqa %xmm5,80(%rsp)
+vpmuludq v38_38(%rip),%xmm5,%xmm5
+vmovdqa %xmm5,96(%rsp)
+vpmuludq 48(%rsp),%xmm10,%xmm5
+vpaddq %xmm0,%xmm0,%xmm6
+vpmuludq %xmm6,%xmm0,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpmuludq 80(%rsp),%xmm10,%xmm0
+vpmuludq %xmm4,%xmm6,%xmm15
+vpaddq %xmm15,%xmm0,%xmm0
+vpmuludq %xmm6,%xmm13,%xmm15
+vpaddq %xmm15,%xmm1,%xmm1
+vpmuludq %xmm6,%xmm2,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpunpcklqdq %xmm7,%xmm8,%xmm15
+vpunpckhqdq %xmm7,%xmm8,%xmm7
+vpaddq subc2(%rip),%xmm7,%xmm8
+vpsubq %xmm15,%xmm8,%xmm8
+vpaddq %xmm7,%xmm15,%xmm15
+vpunpckhqdq %xmm15,%xmm8,%xmm7
+vpunpcklqdq %xmm15,%xmm8,%xmm8
+vmovdqa %xmm8,112(%rsp)
+vpmuludq v19_19(%rip),%xmm8,%xmm8
+vmovdqa %xmm8,160(%rsp)
+vpmuludq 112(%rsp),%xmm10,%xmm8
+vpmuludq %xmm7,%xmm10,%xmm10
+vpmuludq v38_38(%rip),%xmm7,%xmm15
+vpmuludq %xmm15,%xmm7,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq %xmm15,%xmm13,%xmm7
+vpaddq %xmm7,%xmm3,%xmm3
+vpmuludq %xmm15,%xmm2,%xmm7
+vpaddq %xmm7,%xmm11,%xmm11
+vpmuludq 80(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm7,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq 16(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 48(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm0,%xmm0
+vpmuludq 112(%rsp),%xmm13,%xmm7
+vpaddq %xmm7,%xmm10,%xmm10
+vpmuludq %xmm15,%xmm6,%xmm7
+vpaddq %xmm7,%xmm12,%xmm12
+vpmuludq %xmm15,%xmm4,%xmm7
+vpaddq %xmm7,%xmm9,%xmm9
+vpaddq %xmm2,%xmm2,%xmm2
+vpmuludq %xmm4,%xmm2,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 160(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm3,%xmm3
+vpmuludq 160(%rsp),%xmm6,%xmm7
+vpaddq %xmm7,%xmm11,%xmm11
+vpmuludq 0(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm0,%xmm0
+vpmuludq 48(%rsp),%xmm2,%xmm7
+vpaddq %xmm7,%xmm8,%xmm8
+vpmuludq 80(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 96(%rsp),%xmm4,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq %xmm4,%xmm4,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpaddq %xmm4,%xmm4,%xmm2
+vpmuludq 160(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vpmuludq 16(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq 48(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm14,%xmm14
+vpmuludq 96(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 160(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 16(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm8,%xmm8
+vpmuludq 48(%rsp),%xmm6,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 80(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vpmuludq 112(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm0,%xmm0
+vmovdqa 48(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 160(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 80(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 160(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm14,%xmm14
+vpmuludq 64(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 64(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vmovdqa 16(%rsp),%xmm4
+vpmuludq 96(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vmovdqa 48(%rsp),%xmm4
+vpmuludq 96(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 0(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vmovdqa 32(%rsp),%xmm2
+vpmuludq 0(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vmovdqa 64(%rsp),%xmm2
+vpmuludq 48(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vmovdqa 96(%rsp),%xmm2
+vpmuludq 80(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vmovdqa 160(%rsp),%xmm2
+vpmuludq 112(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpsrlq $26,%xmm3,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m26(%rip),%xmm3,%xmm3
+vpsrlq $25,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $25,%xmm11,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpand m25(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm5,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpand m26(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm12,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpand m26(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm0,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm9,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vpand m25(%rip),%xmm9,%xmm9
+vpsrlq $26,%xmm8,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $25,%xmm10,%xmm2
+vpsllq $4,%xmm2,%xmm4
+vpaddq %xmm2,%xmm3,%xmm3
+vpsllq $1,%xmm2,%xmm2
+vpaddq %xmm2,%xmm4,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $26,%xmm3,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m26(%rip),%xmm3,%xmm3
+vpunpckhqdq %xmm11,%xmm3,%xmm2
+vmovdqa %xmm2,0(%rsp)
+vpunpcklqdq %xmm11,%xmm3,%xmm2
+vpmuludq v9_9(%rip),%xmm2,%xmm2
+vmovdqa %xmm2,80(%rsp)
+vpunpckhqdq %xmm9,%xmm12,%xmm2
+vmovdqa %xmm2,16(%rsp)
+vpunpcklqdq %xmm9,%xmm12,%xmm2
+vpmuludq v9_9(%rip),%xmm2,%xmm2
+vmovdqa %xmm2,96(%rsp)
+vpunpckhqdq %xmm14,%xmm1,%xmm2
+vmovdqa %xmm2,32(%rsp)
+vpunpcklqdq %xmm14,%xmm1,%xmm1
+vpmuludq v9_9(%rip),%xmm1,%xmm1
+vmovdqa %xmm1,112(%rsp)
+vpunpckhqdq %xmm0,%xmm5,%xmm1
+vmovdqa %xmm1,48(%rsp)
+vpunpcklqdq %xmm0,%xmm5,%xmm0
+vpmuludq v9_9(%rip),%xmm0,%xmm0
+vmovdqa %xmm0,160(%rsp)
+vpunpckhqdq %xmm10,%xmm8,%xmm0
+vmovdqa %xmm0,64(%rsp)
+vpunpcklqdq %xmm10,%xmm8,%xmm0
+vpmuludq v9_9(%rip),%xmm0,%xmm0
+vmovdqa %xmm0,208(%rsp)
+vmovdqa 144(%rsp),%xmm0
+vpmuludq %xmm0,%xmm0,%xmm1
+vpaddq %xmm0,%xmm0,%xmm0
+vmovdqa 128(%rsp),%xmm2
+vpmuludq %xmm2,%xmm0,%xmm3
+vmovdqa 192(%rsp),%xmm4
+vpmuludq %xmm4,%xmm0,%xmm5
+vmovdqa 176(%rsp),%xmm6
+vpmuludq %xmm6,%xmm0,%xmm7
+vmovdqa 240(%rsp),%xmm8
+vpmuludq %xmm8,%xmm0,%xmm9
+vpmuludq 224(%rsp),%xmm0,%xmm10
+vpmuludq 304(%rsp),%xmm0,%xmm11
+vpmuludq 288(%rsp),%xmm0,%xmm12
+vpmuludq 336(%rsp),%xmm0,%xmm13
+vmovdqa 384(%rsp),%xmm14
+vpmuludq %xmm14,%xmm0,%xmm0
+vpmuludq v38_38(%rip),%xmm14,%xmm15
+vpmuludq %xmm15,%xmm14,%xmm14
+vpaddq %xmm14,%xmm13,%xmm13
+vpaddq %xmm6,%xmm6,%xmm14
+vpmuludq %xmm14,%xmm6,%xmm6
+vpaddq %xmm6,%xmm11,%xmm11
+vpaddq %xmm2,%xmm2,%xmm6
+vpmuludq %xmm6,%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq %xmm15,%xmm6,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vpmuludq %xmm15,%xmm4,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpmuludq 256(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 304(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 352(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 336(%rsp),%xmm6,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq %xmm4,%xmm6,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq %xmm14,%xmm6,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq %xmm8,%xmm6,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq %xmm15,%xmm14,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq %xmm15,%xmm8,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq %xmm4,%xmm4,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq %xmm14,%xmm4,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpaddq %xmm4,%xmm4,%xmm2
+vpmuludq %xmm8,%xmm2,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vpmuludq 400(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpmuludq 400(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vpmuludq 224(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vpmuludq 304(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm13,%xmm13
+vpmuludq 288(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpmuludq 368(%rsp),%xmm8,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpmuludq %xmm8,%xmm14,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq %xmm8,%xmm8,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpaddq %xmm8,%xmm8,%xmm2
+vpmuludq 400(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vpmuludq 256(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 304(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 368(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 256(%rsp),%xmm4
+vpmuludq 400(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm7,%xmm7
+vpmuludq 256(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm13,%xmm13
+vpmuludq 304(%rsp),%xmm14,%xmm4
+vpaddq %xmm4,%xmm0,%xmm0
+vpmuludq 352(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm11,%xmm11
+vpmuludq 336(%rsp),%xmm15,%xmm4
+vpaddq %xmm4,%xmm12,%xmm12
+vmovdqa 304(%rsp),%xmm4
+vpaddq %xmm4,%xmm4,%xmm4
+vpmuludq 400(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm9,%xmm9
+vpmuludq 320(%rsp),%xmm2,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vmovdqa 256(%rsp),%xmm4
+vpmuludq 320(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm3,%xmm3
+vmovdqa 256(%rsp),%xmm4
+vpmuludq 368(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm5,%xmm5
+vmovdqa 304(%rsp),%xmm4
+vpmuludq 368(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm7,%xmm7
+vmovdqa 352(%rsp),%xmm4
+vpmuludq 400(%rsp),%xmm4,%xmm4
+vpaddq %xmm4,%xmm10,%xmm10
+vpmuludq 224(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vmovdqa 272(%rsp),%xmm2
+vpmuludq 224(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm1,%xmm1
+vmovdqa 320(%rsp),%xmm2
+vpmuludq 304(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vmovdqa 368(%rsp),%xmm2
+vpmuludq 288(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vmovdqa 400(%rsp),%xmm2
+vpmuludq 336(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpand m26(%rip),%xmm1,%xmm1
+vpsrlq $25,%xmm10,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm3,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpand m25(%rip),%xmm3,%xmm3
+vpsrlq $26,%xmm11,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm5,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpand m26(%rip),%xmm5,%xmm5
+vpsrlq $25,%xmm12,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpand m25(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm7,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $26,%xmm13,%xmm2
+vpaddq %xmm2,%xmm0,%xmm0
+vpand m26(%rip),%xmm13,%xmm13
+vpsrlq $26,%xmm9,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $25,%xmm0,%xmm2
+vpsllq $4,%xmm2,%xmm4
+vpaddq %xmm2,%xmm1,%xmm1
+vpsllq $1,%xmm2,%xmm2
+vpaddq %xmm2,%xmm4,%xmm4
+vpaddq %xmm4,%xmm1,%xmm1
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm10,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $26,%xmm1,%xmm2
+vpaddq %xmm2,%xmm3,%xmm3
+vpand m26(%rip),%xmm1,%xmm1
+vpunpckhqdq %xmm3,%xmm1,%xmm2
+vpunpcklqdq %xmm3,%xmm1,%xmm1
+vmovdqa %xmm1,176(%rsp)
+vpaddq subc0(%rip),%xmm2,%xmm3
+vpsubq %xmm1,%xmm3,%xmm3
+vpunpckhqdq %xmm3,%xmm2,%xmm1
+vpunpcklqdq %xmm3,%xmm2,%xmm2
+vmovdqa %xmm2,192(%rsp)
+vmovdqa %xmm1,224(%rsp)
+vpsllq $1,%xmm1,%xmm1
+vmovdqa %xmm1,240(%rsp)
+vpmuludq v121666_121666(%rip),%xmm3,%xmm3
+vmovdqa 80(%rsp),%xmm1
+vpunpcklqdq %xmm1,%xmm3,%xmm2
+vpunpckhqdq %xmm1,%xmm3,%xmm1
+vpunpckhqdq %xmm7,%xmm5,%xmm3
+vpunpcklqdq %xmm7,%xmm5,%xmm4
+vmovdqa %xmm4,256(%rsp)
+vpaddq subc2(%rip),%xmm3,%xmm5
+vpsubq %xmm4,%xmm5,%xmm5
+vpunpckhqdq %xmm5,%xmm3,%xmm4
+vpunpcklqdq %xmm5,%xmm3,%xmm3
+vmovdqa %xmm3,272(%rsp)
+vmovdqa %xmm4,288(%rsp)
+vpsllq $1,%xmm4,%xmm4
+vmovdqa %xmm4,304(%rsp)
+vpmuludq v121666_121666(%rip),%xmm5,%xmm5
+vmovdqa 96(%rsp),%xmm3
+vpunpcklqdq %xmm3,%xmm5,%xmm4
+vpunpckhqdq %xmm3,%xmm5,%xmm3
+vpunpckhqdq %xmm10,%xmm9,%xmm5
+vpunpcklqdq %xmm10,%xmm9,%xmm6
+vmovdqa %xmm6,320(%rsp)
+vpaddq subc2(%rip),%xmm5,%xmm7
+vpsubq %xmm6,%xmm7,%xmm7
+vpunpckhqdq %xmm7,%xmm5,%xmm6
+vpunpcklqdq %xmm7,%xmm5,%xmm5
+vmovdqa %xmm5,336(%rsp)
+vmovdqa %xmm6,352(%rsp)
+vpsllq $1,%xmm6,%xmm6
+vmovdqa %xmm6,368(%rsp)
+vpmuludq v121666_121666(%rip),%xmm7,%xmm7
+vmovdqa 112(%rsp),%xmm5
+vpunpcklqdq %xmm5,%xmm7,%xmm6
+vpunpckhqdq %xmm5,%xmm7,%xmm5
+vpunpckhqdq %xmm12,%xmm11,%xmm7
+vpunpcklqdq %xmm12,%xmm11,%xmm8
+vmovdqa %xmm8,384(%rsp)
+vpaddq subc2(%rip),%xmm7,%xmm9
+vpsubq %xmm8,%xmm9,%xmm9
+vpunpckhqdq %xmm9,%xmm7,%xmm8
+vpunpcklqdq %xmm9,%xmm7,%xmm7
+vmovdqa %xmm7,400(%rsp)
+vmovdqa %xmm8,416(%rsp)
+vpsllq $1,%xmm8,%xmm8
+vmovdqa %xmm8,432(%rsp)
+vpmuludq v121666_121666(%rip),%xmm9,%xmm9
+vmovdqa 160(%rsp),%xmm7
+vpunpcklqdq %xmm7,%xmm9,%xmm8
+vpunpckhqdq %xmm7,%xmm9,%xmm7
+vpunpckhqdq %xmm0,%xmm13,%xmm9
+vpunpcklqdq %xmm0,%xmm13,%xmm0
+vmovdqa %xmm0,160(%rsp)
+vpaddq subc2(%rip),%xmm9,%xmm10
+vpsubq %xmm0,%xmm10,%xmm10
+vpunpckhqdq %xmm10,%xmm9,%xmm0
+vpunpcklqdq %xmm10,%xmm9,%xmm9
+vmovdqa %xmm9,448(%rsp)
+vmovdqa %xmm0,464(%rsp)
+vpsllq $1,%xmm0,%xmm0
+vmovdqa %xmm0,480(%rsp)
+vpmuludq v121666_121666(%rip),%xmm10,%xmm10
+vmovdqa 208(%rsp),%xmm0
+vpunpcklqdq %xmm0,%xmm10,%xmm9
+vpunpckhqdq %xmm0,%xmm10,%xmm0
+vpsrlq $26,%xmm2,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpand m26(%rip),%xmm2,%xmm2
+vpsrlq $25,%xmm5,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $25,%xmm1,%xmm10
+vpaddq %xmm10,%xmm4,%xmm4
+vpand m25(%rip),%xmm1,%xmm1
+vpsrlq $26,%xmm8,%xmm10
+vpaddq %xmm10,%xmm7,%xmm7
+vpand m26(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm4,%xmm10
+vpaddq %xmm10,%xmm3,%xmm3
+vpand m26(%rip),%xmm4,%xmm4
+vpsrlq $25,%xmm7,%xmm10
+vpaddq %xmm10,%xmm9,%xmm9
+vpand m25(%rip),%xmm7,%xmm7
+vpsrlq $25,%xmm3,%xmm10
+vpaddq %xmm10,%xmm6,%xmm6
+vpand m25(%rip),%xmm3,%xmm3
+vpsrlq $26,%xmm9,%xmm10
+vpaddq %xmm10,%xmm0,%xmm0
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $26,%xmm6,%xmm10
+vpaddq %xmm10,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm0,%xmm10
+vpsllq $4,%xmm10,%xmm11
+vpaddq %xmm10,%xmm2,%xmm2
+vpsllq $1,%xmm10,%xmm10
+vpaddq %xmm10,%xmm11,%xmm11
+vpaddq %xmm11,%xmm2,%xmm2
+vpand m25(%rip),%xmm0,%xmm0
+vpsrlq $25,%xmm5,%xmm10
+vpaddq %xmm10,%xmm8,%xmm8
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm2,%xmm10
+vpaddq %xmm10,%xmm1,%xmm1
+vpand m26(%rip),%xmm2,%xmm2
+vpunpckhqdq %xmm1,%xmm2,%xmm10
+vmovdqa %xmm10,80(%rsp)
+vpunpcklqdq %xmm1,%xmm2,%xmm1
+vpunpckhqdq %xmm3,%xmm4,%xmm2
+vmovdqa %xmm2,96(%rsp)
+vpunpcklqdq %xmm3,%xmm4,%xmm2
+vpunpckhqdq %xmm5,%xmm6,%xmm3
+vmovdqa %xmm3,112(%rsp)
+vpunpcklqdq %xmm5,%xmm6,%xmm3
+vpunpckhqdq %xmm7,%xmm8,%xmm4
+vmovdqa %xmm4,128(%rsp)
+vpunpcklqdq %xmm7,%xmm8,%xmm4
+vpunpckhqdq %xmm0,%xmm9,%xmm5
+vmovdqa %xmm5,144(%rsp)
+vpunpcklqdq %xmm0,%xmm9,%xmm0
+vmovdqa 176(%rsp),%xmm5
+vpaddq %xmm5,%xmm1,%xmm1
+vpunpcklqdq %xmm1,%xmm5,%xmm6
+vpunpckhqdq %xmm1,%xmm5,%xmm1
+vpmuludq 224(%rsp),%xmm6,%xmm5
+vpmuludq 192(%rsp),%xmm1,%xmm7
+vpaddq %xmm7,%xmm5,%xmm5
+vpmuludq 272(%rsp),%xmm6,%xmm7
+vpmuludq 240(%rsp),%xmm1,%xmm8
+vpaddq %xmm8,%xmm7,%xmm7
+vpmuludq 288(%rsp),%xmm6,%xmm8
+vpmuludq 272(%rsp),%xmm1,%xmm9
+vpaddq %xmm9,%xmm8,%xmm8
+vpmuludq 336(%rsp),%xmm6,%xmm9
+vpmuludq 304(%rsp),%xmm1,%xmm10
+vpaddq %xmm10,%xmm9,%xmm9
+vpmuludq 352(%rsp),%xmm6,%xmm10
+vpmuludq 336(%rsp),%xmm1,%xmm11
+vpaddq %xmm11,%xmm10,%xmm10
+vpmuludq 400(%rsp),%xmm6,%xmm11
+vpmuludq 368(%rsp),%xmm1,%xmm12
+vpaddq %xmm12,%xmm11,%xmm11
+vpmuludq 416(%rsp),%xmm6,%xmm12
+vpmuludq 400(%rsp),%xmm1,%xmm13
+vpaddq %xmm13,%xmm12,%xmm12
+vpmuludq 448(%rsp),%xmm6,%xmm13
+vpmuludq 432(%rsp),%xmm1,%xmm14
+vpaddq %xmm14,%xmm13,%xmm13
+vpmuludq 464(%rsp),%xmm6,%xmm14
+vpmuludq 448(%rsp),%xmm1,%xmm15
+vpaddq %xmm15,%xmm14,%xmm14
+vpmuludq 192(%rsp),%xmm6,%xmm6
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 480(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vmovdqa 256(%rsp),%xmm1
+vpaddq %xmm1,%xmm2,%xmm2
+vpunpcklqdq %xmm2,%xmm1,%xmm15
+vpunpckhqdq %xmm2,%xmm1,%xmm1
+vpmuludq 192(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 224(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 272(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 288(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 336(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 352(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 400(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 416(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm15,%xmm15
+vpmuludq 448(%rsp),%xmm15,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 464(%rsp),%xmm15,%xmm15
+vpaddq %xmm15,%xmm5,%xmm5
+vpmuludq 192(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 240(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 272(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 304(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 336(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 368(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 400(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 432(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 448(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 480(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vmovdqa 320(%rsp),%xmm1
+vpaddq %xmm1,%xmm3,%xmm3
+vpunpcklqdq %xmm3,%xmm1,%xmm2
+vpunpckhqdq %xmm3,%xmm1,%xmm1
+vpmuludq 192(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpmuludq 224(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm10,%xmm10
+vpmuludq 272(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 288(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm12,%xmm12
+vpmuludq 336(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 352(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 400(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 416(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 448(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 464(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 192(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 240(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm11,%xmm11
+vpmuludq 272(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 304(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 336(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 368(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 400(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 432(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 448(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 480(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vmovdqa 384(%rsp),%xmm1
+vpaddq %xmm1,%xmm4,%xmm4
+vpunpcklqdq %xmm4,%xmm1,%xmm2
+vpunpckhqdq %xmm4,%xmm1,%xmm1
+vpmuludq 192(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm11,%xmm11
+vpmuludq 224(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm12,%xmm12
+vpmuludq 272(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm13,%xmm13
+vpmuludq 288(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 336(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm6,%xmm6
+vpmuludq 352(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm5,%xmm5
+vpmuludq 400(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm7,%xmm7
+vpmuludq 416(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm8,%xmm8
+vpmuludq 448(%rsp),%xmm2,%xmm3
+vpaddq %xmm3,%xmm9,%xmm9
+vpmuludq 464(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 192(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 240(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm13,%xmm13
+vpmuludq 272(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm1,%xmm1
+vpmuludq 304(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm6,%xmm6
+vpmuludq 336(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm5,%xmm5
+vpmuludq 368(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm7,%xmm7
+vpmuludq 400(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm8,%xmm8
+vpmuludq 432(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm9,%xmm9
+vpmuludq 448(%rsp),%xmm1,%xmm2
+vpaddq %xmm2,%xmm10,%xmm10
+vpmuludq 480(%rsp),%xmm1,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vmovdqa 160(%rsp),%xmm1
+vpaddq %xmm1,%xmm0,%xmm0
+vpunpcklqdq %xmm0,%xmm1,%xmm2
+vpunpckhqdq %xmm0,%xmm1,%xmm0
+vpmuludq 192(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm13,%xmm13
+vpmuludq 224(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm2,%xmm2
+vpmuludq 272(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpmuludq 288(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm5,%xmm5
+vpmuludq 336(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vpmuludq 352(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm8,%xmm8
+vpmuludq 400(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vpmuludq 416(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm10,%xmm10
+vpmuludq 448(%rsp),%xmm2,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vpmuludq 464(%rsp),%xmm2,%xmm2
+vpaddq %xmm2,%xmm12,%xmm12
+vpmuludq 192(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm14,%xmm14
+vpmuludq v19_19(%rip),%xmm0,%xmm0
+vpmuludq 240(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpmuludq 272(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm5,%xmm5
+vpmuludq 304(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm7,%xmm7
+vpmuludq 336(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm8,%xmm8
+vpmuludq 368(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm9,%xmm9
+vpmuludq 400(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm10,%xmm10
+vpmuludq 432(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm11,%xmm11
+vpmuludq 448(%rsp),%xmm0,%xmm1
+vpaddq %xmm1,%xmm12,%xmm12
+vpmuludq 480(%rsp),%xmm0,%xmm0
+vpaddq %xmm0,%xmm13,%xmm13
+vpsrlq $26,%xmm6,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpsrlq $25,%xmm10,%xmm0
+vpaddq %xmm0,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $25,%xmm5,%xmm0
+vpaddq %xmm0,%xmm7,%xmm7
+vpand m25(%rip),%xmm5,%xmm5
+vpsrlq $26,%xmm11,%xmm0
+vpaddq %xmm0,%xmm12,%xmm12
+vpand m26(%rip),%xmm11,%xmm11
+vpsrlq $26,%xmm7,%xmm0
+vpaddq %xmm0,%xmm8,%xmm8
+vpand m26(%rip),%xmm7,%xmm7
+vpsrlq $25,%xmm12,%xmm0
+vpaddq %xmm0,%xmm13,%xmm13
+vpand m25(%rip),%xmm12,%xmm12
+vpsrlq $25,%xmm8,%xmm0
+vpaddq %xmm0,%xmm9,%xmm9
+vpand m25(%rip),%xmm8,%xmm8
+vpsrlq $26,%xmm13,%xmm0
+vpaddq %xmm0,%xmm14,%xmm14
+vpand m26(%rip),%xmm13,%xmm13
+vpsrlq $26,%xmm9,%xmm0
+vpaddq %xmm0,%xmm10,%xmm10
+vpand m26(%rip),%xmm9,%xmm9
+vpsrlq $25,%xmm14,%xmm0
+vpsllq $4,%xmm0,%xmm1
+vpaddq %xmm0,%xmm6,%xmm6
+vpsllq $1,%xmm0,%xmm0
+vpaddq %xmm0,%xmm1,%xmm1
+vpaddq %xmm1,%xmm6,%xmm6
+vpand m25(%rip),%xmm14,%xmm14
+vpsrlq $25,%xmm10,%xmm0
+vpaddq %xmm0,%xmm11,%xmm11
+vpand m25(%rip),%xmm10,%xmm10
+vpsrlq $26,%xmm6,%xmm0
+vpaddq %xmm0,%xmm5,%xmm5
+vpand m26(%rip),%xmm6,%xmm6
+vpunpckhqdq %xmm5,%xmm6,%xmm1
+vpunpcklqdq %xmm5,%xmm6,%xmm0
+vpunpckhqdq %xmm8,%xmm7,%xmm3
+vpunpcklqdq %xmm8,%xmm7,%xmm2
+vpunpckhqdq %xmm10,%xmm9,%xmm5
+vpunpcklqdq %xmm10,%xmm9,%xmm4
+vpunpckhqdq %xmm12,%xmm11,%xmm7
+vpunpcklqdq %xmm12,%xmm11,%xmm6
+vpunpckhqdq %xmm14,%xmm13,%xmm9
+vpunpcklqdq %xmm14,%xmm13,%xmm8
+cmp $0,%rdx
+jne ._ladder_base_loop
+vmovdqu %xmm1,80(%rdi)
+vmovdqu %xmm0,0(%rdi)
+vmovdqu %xmm3,96(%rdi)
+vmovdqu %xmm2,16(%rdi)
+vmovdqu %xmm5,112(%rdi)
+vmovdqu %xmm4,32(%rdi)
+vmovdqu %xmm7,128(%rdi)
+vmovdqu %xmm6,48(%rdi)
+vmovdqu %xmm9,144(%rdi)
+vmovdqu %xmm8,64(%rdi)
+movq 1536(%rsp),%r11
+movq 1544(%rsp),%r12
+movq 1552(%rsp),%r13
+add %r11,%rsp
+ret
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h
new file mode 100644
index 0000000000..a69be13f0d
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h
@@ -0,0 +1,18 @@
+#ifndef ladder_base_H
+#define ladder_base_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fe.h"
+#include "ladder_base_namespace.h"
+
+extern void ladder_base(fe *, const unsigned char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef ladder_base_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h
new file mode 100644
index 0000000000..304546a185
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h
@@ -0,0 +1,8 @@
+#ifndef ladder_base_namespace_H
+#define ladder_base_namespace_H
+
+#define ladder_base crypto_scalarmult_curve25519_sandy2x_ladder_base
+#define _ladder_base _crypto_scalarmult_curve25519_sandy2x_ladder_base
+
+#endif /* ifndef ladder_base_namespace_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h
new file mode 100644
index 0000000000..6637074bec
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h
@@ -0,0 +1,8 @@
+#ifndef ladder_namespace_H
+#define ladder_namespace_H
+
+#define ladder crypto_scalarmult_curve25519_sandy2x_ladder
+#define _ladder _crypto_scalarmult_curve25519_sandy2x_ladder
+
+#endif /* ifndef ladder_namespace_H */
+
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S
new file mode 100644
index 0000000000..1fd632057b
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S
@@ -0,0 +1,17 @@
+
+#ifdef HAVE_AVX_ASM
+
+#define IN_SANDY2X
+
+#include "consts.S"
+#include "fe51_mul.S"
+#include "fe51_nsquare.S"
+#include "fe51_pack.S"
+#include "ladder.S"
+#include "ladder_base.S"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c
new file mode 100644
index 0000000000..2d3ffc0563
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c
@@ -0,0 +1,59 @@
+
+#include "crypto_scalarmult_curve25519.h"
+#include "private/implementations.h"
+#include "scalarmult_curve25519.h"
+#include "runtime.h"
+
+#ifdef HAVE_AVX_ASM
+# include "sandy2x/curve25519_sandy2x.h"
+#endif
+#include "ref10/x25519_ref10.h"
+static const crypto_scalarmult_curve25519_implementation *implementation =
+ &crypto_scalarmult_curve25519_ref10_implementation;
+
+int
+crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+{
+ size_t i;
+ volatile unsigned char d = 0;
+
+ if (implementation->mult(q, n, p) != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ for (i = 0; i < crypto_scalarmult_curve25519_BYTES; i++) {
+ d |= q[i];
+ }
+ return -(1 & ((d - 1) >> 8));
+}
+
+int
+crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n)
+{
+ return implementation->mult_base(q, n);
+}
+
+size_t
+crypto_scalarmult_curve25519_bytes(void)
+{
+ return crypto_scalarmult_curve25519_BYTES;
+}
+
+size_t
+crypto_scalarmult_curve25519_scalarbytes(void)
+{
+ return crypto_scalarmult_curve25519_SCALARBYTES;
+}
+
+int
+_crypto_scalarmult_curve25519_pick_best_implementation(void)
+{
+ implementation = &crypto_scalarmult_curve25519_ref10_implementation;
+
+#ifdef HAVE_AVX_ASM
+ if (sodium_runtime_has_avx()) {
+ implementation = &crypto_scalarmult_curve25519_sandy2x_implementation;
+ }
+#endif
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h
new file mode 100644
index 0000000000..66edbf6a8a
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h
@@ -0,0 +1,11 @@
+
+#ifndef scalarmult_poly1305_H
+#define scalarmult_poly1305_H
+
+typedef struct crypto_scalarmult_curve25519_implementation {
+ int (*mult)(unsigned char *q, const unsigned char *n,
+ const unsigned char *p);
+ int (*mult_base)(unsigned char *q, const unsigned char *n);
+} crypto_scalarmult_curve25519_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c
new file mode 100644
index 0000000000..0e317cf7cc
--- /dev/null
+++ b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c
@@ -0,0 +1,86 @@
+
+#include <string.h>
+
+#include "crypto_scalarmult_ed25519.h"
+#include "private/ed25519_ref10.h"
+#include "utils.h"
+
+static int
+_crypto_scalarmult_ed25519_is_inf(const unsigned char s[32])
+{
+ unsigned char c;
+ unsigned int i;
+
+ c = s[0] ^ 0x01;
+ for (i = 1; i < 31; i++) {
+ c |= s[i];
+ }
+ c |= s[31] & 0x7f;
+
+ return ((((unsigned int) c) - 1U) >> 8) & 1;
+}
+
+static inline void
+_crypto_scalarmult_ed25519_clamp(unsigned char k[32])
+{
+ k[0] &= 248;
+ k[31] &= 127;
+ k[31] |= 64;
+}
+
+int
+crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+{
+ unsigned char *t = q;
+ ge25519_p3 Q;
+ ge25519_p3 P;
+ unsigned int i;
+
+ if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 ||
+ ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) {
+ return -1;
+ }
+ for (i = 0; i < 32; ++i) {
+ t[i] = n[i];
+ }
+ _crypto_scalarmult_ed25519_clamp(t);
+ ge25519_scalarmult(&Q, t, &P);
+ ge25519_p3_tobytes(q, &Q);
+ if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+crypto_scalarmult_ed25519_base(unsigned char *q,
+ const unsigned char *n)
+{
+ unsigned char *t = q;
+ ge25519_p3 Q;
+ unsigned int i;
+
+ for (i = 0; i < 32; ++i) {
+ t[i] = n[i];
+ }
+ _crypto_scalarmult_ed25519_clamp(t);
+ ge25519_scalarmult_base(&Q, t);
+ ge25519_p3_tobytes(q, &Q);
+ if (sodium_is_zero(n, 32) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+size_t
+crypto_scalarmult_ed25519_bytes(void)
+{
+ return crypto_scalarmult_ed25519_BYTES;
+}
+
+size_t
+crypto_scalarmult_ed25519_scalarbytes(void)
+{
+ return crypto_scalarmult_ed25519_SCALARBYTES;
+}
diff --git a/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c b/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c
new file mode 100644
index 0000000000..45f678ecdf
--- /dev/null
+++ b/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c
@@ -0,0 +1,67 @@
+
+#include "crypto_secretbox.h"
+#include "randombytes.h"
+
+size_t
+crypto_secretbox_keybytes(void)
+{
+ return crypto_secretbox_KEYBYTES;
+}
+
+size_t
+crypto_secretbox_noncebytes(void)
+{
+ return crypto_secretbox_NONCEBYTES;
+}
+
+size_t
+crypto_secretbox_zerobytes(void)
+{
+ return crypto_secretbox_ZEROBYTES;
+}
+
+size_t
+crypto_secretbox_boxzerobytes(void)
+{
+ return crypto_secretbox_BOXZEROBYTES;
+}
+
+size_t
+crypto_secretbox_macbytes(void)
+{
+ return crypto_secretbox_MACBYTES;
+}
+
+size_t
+crypto_secretbox_messagebytes_max(void)
+{
+ return crypto_secretbox_MESSAGEBYTES_MAX;
+}
+
+const char *
+crypto_secretbox_primitive(void)
+{
+ return crypto_secretbox_PRIMITIVE;
+}
+
+int
+crypto_secretbox(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k);
+}
+
+int
+crypto_secretbox_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k);
+}
+
+void
+crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES])
+{
+ randombytes_buf(k, crypto_secretbox_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c
new file mode 100644
index 0000000000..b1203849f2
--- /dev/null
+++ b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c
@@ -0,0 +1,144 @@
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_core_hsalsa20.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_secretbox.h"
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "utils.h"
+
+int
+crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
+ unsigned long long i;
+ unsigned long long mlen0;
+
+ crypto_core_hsalsa20(subkey, n, k, NULL);
+
+ if (((uintptr_t) c > (uintptr_t) m &&
+ (uintptr_t) c - (uintptr_t) m < mlen) ||
+ ((uintptr_t) m > (uintptr_t) c &&
+ (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */
+ memmove(c, m, mlen);
+ m = c;
+ }
+ memset(block0, 0U, crypto_secretbox_ZEROBYTES);
+ COMPILER_ASSERT(64U >= crypto_secretbox_ZEROBYTES);
+ mlen0 = mlen;
+ if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
+ mlen0 = 64U - crypto_secretbox_ZEROBYTES;
+ }
+ for (i = 0U; i < mlen0; i++) {
+ block0[i + crypto_secretbox_ZEROBYTES] = m[i];
+ }
+ crypto_stream_salsa20_xor(block0, block0,
+ mlen0 + crypto_secretbox_ZEROBYTES,
+ n + 16, subkey);
+ COMPILER_ASSERT(crypto_secretbox_ZEROBYTES >=
+ crypto_onetimeauth_poly1305_KEYBYTES);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+
+ for (i = 0U; i < mlen0; i++) {
+ c[i] = block0[crypto_secretbox_ZEROBYTES + i];
+ }
+ sodium_memzero(block0, sizeof block0);
+ if (mlen > mlen0) {
+ crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
+ n + 16, 1U, subkey);
+ }
+ sodium_memzero(subkey, sizeof subkey);
+
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_final(&state, mac);
+ sodium_memzero(&state, sizeof state);
+
+ return 0;
+}
+
+int
+crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ if (mlen > crypto_secretbox_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_secretbox_detached(c + crypto_secretbox_MACBYTES,
+ c, m, mlen, n, k);
+}
+
+int
+crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char block0[64U];
+ unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
+ unsigned long long i;
+ unsigned long long mlen0;
+
+ crypto_core_hsalsa20(subkey, n, k, NULL);
+ crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES,
+ n + 16, subkey);
+ if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) {
+ sodium_memzero(subkey, sizeof subkey);
+ return -1;
+ }
+ if (m == NULL) {
+ return 0;
+ }
+ if (((uintptr_t) c >= (uintptr_t) m &&
+ (uintptr_t) c - (uintptr_t) m < clen) ||
+ ((uintptr_t) m >= (uintptr_t) c &&
+ (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */
+ memmove(m, c, clen);
+ c = m;
+ }
+ mlen0 = clen;
+ if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
+ mlen0 = 64U - crypto_secretbox_ZEROBYTES;
+ }
+ for (i = 0U; i < mlen0; i++) {
+ block0[crypto_secretbox_ZEROBYTES + i] = c[i];
+ }
+ crypto_stream_salsa20_xor(block0, block0,
+ crypto_secretbox_ZEROBYTES + mlen0,
+ n + 16, subkey);
+ for (i = 0U; i < mlen0; i++) {
+ m[i] = block0[i + crypto_secretbox_ZEROBYTES];
+ }
+ if (clen > mlen0) {
+ crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0,
+ n + 16, 1U, subkey);
+ }
+ sodium_memzero(subkey, sizeof subkey);
+
+ return 0;
+}
+
+int
+crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ if (clen < crypto_secretbox_MACBYTES) {
+ return -1;
+ }
+ return crypto_secretbox_open_detached(m, c + crypto_secretbox_MACBYTES, c,
+ clen - crypto_secretbox_MACBYTES,
+ n, k);
+}
diff --git a/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c
new file mode 100644
index 0000000000..e76167d2ee
--- /dev/null
+++ b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c
@@ -0,0 +1,177 @@
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_core_hchacha20.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_secretbox_xchacha20poly1305.h"
+#include "crypto_stream_chacha20.h"
+#include "private/common.h"
+#include "utils.h"
+
+#define crypto_secretbox_xchacha20poly1305_ZEROBYTES 32U
+
+int
+crypto_secretbox_xchacha20poly1305_detached(unsigned char *c,
+ unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ crypto_onetimeauth_poly1305_state state;
+ unsigned char block0[64U];
+ unsigned char subkey[crypto_stream_chacha20_KEYBYTES];
+ unsigned long long i;
+ unsigned long long mlen0;
+
+ crypto_core_hchacha20(subkey, n, k, NULL);
+
+ if (((uintptr_t) c > (uintptr_t) m &&
+ (uintptr_t) c - (uintptr_t) m < mlen) ||
+ ((uintptr_t) m > (uintptr_t) c &&
+ (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */
+ memmove(c, m, mlen);
+ m = c;
+ }
+ memset(block0, 0U, crypto_secretbox_xchacha20poly1305_ZEROBYTES);
+ COMPILER_ASSERT(64U >= crypto_secretbox_xchacha20poly1305_ZEROBYTES);
+ mlen0 = mlen;
+ if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) {
+ mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES;
+ }
+ for (i = 0U; i < mlen0; i++) {
+ block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES] = m[i];
+ }
+ crypto_stream_chacha20_xor(block0, block0,
+ mlen0 + crypto_secretbox_xchacha20poly1305_ZEROBYTES,
+ n + 16, subkey);
+ COMPILER_ASSERT(crypto_secretbox_xchacha20poly1305_ZEROBYTES >=
+ crypto_onetimeauth_poly1305_KEYBYTES);
+ crypto_onetimeauth_poly1305_init(&state, block0);
+
+ for (i = 0U; i < mlen0; i++) {
+ c[i] = block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i];
+ }
+ sodium_memzero(block0, sizeof block0);
+ if (mlen > mlen0) {
+ crypto_stream_chacha20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
+ n + 16, 1U, subkey);
+ }
+ sodium_memzero(subkey, sizeof subkey);
+
+ crypto_onetimeauth_poly1305_update(&state, c, mlen);
+ crypto_onetimeauth_poly1305_final(&state, mac);
+ sodium_memzero(&state, sizeof state);
+
+ return 0;
+}
+
+int
+crypto_secretbox_xchacha20poly1305_easy(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ if (mlen > crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ return crypto_secretbox_xchacha20poly1305_detached
+ (c + crypto_secretbox_xchacha20poly1305_MACBYTES, c, m, mlen, n, k);
+}
+
+int
+crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m,
+ const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char block0[64U];
+ unsigned char subkey[crypto_stream_chacha20_KEYBYTES];
+ unsigned long long i;
+ unsigned long long mlen0;
+
+ crypto_core_hchacha20(subkey, n, k, NULL);
+ crypto_stream_chacha20(block0, crypto_stream_chacha20_KEYBYTES,
+ n + 16, subkey);
+ if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) {
+ sodium_memzero(subkey, sizeof subkey);
+ return -1;
+ }
+ if (m == NULL) {
+ return 0;
+ }
+ if (((uintptr_t) c >= (uintptr_t) m &&
+ (uintptr_t) c - (uintptr_t) m < clen) ||
+ ((uintptr_t) m >= (uintptr_t) c &&
+ (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */
+ memmove(m, c, clen);
+ c = m;
+ }
+ mlen0 = clen;
+ if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) {
+ mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES;
+ }
+ for (i = 0U; i < mlen0; i++) {
+ block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i] = c[i];
+ }
+ crypto_stream_chacha20_xor(block0, block0,
+ crypto_secretbox_xchacha20poly1305_ZEROBYTES + mlen0,
+ n + 16, subkey);
+ for (i = 0U; i < mlen0; i++) {
+ m[i] = block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES];
+ }
+ if (clen > mlen0) {
+ crypto_stream_chacha20_xor_ic(m + mlen0, c + mlen0, clen - mlen0,
+ n + 16, 1U, subkey);
+ }
+ sodium_memzero(subkey, sizeof subkey);
+
+ return 0;
+}
+
+int
+crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ if (clen < crypto_secretbox_xchacha20poly1305_MACBYTES) {
+ return -1;
+ }
+ return crypto_secretbox_xchacha20poly1305_open_detached
+ (m, c + crypto_secretbox_xchacha20poly1305_MACBYTES, c,
+ clen - crypto_secretbox_xchacha20poly1305_MACBYTES, n, k);
+}
+
+size_t
+crypto_secretbox_xchacha20poly1305_keybytes(void)
+{
+ return crypto_secretbox_xchacha20poly1305_KEYBYTES;
+}
+
+size_t
+crypto_secretbox_xchacha20poly1305_noncebytes(void)
+{
+ return crypto_secretbox_xchacha20poly1305_NONCEBYTES;
+}
+
+size_t
+crypto_secretbox_xchacha20poly1305_macbytes(void)
+{
+ return crypto_secretbox_xchacha20poly1305_MACBYTES;
+}
+
+size_t
+crypto_secretbox_xchacha20poly1305_messagebytes_max(void)
+{
+ return crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX;
+}
diff --git a/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c b/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c
new file mode 100644
index 0000000000..7240050dfd
--- /dev/null
+++ b/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c
@@ -0,0 +1,89 @@
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_secretbox_xsalsa20poly1305.h"
+#include "crypto_stream_xsalsa20.h"
+#include "randombytes.h"
+
+int
+crypto_secretbox_xsalsa20poly1305(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ int i;
+
+ if (mlen < 32) {
+ return -1;
+ }
+ crypto_stream_xsalsa20_xor(c, m, mlen, n, k);
+ crypto_onetimeauth_poly1305(c + 16, c + 32, mlen - 32, c);
+ for (i = 0; i < 16; ++i) {
+ c[i] = 0;
+ }
+ return 0;
+}
+
+int
+crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char subkey[32];
+ int i;
+
+ if (clen < 32) {
+ return -1;
+ }
+ crypto_stream_xsalsa20(subkey, 32, n, k);
+ if (crypto_onetimeauth_poly1305_verify(c + 16, c + 32,
+ clen - 32, subkey) != 0) {
+ return -1;
+ }
+ crypto_stream_xsalsa20_xor(m, c, clen, n, k);
+ for (i = 0; i < 32; ++i) {
+ m[i] = 0;
+ }
+ return 0;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_keybytes(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_KEYBYTES;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_noncebytes(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_NONCEBYTES;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_zerobytes(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_ZEROBYTES;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_boxzerobytes(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_macbytes(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_MACBYTES;
+}
+
+size_t
+crypto_secretbox_xsalsa20poly1305_messagebytes_max(void)
+{
+ return crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES])
+{
+ randombytes_buf(k, crypto_secretbox_xsalsa20poly1305_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c
new file mode 100644
index 0000000000..ef000d16c7
--- /dev/null
+++ b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c
@@ -0,0 +1,311 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_aead_chacha20poly1305.h"
+#include "crypto_aead_xchacha20poly1305.h"
+#include "crypto_core_hchacha20.h"
+#include "crypto_onetimeauth_poly1305.h"
+#include "crypto_secretstream_xchacha20poly1305.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#include "private/common.h"
+
+#define crypto_secretstream_xchacha20poly1305_COUNTERBYTES 4U
+#define crypto_secretstream_xchacha20poly1305_INONCEBYTES 8U
+
+#define STATE_COUNTER(STATE) ((STATE)->nonce)
+#define STATE_INONCE(STATE) ((STATE)->nonce + \
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES)
+
+static const unsigned char _pad0[16] = { 0 };
+
+static inline void
+_crypto_secretstream_xchacha20poly1305_counter_reset
+ (crypto_secretstream_xchacha20poly1305_state *state)
+{
+ memset(STATE_COUNTER(state), 0,
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+ STATE_COUNTER(state)[0] = 1;
+}
+
+void
+crypto_secretstream_xchacha20poly1305_keygen
+ (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
+{
+ randombytes_buf(k, crypto_secretstream_xchacha20poly1305_KEYBYTES);
+}
+
+int
+crypto_secretstream_xchacha20poly1305_init_push
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char out[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
+ const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
+{
+ COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES ==
+ crypto_core_hchacha20_INPUTBYTES +
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES ==
+ crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
+ COMPILER_ASSERT(sizeof state->nonce ==
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES +
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+
+ randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES);
+ crypto_core_hchacha20(state->k, out, k, NULL);
+ _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+ memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES,
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ memset(state->_pad, 0, sizeof state->_pad);
+
+ return 0;
+}
+
+int
+crypto_secretstream_xchacha20poly1305_init_pull
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ const unsigned char in[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
+ const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
+{
+ crypto_core_hchacha20(state->k, in, k, NULL);
+ _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+ memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES,
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ memset(state->_pad, 0, sizeof state->_pad);
+
+ return 0;
+}
+
+void
+crypto_secretstream_xchacha20poly1305_rekey
+ (crypto_secretstream_xchacha20poly1305_state *state)
+{
+ unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES +
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES];
+ size_t i;
+
+ for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+ new_key_and_inonce[i] = state->k[i];
+ }
+ for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+ new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] =
+ STATE_INONCE(state)[i];
+ }
+ crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce,
+ sizeof new_key_and_inonce,
+ state->nonce, state->k);
+ for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+ state->k[i] = new_key_and_inonce[i];
+ }
+ for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+ STATE_INONCE(state)[i] =
+ new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i];
+ }
+ _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+}
+
+int
+crypto_secretstream_xchacha20poly1305_push
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char *out, unsigned long long *outlen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen, unsigned char tag)
+{
+ crypto_onetimeauth_poly1305_state poly1305_state;
+ unsigned char block[64U];
+ unsigned char slen[8U];
+ unsigned char *c;
+ unsigned char *mac;
+
+ if (outlen_p != NULL) {
+ *outlen_p = 0U;
+ }
+ if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+ crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+ sodium_memzero(block, sizeof block);
+
+ crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+ (0x10 - adlen) & 0xf);
+ memset(block, 0, sizeof block);
+ block[0] = tag;
+
+ crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+ state->nonce, 1U, state->k);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+ out[0] = block[0];
+
+ c = out + (sizeof tag);
+ crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+ crypto_onetimeauth_poly1305_update
+ (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+ STORE64_LE(slen, (sizeof block) + mlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+
+ mac = c + mlen;
+ crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+ sodium_memzero(&poly1305_state, sizeof poly1305_state);
+
+ COMPILER_ASSERT(crypto_onetimeauth_poly1305_BYTES >=
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ XOR_BUF(STATE_INONCE(state), mac,
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ sodium_increment(STATE_COUNTER(state),
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+ if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+ sodium_is_zero(STATE_COUNTER(state),
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+ crypto_secretstream_xchacha20poly1305_rekey(state);
+ }
+ if (outlen_p != NULL) {
+ *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen;
+ }
+ return 0;
+}
+
+int
+crypto_secretstream_xchacha20poly1305_pull
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p,
+ const unsigned char *in, unsigned long long inlen,
+ const unsigned char *ad, unsigned long long adlen)
+{
+ crypto_onetimeauth_poly1305_state poly1305_state;
+ unsigned char block[64U];
+ unsigned char slen[8U];
+ unsigned char mac[crypto_onetimeauth_poly1305_BYTES];
+ const unsigned char *c;
+ const unsigned char *stored_mac;
+ unsigned long long mlen;
+ unsigned char tag;
+
+ if (mlen_p != NULL) {
+ *mlen_p = 0U;
+ }
+ if (tag_p != NULL) {
+ *tag_p = 0xff;
+ }
+ if (inlen < crypto_secretstream_xchacha20poly1305_ABYTES) {
+ return -1;
+ }
+ mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES;
+ if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+ crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+ sodium_memzero(block, sizeof block);
+
+ crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+ (0x10 - adlen) & 0xf);
+
+ memset(block, 0, sizeof block);
+ block[0] = in[0];
+ crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+ state->nonce, 1U, state->k);
+ tag = block[0];
+ block[0] = in[0];
+ crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+
+ c = in + (sizeof tag);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+ crypto_onetimeauth_poly1305_update
+ (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+
+ STORE64_LE(slen, (uint64_t) adlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+ STORE64_LE(slen, (sizeof block) + mlen);
+ crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+
+ crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+ sodium_memzero(&poly1305_state, sizeof poly1305_state);
+
+ stored_mac = c + mlen;
+ if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) {
+ sodium_memzero(mac, sizeof mac);
+ return -1;
+ }
+
+ crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
+ XOR_BUF(STATE_INONCE(state), mac,
+ crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+ sodium_increment(STATE_COUNTER(state),
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+ if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+ sodium_is_zero(STATE_COUNTER(state),
+ crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+ crypto_secretstream_xchacha20poly1305_rekey(state);
+ }
+ if (mlen_p != NULL) {
+ *mlen_p = mlen;
+ }
+ if (tag_p != NULL) {
+ *tag_p = tag;
+ }
+ return 0;
+}
+
+size_t
+crypto_secretstream_xchacha20poly1305_statebytes(void)
+{
+ return sizeof(crypto_secretstream_xchacha20poly1305_state);
+}
+
+size_t
+crypto_secretstream_xchacha20poly1305_abytes(void)
+{
+ return crypto_secretstream_xchacha20poly1305_ABYTES;
+}
+
+size_t
+crypto_secretstream_xchacha20poly1305_headerbytes(void)
+{
+ return crypto_secretstream_xchacha20poly1305_HEADERBYTES;
+}
+
+size_t
+crypto_secretstream_xchacha20poly1305_keybytes(void)
+{
+ return crypto_secretstream_xchacha20poly1305_KEYBYTES;
+}
+
+size_t
+crypto_secretstream_xchacha20poly1305_messagebytes_max(void)
+{
+ return crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX;
+}
+
+unsigned char
+crypto_secretstream_xchacha20poly1305_tag_message(void)
+{
+ return crypto_secretstream_xchacha20poly1305_TAG_MESSAGE;
+}
+
+unsigned char
+crypto_secretstream_xchacha20poly1305_tag_push(void)
+{
+ return crypto_secretstream_xchacha20poly1305_TAG_PUSH;
+}
+
+unsigned char
+crypto_secretstream_xchacha20poly1305_tag_rekey(void)
+{
+ return crypto_secretstream_xchacha20poly1305_TAG_REKEY;
+}
+
+unsigned char
+crypto_secretstream_xchacha20poly1305_tag_final(void)
+{
+ return crypto_secretstream_xchacha20poly1305_TAG_FINAL;
+}
diff --git a/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c b/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c
new file mode 100644
index 0000000000..95f52f83ba
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c
@@ -0,0 +1,34 @@
+
+#include "crypto_shorthash.h"
+#include "randombytes.h"
+
+size_t
+crypto_shorthash_bytes(void)
+{
+ return crypto_shorthash_BYTES;
+}
+
+size_t
+crypto_shorthash_keybytes(void)
+{
+ return crypto_shorthash_KEYBYTES;
+}
+
+const char *
+crypto_shorthash_primitive(void)
+{
+ return crypto_shorthash_PRIMITIVE;
+}
+
+int
+crypto_shorthash(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ return crypto_shorthash_siphash24(out, in, inlen, k);
+}
+
+void
+crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES])
+{
+ randombytes_buf(k, crypto_shorthash_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c
new file mode 100644
index 0000000000..0c173d4c89
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c
@@ -0,0 +1,65 @@
+#include "crypto_shorthash_siphash24.h"
+#include "private/common.h"
+#include "shorthash_siphash_ref.h"
+
+int
+crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ /* "somepseudorandomlygeneratedbytes" */
+ uint64_t v0 = 0x736f6d6570736575ULL;
+ uint64_t v1 = 0x646f72616e646f6dULL;
+ uint64_t v2 = 0x6c7967656e657261ULL;
+ uint64_t v3 = 0x7465646279746573ULL;
+ uint64_t b;
+ uint64_t k0 = LOAD64_LE(k);
+ uint64_t k1 = LOAD64_LE(k + 8);
+ uint64_t m;
+ const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
+ const int left = inlen & 7;
+
+ b = ((uint64_t) inlen) << 56;
+ v3 ^= k1;
+ v2 ^= k0;
+ v1 ^= k1;
+ v0 ^= k0;
+ for (; in != end; in += 8) {
+ m = LOAD64_LE(in);
+ v3 ^= m;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= m;
+ }
+ switch (left) {
+ case 7:
+ b |= ((uint64_t) in[6]) << 48;
+ case 6:
+ b |= ((uint64_t) in[5]) << 40;
+ case 5:
+ b |= ((uint64_t) in[4]) << 32;
+ case 4:
+ b |= ((uint64_t) in[3]) << 24;
+ case 3:
+ b |= ((uint64_t) in[2]) << 16;
+ case 2:
+ b |= ((uint64_t) in[1]) << 8;
+ case 1:
+ b |= ((uint64_t) in[0]);
+ break;
+ case 0:
+ break;
+ }
+ v3 ^= b;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= b;
+ v2 ^= 0xff;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ b = v0 ^ v1 ^ v2 ^ v3;
+ STORE64_LE(out, b);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h
new file mode 100644
index 0000000000..3f9a38b510
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h
@@ -0,0 +1,24 @@
+#ifndef shorthash_siphash_H
+#define shorthash_siphash_H
+
+#include "private/common.h"
+
+#define SIPROUND \
+ do { \
+ v0 += v1; \
+ v1 = ROTL64(v1, 13); \
+ v1 ^= v0; \
+ v0 = ROTL64(v0, 32); \
+ v2 += v3; \
+ v3 = ROTL64(v3, 16); \
+ v3 ^= v2; \
+ v0 += v3; \
+ v3 = ROTL64(v3, 21); \
+ v3 ^= v0; \
+ v2 += v1; \
+ v1 = ROTL64(v1, 17); \
+ v1 ^= v2; \
+ v2 = ROTL64(v2, 32); \
+ } while (0)
+
+#endif
diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c
new file mode 100644
index 0000000000..20480d0d5f
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c
@@ -0,0 +1,71 @@
+#include "crypto_shorthash_siphash24.h"
+#include "private/common.h"
+#include "shorthash_siphash_ref.h"
+
+int
+crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+{
+ uint64_t v0 = 0x736f6d6570736575ULL;
+ uint64_t v1 = 0x646f72616e646f83ULL;
+ uint64_t v2 = 0x6c7967656e657261ULL;
+ uint64_t v3 = 0x7465646279746573ULL;
+ uint64_t b;
+ uint64_t k0 = LOAD64_LE(k);
+ uint64_t k1 = LOAD64_LE(k + 8);
+ uint64_t m;
+ const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
+ const int left = inlen & 7;
+
+ b = ((uint64_t) inlen) << 56;
+ v3 ^= k1;
+ v2 ^= k0;
+ v1 ^= k1;
+ v0 ^= k0;
+ for (; in != end; in += 8) {
+ m = LOAD64_LE(in);
+ v3 ^= m;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= m;
+ }
+ switch (left) {
+ case 7:
+ b |= ((uint64_t) in[6]) << 48;
+ case 6:
+ b |= ((uint64_t) in[5]) << 40;
+ case 5:
+ b |= ((uint64_t) in[4]) << 32;
+ case 4:
+ b |= ((uint64_t) in[3]) << 24;
+ case 3:
+ b |= ((uint64_t) in[2]) << 16;
+ case 2:
+ b |= ((uint64_t) in[1]) << 8;
+ case 1:
+ b |= ((uint64_t) in[0]);
+ break;
+ case 0:
+ break;
+ }
+ v3 ^= b;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= b;
+ v2 ^= 0xee;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ b = v0 ^ v1 ^ v2 ^ v3;
+ STORE64_LE(out, b);
+ v1 ^= 0xdd;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ b = v0 ^ v1 ^ v2 ^ v3;
+ STORE64_LE(out + 8, b);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c
new file mode 100644
index 0000000000..e2cea7761e
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c
@@ -0,0 +1,11 @@
+#include "crypto_shorthash_siphash24.h"
+
+size_t
+crypto_shorthash_siphash24_bytes(void) {
+ return crypto_shorthash_siphash24_BYTES;
+}
+
+size_t
+crypto_shorthash_siphash24_keybytes(void) {
+ return crypto_shorthash_siphash24_KEYBYTES;
+}
diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c
new file mode 100644
index 0000000000..2d487dbb6f
--- /dev/null
+++ b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c
@@ -0,0 +1,11 @@
+#include "crypto_shorthash_siphash24.h"
+
+size_t
+crypto_shorthash_siphashx24_bytes(void) {
+ return crypto_shorthash_siphashx24_BYTES;
+}
+
+size_t
+crypto_shorthash_siphashx24_keybytes(void) {
+ return crypto_shorthash_siphashx24_KEYBYTES;
+}
diff --git a/libs/libsodium/src/crypto_sign/crypto_sign.c b/libs/libsodium/src/crypto_sign/crypto_sign.c
new file mode 100644
index 0000000000..127072f726
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/crypto_sign.c
@@ -0,0 +1,115 @@
+
+#include "crypto_sign.h"
+
+size_t
+crypto_sign_statebytes(void)
+{
+ return sizeof(crypto_sign_state);
+}
+
+size_t
+crypto_sign_bytes(void)
+{
+ return crypto_sign_BYTES;
+}
+
+size_t
+crypto_sign_seedbytes(void)
+{
+ return crypto_sign_SEEDBYTES;
+}
+
+size_t
+crypto_sign_publickeybytes(void)
+{
+ return crypto_sign_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_sign_secretkeybytes(void)
+{
+ return crypto_sign_SECRETKEYBYTES;
+}
+
+size_t
+crypto_sign_messagebytes_max(void)
+{
+ return crypto_sign_MESSAGEBYTES_MAX;
+}
+
+const char *
+crypto_sign_primitive(void)
+{
+ return crypto_sign_PRIMITIVE;
+}
+
+int
+crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed)
+{
+ return crypto_sign_ed25519_seed_keypair(pk, sk, seed);
+}
+
+int
+crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
+{
+ return crypto_sign_ed25519_keypair(pk, sk);
+}
+
+int
+crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ return crypto_sign_ed25519(sm, smlen_p, m, mlen, sk);
+}
+
+int
+crypto_sign_open(unsigned char *m, unsigned long long *mlen_p,
+ const unsigned char *sm, unsigned long long smlen,
+ const unsigned char *pk)
+{
+ return crypto_sign_ed25519_open(m, mlen_p, sm, smlen, pk);
+}
+
+int
+crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ return crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk);
+}
+
+int
+crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *pk)
+{
+ return crypto_sign_ed25519_verify_detached(sig, m, mlen, pk);
+}
+
+int
+crypto_sign_init(crypto_sign_state *state)
+{
+ return crypto_sign_ed25519ph_init(state);
+}
+
+int
+crypto_sign_update(crypto_sign_state *state, const unsigned char *m,
+ unsigned long long mlen)
+{
+ return crypto_sign_ed25519ph_update(state, m, mlen);
+}
+
+int
+crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig,
+ unsigned long long *siglen_p, const unsigned char *sk)
+{
+ return crypto_sign_ed25519ph_final_create(state, sig, siglen_p, sk);
+}
+
+int
+crypto_sign_final_verify(crypto_sign_state *state, unsigned char *sig,
+ const unsigned char *pk)
+{
+ return crypto_sign_ed25519ph_final_verify(state, sig, pk);
+}
diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c
new file mode 100644
index 0000000000..8bf3cec8fd
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c
@@ -0,0 +1,91 @@
+
+#include <string.h>
+
+#include "crypto_hash_sha512.h"
+#include "crypto_scalarmult_curve25519.h"
+#include "crypto_sign_ed25519.h"
+#include "sign_ed25519_ref10.h"
+#include "private/ed25519_ref10.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed)
+{
+ ge25519_p3 A;
+
+#ifdef ED25519_NONDETERMINISTIC
+ memmove(sk, seed, 32);
+#else
+ crypto_hash_sha512(sk, seed, 32);
+#endif
+ sk[0] &= 248;
+ sk[31] &= 127;
+ sk[31] |= 64;
+
+ ge25519_scalarmult_base(&A, sk);
+ ge25519_p3_tobytes(pk, &A);
+
+ memmove(sk, seed, 32);
+ memmove(sk + 32, pk, 32);
+
+ return 0;
+}
+
+int
+crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk)
+{
+ unsigned char seed[32];
+ int ret;
+
+ randombytes_buf(seed, sizeof seed);
+ ret = crypto_sign_ed25519_seed_keypair(pk, sk, seed);
+ sodium_memzero(seed, sizeof seed);
+
+ return ret;
+}
+
+int
+crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk,
+ const unsigned char *ed25519_pk)
+{
+ ge25519_p3 A;
+ fe25519 x;
+ fe25519 one_minus_y;
+
+ if (ge25519_has_small_order(ed25519_pk) != 0 ||
+ ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 ||
+ ge25519_is_on_main_subgroup(&A) == 0) {
+ return -1;
+ }
+ fe25519_1(one_minus_y);
+ fe25519_sub(one_minus_y, one_minus_y, A.Y);
+ fe25519_invert(one_minus_y, one_minus_y);
+ fe25519_1(x);
+ fe25519_add(x, x, A.Y);
+ fe25519_mul(x, x, one_minus_y);
+ fe25519_tobytes(curve25519_pk, x);
+
+ return 0;
+}
+
+int
+crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
+ const unsigned char *ed25519_sk)
+{
+ unsigned char h[crypto_hash_sha512_BYTES];
+
+#ifdef ED25519_NONDETERMINISTIC
+ memcpy(h, ed25519_sk, 32);
+#else
+ crypto_hash_sha512(h, ed25519_sk, 32);
+#endif
+ h[0] &= 248;
+ h[31] &= 127;
+ h[31] |= 64;
+ memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES);
+ sodium_memzero(h, sizeof h);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c
new file mode 100644
index 0000000000..03440cfa75
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c
@@ -0,0 +1,116 @@
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_hash_sha512.h"
+#include "crypto_sign_edwards25519sha512batch.h"
+#include "crypto_verify_32.h"
+#include "private/ed25519_ref10.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk,
+ unsigned char *sk)
+{
+ ge25519_p3 A;
+
+ randombytes_buf(sk, 32);
+ crypto_hash_sha512(sk, sk, 32);
+ sk[0] &= 248;
+ sk[31] &= 127;
+ sk[31] |= 64;
+ ge25519_scalarmult_base(&A, sk);
+ ge25519_p3_tobytes(pk, &A);
+
+ return 0;
+}
+
+int
+crypto_sign_edwards25519sha512batch(unsigned char *sm,
+ unsigned long long *smlen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *sk)
+{
+ crypto_hash_sha512_state hs;
+ unsigned char nonce[64];
+ unsigned char hram[64];
+ unsigned char sig[64];
+ ge25519_p3 A;
+ ge25519_p3 R;
+
+ crypto_hash_sha512_init(&hs);
+ crypto_hash_sha512_update(&hs, sk + 32, 32);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, nonce);
+ ge25519_scalarmult_base(&A, sk);
+ ge25519_p3_tobytes(sig + 32, &A);
+ sc25519_reduce(nonce);
+ ge25519_scalarmult_base(&R, nonce);
+ ge25519_p3_tobytes(sig, &R);
+ crypto_hash_sha512_init(&hs);
+ crypto_hash_sha512_update(&hs, sig, 32);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, hram);
+ sc25519_reduce(hram);
+ sc25519_muladd(sig + 32, hram, nonce, sk);
+ sodium_memzero(hram, sizeof hram);
+ memmove(sm + 32, m, (size_t) mlen);
+ memcpy(sm, sig, 32);
+ memcpy(sm + 32 + mlen, sig + 32, 32);
+ *smlen_p = mlen + 64U;
+
+ return 0;
+}
+
+int
+crypto_sign_edwards25519sha512batch_open(unsigned char *m,
+ unsigned long long *mlen_p,
+ const unsigned char *sm,
+ unsigned long long smlen,
+ const unsigned char *pk)
+{
+ unsigned char h[64];
+ unsigned char t1[32], t2[32];
+ unsigned long long mlen;
+ ge25519_cached Ai;
+ ge25519_p1p1 csa;
+ ge25519_p2 cs;
+ ge25519_p3 A;
+ ge25519_p3 R;
+ ge25519_p3 cs3;
+
+ *mlen_p = 0;
+ if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) {
+ return -1;
+ }
+ mlen = smlen - 64;
+ if (sm[smlen - 1] & 224) {
+ return -1;
+ }
+ if (ge25519_has_small_order(pk) != 0 ||
+ ge25519_frombytes_negate_vartime(&A, pk) != 0 ||
+ ge25519_has_small_order(sm) != 0 ||
+ ge25519_frombytes_negate_vartime(&R, sm) != 0) {
+ return -1;
+ }
+ ge25519_p3_to_cached(&Ai, &A);
+ crypto_hash_sha512(h, sm, mlen + 32);
+ sc25519_reduce(h);
+ ge25519_scalarmult(&cs3, h, &R);
+ ge25519_add(&csa, &cs3, &Ai);
+ ge25519_p1p1_to_p2(&cs, &csa);
+ ge25519_tobytes(t1, &cs);
+ t1[31] ^= 1 << 7;
+ ge25519_scalarmult_base(&R, sm + 32 + mlen);
+ ge25519_p3_tobytes(t2, &R);
+ if (crypto_verify_32(t1, t2) != 0) {
+ return -1;
+ }
+ *mlen_p = mlen;
+ memmove(m, sm + 32, mlen);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c
new file mode 100644
index 0000000000..c9e8843c1e
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c
@@ -0,0 +1,93 @@
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "crypto_hash_sha512.h"
+#include "crypto_sign_ed25519.h"
+#include "crypto_verify_32.h"
+#include "sign_ed25519_ref10.h"
+#include "private/ed25519_ref10.h"
+#include "utils.h"
+
+int
+_crypto_sign_ed25519_verify_detached(const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk,
+ int prehashed)
+{
+ crypto_hash_sha512_state hs;
+ unsigned char h[64];
+ unsigned char rcheck[32];
+ ge25519_p3 A;
+ ge25519_p2 R;
+
+#ifndef ED25519_COMPAT
+ if (sc25519_is_canonical(sig + 32) == 0 ||
+ ge25519_has_small_order(sig) != 0) {
+ return -1;
+ }
+ if (ge25519_is_canonical(pk) == 0) {
+ return -1;
+ }
+#else
+ if (sig[63] & 224) {
+ return -1;
+ }
+#endif
+ if (ge25519_has_small_order(pk) != 0 ||
+ ge25519_frombytes_negate_vartime(&A, pk) != 0) {
+ return -1;
+ }
+ _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
+ crypto_hash_sha512_update(&hs, sig, 32);
+ crypto_hash_sha512_update(&hs, pk, 32);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, h);
+ sc25519_reduce(h);
+
+ ge25519_double_scalarmult_vartime(&R, h, &A, sig + 32);
+ ge25519_tobytes(rcheck, &R);
+
+ return crypto_verify_32(rcheck, sig) | (-(rcheck == sig)) |
+ sodium_memcmp(sig, rcheck, 32);
+}
+
+int
+crypto_sign_ed25519_verify_detached(const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk)
+{
+ return _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, 0);
+}
+
+int
+crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p,
+ const unsigned char *sm, unsigned long long smlen,
+ const unsigned char *pk)
+{
+ unsigned long long mlen;
+
+ if (smlen < 64 || smlen - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) {
+ goto badsig;
+ }
+ mlen = smlen - 64;
+ if (crypto_sign_ed25519_verify_detached(sm, sm + 64, mlen, pk) != 0) {
+ memset(m, 0, mlen);
+ goto badsig;
+ }
+ if (mlen_p != NULL) {
+ *mlen_p = mlen;
+ }
+ memmove(m, sm + 64, mlen);
+
+ return 0;
+
+badsig:
+ if (mlen_p != NULL) {
+ *mlen_p = 0;
+ }
+ return -1;
+}
diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c
new file mode 100644
index 0000000000..4df90bddd9
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c
@@ -0,0 +1,144 @@
+
+#include <string.h>
+
+#include "crypto_hash_sha512.h"
+#include "crypto_sign_ed25519.h"
+#include "sign_ed25519_ref10.h"
+#include "private/ed25519_ref10.h"
+#include "randombytes.h"
+#include "utils.h"
+
+void
+_crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, int prehashed)
+{
+ static const unsigned char DOM2PREFIX[32 + 2] = {
+ 'S', 'i', 'g', 'E', 'd', '2', '5', '5', '1', '9', ' ',
+ 'n', 'o', ' ',
+ 'E', 'd', '2', '5', '5', '1', '9', ' ',
+ 'c', 'o', 'l', 'l', 'i', 's', 'i', 'o', 'n', 's', 1, 0
+ };
+
+ crypto_hash_sha512_init(hs);
+ if (prehashed) {
+ crypto_hash_sha512_update(hs, DOM2PREFIX, sizeof DOM2PREFIX);
+ }
+}
+
+static inline void
+_crypto_sign_ed25519_clamp(unsigned char k[32])
+{
+ k[0] &= 248;
+ k[31] &= 127;
+ k[31] |= 64;
+}
+
+#ifdef ED25519_NONDETERMINISTIC
+/* r = hash(B || empty_labelset || Z || pad1 || k || pad2 || empty_labelset || K || extra || M) (mod q) */
+static void
+_crypto_sign_ed25519_synthetic_r_hv(crypto_hash_sha512_state *hs,
+ unsigned char Z[32],
+ const unsigned char sk[64])
+{
+ static const unsigned char B[32] = {
+ 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ };
+ static const unsigned char zeros[128] = { 0x00 };
+ static const unsigned char empty_labelset[3] = { 0x02, 0x00, 0x00 };
+
+ crypto_hash_sha512_update(hs, B, 32);
+ crypto_hash_sha512_update(hs, empty_labelset, 3);
+ randombytes_buf(Z, 32);
+ crypto_hash_sha512_update(hs, Z, 32);
+ crypto_hash_sha512_update(hs, zeros, 128 - (32 + 3 + 32) % 128);
+ crypto_hash_sha512_update(hs, sk, 32);
+ crypto_hash_sha512_update(hs, zeros, 128 - 32 % 128);
+ crypto_hash_sha512_update(hs, empty_labelset, 3);
+ crypto_hash_sha512_update(hs, sk + 32, 32);
+ /* empty extra */
+}
+#endif
+
+int
+_crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk, int prehashed)
+{
+ crypto_hash_sha512_state hs;
+ unsigned char az[64];
+ unsigned char nonce[64];
+ unsigned char hram[64];
+ ge25519_p3 R;
+
+ _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
+
+#ifdef ED25519_NONDETERMINISTIC
+ memcpy(az, sk, 32);
+ _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az);
+#else
+ crypto_hash_sha512(az, sk, 32);
+ crypto_hash_sha512_update(&hs, az + 32, 32);
+#endif
+
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, nonce);
+
+ memmove(sig + 32, sk + 32, 32);
+
+ sc25519_reduce(nonce);
+ ge25519_scalarmult_base(&R, nonce);
+ ge25519_p3_tobytes(sig, &R);
+
+ _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
+ crypto_hash_sha512_update(&hs, sig, 64);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, hram);
+
+ sc25519_reduce(hram);
+ _crypto_sign_ed25519_clamp(az);
+ sc25519_muladd(sig + 32, hram, az, nonce);
+
+ sodium_memzero(az, sizeof az);
+ sodium_memzero(nonce, sizeof nonce);
+
+ if (siglen_p != NULL) {
+ *siglen_p = 64U;
+ }
+ return 0;
+}
+
+int
+crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ return _crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk, 0);
+}
+
+int
+crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ unsigned long long siglen;
+
+ memmove(sm + crypto_sign_ed25519_BYTES, m, mlen);
+ /* LCOV_EXCL_START */
+ if (crypto_sign_ed25519_detached(
+ sm, &siglen, sm + crypto_sign_ed25519_BYTES, mlen, sk) != 0 ||
+ siglen != crypto_sign_ed25519_BYTES) {
+ if (smlen_p != NULL) {
+ *smlen_p = 0;
+ }
+ memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
+ return -1;
+ }
+ /* LCOV_EXCL_STOP */
+
+ if (smlen_p != NULL) {
+ *smlen_p = mlen + siglen;
+ }
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h
new file mode 100644
index 0000000000..29f45a8544
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h
@@ -0,0 +1,18 @@
+#ifndef sign_ed25519_ref10_H
+#define sign_ed25519_ref10_H
+
+void _crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs,
+ int prehashed);
+
+int _crypto_sign_ed25519_detached(unsigned char *sig,
+ unsigned long long *siglen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *sk, int prehashed);
+
+int _crypto_sign_ed25519_verify_detached(const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk,
+ int prehashed);
+#endif
diff --git a/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c b/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c
new file mode 100644
index 0000000000..8a69513ede
--- /dev/null
+++ b/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c
@@ -0,0 +1,97 @@
+
+#include <string.h>
+
+#include "crypto_hash_sha512.h"
+#include "crypto_sign_ed25519.h"
+#include "ref10/sign_ed25519_ref10.h"
+
+size_t
+crypto_sign_ed25519ph_statebytes(void)
+{
+ return sizeof(crypto_sign_ed25519ph_state);
+}
+
+size_t
+crypto_sign_ed25519_bytes(void)
+{
+ return crypto_sign_ed25519_BYTES;
+}
+
+size_t
+crypto_sign_ed25519_seedbytes(void)
+{
+ return crypto_sign_ed25519_SEEDBYTES;
+}
+
+size_t
+crypto_sign_ed25519_publickeybytes(void)
+{
+ return crypto_sign_ed25519_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_sign_ed25519_secretkeybytes(void)
+{
+ return crypto_sign_ed25519_SECRETKEYBYTES;
+}
+
+size_t
+crypto_sign_ed25519_messagebytes_max(void)
+{
+ return crypto_sign_ed25519_MESSAGEBYTES_MAX;
+}
+
+int
+crypto_sign_ed25519_sk_to_seed(unsigned char *seed, const unsigned char *sk)
+{
+ memmove(seed, sk, crypto_sign_ed25519_SEEDBYTES);
+
+ return 0;
+}
+
+int
+crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk)
+{
+ memmove(pk, sk + crypto_sign_ed25519_SEEDBYTES,
+ crypto_sign_ed25519_PUBLICKEYBYTES);
+ return 0;
+}
+
+int
+crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state)
+{
+ crypto_hash_sha512_init(&state->hs);
+ return 0;
+}
+
+int
+crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state,
+ const unsigned char *m, unsigned long long mlen)
+{
+ return crypto_hash_sha512_update(&state->hs, m, mlen);
+}
+
+int
+crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state,
+ unsigned char *sig,
+ unsigned long long *siglen_p,
+ const unsigned char *sk)
+{
+ unsigned char ph[crypto_hash_sha512_BYTES];
+
+ crypto_hash_sha512_final(&state->hs, ph);
+
+ return _crypto_sign_ed25519_detached(sig, siglen_p, ph, sizeof ph, sk, 1);
+}
+
+int
+crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state,
+ unsigned char *sig,
+ const unsigned char *pk)
+{
+ unsigned char ph[crypto_hash_sha512_BYTES];
+
+ crypto_hash_sha512_final(&state->hs, ph);
+
+ return _crypto_sign_ed25519_verify_detached(sig, ph, sizeof ph, pk, 1);
+}
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c
new file mode 100644
index 0000000000..6149af3942
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c
@@ -0,0 +1,180 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_stream_chacha20.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "utils.h"
+
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# pragma GCC target("avx2")
+# endif
+
+# include <emmintrin.h>
+# include <immintrin.h>
+# include <smmintrin.h>
+# include <tmmintrin.h>
+
+# include "../stream_chacha20.h"
+# include "chacha20_dolbeau-avx2.h"
+
+# define ROUNDS 20
+
+typedef struct chacha_ctx {
+ uint32_t input[16];
+} chacha_ctx;
+
+static void
+chacha_keysetup(chacha_ctx *ctx, const uint8_t *k)
+{
+ ctx->input[0] = 0x61707865;
+ ctx->input[1] = 0x3320646e;
+ ctx->input[2] = 0x79622d32;
+ ctx->input[3] = 0x6b206574;
+ ctx->input[4] = LOAD32_LE(k + 0);
+ ctx->input[5] = LOAD32_LE(k + 4);
+ ctx->input[6] = LOAD32_LE(k + 8);
+ ctx->input[7] = LOAD32_LE(k + 12);
+ ctx->input[8] = LOAD32_LE(k + 16);
+ ctx->input[9] = LOAD32_LE(k + 20);
+ ctx->input[10] = LOAD32_LE(k + 24);
+ ctx->input[11] = LOAD32_LE(k + 28);
+}
+
+static void
+chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
+ ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
+ ctx->input[14] = LOAD32_LE(iv + 0);
+ ctx->input[15] = LOAD32_LE(iv + 4);
+}
+
+static void
+chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter);
+ ctx->input[13] = LOAD32_LE(iv + 0);
+ ctx->input[14] = LOAD32_LE(iv + 4);
+ ctx->input[15] = LOAD32_LE(iv + 8);
+}
+
+static void
+chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c,
+ unsigned long long bytes)
+{
+ uint32_t * const x = &ctx->input[0];
+
+ if (!bytes) {
+ return; /* LCOV_EXCL_LINE */
+ }
+ if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+# include "u8.h"
+# include "u4.h"
+# include "u1.h"
+# include "u0.h"
+}
+
+static int
+stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[8];
+ uint32_t ic_high;
+ uint32_t ic_low;
+
+ if (!mlen) {
+ return 0;
+ }
+ ic_high = (uint32_t) (ic >> 32);
+ ic_low = (uint32_t) ic;
+ STORE32_LE(&ic_bytes[0], ic_low);
+ STORE32_LE(&ic_bytes[4], ic_high);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ uint32_t ic, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[4];
+
+ if (!mlen) {
+ return 0;
+ }
+ STORE32_LE(ic_bytes, ic);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_dolbeau_avx2_implementation = {
+ SODIUM_C99(.stream =) stream_ref,
+ SODIUM_C99(.stream_ietf =) stream_ietf_ref,
+ SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
+ SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h
new file mode 100644
index 0000000000..45eb98d797
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_chacha20.h"
+#include "crypto_stream_chacha20.h"
+
+extern struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_dolbeau_avx2_implementation;
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c
new file mode 100644
index 0000000000..b7b9aa4ad3
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c
@@ -0,0 +1,174 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_stream_chacha20.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "utils.h"
+
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# endif
+
+# include <emmintrin.h>
+# include <tmmintrin.h>
+
+# include "../stream_chacha20.h"
+# include "chacha20_dolbeau-ssse3.h"
+
+# define ROUNDS 20
+
+typedef struct chacha_ctx {
+ uint32_t input[16];
+} chacha_ctx;
+
+static void
+chacha_keysetup(chacha_ctx *ctx, const uint8_t *k)
+{
+ ctx->input[0] = 0x61707865;
+ ctx->input[1] = 0x3320646e;
+ ctx->input[2] = 0x79622d32;
+ ctx->input[3] = 0x6b206574;
+ ctx->input[4] = LOAD32_LE(k + 0);
+ ctx->input[5] = LOAD32_LE(k + 4);
+ ctx->input[6] = LOAD32_LE(k + 8);
+ ctx->input[7] = LOAD32_LE(k + 12);
+ ctx->input[8] = LOAD32_LE(k + 16);
+ ctx->input[9] = LOAD32_LE(k + 20);
+ ctx->input[10] = LOAD32_LE(k + 24);
+ ctx->input[11] = LOAD32_LE(k + 28);
+}
+
+static void
+chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
+ ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
+ ctx->input[14] = LOAD32_LE(iv + 0);
+ ctx->input[15] = LOAD32_LE(iv + 4);
+}
+
+static void
+chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter);
+ ctx->input[13] = LOAD32_LE(iv + 0);
+ ctx->input[14] = LOAD32_LE(iv + 4);
+ ctx->input[15] = LOAD32_LE(iv + 8);
+}
+
+static void
+chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c,
+ unsigned long long bytes)
+{
+ uint32_t * const x = &ctx->input[0];
+
+ if (!bytes) {
+ return; /* LCOV_EXCL_LINE */
+ }
+ if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+# include "u4.h"
+# include "u1.h"
+# include "u0.h"
+}
+
+static int
+stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[8];
+ uint32_t ic_high;
+ uint32_t ic_low;
+
+ if (!mlen) {
+ return 0;
+ }
+ ic_high = (uint32_t) (ic >> 32);
+ ic_low = (uint32_t) ic;
+ STORE32_LE(&ic_bytes[0], ic_low);
+ STORE32_LE(&ic_bytes[4], ic_high);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ uint32_t ic, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[4];
+
+ if (!mlen) {
+ return 0;
+ }
+ STORE32_LE(ic_bytes, ic);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_dolbeau_ssse3_implementation = {
+ SODIUM_C99(.stream =) stream_ref,
+ SODIUM_C99(.stream_ietf =) stream_ietf_ref,
+ SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
+ SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h
new file mode 100644
index 0000000000..d67630f6a9
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_chacha20.h"
+#include "crypto_stream_chacha20.h"
+
+extern struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_dolbeau_ssse3_implementation;
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h
new file mode 100644
index 0000000000..17c3ff8e08
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h
@@ -0,0 +1,86 @@
+if (bytes > 0) {
+ __m128i x_0, x_1, x_2, x_3;
+ __m128i t_1;
+ const __m128i rot16 =
+ _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+ const __m128i rot8 =
+ _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+ uint8_t partialblock[64];
+
+ unsigned int i;
+
+ x_0 = _mm_loadu_si128((__m128i*) (x + 0));
+ x_1 = _mm_loadu_si128((__m128i*) (x + 4));
+ x_2 = _mm_loadu_si128((__m128i*) (x + 8));
+ x_3 = _mm_loadu_si128((__m128i*) (x + 12));
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_3 = _mm_shuffle_epi8(x_3, rot16);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_1 = _mm_xor_si128(x_1, x_2);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 12);
+ t_1 = _mm_srli_epi32(t_1, 20);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_0 = _mm_shuffle_epi32(x_0, 0x93);
+ x_3 = _mm_shuffle_epi8(x_3, rot8);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_3 = _mm_shuffle_epi32(x_3, 0x4e);
+ x_1 = _mm_xor_si128(x_1, x_2);
+ x_2 = _mm_shuffle_epi32(x_2, 0x39);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 7);
+ t_1 = _mm_srli_epi32(t_1, 25);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_3 = _mm_shuffle_epi8(x_3, rot16);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_1 = _mm_xor_si128(x_1, x_2);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 12);
+ t_1 = _mm_srli_epi32(t_1, 20);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_0 = _mm_shuffle_epi32(x_0, 0x39);
+ x_3 = _mm_shuffle_epi8(x_3, rot8);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_3 = _mm_shuffle_epi32(x_3, 0x4e);
+ x_1 = _mm_xor_si128(x_1, x_2);
+ x_2 = _mm_shuffle_epi32(x_2, 0x93);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 7);
+ t_1 = _mm_srli_epi32(t_1, 25);
+ x_1 = _mm_xor_si128(x_1, t_1);
+ }
+ x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((__m128i*) (x + 0)));
+ x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((__m128i*) (x + 4)));
+ x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((__m128i*) (x + 8)));
+ x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((__m128i*) (x + 12)));
+ _mm_storeu_si128((__m128i*) (partialblock + 0), x_0);
+ _mm_storeu_si128((__m128i*) (partialblock + 16), x_1);
+ _mm_storeu_si128((__m128i*) (partialblock + 32), x_2);
+ _mm_storeu_si128((__m128i*) (partialblock + 48), x_3);
+
+ for (i = 0; i < bytes; i++) {
+ c[i] = m[i] ^ partialblock[i];
+ }
+
+ sodium_memzero(partialblock, sizeof partialblock);
+}
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h
new file mode 100644
index 0000000000..867b44bcf2
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h
@@ -0,0 +1,98 @@
+while (bytes >= 64) {
+ __m128i x_0, x_1, x_2, x_3;
+ __m128i t_1;
+ const __m128i rot16 =
+ _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+ const __m128i rot8 =
+ _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+
+ uint32_t in12;
+ uint32_t in13;
+ int i;
+
+ x_0 = _mm_loadu_si128((__m128i*) (x + 0));
+ x_1 = _mm_loadu_si128((__m128i*) (x + 4));
+ x_2 = _mm_loadu_si128((__m128i*) (x + 8));
+ x_3 = _mm_loadu_si128((__m128i*) (x + 12));
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_3 = _mm_shuffle_epi8(x_3, rot16);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_1 = _mm_xor_si128(x_1, x_2);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 12);
+ t_1 = _mm_srli_epi32(t_1, 20);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_0 = _mm_shuffle_epi32(x_0, 0x93);
+ x_3 = _mm_shuffle_epi8(x_3, rot8);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_3 = _mm_shuffle_epi32(x_3, 0x4e);
+ x_1 = _mm_xor_si128(x_1, x_2);
+ x_2 = _mm_shuffle_epi32(x_2, 0x39);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 7);
+ t_1 = _mm_srli_epi32(t_1, 25);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_3 = _mm_shuffle_epi8(x_3, rot16);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_1 = _mm_xor_si128(x_1, x_2);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 12);
+ t_1 = _mm_srli_epi32(t_1, 20);
+ x_1 = _mm_xor_si128(x_1, t_1);
+
+ x_0 = _mm_add_epi32(x_0, x_1);
+ x_3 = _mm_xor_si128(x_3, x_0);
+ x_0 = _mm_shuffle_epi32(x_0, 0x39);
+ x_3 = _mm_shuffle_epi8(x_3, rot8);
+
+ x_2 = _mm_add_epi32(x_2, x_3);
+ x_3 = _mm_shuffle_epi32(x_3, 0x4e);
+ x_1 = _mm_xor_si128(x_1, x_2);
+ x_2 = _mm_shuffle_epi32(x_2, 0x93);
+
+ t_1 = x_1;
+ x_1 = _mm_slli_epi32(x_1, 7);
+ t_1 = _mm_srli_epi32(t_1, 25);
+ x_1 = _mm_xor_si128(x_1, t_1);
+ }
+ x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((__m128i*) (x + 0)));
+ x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((__m128i*) (x + 4)));
+ x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((__m128i*) (x + 8)));
+ x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((__m128i*) (x + 12)));
+ x_0 = _mm_xor_si128(x_0, _mm_loadu_si128((__m128i*) (m + 0)));
+ x_1 = _mm_xor_si128(x_1, _mm_loadu_si128((__m128i*) (m + 16)));
+ x_2 = _mm_xor_si128(x_2, _mm_loadu_si128((__m128i*) (m + 32)));
+ x_3 = _mm_xor_si128(x_3, _mm_loadu_si128((__m128i*) (m + 48)));
+ _mm_storeu_si128((__m128i*) (c + 0), x_0);
+ _mm_storeu_si128((__m128i*) (c + 16), x_1);
+ _mm_storeu_si128((__m128i*) (c + 32), x_2);
+ _mm_storeu_si128((__m128i*) (c + 48), x_3);
+
+ in12 = x[12];
+ in13 = x[13];
+ in12++;
+ if (in12 == 0) {
+ in13++;
+ }
+ x[12] = in12;
+ x[13] = in13;
+
+ bytes -= 64;
+ c += 64;
+ m += 64;
+}
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h
new file mode 100644
index 0000000000..3ff8342609
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h
@@ -0,0 +1,175 @@
+
+#define VEC4_ROT(A, IMM) \
+ _mm_or_si128(_mm_slli_epi32(A, IMM), _mm_srli_epi32(A, (32 - IMM)))
+
+/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 &
+ * 16) (better) */
+#define VEC4_QUARTERROUND_SHUFFLE(A, B, C, D) \
+ x_##A = _mm_add_epi32(x_##A, x_##B); \
+ t_##A = _mm_xor_si128(x_##D, x_##A); \
+ x_##D = _mm_shuffle_epi8(t_##A, rot16); \
+ x_##C = _mm_add_epi32(x_##C, x_##D); \
+ t_##C = _mm_xor_si128(x_##B, x_##C); \
+ x_##B = VEC4_ROT(t_##C, 12); \
+ x_##A = _mm_add_epi32(x_##A, x_##B); \
+ t_##A = _mm_xor_si128(x_##D, x_##A); \
+ x_##D = _mm_shuffle_epi8(t_##A, rot8); \
+ x_##C = _mm_add_epi32(x_##C, x_##D); \
+ t_##C = _mm_xor_si128(x_##B, x_##C); \
+ x_##B = VEC4_ROT(t_##C, 7)
+
+#define VEC4_QUARTERROUND(A, B, C, D) VEC4_QUARTERROUND_SHUFFLE(A, B, C, D)
+
+if (bytes >= 256) {
+ /* constant for shuffling bytes (replacing multiple-of-8 rotates) */
+ __m128i rot16 =
+ _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+ __m128i rot8 =
+ _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+
+ __m128i x_0 = _mm_set1_epi32(x[0]);
+ __m128i x_1 = _mm_set1_epi32(x[1]);
+ __m128i x_2 = _mm_set1_epi32(x[2]);
+ __m128i x_3 = _mm_set1_epi32(x[3]);
+ __m128i x_4 = _mm_set1_epi32(x[4]);
+ __m128i x_5 = _mm_set1_epi32(x[5]);
+ __m128i x_6 = _mm_set1_epi32(x[6]);
+ __m128i x_7 = _mm_set1_epi32(x[7]);
+ __m128i x_8 = _mm_set1_epi32(x[8]);
+ __m128i x_9 = _mm_set1_epi32(x[9]);
+ __m128i x_10 = _mm_set1_epi32(x[10]);
+ __m128i x_11 = _mm_set1_epi32(x[11]);
+ __m128i x_12;
+ __m128i x_13;
+ __m128i x_14 = _mm_set1_epi32(x[14]);
+ __m128i x_15 = _mm_set1_epi32(x[15]);
+ __m128i orig0 = x_0;
+ __m128i orig1 = x_1;
+ __m128i orig2 = x_2;
+ __m128i orig3 = x_3;
+ __m128i orig4 = x_4;
+ __m128i orig5 = x_5;
+ __m128i orig6 = x_6;
+ __m128i orig7 = x_7;
+ __m128i orig8 = x_8;
+ __m128i orig9 = x_9;
+ __m128i orig10 = x_10;
+ __m128i orig11 = x_11;
+ __m128i orig12;
+ __m128i orig13;
+ __m128i orig14 = x_14;
+ __m128i orig15 = x_15;
+ __m128i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12,
+ t_13, t_14, t_15;
+
+ uint32_t in12, in13;
+ int i;
+
+ while (bytes >= 256) {
+ const __m128i addv12 = _mm_set_epi64x(1, 0);
+ const __m128i addv13 = _mm_set_epi64x(3, 2);
+ __m128i t12, t13;
+ uint64_t in1213;
+
+ x_0 = orig0;
+ x_1 = orig1;
+ x_2 = orig2;
+ x_3 = orig3;
+ x_4 = orig4;
+ x_5 = orig5;
+ x_6 = orig6;
+ x_7 = orig7;
+ x_8 = orig8;
+ x_9 = orig9;
+ x_10 = orig10;
+ x_11 = orig11;
+ x_14 = orig14;
+ x_15 = orig15;
+
+ in12 = x[12];
+ in13 = x[13];
+ in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32);
+ t12 = _mm_set1_epi64x(in1213);
+ t13 = _mm_set1_epi64x(in1213);
+
+ x_12 = _mm_add_epi64(addv12, t12);
+ x_13 = _mm_add_epi64(addv13, t13);
+
+ t12 = _mm_unpacklo_epi32(x_12, x_13);
+ t13 = _mm_unpackhi_epi32(x_12, x_13);
+
+ x_12 = _mm_unpacklo_epi32(t12, t13);
+ x_13 = _mm_unpackhi_epi32(t12, t13);
+
+ orig12 = x_12;
+ orig13 = x_13;
+
+ in1213 += 4;
+
+ x[12] = in1213 & 0xFFFFFFFF;
+ x[13] = (in1213 >> 32) & 0xFFFFFFFF;
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ VEC4_QUARTERROUND(0, 4, 8, 12);
+ VEC4_QUARTERROUND(1, 5, 9, 13);
+ VEC4_QUARTERROUND(2, 6, 10, 14);
+ VEC4_QUARTERROUND(3, 7, 11, 15);
+ VEC4_QUARTERROUND(0, 5, 10, 15);
+ VEC4_QUARTERROUND(1, 6, 11, 12);
+ VEC4_QUARTERROUND(2, 7, 8, 13);
+ VEC4_QUARTERROUND(3, 4, 9, 14);
+ }
+
+#define ONEQUAD_TRANSPOSE(A, B, C, D) \
+ { \
+ __m128i t0, t1, t2, t3; \
+ \
+ x_##A = _mm_add_epi32(x_##A, orig##A); \
+ x_##B = _mm_add_epi32(x_##B, orig##B); \
+ x_##C = _mm_add_epi32(x_##C, orig##C); \
+ x_##D = _mm_add_epi32(x_##D, orig##D); \
+ t_##A = _mm_unpacklo_epi32(x_##A, x_##B); \
+ t_##B = _mm_unpacklo_epi32(x_##C, x_##D); \
+ t_##C = _mm_unpackhi_epi32(x_##A, x_##B); \
+ t_##D = _mm_unpackhi_epi32(x_##C, x_##D); \
+ x_##A = _mm_unpacklo_epi64(t_##A, t_##B); \
+ x_##B = _mm_unpackhi_epi64(t_##A, t_##B); \
+ x_##C = _mm_unpacklo_epi64(t_##C, t_##D); \
+ x_##D = _mm_unpackhi_epi64(t_##C, t_##D); \
+ \
+ t0 = _mm_xor_si128(x_##A, _mm_loadu_si128((__m128i*) (m + 0))); \
+ _mm_storeu_si128((__m128i*) (c + 0), t0); \
+ t1 = _mm_xor_si128(x_##B, _mm_loadu_si128((__m128i*) (m + 64))); \
+ _mm_storeu_si128((__m128i*) (c + 64), t1); \
+ t2 = _mm_xor_si128(x_##C, _mm_loadu_si128((__m128i*) (m + 128))); \
+ _mm_storeu_si128((__m128i*) (c + 128), t2); \
+ t3 = _mm_xor_si128(x_##D, _mm_loadu_si128((__m128i*) (m + 192))); \
+ _mm_storeu_si128((__m128i*) (c + 192), t3); \
+ }
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D)
+
+ ONEQUAD(0, 1, 2, 3);
+ m += 16;
+ c += 16;
+ ONEQUAD(4, 5, 6, 7);
+ m += 16;
+ c += 16;
+ ONEQUAD(8, 9, 10, 11);
+ m += 16;
+ c += 16;
+ ONEQUAD(12, 13, 14, 15);
+ m -= 48;
+ c -= 48;
+
+#undef ONEQUAD
+#undef ONEQUAD_TRANSPOSE
+
+ bytes -= 256;
+ c += 256;
+ m += 256;
+ }
+}
+#undef VEC4_ROT
+#undef VEC4_QUARTERROUND
+#undef VEC4_QUARTERROUND_SHUFFLE
diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h
new file mode 100644
index 0000000000..22bf9fcfa1
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h
@@ -0,0 +1,357 @@
+
+#define VEC8_ROT(A, IMM) \
+ _mm256_or_si256(_mm256_slli_epi32(A, IMM), _mm256_srli_epi32(A, (32 - IMM)))
+
+/* implements a vector quarter round by-the-book (naive!) */
+#define VEC8_QUARTERROUND_NAIVE(A, B, C, D) \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = VEC8_ROT(t_##A, 16); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 12); \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = VEC8_ROT(t_##A, 8); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 7)
+
+/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 &
+ * 16) (better) */
+#define VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = _mm256_shuffle_epi8(t_##A, rot16); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 12); \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = _mm256_shuffle_epi8(t_##A, rot8); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 7)
+
+/* same, but replace 2 of the shift/shift/or "rotation" by byte & word shuffles
+ * (8 & 16) (not as good as previous) */
+#define VEC8_QUARTERROUND_SHUFFLE2(A, B, C, D) \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = _mm256_shufflehi_epi16(_mm256_shufflelo_epi16(t_##A, 0xb1), 0xb1); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 12); \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ t_##A = _mm256_xor_si256(x_##D, x_##A); \
+ x_##D = _mm256_shuffle_epi8(t_##A, rot8); \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ t_##C = _mm256_xor_si256(x_##B, x_##C); \
+ x_##B = VEC8_ROT(t_##C, 7)
+
+#define VEC8_QUARTERROUND(A, B, C, D) VEC8_QUARTERROUND_SHUFFLE(A, B, C, D)
+
+#define VEC8_LINE1(A, B, C, D) \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot16)
+#define VEC8_LINE2(A, B, C, D) \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 12)
+#define VEC8_LINE3(A, B, C, D) \
+ x_##A = _mm256_add_epi32(x_##A, x_##B); \
+ x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot8)
+#define VEC8_LINE4(A, B, C, D) \
+ x_##C = _mm256_add_epi32(x_##C, x_##D); \
+ x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 7)
+
+#define VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, \
+ C4, D4) \
+ VEC8_LINE1(A1, B1, C1, D1); \
+ VEC8_LINE1(A2, B2, C2, D2); \
+ VEC8_LINE1(A3, B3, C3, D3); \
+ VEC8_LINE1(A4, B4, C4, D4); \
+ VEC8_LINE2(A1, B1, C1, D1); \
+ VEC8_LINE2(A2, B2, C2, D2); \
+ VEC8_LINE2(A3, B3, C3, D3); \
+ VEC8_LINE2(A4, B4, C4, D4); \
+ VEC8_LINE3(A1, B1, C1, D1); \
+ VEC8_LINE3(A2, B2, C2, D2); \
+ VEC8_LINE3(A3, B3, C3, D3); \
+ VEC8_LINE3(A4, B4, C4, D4); \
+ VEC8_LINE4(A1, B1, C1, D1); \
+ VEC8_LINE4(A2, B2, C2, D2); \
+ VEC8_LINE4(A3, B3, C3, D3); \
+ VEC8_LINE4(A4, B4, C4, D4)
+
+#define VEC8_ROUND_HALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, \
+ B4, C4, D4) \
+ VEC8_LINE1(A1, B1, C1, D1); \
+ VEC8_LINE1(A2, B2, C2, D2); \
+ VEC8_LINE2(A1, B1, C1, D1); \
+ VEC8_LINE2(A2, B2, C2, D2); \
+ VEC8_LINE3(A1, B1, C1, D1); \
+ VEC8_LINE3(A2, B2, C2, D2); \
+ VEC8_LINE4(A1, B1, C1, D1); \
+ VEC8_LINE4(A2, B2, C2, D2); \
+ VEC8_LINE1(A3, B3, C3, D3); \
+ VEC8_LINE1(A4, B4, C4, D4); \
+ VEC8_LINE2(A3, B3, C3, D3); \
+ VEC8_LINE2(A4, B4, C4, D4); \
+ VEC8_LINE3(A3, B3, C3, D3); \
+ VEC8_LINE3(A4, B4, C4, D4); \
+ VEC8_LINE4(A3, B3, C3, D3); \
+ VEC8_LINE4(A4, B4, C4, D4)
+
+#define VEC8_ROUND_HALFANDHALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, \
+ A4, B4, C4, D4) \
+ VEC8_LINE1(A1, B1, C1, D1); \
+ VEC8_LINE1(A2, B2, C2, D2); \
+ VEC8_LINE2(A1, B1, C1, D1); \
+ VEC8_LINE2(A2, B2, C2, D2); \
+ VEC8_LINE1(A3, B3, C3, D3); \
+ VEC8_LINE1(A4, B4, C4, D4); \
+ VEC8_LINE2(A3, B3, C3, D3); \
+ VEC8_LINE2(A4, B4, C4, D4); \
+ VEC8_LINE3(A1, B1, C1, D1); \
+ VEC8_LINE3(A2, B2, C2, D2); \
+ VEC8_LINE4(A1, B1, C1, D1); \
+ VEC8_LINE4(A2, B2, C2, D2); \
+ VEC8_LINE3(A3, B3, C3, D3); \
+ VEC8_LINE3(A4, B4, C4, D4); \
+ VEC8_LINE4(A3, B3, C3, D3); \
+ VEC8_LINE4(A4, B4, C4, D4)
+
+#define VEC8_ROUND(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \
+ D4) \
+ VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \
+ D4)
+
+if (bytes >= 512) {
+ /* constant for shuffling bytes (replacing multiple-of-8 rotates) */
+ __m256i rot16 =
+ _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2,
+ 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2);
+ __m256i rot8 =
+ _mm256_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3,
+ 14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3);
+ uint32_t in12, in13;
+
+ /* the naive way seems as fast (if not a bit faster) than the vector way */
+ __m256i x_0 = _mm256_set1_epi32(x[0]);
+ __m256i x_1 = _mm256_set1_epi32(x[1]);
+ __m256i x_2 = _mm256_set1_epi32(x[2]);
+ __m256i x_3 = _mm256_set1_epi32(x[3]);
+ __m256i x_4 = _mm256_set1_epi32(x[4]);
+ __m256i x_5 = _mm256_set1_epi32(x[5]);
+ __m256i x_6 = _mm256_set1_epi32(x[6]);
+ __m256i x_7 = _mm256_set1_epi32(x[7]);
+ __m256i x_8 = _mm256_set1_epi32(x[8]);
+ __m256i x_9 = _mm256_set1_epi32(x[9]);
+ __m256i x_10 = _mm256_set1_epi32(x[10]);
+ __m256i x_11 = _mm256_set1_epi32(x[11]);
+ __m256i x_12;
+ __m256i x_13;
+ __m256i x_14 = _mm256_set1_epi32(x[14]);
+ __m256i x_15 = _mm256_set1_epi32(x[15]);
+
+ __m256i orig0 = x_0;
+ __m256i orig1 = x_1;
+ __m256i orig2 = x_2;
+ __m256i orig3 = x_3;
+ __m256i orig4 = x_4;
+ __m256i orig5 = x_5;
+ __m256i orig6 = x_6;
+ __m256i orig7 = x_7;
+ __m256i orig8 = x_8;
+ __m256i orig9 = x_9;
+ __m256i orig10 = x_10;
+ __m256i orig11 = x_11;
+ __m256i orig12;
+ __m256i orig13;
+ __m256i orig14 = x_14;
+ __m256i orig15 = x_15;
+ __m256i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12,
+ t_13, t_14, t_15;
+
+ while (bytes >= 512) {
+ const __m256i addv12 = _mm256_set_epi64x(3, 2, 1, 0);
+ const __m256i addv13 = _mm256_set_epi64x(7, 6, 5, 4);
+ const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0);
+ __m256i t12, t13;
+
+ uint64_t in1213;
+ int i;
+
+ x_0 = orig0;
+ x_1 = orig1;
+ x_2 = orig2;
+ x_3 = orig3;
+ x_4 = orig4;
+ x_5 = orig5;
+ x_6 = orig6;
+ x_7 = orig7;
+ x_8 = orig8;
+ x_9 = orig9;
+ x_10 = orig10;
+ x_11 = orig11;
+ x_14 = orig14;
+ x_15 = orig15;
+
+ in12 = x[12];
+ in13 = x[13];
+ in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32);
+ x_12 = x_13 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in1213));
+
+ t12 = _mm256_add_epi64(addv12, x_12);
+ t13 = _mm256_add_epi64(addv13, x_13);
+
+ x_12 = _mm256_unpacklo_epi32(t12, t13);
+ x_13 = _mm256_unpackhi_epi32(t12, t13);
+
+ t12 = _mm256_unpacklo_epi32(x_12, x_13);
+ t13 = _mm256_unpackhi_epi32(x_12, x_13);
+
+ /* required because unpack* are intra-lane */
+ x_12 = _mm256_permutevar8x32_epi32(t12, permute);
+ x_13 = _mm256_permutevar8x32_epi32(t13, permute);
+
+ orig12 = x_12;
+ orig13 = x_13;
+
+ in1213 += 8;
+
+ x[12] = in1213 & 0xFFFFFFFF;
+ x[13] = (in1213 >> 32) & 0xFFFFFFFF;
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ VEC8_ROUND(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
+ VEC8_ROUND(0, 5, 10, 15, 1, 6, 11, 12, 2, 7, 8, 13, 3, 4, 9, 14);
+ }
+
+#define ONEQUAD_TRANSPOSE(A, B, C, D) \
+ { \
+ __m128i t0, t1, t2, t3; \
+ x_##A = _mm256_add_epi32(x_##A, orig##A); \
+ x_##B = _mm256_add_epi32(x_##B, orig##B); \
+ x_##C = _mm256_add_epi32(x_##C, orig##C); \
+ x_##D = _mm256_add_epi32(x_##D, orig##D); \
+ t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \
+ t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \
+ t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \
+ t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \
+ x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \
+ x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \
+ x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \
+ x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \
+ t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 0), \
+ _mm_loadu_si128((__m128i*) (m + 0))); \
+ _mm_storeu_si128((__m128i*) (c + 0), t0); \
+ t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 0), \
+ _mm_loadu_si128((__m128i*) (m + 64))); \
+ _mm_storeu_si128((__m128i*) (c + 64), t1); \
+ t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 0), \
+ _mm_loadu_si128((__m128i*) (m + 128))); \
+ _mm_storeu_si128((__m128i*) (c + 128), t2); \
+ t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 0), \
+ _mm_loadu_si128((__m128i*) (m + 192))); \
+ _mm_storeu_si128((__m128i*) (c + 192), t3); \
+ t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 1), \
+ _mm_loadu_si128((__m128i*) (m + 256))); \
+ _mm_storeu_si128((__m128i*) (c + 256), t0); \
+ t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 1), \
+ _mm_loadu_si128((__m128i*) (m + 320))); \
+ _mm_storeu_si128((__m128i*) (c + 320), t1); \
+ t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 1), \
+ _mm_loadu_si128((__m128i*) (m + 384))); \
+ _mm_storeu_si128((__m128i*) (c + 384), t2); \
+ t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 1), \
+ _mm_loadu_si128((__m128i*) (m + 448))); \
+ _mm_storeu_si128((__m128i*) (c + 448), t3); \
+ }
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D)
+
+#define ONEQUAD_UNPCK(A, B, C, D) \
+ { \
+ x_##A = _mm256_add_epi32(x_##A, orig##A); \
+ x_##B = _mm256_add_epi32(x_##B, orig##B); \
+ x_##C = _mm256_add_epi32(x_##C, orig##C); \
+ x_##D = _mm256_add_epi32(x_##D, orig##D); \
+ t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \
+ t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \
+ t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \
+ t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \
+ x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \
+ x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \
+ x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \
+ x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \
+ }
+
+#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \
+ { \
+ ONEQUAD_UNPCK(A, B, C, D); \
+ ONEQUAD_UNPCK(A2, B2, C2, D2); \
+ t_##A = _mm256_permute2x128_si256(x_##A, x_##A2, 0x20); \
+ t_##A2 = _mm256_permute2x128_si256(x_##A, x_##A2, 0x31); \
+ t_##B = _mm256_permute2x128_si256(x_##B, x_##B2, 0x20); \
+ t_##B2 = _mm256_permute2x128_si256(x_##B, x_##B2, 0x31); \
+ t_##C = _mm256_permute2x128_si256(x_##C, x_##C2, 0x20); \
+ t_##C2 = _mm256_permute2x128_si256(x_##C, x_##C2, 0x31); \
+ t_##D = _mm256_permute2x128_si256(x_##D, x_##D2, 0x20); \
+ t_##D2 = _mm256_permute2x128_si256(x_##D, x_##D2, 0x31); \
+ t_##A = \
+ _mm256_xor_si256(t_##A, _mm256_loadu_si256((__m256i*) (m + 0))); \
+ t_##B = \
+ _mm256_xor_si256(t_##B, _mm256_loadu_si256((__m256i*) (m + 64))); \
+ t_##C = \
+ _mm256_xor_si256(t_##C, _mm256_loadu_si256((__m256i*) (m + 128))); \
+ t_##D = \
+ _mm256_xor_si256(t_##D, _mm256_loadu_si256((__m256i*) (m + 192))); \
+ t_##A2 = _mm256_xor_si256(t_##A2, \
+ _mm256_loadu_si256((__m256i*) (m + 256))); \
+ t_##B2 = _mm256_xor_si256(t_##B2, \
+ _mm256_loadu_si256((__m256i*) (m + 320))); \
+ t_##C2 = _mm256_xor_si256(t_##C2, \
+ _mm256_loadu_si256((__m256i*) (m + 384))); \
+ t_##D2 = _mm256_xor_si256(t_##D2, \
+ _mm256_loadu_si256((__m256i*) (m + 448))); \
+ _mm256_storeu_si256((__m256i*) (c + 0), t_##A); \
+ _mm256_storeu_si256((__m256i*) (c + 64), t_##B); \
+ _mm256_storeu_si256((__m256i*) (c + 128), t_##C); \
+ _mm256_storeu_si256((__m256i*) (c + 192), t_##D); \
+ _mm256_storeu_si256((__m256i*) (c + 256), t_##A2); \
+ _mm256_storeu_si256((__m256i*) (c + 320), t_##B2); \
+ _mm256_storeu_si256((__m256i*) (c + 384), t_##C2); \
+ _mm256_storeu_si256((__m256i*) (c + 448), t_##D2); \
+ }
+
+ ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7);
+ m += 32;
+ c += 32;
+ ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15);
+ m -= 32;
+ c -= 32;
+
+#undef ONEQUAD
+#undef ONEQUAD_TRANSPOSE
+#undef ONEQUAD_UNPCK
+#undef ONEOCTO
+
+ bytes -= 512;
+ c += 512;
+ m += 512;
+ }
+}
+#undef VEC8_ROT
+#undef VEC8_QUARTERROUND
+#undef VEC8_QUARTERROUND_NAIVE
+#undef VEC8_QUARTERROUND_SHUFFLE
+#undef VEC8_QUARTERROUND_SHUFFLE2
+#undef VEC8_LINE1
+#undef VEC8_LINE2
+#undef VEC8_LINE3
+#undef VEC8_LINE4
+#undef VEC8_ROUND
+#undef VEC8_ROUND_SEQ
+#undef VEC8_ROUND_HALF
+#undef VEC8_ROUND_HALFANDHALF
diff --git a/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c
new file mode 100644
index 0000000000..f88a99dbdf
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c
@@ -0,0 +1,315 @@
+
+/*
+ chacha-merged.c version 20080118
+ D. J. Bernstein
+ Public domain.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "crypto_stream_chacha20.h"
+#include "private/common.h"
+#include "utils.h"
+
+#include "../stream_chacha20.h"
+#include "chacha20_ref.h"
+
+struct chacha_ctx {
+ uint32_t input[16];
+};
+
+typedef struct chacha_ctx chacha_ctx;
+
+#define U32C(v) (v##U)
+
+#define U32V(v) ((uint32_t)(v) &U32C(0xFFFFFFFF))
+
+#define ROTATE(v, c) (ROTL32(v, c))
+#define XOR(v, w) ((v) ^ (w))
+#define PLUS(v, w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v), 1))
+
+#define QUARTERROUND(a, b, c, d) \
+ a = PLUS(a, b); \
+ d = ROTATE(XOR(d, a), 16); \
+ c = PLUS(c, d); \
+ b = ROTATE(XOR(b, c), 12); \
+ a = PLUS(a, b); \
+ d = ROTATE(XOR(d, a), 8); \
+ c = PLUS(c, d); \
+ b = ROTATE(XOR(b, c), 7);
+
+static void
+chacha_keysetup(chacha_ctx *ctx, const uint8_t *k)
+{
+ ctx->input[0] = U32C(0x61707865);
+ ctx->input[1] = U32C(0x3320646e);
+ ctx->input[2] = U32C(0x79622d32);
+ ctx->input[3] = U32C(0x6b206574);
+ ctx->input[4] = LOAD32_LE(k + 0);
+ ctx->input[5] = LOAD32_LE(k + 4);
+ ctx->input[6] = LOAD32_LE(k + 8);
+ ctx->input[7] = LOAD32_LE(k + 12);
+ ctx->input[8] = LOAD32_LE(k + 16);
+ ctx->input[9] = LOAD32_LE(k + 20);
+ ctx->input[10] = LOAD32_LE(k + 24);
+ ctx->input[11] = LOAD32_LE(k + 28);
+}
+
+static void
+chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
+ ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
+ ctx->input[14] = LOAD32_LE(iv + 0);
+ ctx->input[15] = LOAD32_LE(iv + 4);
+}
+
+static void
+chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter);
+ ctx->input[13] = LOAD32_LE(iv + 0);
+ ctx->input[14] = LOAD32_LE(iv + 4);
+ ctx->input[15] = LOAD32_LE(iv + 8);
+}
+
+static void
+chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c,
+ unsigned long long bytes)
+{
+ uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14,
+ x15;
+ uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14,
+ j15;
+ uint8_t *ctarget = NULL;
+ uint8_t tmp[64];
+ unsigned int i;
+
+ if (!bytes) {
+ return; /* LCOV_EXCL_LINE */
+ }
+ if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) {
+ sodium_misuse();
+ }
+ j0 = ctx->input[0];
+ j1 = ctx->input[1];
+ j2 = ctx->input[2];
+ j3 = ctx->input[3];
+ j4 = ctx->input[4];
+ j5 = ctx->input[5];
+ j6 = ctx->input[6];
+ j7 = ctx->input[7];
+ j8 = ctx->input[8];
+ j9 = ctx->input[9];
+ j10 = ctx->input[10];
+ j11 = ctx->input[11];
+ j12 = ctx->input[12];
+ j13 = ctx->input[13];
+ j14 = ctx->input[14];
+ j15 = ctx->input[15];
+
+ for (;;) {
+ if (bytes < 64) {
+ memset(tmp, 0, 64);
+ for (i = 0; i < bytes; ++i) {
+ tmp[i] = m[i];
+ }
+ m = tmp;
+ ctarget = c;
+ c = tmp;
+ }
+ x0 = j0;
+ x1 = j1;
+ x2 = j2;
+ x3 = j3;
+ x4 = j4;
+ x5 = j5;
+ x6 = j6;
+ x7 = j7;
+ x8 = j8;
+ x9 = j9;
+ x10 = j10;
+ x11 = j11;
+ x12 = j12;
+ x13 = j13;
+ x14 = j14;
+ x15 = j15;
+ for (i = 20; i > 0; i -= 2) {
+ QUARTERROUND(x0, x4, x8, x12)
+ QUARTERROUND(x1, x5, x9, x13)
+ QUARTERROUND(x2, x6, x10, x14)
+ QUARTERROUND(x3, x7, x11, x15)
+ QUARTERROUND(x0, x5, x10, x15)
+ QUARTERROUND(x1, x6, x11, x12)
+ QUARTERROUND(x2, x7, x8, x13)
+ QUARTERROUND(x3, x4, x9, x14)
+ }
+ x0 = PLUS(x0, j0);
+ x1 = PLUS(x1, j1);
+ x2 = PLUS(x2, j2);
+ x3 = PLUS(x3, j3);
+ x4 = PLUS(x4, j4);
+ x5 = PLUS(x5, j5);
+ x6 = PLUS(x6, j6);
+ x7 = PLUS(x7, j7);
+ x8 = PLUS(x8, j8);
+ x9 = PLUS(x9, j9);
+ x10 = PLUS(x10, j10);
+ x11 = PLUS(x11, j11);
+ x12 = PLUS(x12, j12);
+ x13 = PLUS(x13, j13);
+ x14 = PLUS(x14, j14);
+ x15 = PLUS(x15, j15);
+
+ x0 = XOR(x0, LOAD32_LE(m + 0));
+ x1 = XOR(x1, LOAD32_LE(m + 4));
+ x2 = XOR(x2, LOAD32_LE(m + 8));
+ x3 = XOR(x3, LOAD32_LE(m + 12));
+ x4 = XOR(x4, LOAD32_LE(m + 16));
+ x5 = XOR(x5, LOAD32_LE(m + 20));
+ x6 = XOR(x6, LOAD32_LE(m + 24));
+ x7 = XOR(x7, LOAD32_LE(m + 28));
+ x8 = XOR(x8, LOAD32_LE(m + 32));
+ x9 = XOR(x9, LOAD32_LE(m + 36));
+ x10 = XOR(x10, LOAD32_LE(m + 40));
+ x11 = XOR(x11, LOAD32_LE(m + 44));
+ x12 = XOR(x12, LOAD32_LE(m + 48));
+ x13 = XOR(x13, LOAD32_LE(m + 52));
+ x14 = XOR(x14, LOAD32_LE(m + 56));
+ x15 = XOR(x15, LOAD32_LE(m + 60));
+
+ j12 = PLUSONE(j12);
+ /* LCOV_EXCL_START */
+ if (!j12) {
+ j13 = PLUSONE(j13);
+ }
+ /* LCOV_EXCL_STOP */
+
+ STORE32_LE(c + 0, x0);
+ STORE32_LE(c + 4, x1);
+ STORE32_LE(c + 8, x2);
+ STORE32_LE(c + 12, x3);
+ STORE32_LE(c + 16, x4);
+ STORE32_LE(c + 20, x5);
+ STORE32_LE(c + 24, x6);
+ STORE32_LE(c + 28, x7);
+ STORE32_LE(c + 32, x8);
+ STORE32_LE(c + 36, x9);
+ STORE32_LE(c + 40, x10);
+ STORE32_LE(c + 44, x11);
+ STORE32_LE(c + 48, x12);
+ STORE32_LE(c + 52, x13);
+ STORE32_LE(c + 56, x14);
+ STORE32_LE(c + 60, x15);
+
+ if (bytes <= 64) {
+ if (bytes < 64) {
+ for (i = 0; i < (unsigned int) bytes; ++i) {
+ ctarget[i] = c[i]; /* ctarget cannot be NULL */
+ }
+ }
+ ctx->input[12] = j12;
+ ctx->input[13] = j13;
+
+ return;
+ }
+ bytes -= 64;
+ c += 64;
+ m += 64;
+ }
+}
+
+static int
+stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ chacha20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[8];
+ uint32_t ic_high;
+ uint32_t ic_low;
+
+ if (!mlen) {
+ return 0;
+ }
+ ic_high = U32V(ic >> 32);
+ ic_low = U32V(ic);
+ STORE32_LE(&ic_bytes[0], ic_low);
+ STORE32_LE(&ic_bytes[4], ic_high);
+ chacha_keysetup(&ctx, k);
+ chacha_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ uint32_t ic, const unsigned char *k)
+{
+ struct chacha_ctx ctx;
+ uint8_t ic_bytes[4];
+
+ if (!mlen) {
+ return 0;
+ }
+ STORE32_LE(ic_bytes, ic);
+ chacha_keysetup(&ctx, k);
+ chacha_ietf_ivsetup(&ctx, n, ic_bytes);
+ chacha20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_ref_implementation = {
+ SODIUM_C99(.stream =) stream_ref,
+ SODIUM_C99(.stream_ietf =) stream_ietf_ref,
+ SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
+ SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic
+ };
diff --git a/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h
new file mode 100644
index 0000000000..6ac4807554
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_chacha20.h"
+#include "crypto_stream_chacha20.h"
+
+extern struct crypto_stream_chacha20_implementation
+ crypto_stream_chacha20_ref_implementation;
diff --git a/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c
new file mode 100644
index 0000000000..3b0895112c
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c
@@ -0,0 +1,130 @@
+#include "crypto_stream_chacha20.h"
+#include "private/common.h"
+#include "private/implementations.h"
+#include "randombytes.h"
+#include "runtime.h"
+#include "stream_chacha20.h"
+
+#include "ref/chacha20_ref.h"
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+# include "dolbeau/chacha20_dolbeau-avx2.h"
+#endif
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+# include "dolbeau/chacha20_dolbeau-ssse3.h"
+#endif
+
+static const crypto_stream_chacha20_implementation *implementation =
+ &crypto_stream_chacha20_ref_implementation;
+
+size_t
+crypto_stream_chacha20_keybytes(void) {
+ return crypto_stream_chacha20_KEYBYTES;
+}
+
+size_t
+crypto_stream_chacha20_noncebytes(void) {
+ return crypto_stream_chacha20_NONCEBYTES;
+}
+
+size_t
+crypto_stream_chacha20_messagebytes_max(void)
+{
+ return crypto_stream_chacha20_MESSAGEBYTES_MAX;
+}
+
+size_t
+crypto_stream_chacha20_ietf_keybytes(void) {
+ return crypto_stream_chacha20_ietf_KEYBYTES;
+}
+
+size_t
+crypto_stream_chacha20_ietf_noncebytes(void) {
+ return crypto_stream_chacha20_ietf_NONCEBYTES;
+}
+
+size_t
+crypto_stream_chacha20_ietf_messagebytes_max(void)
+{
+ return crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX;
+}
+
+int
+crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ return implementation->stream(c, clen, n, k);
+}
+
+int
+crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ return implementation->stream_ietf(c, clen, n, k);
+}
+
+int
+crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ return implementation->stream_xor_ic(c, m, mlen, n, ic, k);
+}
+
+int
+crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint32_t ic,
+ const unsigned char *k)
+{
+ return implementation->stream_ietf_xor_ic(c, m, mlen, n, ic, k);
+}
+
+int
+crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return implementation->stream_xor_ic(c, m, mlen, n, 0U, k);
+}
+
+int
+crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return implementation->stream_ietf_xor_ic(c, m, mlen, n, 0U, k);
+}
+
+void
+crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_chacha20_ietf_KEYBYTES);
+}
+
+void
+crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_chacha20_KEYBYTES);
+}
+
+int
+_crypto_stream_chacha20_pick_best_implementation(void)
+{
+ implementation = &crypto_stream_chacha20_ref_implementation;
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_avx2()) {
+ implementation = &crypto_stream_chacha20_dolbeau_avx2_implementation;
+ return 0;
+ }
+#endif
+#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
+ if (sodium_runtime_has_ssse3()) {
+ implementation = &crypto_stream_chacha20_dolbeau_ssse3_implementation;
+ return 0;
+ }
+#endif
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h
new file mode 100644
index 0000000000..d6b71c5e0d
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h
@@ -0,0 +1,22 @@
+
+#ifndef stream_chacha20_H
+#define stream_chacha20_H
+
+#include <stdint.h>
+
+typedef struct crypto_stream_chacha20_implementation {
+ int (*stream)(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+ int (*stream_ietf)(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+ int (*stream_xor_ic)(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+ int (*stream_ietf_xor_ic)(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint32_t ic,
+ const unsigned char *k);
+} crypto_stream_chacha20_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/crypto_stream.c b/libs/libsodium/src/crypto_stream/crypto_stream.c
new file mode 100644
index 0000000000..58d25381ab
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/crypto_stream.c
@@ -0,0 +1,49 @@
+
+#include "crypto_stream.h"
+#include "randombytes.h"
+
+size_t
+crypto_stream_keybytes(void)
+{
+ return crypto_stream_KEYBYTES;
+}
+
+size_t
+crypto_stream_noncebytes(void)
+{
+ return crypto_stream_NONCEBYTES;
+}
+
+size_t
+crypto_stream_messagebytes_max(void)
+{
+ return crypto_stream_MESSAGEBYTES_MAX;
+}
+
+const char *
+crypto_stream_primitive(void)
+{
+ return crypto_stream_PRIMITIVE;
+}
+
+int
+crypto_stream(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ return crypto_stream_xsalsa20(c, clen, n, k);
+}
+
+
+int
+crypto_stream_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_stream_xsalsa20_xor(c, m, mlen, n, k);
+}
+
+void
+crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c
new file mode 100644
index 0000000000..f0854ebf7e
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c
@@ -0,0 +1,120 @@
+/*
+version 20140420
+D. J. Bernstein
+Public domain.
+*/
+
+#include <stdint.h>
+
+#include "crypto_core_salsa20.h"
+#include "crypto_stream_salsa20.h"
+#include "utils.h"
+
+#include "../stream_salsa20.h"
+#include "salsa20_ref.h"
+
+#ifndef HAVE_AMD64_ASM
+
+static int
+stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!clen) {
+ return 0;
+ }
+ for (i = 0; i < 32; i++) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; i++) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; i++) {
+ in[i] = 0;
+ }
+ while (clen >= 64) {
+ crypto_core_salsa20(c, in, kcopy, NULL);
+ u = 1;
+ for (i = 8; i < 16; i++) {
+ u += (unsigned int) in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ clen -= 64;
+ c += 64;
+ }
+ if (clen) {
+ crypto_core_salsa20(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int) clen; i++) {
+ c[i] = block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
+
+static int
+stream_ref_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!mlen) {
+ return 0;
+ }
+ for (i = 0; i < 32; i++) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; i++) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; i++) {
+ in[i] = (unsigned char) (ic & 0xff);
+ ic >>= 8;
+ }
+ while (mlen >= 64) {
+ crypto_core_salsa20(block, in, kcopy, NULL);
+ for (i = 0; i < 64; i++) {
+ c[i] = m[i] ^ block[i];
+ }
+ u = 1;
+ for (i = 8; i < 16; i++) {
+ u += (unsigned int) in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ mlen -= 64;
+ c += 64;
+ m += 64;
+ }
+ if (mlen) {
+ crypto_core_salsa20(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int) mlen; i++) {
+ c[i] = m[i] ^ block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
+
+struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_ref_implementation = {
+ SODIUM_C99(.stream =) stream_ref,
+ SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic,
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h
new file mode 100644
index 0000000000..8716cb4048
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_salsa20.h"
+#include "crypto_stream_salsa20.h"
+
+extern struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_ref_implementation;
diff --git a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c
new file mode 100644
index 0000000000..4529850136
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c
@@ -0,0 +1,100 @@
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "private/implementations.h"
+#include "randombytes.h"
+#include "runtime.h"
+#include "stream_salsa20.h"
+
+#ifdef HAVE_AMD64_ASM
+# include "xmm6/salsa20_xmm6.h"
+#else
+# include "ref/salsa20_ref.h"
+#endif
+#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H)
+# include "xmm6int/salsa20_xmm6int-sse2.h"
+#endif
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+# include "xmm6int/salsa20_xmm6int-avx2.h"
+#endif
+
+#if HAVE_AMD64_ASM
+static const crypto_stream_salsa20_implementation *implementation =
+ &crypto_stream_salsa20_xmm6_implementation;
+#else
+static const crypto_stream_salsa20_implementation *implementation =
+ &crypto_stream_salsa20_ref_implementation;
+#endif
+
+size_t
+crypto_stream_salsa20_keybytes(void)
+{
+ return crypto_stream_salsa20_KEYBYTES;
+}
+
+size_t
+crypto_stream_salsa20_noncebytes(void)
+{
+ return crypto_stream_salsa20_NONCEBYTES;
+}
+
+size_t
+crypto_stream_salsa20_messagebytes_max(void)
+{
+ return crypto_stream_salsa20_MESSAGEBYTES_MAX;
+}
+
+int
+crypto_stream_salsa20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ return implementation->stream(c, clen, n, k);
+}
+
+int
+crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ return implementation->stream_xor_ic(c, m, mlen, n, ic, k);
+}
+
+int
+crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return implementation->stream_xor_ic(c, m, mlen, n, 0U, k);
+}
+
+void
+crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_salsa20_KEYBYTES);
+}
+
+int
+_crypto_stream_salsa20_pick_best_implementation(void)
+{
+#ifdef HAVE_AMD64_ASM
+ implementation = &crypto_stream_salsa20_xmm6_implementation;
+#else
+ implementation = &crypto_stream_salsa20_ref_implementation;
+#endif
+
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+ if (sodium_runtime_has_avx2()) {
+ implementation = &crypto_stream_salsa20_xmm6int_avx2_implementation;
+ return 0;
+ }
+#endif
+#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H)
+ if (sodium_runtime_has_sse2()) {
+ implementation = &crypto_stream_salsa20_xmm6int_sse2_implementation;
+ return 0;
+ }
+#endif
+ return 0; /* LCOV_EXCL_LINE */
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h
new file mode 100644
index 0000000000..1949d38113
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h
@@ -0,0 +1,16 @@
+
+#ifndef stream_salsa20_H
+#define stream_salsa20_H
+
+#include <stdint.h>
+
+typedef struct crypto_stream_salsa20_implementation {
+ int (*stream)(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+ int (*stream_xor_ic)(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+} crypto_stream_salsa20_implementation;
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S
new file mode 100644
index 0000000000..6d9f354e10
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S
@@ -0,0 +1,960 @@
+#ifdef HAVE_AMD64_ASM
+
+.text
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL stream_salsa20_xmm6
+ASM_HIDE_SYMBOL _stream_salsa20_xmm6
+#endif
+.globl stream_salsa20_xmm6
+.globl _stream_salsa20_xmm6
+#ifdef __ELF__
+.type stream_salsa20_xmm6, @function
+.type _stream_salsa20_xmm6, @function
+#endif
+stream_salsa20_xmm6:
+_stream_salsa20_xmm6:
+mov %rsp,%r11
+and $31,%r11
+add $512,%r11
+sub %r11,%rsp
+movq %r11,416(%rsp)
+movq %r12,424(%rsp)
+movq %r13,432(%rsp)
+movq %r14,440(%rsp)
+movq %r15,448(%rsp)
+movq %rbx,456(%rsp)
+movq %rbp,464(%rsp)
+mov %rsi,%r9
+mov %rdi,%rdi
+mov %rdi,%rsi
+mov %rdx,%rdx
+mov %rcx,%r10
+cmp $0,%r9
+jbe ._done
+mov $0,%rax
+mov %r9,%rcx
+rep stosb
+sub %r9,%rdi
+movq $0,472(%rsp)
+jmp ._start
+
+.text
+.p2align 5
+
+#ifdef ASM_HIDE_SYMBOL
+ASM_HIDE_SYMBOL stream_salsa20_xmm6_xor_ic
+ASM_HIDE_SYMBOL _stream_salsa20_xmm6_xor_ic
+#endif
+.globl stream_salsa20_xmm6_xor_ic
+.globl _stream_salsa20_xmm6_xor_ic
+#ifdef __ELF__
+.type stream_salsa20_xmm6_xor_ic, @function
+.type _stream_salsa20_xmm6_xor_ic, @function
+#endif
+stream_salsa20_xmm6_xor_ic:
+_stream_salsa20_xmm6_xor_ic:
+
+mov %rsp,%r11
+and $31,%r11
+add $512,%r11
+sub %r11,%rsp
+movq %r11,416(%rsp)
+movq %r12,424(%rsp)
+movq %r13,432(%rsp)
+movq %r14,440(%rsp)
+movq %r15,448(%rsp)
+movq %rbx,456(%rsp)
+movq %rbp,464(%rsp)
+mov %rdi,%rdi
+mov %rsi,%rsi
+mov %r9,%r10
+movq %r8,472(%rsp)
+mov %rdx,%r9
+mov %rcx,%rdx
+cmp $0,%r9
+jbe ._done
+
+._start:
+movl 20(%r10),%ecx
+movl 0(%r10),%r8d
+movl 0(%rdx),%eax
+movl 16(%r10),%r11d
+movl %ecx,64(%rsp)
+movl %r8d,4+64(%rsp)
+movl %eax,8+64(%rsp)
+movl %r11d,12+64(%rsp)
+movl 24(%r10),%r8d
+movl 4(%r10),%eax
+movl 4(%rdx),%edx
+movq 472(%rsp),%rcx
+movl %ecx,80(%rsp)
+movl %r8d,4+80(%rsp)
+movl %eax,8+80(%rsp)
+movl %edx,12+80(%rsp)
+movl 12(%r10),%edx
+shr $32,%rcx
+movl 28(%r10),%r8d
+movl 8(%r10),%eax
+movl %edx,96(%rsp)
+movl %ecx,4+96(%rsp)
+movl %r8d,8+96(%rsp)
+movl %eax,12+96(%rsp)
+mov $1634760805,%rdx
+mov $857760878,%rcx
+mov $2036477234,%r8
+mov $1797285236,%rax
+movl %edx,112(%rsp)
+movl %ecx,4+112(%rsp)
+movl %r8d,8+112(%rsp)
+movl %eax,12+112(%rsp)
+cmp $256,%r9
+jb ._bytesbetween1and255
+movdqa 112(%rsp),%xmm0
+pshufd $0x55,%xmm0,%xmm1
+pshufd $0xaa,%xmm0,%xmm2
+pshufd $0xff,%xmm0,%xmm3
+pshufd $0x00,%xmm0,%xmm0
+movdqa %xmm1,128(%rsp)
+movdqa %xmm2,144(%rsp)
+movdqa %xmm3,160(%rsp)
+movdqa %xmm0,176(%rsp)
+movdqa 64(%rsp),%xmm0
+pshufd $0xaa,%xmm0,%xmm1
+pshufd $0xff,%xmm0,%xmm2
+pshufd $0x00,%xmm0,%xmm3
+pshufd $0x55,%xmm0,%xmm0
+movdqa %xmm1,192(%rsp)
+movdqa %xmm2,208(%rsp)
+movdqa %xmm3,224(%rsp)
+movdqa %xmm0,240(%rsp)
+movdqa 80(%rsp),%xmm0
+pshufd $0xff,%xmm0,%xmm1
+pshufd $0x55,%xmm0,%xmm2
+pshufd $0xaa,%xmm0,%xmm0
+movdqa %xmm1,256(%rsp)
+movdqa %xmm2,272(%rsp)
+movdqa %xmm0,288(%rsp)
+movdqa 96(%rsp),%xmm0
+pshufd $0x00,%xmm0,%xmm1
+pshufd $0xaa,%xmm0,%xmm2
+pshufd $0xff,%xmm0,%xmm0
+movdqa %xmm1,304(%rsp)
+movdqa %xmm2,320(%rsp)
+movdqa %xmm0,336(%rsp)
+
+.p2align 4
+._bytesatleast256:
+movq 472(%rsp),%rdx
+mov %rdx,%rcx
+shr $32,%rcx
+movl %edx,352(%rsp)
+movl %ecx,368(%rsp)
+add $1,%rdx
+mov %rdx,%rcx
+shr $32,%rcx
+movl %edx,4+352(%rsp)
+movl %ecx,4+368(%rsp)
+add $1,%rdx
+mov %rdx,%rcx
+shr $32,%rcx
+movl %edx,8+352(%rsp)
+movl %ecx,8+368(%rsp)
+add $1,%rdx
+mov %rdx,%rcx
+shr $32,%rcx
+movl %edx,12+352(%rsp)
+movl %ecx,12+368(%rsp)
+add $1,%rdx
+mov %rdx,%rcx
+shr $32,%rcx
+movl %edx,80(%rsp)
+movl %ecx,4+96(%rsp)
+movq %rdx,472(%rsp)
+movq %r9,480(%rsp)
+mov $20,%rdx
+movdqa 128(%rsp),%xmm0
+movdqa 144(%rsp),%xmm1
+movdqa 160(%rsp),%xmm2
+movdqa 320(%rsp),%xmm3
+movdqa 336(%rsp),%xmm4
+movdqa 192(%rsp),%xmm5
+movdqa 208(%rsp),%xmm6
+movdqa 240(%rsp),%xmm7
+movdqa 256(%rsp),%xmm8
+movdqa 272(%rsp),%xmm9
+movdqa 288(%rsp),%xmm10
+movdqa 368(%rsp),%xmm11
+movdqa 176(%rsp),%xmm12
+movdqa 224(%rsp),%xmm13
+movdqa 304(%rsp),%xmm14
+movdqa 352(%rsp),%xmm15
+
+.p2align 4
+._mainloop1:
+movdqa %xmm1,384(%rsp)
+movdqa %xmm2,400(%rsp)
+movdqa %xmm13,%xmm1
+paddd %xmm12,%xmm1
+movdqa %xmm1,%xmm2
+pslld $7,%xmm1
+pxor %xmm1,%xmm14
+psrld $25,%xmm2
+pxor %xmm2,%xmm14
+movdqa %xmm7,%xmm1
+paddd %xmm0,%xmm1
+movdqa %xmm1,%xmm2
+pslld $7,%xmm1
+pxor %xmm1,%xmm11
+psrld $25,%xmm2
+pxor %xmm2,%xmm11
+movdqa %xmm12,%xmm1
+paddd %xmm14,%xmm1
+movdqa %xmm1,%xmm2
+pslld $9,%xmm1
+pxor %xmm1,%xmm15
+psrld $23,%xmm2
+pxor %xmm2,%xmm15
+movdqa %xmm0,%xmm1
+paddd %xmm11,%xmm1
+movdqa %xmm1,%xmm2
+pslld $9,%xmm1
+pxor %xmm1,%xmm9
+psrld $23,%xmm2
+pxor %xmm2,%xmm9
+movdqa %xmm14,%xmm1
+paddd %xmm15,%xmm1
+movdqa %xmm1,%xmm2
+pslld $13,%xmm1
+pxor %xmm1,%xmm13
+psrld $19,%xmm2
+pxor %xmm2,%xmm13
+movdqa %xmm11,%xmm1
+paddd %xmm9,%xmm1
+movdqa %xmm1,%xmm2
+pslld $13,%xmm1
+pxor %xmm1,%xmm7
+psrld $19,%xmm2
+pxor %xmm2,%xmm7
+movdqa %xmm15,%xmm1
+paddd %xmm13,%xmm1
+movdqa %xmm1,%xmm2
+pslld $18,%xmm1
+pxor %xmm1,%xmm12
+psrld $14,%xmm2
+pxor %xmm2,%xmm12
+movdqa 384(%rsp),%xmm1
+movdqa %xmm12,384(%rsp)
+movdqa %xmm9,%xmm2
+paddd %xmm7,%xmm2
+movdqa %xmm2,%xmm12
+pslld $18,%xmm2
+pxor %xmm2,%xmm0
+psrld $14,%xmm12
+pxor %xmm12,%xmm0
+movdqa %xmm5,%xmm2
+paddd %xmm1,%xmm2
+movdqa %xmm2,%xmm12
+pslld $7,%xmm2
+pxor %xmm2,%xmm3
+psrld $25,%xmm12
+pxor %xmm12,%xmm3
+movdqa 400(%rsp),%xmm2
+movdqa %xmm0,400(%rsp)
+movdqa %xmm6,%xmm0
+paddd %xmm2,%xmm0
+movdqa %xmm0,%xmm12
+pslld $7,%xmm0
+pxor %xmm0,%xmm4
+psrld $25,%xmm12
+pxor %xmm12,%xmm4
+movdqa %xmm1,%xmm0
+paddd %xmm3,%xmm0
+movdqa %xmm0,%xmm12
+pslld $9,%xmm0
+pxor %xmm0,%xmm10
+psrld $23,%xmm12
+pxor %xmm12,%xmm10
+movdqa %xmm2,%xmm0
+paddd %xmm4,%xmm0
+movdqa %xmm0,%xmm12
+pslld $9,%xmm0
+pxor %xmm0,%xmm8
+psrld $23,%xmm12
+pxor %xmm12,%xmm8
+movdqa %xmm3,%xmm0
+paddd %xmm10,%xmm0
+movdqa %xmm0,%xmm12
+pslld $13,%xmm0
+pxor %xmm0,%xmm5
+psrld $19,%xmm12
+pxor %xmm12,%xmm5
+movdqa %xmm4,%xmm0
+paddd %xmm8,%xmm0
+movdqa %xmm0,%xmm12
+pslld $13,%xmm0
+pxor %xmm0,%xmm6
+psrld $19,%xmm12
+pxor %xmm12,%xmm6
+movdqa %xmm10,%xmm0
+paddd %xmm5,%xmm0
+movdqa %xmm0,%xmm12
+pslld $18,%xmm0
+pxor %xmm0,%xmm1
+psrld $14,%xmm12
+pxor %xmm12,%xmm1
+movdqa 384(%rsp),%xmm0
+movdqa %xmm1,384(%rsp)
+movdqa %xmm4,%xmm1
+paddd %xmm0,%xmm1
+movdqa %xmm1,%xmm12
+pslld $7,%xmm1
+pxor %xmm1,%xmm7
+psrld $25,%xmm12
+pxor %xmm12,%xmm7
+movdqa %xmm8,%xmm1
+paddd %xmm6,%xmm1
+movdqa %xmm1,%xmm12
+pslld $18,%xmm1
+pxor %xmm1,%xmm2
+psrld $14,%xmm12
+pxor %xmm12,%xmm2
+movdqa 400(%rsp),%xmm12
+movdqa %xmm2,400(%rsp)
+movdqa %xmm14,%xmm1
+paddd %xmm12,%xmm1
+movdqa %xmm1,%xmm2
+pslld $7,%xmm1
+pxor %xmm1,%xmm5
+psrld $25,%xmm2
+pxor %xmm2,%xmm5
+movdqa %xmm0,%xmm1
+paddd %xmm7,%xmm1
+movdqa %xmm1,%xmm2
+pslld $9,%xmm1
+pxor %xmm1,%xmm10
+psrld $23,%xmm2
+pxor %xmm2,%xmm10
+movdqa %xmm12,%xmm1
+paddd %xmm5,%xmm1
+movdqa %xmm1,%xmm2
+pslld $9,%xmm1
+pxor %xmm1,%xmm8
+psrld $23,%xmm2
+pxor %xmm2,%xmm8
+movdqa %xmm7,%xmm1
+paddd %xmm10,%xmm1
+movdqa %xmm1,%xmm2
+pslld $13,%xmm1
+pxor %xmm1,%xmm4
+psrld $19,%xmm2
+pxor %xmm2,%xmm4
+movdqa %xmm5,%xmm1
+paddd %xmm8,%xmm1
+movdqa %xmm1,%xmm2
+pslld $13,%xmm1
+pxor %xmm1,%xmm14
+psrld $19,%xmm2
+pxor %xmm2,%xmm14
+movdqa %xmm10,%xmm1
+paddd %xmm4,%xmm1
+movdqa %xmm1,%xmm2
+pslld $18,%xmm1
+pxor %xmm1,%xmm0
+psrld $14,%xmm2
+pxor %xmm2,%xmm0
+movdqa 384(%rsp),%xmm1
+movdqa %xmm0,384(%rsp)
+movdqa %xmm8,%xmm0
+paddd %xmm14,%xmm0
+movdqa %xmm0,%xmm2
+pslld $18,%xmm0
+pxor %xmm0,%xmm12
+psrld $14,%xmm2
+pxor %xmm2,%xmm12
+movdqa %xmm11,%xmm0
+paddd %xmm1,%xmm0
+movdqa %xmm0,%xmm2
+pslld $7,%xmm0
+pxor %xmm0,%xmm6
+psrld $25,%xmm2
+pxor %xmm2,%xmm6
+movdqa 400(%rsp),%xmm2
+movdqa %xmm12,400(%rsp)
+movdqa %xmm3,%xmm0
+paddd %xmm2,%xmm0
+movdqa %xmm0,%xmm12
+pslld $7,%xmm0
+pxor %xmm0,%xmm13
+psrld $25,%xmm12
+pxor %xmm12,%xmm13
+movdqa %xmm1,%xmm0
+paddd %xmm6,%xmm0
+movdqa %xmm0,%xmm12
+pslld $9,%xmm0
+pxor %xmm0,%xmm15
+psrld $23,%xmm12
+pxor %xmm12,%xmm15
+movdqa %xmm2,%xmm0
+paddd %xmm13,%xmm0
+movdqa %xmm0,%xmm12
+pslld $9,%xmm0
+pxor %xmm0,%xmm9
+psrld $23,%xmm12
+pxor %xmm12,%xmm9
+movdqa %xmm6,%xmm0
+paddd %xmm15,%xmm0
+movdqa %xmm0,%xmm12
+pslld $13,%xmm0
+pxor %xmm0,%xmm11
+psrld $19,%xmm12
+pxor %xmm12,%xmm11
+movdqa %xmm13,%xmm0
+paddd %xmm9,%xmm0
+movdqa %xmm0,%xmm12
+pslld $13,%xmm0
+pxor %xmm0,%xmm3
+psrld $19,%xmm12
+pxor %xmm12,%xmm3
+movdqa %xmm15,%xmm0
+paddd %xmm11,%xmm0
+movdqa %xmm0,%xmm12
+pslld $18,%xmm0
+pxor %xmm0,%xmm1
+psrld $14,%xmm12
+pxor %xmm12,%xmm1
+movdqa %xmm9,%xmm0
+paddd %xmm3,%xmm0
+movdqa %xmm0,%xmm12
+pslld $18,%xmm0
+pxor %xmm0,%xmm2
+psrld $14,%xmm12
+pxor %xmm12,%xmm2
+movdqa 384(%rsp),%xmm12
+movdqa 400(%rsp),%xmm0
+sub $2,%rdx
+ja ._mainloop1
+
+paddd 176(%rsp),%xmm12
+paddd 240(%rsp),%xmm7
+paddd 288(%rsp),%xmm10
+paddd 336(%rsp),%xmm4
+movd %xmm12,%rdx
+movd %xmm7,%rcx
+movd %xmm10,%r8
+movd %xmm4,%r9
+pshufd $0x39,%xmm12,%xmm12
+pshufd $0x39,%xmm7,%xmm7
+pshufd $0x39,%xmm10,%xmm10
+pshufd $0x39,%xmm4,%xmm4
+xorl 0(%rsi),%edx
+xorl 4(%rsi),%ecx
+xorl 8(%rsi),%r8d
+xorl 12(%rsi),%r9d
+movl %edx,0(%rdi)
+movl %ecx,4(%rdi)
+movl %r8d,8(%rdi)
+movl %r9d,12(%rdi)
+movd %xmm12,%rdx
+movd %xmm7,%rcx
+movd %xmm10,%r8
+movd %xmm4,%r9
+pshufd $0x39,%xmm12,%xmm12
+pshufd $0x39,%xmm7,%xmm7
+pshufd $0x39,%xmm10,%xmm10
+pshufd $0x39,%xmm4,%xmm4
+xorl 64(%rsi),%edx
+xorl 68(%rsi),%ecx
+xorl 72(%rsi),%r8d
+xorl 76(%rsi),%r9d
+movl %edx,64(%rdi)
+movl %ecx,68(%rdi)
+movl %r8d,72(%rdi)
+movl %r9d,76(%rdi)
+movd %xmm12,%rdx
+movd %xmm7,%rcx
+movd %xmm10,%r8
+movd %xmm4,%r9
+pshufd $0x39,%xmm12,%xmm12
+pshufd $0x39,%xmm7,%xmm7
+pshufd $0x39,%xmm10,%xmm10
+pshufd $0x39,%xmm4,%xmm4
+xorl 128(%rsi),%edx
+xorl 132(%rsi),%ecx
+xorl 136(%rsi),%r8d
+xorl 140(%rsi),%r9d
+movl %edx,128(%rdi)
+movl %ecx,132(%rdi)
+movl %r8d,136(%rdi)
+movl %r9d,140(%rdi)
+movd %xmm12,%rdx
+movd %xmm7,%rcx
+movd %xmm10,%r8
+movd %xmm4,%r9
+xorl 192(%rsi),%edx
+xorl 196(%rsi),%ecx
+xorl 200(%rsi),%r8d
+xorl 204(%rsi),%r9d
+movl %edx,192(%rdi)
+movl %ecx,196(%rdi)
+movl %r8d,200(%rdi)
+movl %r9d,204(%rdi)
+paddd 304(%rsp),%xmm14
+paddd 128(%rsp),%xmm0
+paddd 192(%rsp),%xmm5
+paddd 256(%rsp),%xmm8
+movd %xmm14,%rdx
+movd %xmm0,%rcx
+movd %xmm5,%r8
+movd %xmm8,%r9
+pshufd $0x39,%xmm14,%xmm14
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm5,%xmm5
+pshufd $0x39,%xmm8,%xmm8
+xorl 16(%rsi),%edx
+xorl 20(%rsi),%ecx
+xorl 24(%rsi),%r8d
+xorl 28(%rsi),%r9d
+movl %edx,16(%rdi)
+movl %ecx,20(%rdi)
+movl %r8d,24(%rdi)
+movl %r9d,28(%rdi)
+movd %xmm14,%rdx
+movd %xmm0,%rcx
+movd %xmm5,%r8
+movd %xmm8,%r9
+pshufd $0x39,%xmm14,%xmm14
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm5,%xmm5
+pshufd $0x39,%xmm8,%xmm8
+xorl 80(%rsi),%edx
+xorl 84(%rsi),%ecx
+xorl 88(%rsi),%r8d
+xorl 92(%rsi),%r9d
+movl %edx,80(%rdi)
+movl %ecx,84(%rdi)
+movl %r8d,88(%rdi)
+movl %r9d,92(%rdi)
+movd %xmm14,%rdx
+movd %xmm0,%rcx
+movd %xmm5,%r8
+movd %xmm8,%r9
+pshufd $0x39,%xmm14,%xmm14
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm5,%xmm5
+pshufd $0x39,%xmm8,%xmm8
+xorl 144(%rsi),%edx
+xorl 148(%rsi),%ecx
+xorl 152(%rsi),%r8d
+xorl 156(%rsi),%r9d
+movl %edx,144(%rdi)
+movl %ecx,148(%rdi)
+movl %r8d,152(%rdi)
+movl %r9d,156(%rdi)
+movd %xmm14,%rdx
+movd %xmm0,%rcx
+movd %xmm5,%r8
+movd %xmm8,%r9
+xorl 208(%rsi),%edx
+xorl 212(%rsi),%ecx
+xorl 216(%rsi),%r8d
+xorl 220(%rsi),%r9d
+movl %edx,208(%rdi)
+movl %ecx,212(%rdi)
+movl %r8d,216(%rdi)
+movl %r9d,220(%rdi)
+paddd 352(%rsp),%xmm15
+paddd 368(%rsp),%xmm11
+paddd 144(%rsp),%xmm1
+paddd 208(%rsp),%xmm6
+movd %xmm15,%rdx
+movd %xmm11,%rcx
+movd %xmm1,%r8
+movd %xmm6,%r9
+pshufd $0x39,%xmm15,%xmm15
+pshufd $0x39,%xmm11,%xmm11
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm6,%xmm6
+xorl 32(%rsi),%edx
+xorl 36(%rsi),%ecx
+xorl 40(%rsi),%r8d
+xorl 44(%rsi),%r9d
+movl %edx,32(%rdi)
+movl %ecx,36(%rdi)
+movl %r8d,40(%rdi)
+movl %r9d,44(%rdi)
+movd %xmm15,%rdx
+movd %xmm11,%rcx
+movd %xmm1,%r8
+movd %xmm6,%r9
+pshufd $0x39,%xmm15,%xmm15
+pshufd $0x39,%xmm11,%xmm11
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm6,%xmm6
+xorl 96(%rsi),%edx
+xorl 100(%rsi),%ecx
+xorl 104(%rsi),%r8d
+xorl 108(%rsi),%r9d
+movl %edx,96(%rdi)
+movl %ecx,100(%rdi)
+movl %r8d,104(%rdi)
+movl %r9d,108(%rdi)
+movd %xmm15,%rdx
+movd %xmm11,%rcx
+movd %xmm1,%r8
+movd %xmm6,%r9
+pshufd $0x39,%xmm15,%xmm15
+pshufd $0x39,%xmm11,%xmm11
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm6,%xmm6
+xorl 160(%rsi),%edx
+xorl 164(%rsi),%ecx
+xorl 168(%rsi),%r8d
+xorl 172(%rsi),%r9d
+movl %edx,160(%rdi)
+movl %ecx,164(%rdi)
+movl %r8d,168(%rdi)
+movl %r9d,172(%rdi)
+movd %xmm15,%rdx
+movd %xmm11,%rcx
+movd %xmm1,%r8
+movd %xmm6,%r9
+xorl 224(%rsi),%edx
+xorl 228(%rsi),%ecx
+xorl 232(%rsi),%r8d
+xorl 236(%rsi),%r9d
+movl %edx,224(%rdi)
+movl %ecx,228(%rdi)
+movl %r8d,232(%rdi)
+movl %r9d,236(%rdi)
+paddd 224(%rsp),%xmm13
+paddd 272(%rsp),%xmm9
+paddd 320(%rsp),%xmm3
+paddd 160(%rsp),%xmm2
+movd %xmm13,%rdx
+movd %xmm9,%rcx
+movd %xmm3,%r8
+movd %xmm2,%r9
+pshufd $0x39,%xmm13,%xmm13
+pshufd $0x39,%xmm9,%xmm9
+pshufd $0x39,%xmm3,%xmm3
+pshufd $0x39,%xmm2,%xmm2
+xorl 48(%rsi),%edx
+xorl 52(%rsi),%ecx
+xorl 56(%rsi),%r8d
+xorl 60(%rsi),%r9d
+movl %edx,48(%rdi)
+movl %ecx,52(%rdi)
+movl %r8d,56(%rdi)
+movl %r9d,60(%rdi)
+movd %xmm13,%rdx
+movd %xmm9,%rcx
+movd %xmm3,%r8
+movd %xmm2,%r9
+pshufd $0x39,%xmm13,%xmm13
+pshufd $0x39,%xmm9,%xmm9
+pshufd $0x39,%xmm3,%xmm3
+pshufd $0x39,%xmm2,%xmm2
+xorl 112(%rsi),%edx
+xorl 116(%rsi),%ecx
+xorl 120(%rsi),%r8d
+xorl 124(%rsi),%r9d
+movl %edx,112(%rdi)
+movl %ecx,116(%rdi)
+movl %r8d,120(%rdi)
+movl %r9d,124(%rdi)
+movd %xmm13,%rdx
+movd %xmm9,%rcx
+movd %xmm3,%r8
+movd %xmm2,%r9
+pshufd $0x39,%xmm13,%xmm13
+pshufd $0x39,%xmm9,%xmm9
+pshufd $0x39,%xmm3,%xmm3
+pshufd $0x39,%xmm2,%xmm2
+xorl 176(%rsi),%edx
+xorl 180(%rsi),%ecx
+xorl 184(%rsi),%r8d
+xorl 188(%rsi),%r9d
+movl %edx,176(%rdi)
+movl %ecx,180(%rdi)
+movl %r8d,184(%rdi)
+movl %r9d,188(%rdi)
+movd %xmm13,%rdx
+movd %xmm9,%rcx
+movd %xmm3,%r8
+movd %xmm2,%r9
+xorl 240(%rsi),%edx
+xorl 244(%rsi),%ecx
+xorl 248(%rsi),%r8d
+xorl 252(%rsi),%r9d
+movl %edx,240(%rdi)
+movl %ecx,244(%rdi)
+movl %r8d,248(%rdi)
+movl %r9d,252(%rdi)
+movq 480(%rsp),%r9
+sub $256,%r9
+add $256,%rsi
+add $256,%rdi
+cmp $256,%r9
+jae ._bytesatleast256
+
+cmp $0,%r9
+jbe ._done
+
+._bytesbetween1and255:
+cmp $64,%r9
+jae ._nocopy
+
+mov %rdi,%rdx
+leaq 0(%rsp),%rdi
+mov %r9,%rcx
+rep movsb
+leaq 0(%rsp),%rdi
+leaq 0(%rsp),%rsi
+
+._nocopy:
+movq %r9,480(%rsp)
+movdqa 112(%rsp),%xmm0
+movdqa 64(%rsp),%xmm1
+movdqa 80(%rsp),%xmm2
+movdqa 96(%rsp),%xmm3
+movdqa %xmm1,%xmm4
+mov $20,%rcx
+
+.p2align 4
+._mainloop2:
+paddd %xmm0,%xmm4
+movdqa %xmm0,%xmm5
+movdqa %xmm4,%xmm6
+pslld $7,%xmm4
+psrld $25,%xmm6
+pxor %xmm4,%xmm3
+pxor %xmm6,%xmm3
+paddd %xmm3,%xmm5
+movdqa %xmm3,%xmm4
+movdqa %xmm5,%xmm6
+pslld $9,%xmm5
+psrld $23,%xmm6
+pxor %xmm5,%xmm2
+pshufd $0x93,%xmm3,%xmm3
+pxor %xmm6,%xmm2
+paddd %xmm2,%xmm4
+movdqa %xmm2,%xmm5
+movdqa %xmm4,%xmm6
+pslld $13,%xmm4
+psrld $19,%xmm6
+pxor %xmm4,%xmm1
+pshufd $0x4e,%xmm2,%xmm2
+pxor %xmm6,%xmm1
+paddd %xmm1,%xmm5
+movdqa %xmm3,%xmm4
+movdqa %xmm5,%xmm6
+pslld $18,%xmm5
+psrld $14,%xmm6
+pxor %xmm5,%xmm0
+pshufd $0x39,%xmm1,%xmm1
+pxor %xmm6,%xmm0
+paddd %xmm0,%xmm4
+movdqa %xmm0,%xmm5
+movdqa %xmm4,%xmm6
+pslld $7,%xmm4
+psrld $25,%xmm6
+pxor %xmm4,%xmm1
+pxor %xmm6,%xmm1
+paddd %xmm1,%xmm5
+movdqa %xmm1,%xmm4
+movdqa %xmm5,%xmm6
+pslld $9,%xmm5
+psrld $23,%xmm6
+pxor %xmm5,%xmm2
+pshufd $0x93,%xmm1,%xmm1
+pxor %xmm6,%xmm2
+paddd %xmm2,%xmm4
+movdqa %xmm2,%xmm5
+movdqa %xmm4,%xmm6
+pslld $13,%xmm4
+psrld $19,%xmm6
+pxor %xmm4,%xmm3
+pshufd $0x4e,%xmm2,%xmm2
+pxor %xmm6,%xmm3
+paddd %xmm3,%xmm5
+movdqa %xmm1,%xmm4
+movdqa %xmm5,%xmm6
+pslld $18,%xmm5
+psrld $14,%xmm6
+pxor %xmm5,%xmm0
+pshufd $0x39,%xmm3,%xmm3
+pxor %xmm6,%xmm0
+paddd %xmm0,%xmm4
+movdqa %xmm0,%xmm5
+movdqa %xmm4,%xmm6
+pslld $7,%xmm4
+psrld $25,%xmm6
+pxor %xmm4,%xmm3
+pxor %xmm6,%xmm3
+paddd %xmm3,%xmm5
+movdqa %xmm3,%xmm4
+movdqa %xmm5,%xmm6
+pslld $9,%xmm5
+psrld $23,%xmm6
+pxor %xmm5,%xmm2
+pshufd $0x93,%xmm3,%xmm3
+pxor %xmm6,%xmm2
+paddd %xmm2,%xmm4
+movdqa %xmm2,%xmm5
+movdqa %xmm4,%xmm6
+pslld $13,%xmm4
+psrld $19,%xmm6
+pxor %xmm4,%xmm1
+pshufd $0x4e,%xmm2,%xmm2
+pxor %xmm6,%xmm1
+paddd %xmm1,%xmm5
+movdqa %xmm3,%xmm4
+movdqa %xmm5,%xmm6
+pslld $18,%xmm5
+psrld $14,%xmm6
+pxor %xmm5,%xmm0
+pshufd $0x39,%xmm1,%xmm1
+pxor %xmm6,%xmm0
+paddd %xmm0,%xmm4
+movdqa %xmm0,%xmm5
+movdqa %xmm4,%xmm6
+pslld $7,%xmm4
+psrld $25,%xmm6
+pxor %xmm4,%xmm1
+pxor %xmm6,%xmm1
+paddd %xmm1,%xmm5
+movdqa %xmm1,%xmm4
+movdqa %xmm5,%xmm6
+pslld $9,%xmm5
+psrld $23,%xmm6
+pxor %xmm5,%xmm2
+pshufd $0x93,%xmm1,%xmm1
+pxor %xmm6,%xmm2
+paddd %xmm2,%xmm4
+movdqa %xmm2,%xmm5
+movdqa %xmm4,%xmm6
+pslld $13,%xmm4
+psrld $19,%xmm6
+pxor %xmm4,%xmm3
+pshufd $0x4e,%xmm2,%xmm2
+pxor %xmm6,%xmm3
+sub $4,%rcx
+paddd %xmm3,%xmm5
+movdqa %xmm1,%xmm4
+movdqa %xmm5,%xmm6
+pslld $18,%xmm5
+pxor %xmm7,%xmm7
+psrld $14,%xmm6
+pxor %xmm5,%xmm0
+pshufd $0x39,%xmm3,%xmm3
+pxor %xmm6,%xmm0
+ja ._mainloop2
+
+paddd 112(%rsp),%xmm0
+paddd 64(%rsp),%xmm1
+paddd 80(%rsp),%xmm2
+paddd 96(%rsp),%xmm3
+movd %xmm0,%rcx
+movd %xmm1,%r8
+movd %xmm2,%r9
+movd %xmm3,%rax
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm2,%xmm2
+pshufd $0x39,%xmm3,%xmm3
+xorl 0(%rsi),%ecx
+xorl 48(%rsi),%r8d
+xorl 32(%rsi),%r9d
+xorl 16(%rsi),%eax
+movl %ecx,0(%rdi)
+movl %r8d,48(%rdi)
+movl %r9d,32(%rdi)
+movl %eax,16(%rdi)
+movd %xmm0,%rcx
+movd %xmm1,%r8
+movd %xmm2,%r9
+movd %xmm3,%rax
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm2,%xmm2
+pshufd $0x39,%xmm3,%xmm3
+xorl 20(%rsi),%ecx
+xorl 4(%rsi),%r8d
+xorl 52(%rsi),%r9d
+xorl 36(%rsi),%eax
+movl %ecx,20(%rdi)
+movl %r8d,4(%rdi)
+movl %r9d,52(%rdi)
+movl %eax,36(%rdi)
+movd %xmm0,%rcx
+movd %xmm1,%r8
+movd %xmm2,%r9
+movd %xmm3,%rax
+pshufd $0x39,%xmm0,%xmm0
+pshufd $0x39,%xmm1,%xmm1
+pshufd $0x39,%xmm2,%xmm2
+pshufd $0x39,%xmm3,%xmm3
+xorl 40(%rsi),%ecx
+xorl 24(%rsi),%r8d
+xorl 8(%rsi),%r9d
+xorl 56(%rsi),%eax
+movl %ecx,40(%rdi)
+movl %r8d,24(%rdi)
+movl %r9d,8(%rdi)
+movl %eax,56(%rdi)
+movd %xmm0,%rcx
+movd %xmm1,%r8
+movd %xmm2,%r9
+movd %xmm3,%rax
+xorl 60(%rsi),%ecx
+xorl 44(%rsi),%r8d
+xorl 28(%rsi),%r9d
+xorl 12(%rsi),%eax
+movl %ecx,60(%rdi)
+movl %r8d,44(%rdi)
+movl %r9d,28(%rdi)
+movl %eax,12(%rdi)
+movq 480(%rsp),%r9
+movq 472(%rsp),%rcx
+add $1,%rcx
+mov %rcx,%r8
+shr $32,%r8
+movl %ecx,80(%rsp)
+movl %r8d,4+96(%rsp)
+movq %rcx,472(%rsp)
+cmp $64,%r9
+ja ._bytesatleast65
+jae ._bytesatleast64
+
+mov %rdi,%rsi
+mov %rdx,%rdi
+mov %r9,%rcx
+rep movsb
+
+._bytesatleast64:
+._done:
+movq 416(%rsp),%r11
+movq 424(%rsp),%r12
+movq 432(%rsp),%r13
+movq 440(%rsp),%r14
+movq 448(%rsp),%r15
+movq 456(%rsp),%rbx
+movq 464(%rsp),%rbp
+add %r11,%rsp
+xor %rax,%rax
+mov %rsi,%rdx
+ret
+
+._bytesatleast65:
+sub $64,%r9
+add $64,%rdi
+add $64,%rsi
+jmp ._bytesbetween1and255
+
+#endif
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c
new file mode 100644
index 0000000000..0a6fee0f3e
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c
@@ -0,0 +1,31 @@
+
+#include <stdint.h>
+
+#include "utils.h"
+
+#include "../stream_salsa20.h"
+#include "salsa20_xmm6.h"
+
+#ifdef HAVE_AMD64_ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int stream_salsa20_xmm6(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+extern int stream_salsa20_xmm6_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ uint64_t ic, const unsigned char *k);
+#ifdef __cplusplus
+}
+#endif
+
+struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6_implementation = {
+ SODIUM_C99(.stream =) stream_salsa20_xmm6,
+ SODIUM_C99(.stream_xor_ic =) stream_salsa20_xmm6_xor_ic,
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h
new file mode 100644
index 0000000000..d38473a9ff
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_salsa20.h"
+#include "crypto_stream_salsa20.h"
+
+extern struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6_implementation;
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c
new file mode 100644
index 0000000000..18d4773ec9
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c
@@ -0,0 +1,131 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "utils.h"
+
+#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
+ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# pragma GCC target("ssse3")
+# pragma GCC target("sse4.1")
+# pragma GCC target("avx2")
+# endif
+
+#include <emmintrin.h>
+#include <immintrin.h>
+#include <smmintrin.h>
+#include <tmmintrin.h>
+
+# include "../stream_salsa20.h"
+# include "salsa20_xmm6int-avx2.h"
+
+# define ROUNDS 20
+
+typedef struct salsa_ctx {
+ uint32_t input[16];
+} salsa_ctx;
+
+static const int TR[16] = {
+ 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3
+};
+
+static void
+salsa_keysetup(salsa_ctx *ctx, const uint8_t *k)
+{
+ ctx->input[TR[1]] = LOAD32_LE(k + 0);
+ ctx->input[TR[2]] = LOAD32_LE(k + 4);
+ ctx->input[TR[3]] = LOAD32_LE(k + 8);
+ ctx->input[TR[4]] = LOAD32_LE(k + 12);
+ ctx->input[TR[11]] = LOAD32_LE(k + 16);
+ ctx->input[TR[12]] = LOAD32_LE(k + 20);
+ ctx->input[TR[13]] = LOAD32_LE(k + 24);
+ ctx->input[TR[14]] = LOAD32_LE(k + 28);
+ ctx->input[TR[0]] = 0x61707865;
+ ctx->input[TR[5]] = 0x3320646e;
+ ctx->input[TR[10]] = 0x79622d32;
+ ctx->input[TR[15]] = 0x6b206574;
+}
+
+static void
+salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[TR[6]] = LOAD32_LE(iv + 0);
+ ctx->input[TR[7]] = LOAD32_LE(iv + 4);
+ ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
+ ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
+}
+
+static void
+salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c,
+ unsigned long long bytes)
+{
+ uint32_t * const x = &ctx->input[0];
+
+ if (!bytes) {
+ return; /* LCOV_EXCL_LINE */
+ }
+
+#include "u8.h"
+#include "u4.h"
+#include "u1.h"
+#include "u0.h"
+}
+
+static int
+stream_avx2(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ struct salsa_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8);
+ salsa_keysetup(&ctx, k);
+ salsa_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ salsa20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_avx2_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ struct salsa_ctx ctx;
+ uint8_t ic_bytes[8];
+ uint32_t ic_high;
+ uint32_t ic_low;
+
+ if (!mlen) {
+ return 0;
+ }
+ ic_high = (uint32_t) (ic >> 32);
+ ic_low = (uint32_t) ic;
+ STORE32_LE(&ic_bytes[0], ic_low);
+ STORE32_LE(&ic_bytes[4], ic_high);
+ salsa_keysetup(&ctx, k);
+ salsa_ivsetup(&ctx, n, ic_bytes);
+ salsa20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6int_avx2_implementation = {
+ SODIUM_C99(.stream =) stream_avx2,
+ SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h
new file mode 100644
index 0000000000..0924e9baff
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_salsa20.h"
+#include "crypto_stream_salsa20.h"
+
+extern struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6int_avx2_implementation;
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c
new file mode 100644
index 0000000000..d8e53a6554
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c
@@ -0,0 +1,122 @@
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "private/sse2_64_32.h"
+#include "utils.h"
+
+#ifdef HAVE_EMMINTRIN_H
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# endif
+# include <emmintrin.h>
+
+# include "../stream_salsa20.h"
+# include "salsa20_xmm6int-sse2.h"
+
+# define ROUNDS 20
+
+typedef struct salsa_ctx {
+ uint32_t input[16];
+} salsa_ctx;
+
+static const int TR[16] = {
+ 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3
+};
+
+static void
+salsa_keysetup(salsa_ctx *ctx, const uint8_t *k)
+{
+ ctx->input[TR[1]] = LOAD32_LE(k + 0);
+ ctx->input[TR[2]] = LOAD32_LE(k + 4);
+ ctx->input[TR[3]] = LOAD32_LE(k + 8);
+ ctx->input[TR[4]] = LOAD32_LE(k + 12);
+ ctx->input[TR[11]] = LOAD32_LE(k + 16);
+ ctx->input[TR[12]] = LOAD32_LE(k + 20);
+ ctx->input[TR[13]] = LOAD32_LE(k + 24);
+ ctx->input[TR[14]] = LOAD32_LE(k + 28);
+ ctx->input[TR[0]] = 0x61707865;
+ ctx->input[TR[5]] = 0x3320646e;
+ ctx->input[TR[10]] = 0x79622d32;
+ ctx->input[TR[15]] = 0x6b206574;
+}
+
+static void
+salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
+{
+ ctx->input[TR[6]] = LOAD32_LE(iv + 0);
+ ctx->input[TR[7]] = LOAD32_LE(iv + 4);
+ ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
+ ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
+}
+
+static void
+salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c,
+ unsigned long long bytes)
+{
+ uint32_t * const x = &ctx->input[0];
+
+ if (!bytes) {
+ return; /* LCOV_EXCL_LINE */
+ }
+
+#include "u4.h"
+#include "u1.h"
+#include "u0.h"
+}
+
+static int
+stream_sse2(unsigned char *c, unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+{
+ struct salsa_ctx ctx;
+
+ if (!clen) {
+ return 0;
+ }
+ COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8);
+ salsa_keysetup(&ctx, k);
+ salsa_ivsetup(&ctx, n, NULL);
+ memset(c, 0, clen);
+ salsa20_encrypt_bytes(&ctx, c, c, clen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+static int
+stream_sse2_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n, uint64_t ic,
+ const unsigned char *k)
+{
+ struct salsa_ctx ctx;
+ uint8_t ic_bytes[8];
+ uint32_t ic_high;
+ uint32_t ic_low;
+
+ if (!mlen) {
+ return 0;
+ }
+ ic_high = (uint32_t) (ic >> 32);
+ ic_low = (uint32_t) (ic);
+ STORE32_LE(&ic_bytes[0], ic_low);
+ STORE32_LE(&ic_bytes[4], ic_high);
+ salsa_keysetup(&ctx, k);
+ salsa_ivsetup(&ctx, n, ic_bytes);
+ salsa20_encrypt_bytes(&ctx, m, c, mlen);
+ sodium_memzero(&ctx, sizeof ctx);
+
+ return 0;
+}
+
+struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6int_sse2_implementation = {
+ SODIUM_C99(.stream =) stream_sse2,
+ SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic
+ };
+
+#endif
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h
new file mode 100644
index 0000000000..ed52a8bcbe
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h
@@ -0,0 +1,8 @@
+
+#include <stdint.h>
+
+#include "../stream_salsa20.h"
+#include "crypto_stream_salsa20.h"
+
+extern struct crypto_stream_salsa20_implementation
+ crypto_stream_salsa20_xmm6int_sse2_implementation;
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h
new file mode 100644
index 0000000000..b2d4168058
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h
@@ -0,0 +1,195 @@
+if (bytes > 0) {
+ __m128i diag0 = _mm_loadu_si128((__m128i *) (x + 0));
+ __m128i diag1 = _mm_loadu_si128((__m128i *) (x + 4));
+ __m128i diag2 = _mm_loadu_si128((__m128i *) (x + 8));
+ __m128i diag3 = _mm_loadu_si128((__m128i *) (x + 12));
+ __m128i a0, a1, a2, a3, a4, a5, a6, a7;
+ __m128i b0, b1, b2, b3, b4, b5, b6, b7;
+ uint8_t partialblock[64];
+
+ unsigned int i;
+
+ a0 = diag1;
+ for (i = 0; i < ROUNDS; i += 4) {
+ a0 = _mm_add_epi32(a0, diag0);
+ a1 = diag0;
+ b0 = a0;
+ a0 = _mm_slli_epi32(a0, 7);
+ b0 = _mm_srli_epi32(b0, 25);
+ diag3 = _mm_xor_si128(diag3, a0);
+
+ diag3 = _mm_xor_si128(diag3, b0);
+
+ a1 = _mm_add_epi32(a1, diag3);
+ a2 = diag3;
+ b1 = a1;
+ a1 = _mm_slli_epi32(a1, 9);
+ b1 = _mm_srli_epi32(b1, 23);
+ diag2 = _mm_xor_si128(diag2, a1);
+ diag3 = _mm_shuffle_epi32(diag3, 0x93);
+ diag2 = _mm_xor_si128(diag2, b1);
+
+ a2 = _mm_add_epi32(a2, diag2);
+ a3 = diag2;
+ b2 = a2;
+ a2 = _mm_slli_epi32(a2, 13);
+ b2 = _mm_srli_epi32(b2, 19);
+ diag1 = _mm_xor_si128(diag1, a2);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag1 = _mm_xor_si128(diag1, b2);
+
+ a3 = _mm_add_epi32(a3, diag1);
+ a4 = diag3;
+ b3 = a3;
+ a3 = _mm_slli_epi32(a3, 18);
+ b3 = _mm_srli_epi32(b3, 14);
+ diag0 = _mm_xor_si128(diag0, a3);
+ diag1 = _mm_shuffle_epi32(diag1, 0x39);
+ diag0 = _mm_xor_si128(diag0, b3);
+
+ a4 = _mm_add_epi32(a4, diag0);
+ a5 = diag0;
+ b4 = a4;
+ a4 = _mm_slli_epi32(a4, 7);
+ b4 = _mm_srli_epi32(b4, 25);
+ diag1 = _mm_xor_si128(diag1, a4);
+
+ diag1 = _mm_xor_si128(diag1, b4);
+
+ a5 = _mm_add_epi32(a5, diag1);
+ a6 = diag1;
+ b5 = a5;
+ a5 = _mm_slli_epi32(a5, 9);
+ b5 = _mm_srli_epi32(b5, 23);
+ diag2 = _mm_xor_si128(diag2, a5);
+ diag1 = _mm_shuffle_epi32(diag1, 0x93);
+ diag2 = _mm_xor_si128(diag2, b5);
+
+ a6 = _mm_add_epi32(a6, diag2);
+ a7 = diag2;
+ b6 = a6;
+ a6 = _mm_slli_epi32(a6, 13);
+ b6 = _mm_srli_epi32(b6, 19);
+ diag3 = _mm_xor_si128(diag3, a6);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag3 = _mm_xor_si128(diag3, b6);
+
+ a7 = _mm_add_epi32(a7, diag3);
+ a0 = diag1;
+ b7 = a7;
+ a7 = _mm_slli_epi32(a7, 18);
+ b7 = _mm_srli_epi32(b7, 14);
+ diag0 = _mm_xor_si128(diag0, a7);
+ diag3 = _mm_shuffle_epi32(diag3, 0x39);
+ diag0 = _mm_xor_si128(diag0, b7);
+
+ a0 = _mm_add_epi32(a0, diag0);
+ a1 = diag0;
+ b0 = a0;
+ a0 = _mm_slli_epi32(a0, 7);
+ b0 = _mm_srli_epi32(b0, 25);
+ diag3 = _mm_xor_si128(diag3, a0);
+
+ diag3 = _mm_xor_si128(diag3, b0);
+
+ a1 = _mm_add_epi32(a1, diag3);
+ a2 = diag3;
+ b1 = a1;
+ a1 = _mm_slli_epi32(a1, 9);
+ b1 = _mm_srli_epi32(b1, 23);
+ diag2 = _mm_xor_si128(diag2, a1);
+ diag3 = _mm_shuffle_epi32(diag3, 0x93);
+ diag2 = _mm_xor_si128(diag2, b1);
+
+ a2 = _mm_add_epi32(a2, diag2);
+ a3 = diag2;
+ b2 = a2;
+ a2 = _mm_slli_epi32(a2, 13);
+ b2 = _mm_srli_epi32(b2, 19);
+ diag1 = _mm_xor_si128(diag1, a2);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag1 = _mm_xor_si128(diag1, b2);
+
+ a3 = _mm_add_epi32(a3, diag1);
+ a4 = diag3;
+ b3 = a3;
+ a3 = _mm_slli_epi32(a3, 18);
+ b3 = _mm_srli_epi32(b3, 14);
+ diag0 = _mm_xor_si128(diag0, a3);
+ diag1 = _mm_shuffle_epi32(diag1, 0x39);
+ diag0 = _mm_xor_si128(diag0, b3);
+
+ a4 = _mm_add_epi32(a4, diag0);
+ a5 = diag0;
+ b4 = a4;
+ a4 = _mm_slli_epi32(a4, 7);
+ b4 = _mm_srli_epi32(b4, 25);
+ diag1 = _mm_xor_si128(diag1, a4);
+
+ diag1 = _mm_xor_si128(diag1, b4);
+
+ a5 = _mm_add_epi32(a5, diag1);
+ a6 = diag1;
+ b5 = a5;
+ a5 = _mm_slli_epi32(a5, 9);
+ b5 = _mm_srli_epi32(b5, 23);
+ diag2 = _mm_xor_si128(diag2, a5);
+ diag1 = _mm_shuffle_epi32(diag1, 0x93);
+ diag2 = _mm_xor_si128(diag2, b5);
+
+ a6 = _mm_add_epi32(a6, diag2);
+ a7 = diag2;
+ b6 = a6;
+ a6 = _mm_slli_epi32(a6, 13);
+ b6 = _mm_srli_epi32(b6, 19);
+ diag3 = _mm_xor_si128(diag3, a6);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag3 = _mm_xor_si128(diag3, b6);
+
+ a7 = _mm_add_epi32(a7, diag3);
+ a0 = diag1;
+ b7 = a7;
+ a7 = _mm_slli_epi32(a7, 18);
+ b7 = _mm_srli_epi32(b7, 14);
+ diag0 = _mm_xor_si128(diag0, a7);
+ diag3 = _mm_shuffle_epi32(diag3, 0x39);
+ diag0 = _mm_xor_si128(diag0, b7);
+ }
+
+ diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((__m128i *) (x + 0)));
+ diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((__m128i *) (x + 4)));
+ diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((__m128i *) (x + 8)));
+ diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((__m128i *) (x + 12)));
+
+#define ONEQUAD_SHUFFLE(A, B, C, D) \
+ do { \
+ uint32_t in##A = _mm_cvtsi128_si32(diag0); \
+ uint32_t in##B = _mm_cvtsi128_si32(diag1); \
+ uint32_t in##C = _mm_cvtsi128_si32(diag2); \
+ uint32_t in##D = _mm_cvtsi128_si32(diag3); \
+ diag0 = _mm_shuffle_epi32(diag0, 0x39); \
+ diag1 = _mm_shuffle_epi32(diag1, 0x39); \
+ diag2 = _mm_shuffle_epi32(diag2, 0x39); \
+ diag3 = _mm_shuffle_epi32(diag3, 0x39); \
+ *(uint32_t *) (partialblock + (A * 4)) = in##A; \
+ *(uint32_t *) (partialblock + (B * 4)) = in##B; \
+ *(uint32_t *) (partialblock + (C * 4)) = in##C; \
+ *(uint32_t *) (partialblock + (D * 4)) = in##D; \
+ } while (0)
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D)
+
+ ONEQUAD(0, 12, 8, 4);
+ ONEQUAD(5, 1, 13, 9);
+ ONEQUAD(10, 6, 2, 14);
+ ONEQUAD(15, 11, 7, 3);
+
+#undef ONEQUAD
+#undef ONEQUAD_SHUFFLE
+
+ for (i = 0; i < bytes; i++) {
+ c[i] = m[i] ^ partialblock[i];
+ }
+
+ sodium_memzero(partialblock, sizeof partialblock);
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h
new file mode 100644
index 0000000000..c245d9565f
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h
@@ -0,0 +1,207 @@
+while (bytes >= 64) {
+ __m128i diag0 = _mm_loadu_si128((__m128i *) (x + 0));
+ __m128i diag1 = _mm_loadu_si128((__m128i *) (x + 4));
+ __m128i diag2 = _mm_loadu_si128((__m128i *) (x + 8));
+ __m128i diag3 = _mm_loadu_si128((__m128i *) (x + 12));
+ __m128i a0, a1, a2, a3, a4, a5, a6, a7;
+ __m128i b0, b1, b2, b3, b4, b5, b6, b7;
+
+ uint32_t in8;
+ uint32_t in9;
+ int i;
+
+ a0 = diag1;
+ for (i = 0; i < ROUNDS; i += 4) {
+ a0 = _mm_add_epi32(a0, diag0);
+ a1 = diag0;
+ b0 = a0;
+ a0 = _mm_slli_epi32(a0, 7);
+ b0 = _mm_srli_epi32(b0, 25);
+ diag3 = _mm_xor_si128(diag3, a0);
+
+ diag3 = _mm_xor_si128(diag3, b0);
+
+ a1 = _mm_add_epi32(a1, diag3);
+ a2 = diag3;
+ b1 = a1;
+ a1 = _mm_slli_epi32(a1, 9);
+ b1 = _mm_srli_epi32(b1, 23);
+ diag2 = _mm_xor_si128(diag2, a1);
+ diag3 = _mm_shuffle_epi32(diag3, 0x93);
+ diag2 = _mm_xor_si128(diag2, b1);
+
+ a2 = _mm_add_epi32(a2, diag2);
+ a3 = diag2;
+ b2 = a2;
+ a2 = _mm_slli_epi32(a2, 13);
+ b2 = _mm_srli_epi32(b2, 19);
+ diag1 = _mm_xor_si128(diag1, a2);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag1 = _mm_xor_si128(diag1, b2);
+
+ a3 = _mm_add_epi32(a3, diag1);
+ a4 = diag3;
+ b3 = a3;
+ a3 = _mm_slli_epi32(a3, 18);
+ b3 = _mm_srli_epi32(b3, 14);
+ diag0 = _mm_xor_si128(diag0, a3);
+ diag1 = _mm_shuffle_epi32(diag1, 0x39);
+ diag0 = _mm_xor_si128(diag0, b3);
+
+ a4 = _mm_add_epi32(a4, diag0);
+ a5 = diag0;
+ b4 = a4;
+ a4 = _mm_slli_epi32(a4, 7);
+ b4 = _mm_srli_epi32(b4, 25);
+ diag1 = _mm_xor_si128(diag1, a4);
+
+ diag1 = _mm_xor_si128(diag1, b4);
+
+ a5 = _mm_add_epi32(a5, diag1);
+ a6 = diag1;
+ b5 = a5;
+ a5 = _mm_slli_epi32(a5, 9);
+ b5 = _mm_srli_epi32(b5, 23);
+ diag2 = _mm_xor_si128(diag2, a5);
+ diag1 = _mm_shuffle_epi32(diag1, 0x93);
+ diag2 = _mm_xor_si128(diag2, b5);
+
+ a6 = _mm_add_epi32(a6, diag2);
+ a7 = diag2;
+ b6 = a6;
+ a6 = _mm_slli_epi32(a6, 13);
+ b6 = _mm_srli_epi32(b6, 19);
+ diag3 = _mm_xor_si128(diag3, a6);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag3 = _mm_xor_si128(diag3, b6);
+
+ a7 = _mm_add_epi32(a7, diag3);
+ a0 = diag1;
+ b7 = a7;
+ a7 = _mm_slli_epi32(a7, 18);
+ b7 = _mm_srli_epi32(b7, 14);
+ diag0 = _mm_xor_si128(diag0, a7);
+ diag3 = _mm_shuffle_epi32(diag3, 0x39);
+ diag0 = _mm_xor_si128(diag0, b7);
+
+ a0 = _mm_add_epi32(a0, diag0);
+ a1 = diag0;
+ b0 = a0;
+ a0 = _mm_slli_epi32(a0, 7);
+ b0 = _mm_srli_epi32(b0, 25);
+ diag3 = _mm_xor_si128(diag3, a0);
+
+ diag3 = _mm_xor_si128(diag3, b0);
+
+ a1 = _mm_add_epi32(a1, diag3);
+ a2 = diag3;
+ b1 = a1;
+ a1 = _mm_slli_epi32(a1, 9);
+ b1 = _mm_srli_epi32(b1, 23);
+ diag2 = _mm_xor_si128(diag2, a1);
+ diag3 = _mm_shuffle_epi32(diag3, 0x93);
+ diag2 = _mm_xor_si128(diag2, b1);
+
+ a2 = _mm_add_epi32(a2, diag2);
+ a3 = diag2;
+ b2 = a2;
+ a2 = _mm_slli_epi32(a2, 13);
+ b2 = _mm_srli_epi32(b2, 19);
+ diag1 = _mm_xor_si128(diag1, a2);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag1 = _mm_xor_si128(diag1, b2);
+
+ a3 = _mm_add_epi32(a3, diag1);
+ a4 = diag3;
+ b3 = a3;
+ a3 = _mm_slli_epi32(a3, 18);
+ b3 = _mm_srli_epi32(b3, 14);
+ diag0 = _mm_xor_si128(diag0, a3);
+ diag1 = _mm_shuffle_epi32(diag1, 0x39);
+ diag0 = _mm_xor_si128(diag0, b3);
+
+ a4 = _mm_add_epi32(a4, diag0);
+ a5 = diag0;
+ b4 = a4;
+ a4 = _mm_slli_epi32(a4, 7);
+ b4 = _mm_srli_epi32(b4, 25);
+ diag1 = _mm_xor_si128(diag1, a4);
+
+ diag1 = _mm_xor_si128(diag1, b4);
+
+ a5 = _mm_add_epi32(a5, diag1);
+ a6 = diag1;
+ b5 = a5;
+ a5 = _mm_slli_epi32(a5, 9);
+ b5 = _mm_srli_epi32(b5, 23);
+ diag2 = _mm_xor_si128(diag2, a5);
+ diag1 = _mm_shuffle_epi32(diag1, 0x93);
+ diag2 = _mm_xor_si128(diag2, b5);
+
+ a6 = _mm_add_epi32(a6, diag2);
+ a7 = diag2;
+ b6 = a6;
+ a6 = _mm_slli_epi32(a6, 13);
+ b6 = _mm_srli_epi32(b6, 19);
+ diag3 = _mm_xor_si128(diag3, a6);
+ diag2 = _mm_shuffle_epi32(diag2, 0x4e);
+ diag3 = _mm_xor_si128(diag3, b6);
+
+ a7 = _mm_add_epi32(a7, diag3);
+ a0 = diag1;
+ b7 = a7;
+ a7 = _mm_slli_epi32(a7, 18);
+ b7 = _mm_srli_epi32(b7, 14);
+ diag0 = _mm_xor_si128(diag0, a7);
+ diag3 = _mm_shuffle_epi32(diag3, 0x39);
+ diag0 = _mm_xor_si128(diag0, b7);
+ }
+
+ diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((__m128i *) (x + 0)));
+ diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((__m128i *) (x + 4)));
+ diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((__m128i *) (x + 8)));
+ diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((__m128i *) (x + 12)));
+
+#define ONEQUAD_SHUFFLE(A, B, C, D) \
+ do { \
+ uint32_t in##A = _mm_cvtsi128_si32(diag0); \
+ uint32_t in##B = _mm_cvtsi128_si32(diag1); \
+ uint32_t in##C = _mm_cvtsi128_si32(diag2); \
+ uint32_t in##D = _mm_cvtsi128_si32(diag3); \
+ diag0 = _mm_shuffle_epi32(diag0, 0x39); \
+ diag1 = _mm_shuffle_epi32(diag1, 0x39); \
+ diag2 = _mm_shuffle_epi32(diag2, 0x39); \
+ diag3 = _mm_shuffle_epi32(diag3, 0x39); \
+ in##A ^= *(uint32_t *) (m + (A * 4)); \
+ in##B ^= *(uint32_t *) (m + (B * 4)); \
+ in##C ^= *(uint32_t *) (m + (C * 4)); \
+ in##D ^= *(uint32_t *) (m + (D * 4)); \
+ *(uint32_t *) (c + (A * 4)) = in##A; \
+ *(uint32_t *) (c + (B * 4)) = in##B; \
+ *(uint32_t *) (c + (C * 4)) = in##C; \
+ *(uint32_t *) (c + (D * 4)) = in##D; \
+ } while (0)
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D)
+
+ ONEQUAD(0, 12, 8, 4);
+ ONEQUAD(5, 1, 13, 9);
+ ONEQUAD(10, 6, 2, 14);
+ ONEQUAD(15, 11, 7, 3);
+
+#undef ONEQUAD
+#undef ONEQUAD_SHUFFLE
+
+ in8 = x[8];
+ in9 = x[13];
+ in8++;
+ if (in8 == 0) {
+ in9++;
+ }
+ x[8] = in8;
+ x[13] = in9;
+
+ c += 64;
+ m += 64;
+ bytes -= 64;
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h
new file mode 100644
index 0000000000..61d935fc90
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h
@@ -0,0 +1,547 @@
+if (bytes >= 256) {
+ __m128i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14,
+ y15;
+ __m128i z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14,
+ z15;
+ __m128i orig0, orig1, orig2, orig3, orig4, orig5, orig6, orig7, orig8,
+ orig9, orig10, orig11, orig12, orig13, orig14, orig15;
+
+ uint32_t in8;
+ uint32_t in9;
+ int i;
+
+ /* element broadcast immediate for _mm_shuffle_epi32 are in order:
+ 0x00, 0x55, 0xaa, 0xff */
+ z0 = _mm_loadu_si128((__m128i *) (x + 0));
+ z5 = _mm_shuffle_epi32(z0, 0x55);
+ z10 = _mm_shuffle_epi32(z0, 0xaa);
+ z15 = _mm_shuffle_epi32(z0, 0xff);
+ z0 = _mm_shuffle_epi32(z0, 0x00);
+ z1 = _mm_loadu_si128((__m128i *) (x + 4));
+ z6 = _mm_shuffle_epi32(z1, 0xaa);
+ z11 = _mm_shuffle_epi32(z1, 0xff);
+ z12 = _mm_shuffle_epi32(z1, 0x00);
+ z1 = _mm_shuffle_epi32(z1, 0x55);
+ z2 = _mm_loadu_si128((__m128i *) (x + 8));
+ z7 = _mm_shuffle_epi32(z2, 0xff);
+ z13 = _mm_shuffle_epi32(z2, 0x55);
+ z2 = _mm_shuffle_epi32(z2, 0xaa);
+ /* no z8 -> first half of the nonce, will fill later */
+ z3 = _mm_loadu_si128((__m128i *) (x + 12));
+ z4 = _mm_shuffle_epi32(z3, 0x00);
+ z14 = _mm_shuffle_epi32(z3, 0xaa);
+ z3 = _mm_shuffle_epi32(z3, 0xff);
+ /* no z9 -> second half of the nonce, will fill later */
+ orig0 = z0;
+ orig1 = z1;
+ orig2 = z2;
+ orig3 = z3;
+ orig4 = z4;
+ orig5 = z5;
+ orig6 = z6;
+ orig7 = z7;
+ orig10 = z10;
+ orig11 = z11;
+ orig12 = z12;
+ orig13 = z13;
+ orig14 = z14;
+ orig15 = z15;
+
+ while (bytes >= 256) {
+ /* vector implementation for z8 and z9 */
+ /* not sure if it helps for only 4 blocks */
+ const __m128i addv8 = _mm_set_epi64x(1, 0);
+ const __m128i addv9 = _mm_set_epi64x(3, 2);
+ __m128i t8, t9;
+ uint64_t in89;
+
+ in8 = x[8];
+ in9 = x[13];
+ in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32);
+ t8 = _mm_set1_epi64x(in89);
+ t9 = _mm_set1_epi64x(in89);
+
+ z8 = _mm_add_epi64(addv8, t8);
+ z9 = _mm_add_epi64(addv9, t9);
+
+ t8 = _mm_unpacklo_epi32(z8, z9);
+ t9 = _mm_unpackhi_epi32(z8, z9);
+
+ z8 = _mm_unpacklo_epi32(t8, t9);
+ z9 = _mm_unpackhi_epi32(t8, t9);
+
+ orig8 = z8;
+ orig9 = z9;
+
+ in89 += 4;
+
+ x[8] = in89 & 0xFFFFFFFF;
+ x[13] = (in89 >> 32) & 0xFFFFFFFF;
+
+ z5 = orig5;
+ z10 = orig10;
+ z15 = orig15;
+ z14 = orig14;
+ z3 = orig3;
+ z6 = orig6;
+ z11 = orig11;
+ z1 = orig1;
+
+ z7 = orig7;
+ z13 = orig13;
+ z2 = orig2;
+ z9 = orig9;
+ z0 = orig0;
+ z12 = orig12;
+ z4 = orig4;
+ z8 = orig8;
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ /* the inner loop is a direct translation (regexp search/replace)
+ * from the amd64-xmm6 ASM */
+ __m128i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13,
+ r14, r15;
+
+ y4 = z12;
+ y4 = _mm_add_epi32(y4, z0);
+ r4 = y4;
+ y4 = _mm_slli_epi32(y4, 7);
+ z4 = _mm_xor_si128(z4, y4);
+ r4 = _mm_srli_epi32(r4, 25);
+ z4 = _mm_xor_si128(z4, r4);
+
+ y9 = z1;
+ y9 = _mm_add_epi32(y9, z5);
+ r9 = y9;
+ y9 = _mm_slli_epi32(y9, 7);
+ z9 = _mm_xor_si128(z9, y9);
+ r9 = _mm_srli_epi32(r9, 25);
+ z9 = _mm_xor_si128(z9, r9);
+
+ y8 = z0;
+ y8 = _mm_add_epi32(y8, z4);
+ r8 = y8;
+ y8 = _mm_slli_epi32(y8, 9);
+ z8 = _mm_xor_si128(z8, y8);
+ r8 = _mm_srli_epi32(r8, 23);
+ z8 = _mm_xor_si128(z8, r8);
+
+ y13 = z5;
+ y13 = _mm_add_epi32(y13, z9);
+ r13 = y13;
+ y13 = _mm_slli_epi32(y13, 9);
+ z13 = _mm_xor_si128(z13, y13);
+ r13 = _mm_srli_epi32(r13, 23);
+ z13 = _mm_xor_si128(z13, r13);
+
+ y12 = z4;
+ y12 = _mm_add_epi32(y12, z8);
+ r12 = y12;
+ y12 = _mm_slli_epi32(y12, 13);
+ z12 = _mm_xor_si128(z12, y12);
+ r12 = _mm_srli_epi32(r12, 19);
+ z12 = _mm_xor_si128(z12, r12);
+
+ y1 = z9;
+ y1 = _mm_add_epi32(y1, z13);
+ r1 = y1;
+ y1 = _mm_slli_epi32(y1, 13);
+ z1 = _mm_xor_si128(z1, y1);
+ r1 = _mm_srli_epi32(r1, 19);
+ z1 = _mm_xor_si128(z1, r1);
+
+ y0 = z8;
+ y0 = _mm_add_epi32(y0, z12);
+ r0 = y0;
+ y0 = _mm_slli_epi32(y0, 18);
+ z0 = _mm_xor_si128(z0, y0);
+ r0 = _mm_srli_epi32(r0, 14);
+ z0 = _mm_xor_si128(z0, r0);
+
+ y5 = z13;
+ y5 = _mm_add_epi32(y5, z1);
+ r5 = y5;
+ y5 = _mm_slli_epi32(y5, 18);
+ z5 = _mm_xor_si128(z5, y5);
+ r5 = _mm_srli_epi32(r5, 14);
+ z5 = _mm_xor_si128(z5, r5);
+
+ y14 = z6;
+ y14 = _mm_add_epi32(y14, z10);
+ r14 = y14;
+ y14 = _mm_slli_epi32(y14, 7);
+ z14 = _mm_xor_si128(z14, y14);
+ r14 = _mm_srli_epi32(r14, 25);
+ z14 = _mm_xor_si128(z14, r14);
+
+ y3 = z11;
+ y3 = _mm_add_epi32(y3, z15);
+ r3 = y3;
+ y3 = _mm_slli_epi32(y3, 7);
+ z3 = _mm_xor_si128(z3, y3);
+ r3 = _mm_srli_epi32(r3, 25);
+ z3 = _mm_xor_si128(z3, r3);
+
+ y2 = z10;
+ y2 = _mm_add_epi32(y2, z14);
+ r2 = y2;
+ y2 = _mm_slli_epi32(y2, 9);
+ z2 = _mm_xor_si128(z2, y2);
+ r2 = _mm_srli_epi32(r2, 23);
+ z2 = _mm_xor_si128(z2, r2);
+
+ y7 = z15;
+ y7 = _mm_add_epi32(y7, z3);
+ r7 = y7;
+ y7 = _mm_slli_epi32(y7, 9);
+ z7 = _mm_xor_si128(z7, y7);
+ r7 = _mm_srli_epi32(r7, 23);
+ z7 = _mm_xor_si128(z7, r7);
+
+ y6 = z14;
+ y6 = _mm_add_epi32(y6, z2);
+ r6 = y6;
+ y6 = _mm_slli_epi32(y6, 13);
+ z6 = _mm_xor_si128(z6, y6);
+ r6 = _mm_srli_epi32(r6, 19);
+ z6 = _mm_xor_si128(z6, r6);
+
+ y11 = z3;
+ y11 = _mm_add_epi32(y11, z7);
+ r11 = y11;
+ y11 = _mm_slli_epi32(y11, 13);
+ z11 = _mm_xor_si128(z11, y11);
+ r11 = _mm_srli_epi32(r11, 19);
+ z11 = _mm_xor_si128(z11, r11);
+
+ y10 = z2;
+ y10 = _mm_add_epi32(y10, z6);
+ r10 = y10;
+ y10 = _mm_slli_epi32(y10, 18);
+ z10 = _mm_xor_si128(z10, y10);
+ r10 = _mm_srli_epi32(r10, 14);
+ z10 = _mm_xor_si128(z10, r10);
+
+ y1 = z3;
+ y1 = _mm_add_epi32(y1, z0);
+ r1 = y1;
+ y1 = _mm_slli_epi32(y1, 7);
+ z1 = _mm_xor_si128(z1, y1);
+ r1 = _mm_srli_epi32(r1, 25);
+ z1 = _mm_xor_si128(z1, r1);
+
+ y15 = z7;
+ y15 = _mm_add_epi32(y15, z11);
+ r15 = y15;
+ y15 = _mm_slli_epi32(y15, 18);
+ z15 = _mm_xor_si128(z15, y15);
+ r15 = _mm_srli_epi32(r15, 14);
+ z15 = _mm_xor_si128(z15, r15);
+
+ y6 = z4;
+ y6 = _mm_add_epi32(y6, z5);
+ r6 = y6;
+ y6 = _mm_slli_epi32(y6, 7);
+ z6 = _mm_xor_si128(z6, y6);
+ r6 = _mm_srli_epi32(r6, 25);
+ z6 = _mm_xor_si128(z6, r6);
+
+ y2 = z0;
+ y2 = _mm_add_epi32(y2, z1);
+ r2 = y2;
+ y2 = _mm_slli_epi32(y2, 9);
+ z2 = _mm_xor_si128(z2, y2);
+ r2 = _mm_srli_epi32(r2, 23);
+ z2 = _mm_xor_si128(z2, r2);
+
+ y7 = z5;
+ y7 = _mm_add_epi32(y7, z6);
+ r7 = y7;
+ y7 = _mm_slli_epi32(y7, 9);
+ z7 = _mm_xor_si128(z7, y7);
+ r7 = _mm_srli_epi32(r7, 23);
+ z7 = _mm_xor_si128(z7, r7);
+
+ y3 = z1;
+ y3 = _mm_add_epi32(y3, z2);
+ r3 = y3;
+ y3 = _mm_slli_epi32(y3, 13);
+ z3 = _mm_xor_si128(z3, y3);
+ r3 = _mm_srli_epi32(r3, 19);
+ z3 = _mm_xor_si128(z3, r3);
+
+ y4 = z6;
+ y4 = _mm_add_epi32(y4, z7);
+ r4 = y4;
+ y4 = _mm_slli_epi32(y4, 13);
+ z4 = _mm_xor_si128(z4, y4);
+ r4 = _mm_srli_epi32(r4, 19);
+ z4 = _mm_xor_si128(z4, r4);
+
+ y0 = z2;
+ y0 = _mm_add_epi32(y0, z3);
+ r0 = y0;
+ y0 = _mm_slli_epi32(y0, 18);
+ z0 = _mm_xor_si128(z0, y0);
+ r0 = _mm_srli_epi32(r0, 14);
+ z0 = _mm_xor_si128(z0, r0);
+
+ y5 = z7;
+ y5 = _mm_add_epi32(y5, z4);
+ r5 = y5;
+ y5 = _mm_slli_epi32(y5, 18);
+ z5 = _mm_xor_si128(z5, y5);
+ r5 = _mm_srli_epi32(r5, 14);
+ z5 = _mm_xor_si128(z5, r5);
+
+ y11 = z9;
+ y11 = _mm_add_epi32(y11, z10);
+ r11 = y11;
+ y11 = _mm_slli_epi32(y11, 7);
+ z11 = _mm_xor_si128(z11, y11);
+ r11 = _mm_srli_epi32(r11, 25);
+ z11 = _mm_xor_si128(z11, r11);
+
+ y12 = z14;
+ y12 = _mm_add_epi32(y12, z15);
+ r12 = y12;
+ y12 = _mm_slli_epi32(y12, 7);
+ z12 = _mm_xor_si128(z12, y12);
+ r12 = _mm_srli_epi32(r12, 25);
+ z12 = _mm_xor_si128(z12, r12);
+
+ y8 = z10;
+ y8 = _mm_add_epi32(y8, z11);
+ r8 = y8;
+ y8 = _mm_slli_epi32(y8, 9);
+ z8 = _mm_xor_si128(z8, y8);
+ r8 = _mm_srli_epi32(r8, 23);
+ z8 = _mm_xor_si128(z8, r8);
+
+ y13 = z15;
+ y13 = _mm_add_epi32(y13, z12);
+ r13 = y13;
+ y13 = _mm_slli_epi32(y13, 9);
+ z13 = _mm_xor_si128(z13, y13);
+ r13 = _mm_srli_epi32(r13, 23);
+ z13 = _mm_xor_si128(z13, r13);
+
+ y9 = z11;
+ y9 = _mm_add_epi32(y9, z8);
+ r9 = y9;
+ y9 = _mm_slli_epi32(y9, 13);
+ z9 = _mm_xor_si128(z9, y9);
+ r9 = _mm_srli_epi32(r9, 19);
+ z9 = _mm_xor_si128(z9, r9);
+
+ y14 = z12;
+ y14 = _mm_add_epi32(y14, z13);
+ r14 = y14;
+ y14 = _mm_slli_epi32(y14, 13);
+ z14 = _mm_xor_si128(z14, y14);
+ r14 = _mm_srli_epi32(r14, 19);
+ z14 = _mm_xor_si128(z14, r14);
+
+ y10 = z8;
+ y10 = _mm_add_epi32(y10, z9);
+ r10 = y10;
+ y10 = _mm_slli_epi32(y10, 18);
+ z10 = _mm_xor_si128(z10, y10);
+ r10 = _mm_srli_epi32(r10, 14);
+ z10 = _mm_xor_si128(z10, r10);
+
+ y15 = z13;
+ y15 = _mm_add_epi32(y15, z14);
+ r15 = y15;
+ y15 = _mm_slli_epi32(y15, 18);
+ z15 = _mm_xor_si128(z15, y15);
+ r15 = _mm_srli_epi32(r15, 14);
+ z15 = _mm_xor_si128(z15, r15);
+ }
+
+/* store data ; this macro replicates the original amd64-xmm6 code */
+#define ONEQUAD_SHUFFLE(A, B, C, D) \
+ z##A = _mm_add_epi32(z##A, orig##A); \
+ z##B = _mm_add_epi32(z##B, orig##B); \
+ z##C = _mm_add_epi32(z##C, orig##C); \
+ z##D = _mm_add_epi32(z##D, orig##D); \
+ in##A = _mm_cvtsi128_si32(z##A); \
+ in##B = _mm_cvtsi128_si32(z##B); \
+ in##C = _mm_cvtsi128_si32(z##C); \
+ in##D = _mm_cvtsi128_si32(z##D); \
+ z##A = _mm_shuffle_epi32(z##A, 0x39); \
+ z##B = _mm_shuffle_epi32(z##B, 0x39); \
+ z##C = _mm_shuffle_epi32(z##C, 0x39); \
+ z##D = _mm_shuffle_epi32(z##D, 0x39); \
+ \
+ in##A ^= *(uint32_t *) (m + 0); \
+ in##B ^= *(uint32_t *) (m + 4); \
+ in##C ^= *(uint32_t *) (m + 8); \
+ in##D ^= *(uint32_t *) (m + 12); \
+ \
+ *(uint32_t *) (c + 0) = in##A; \
+ *(uint32_t *) (c + 4) = in##B; \
+ *(uint32_t *) (c + 8) = in##C; \
+ *(uint32_t *) (c + 12) = in##D; \
+ \
+ in##A = _mm_cvtsi128_si32(z##A); \
+ in##B = _mm_cvtsi128_si32(z##B); \
+ in##C = _mm_cvtsi128_si32(z##C); \
+ in##D = _mm_cvtsi128_si32(z##D); \
+ z##A = _mm_shuffle_epi32(z##A, 0x39); \
+ z##B = _mm_shuffle_epi32(z##B, 0x39); \
+ z##C = _mm_shuffle_epi32(z##C, 0x39); \
+ z##D = _mm_shuffle_epi32(z##D, 0x39); \
+ \
+ in##A ^= *(uint32_t *) (m + 64); \
+ in##B ^= *(uint32_t *) (m + 68); \
+ in##C ^= *(uint32_t *) (m + 72); \
+ in##D ^= *(uint32_t *) (m + 76); \
+ *(uint32_t *) (c + 64) = in##A; \
+ *(uint32_t *) (c + 68) = in##B; \
+ *(uint32_t *) (c + 72) = in##C; \
+ *(uint32_t *) (c + 76) = in##D; \
+ \
+ in##A = _mm_cvtsi128_si32(z##A); \
+ in##B = _mm_cvtsi128_si32(z##B); \
+ in##C = _mm_cvtsi128_si32(z##C); \
+ in##D = _mm_cvtsi128_si32(z##D); \
+ z##A = _mm_shuffle_epi32(z##A, 0x39); \
+ z##B = _mm_shuffle_epi32(z##B, 0x39); \
+ z##C = _mm_shuffle_epi32(z##C, 0x39); \
+ z##D = _mm_shuffle_epi32(z##D, 0x39); \
+ \
+ in##A ^= *(uint32_t *) (m + 128); \
+ in##B ^= *(uint32_t *) (m + 132); \
+ in##C ^= *(uint32_t *) (m + 136); \
+ in##D ^= *(uint32_t *) (m + 140); \
+ *(uint32_t *) (c + 128) = in##A; \
+ *(uint32_t *) (c + 132) = in##B; \
+ *(uint32_t *) (c + 136) = in##C; \
+ *(uint32_t *) (c + 140) = in##D; \
+ \
+ in##A = _mm_cvtsi128_si32(z##A); \
+ in##B = _mm_cvtsi128_si32(z##B); \
+ in##C = _mm_cvtsi128_si32(z##C); \
+ in##D = _mm_cvtsi128_si32(z##D); \
+ \
+ in##A ^= *(uint32_t *) (m + 192); \
+ in##B ^= *(uint32_t *) (m + 196); \
+ in##C ^= *(uint32_t *) (m + 200); \
+ in##D ^= *(uint32_t *) (m + 204); \
+ *(uint32_t *) (c + 192) = in##A; \
+ *(uint32_t *) (c + 196) = in##B; \
+ *(uint32_t *) (c + 200) = in##C; \
+ *(uint32_t *) (c + 204) = in##D
+
+/* store data ; this macro replaces shuffle+mov by a direct extract; not much
+ * difference */
+#define ONEQUAD_EXTRACT(A, B, C, D) \
+ z##A = _mm_add_epi32(z##A, orig##A); \
+ z##B = _mm_add_epi32(z##B, orig##B); \
+ z##C = _mm_add_epi32(z##C, orig##C); \
+ z##D = _mm_add_epi32(z##D, orig##D); \
+ in##A = _mm_cvtsi128_si32(z##A); \
+ in##B = _mm_cvtsi128_si32(z##B); \
+ in##C = _mm_cvtsi128_si32(z##C); \
+ in##D = _mm_cvtsi128_si32(z##D); \
+ in##A ^= *(uint32_t *) (m + 0); \
+ in##B ^= *(uint32_t *) (m + 4); \
+ in##C ^= *(uint32_t *) (m + 8); \
+ in##D ^= *(uint32_t *) (m + 12); \
+ *(uint32_t *) (c + 0) = in##A; \
+ *(uint32_t *) (c + 4) = in##B; \
+ *(uint32_t *) (c + 8) = in##C; \
+ *(uint32_t *) (c + 12) = in##D; \
+ \
+ in##A = _mm_extract_epi32(z##A, 1); \
+ in##B = _mm_extract_epi32(z##B, 1); \
+ in##C = _mm_extract_epi32(z##C, 1); \
+ in##D = _mm_extract_epi32(z##D, 1); \
+ \
+ in##A ^= *(uint32_t *) (m + 64); \
+ in##B ^= *(uint32_t *) (m + 68); \
+ in##C ^= *(uint32_t *) (m + 72); \
+ in##D ^= *(uint32_t *) (m + 76); \
+ *(uint32_t *) (c + 64) = in##A; \
+ *(uint32_t *) (c + 68) = in##B; \
+ *(uint32_t *) (c + 72) = in##C; \
+ *(uint32_t *) (c + 76) = in##D; \
+ \
+ in##A = _mm_extract_epi32(z##A, 2); \
+ in##B = _mm_extract_epi32(z##B, 2); \
+ in##C = _mm_extract_epi32(z##C, 2); \
+ in##D = _mm_extract_epi32(z##D, 2); \
+ \
+ in##A ^= *(uint32_t *) (m + 128); \
+ in##B ^= *(uint32_t *) (m + 132); \
+ in##C ^= *(uint32_t *) (m + 136); \
+ in##D ^= *(uint32_t *) (m + 140); \
+ *(uint32_t *) (c + 128) = in##A; \
+ *(uint32_t *) (c + 132) = in##B; \
+ *(uint32_t *) (c + 136) = in##C; \
+ *(uint32_t *) (c + 140) = in##D; \
+ \
+ in##A = _mm_extract_epi32(z##A, 3); \
+ in##B = _mm_extract_epi32(z##B, 3); \
+ in##C = _mm_extract_epi32(z##C, 3); \
+ in##D = _mm_extract_epi32(z##D, 3); \
+ \
+ in##A ^= *(uint32_t *) (m + 192); \
+ in##B ^= *(uint32_t *) (m + 196); \
+ in##C ^= *(uint32_t *) (m + 200); \
+ in##D ^= *(uint32_t *) (m + 204); \
+ *(uint32_t *) (c + 192) = in##A; \
+ *(uint32_t *) (c + 196) = in##B; \
+ *(uint32_t *) (c + 200) = in##C; \
+ *(uint32_t *) (c + 204) = in##D
+
+/* store data ; this macro first transpose data in-registers, and then store
+ * them in memory. much faster with icc. */
+#define ONEQUAD_TRANSPOSE(A, B, C, D) \
+ z##A = _mm_add_epi32(z##A, orig##A); \
+ z##B = _mm_add_epi32(z##B, orig##B); \
+ z##C = _mm_add_epi32(z##C, orig##C); \
+ z##D = _mm_add_epi32(z##D, orig##D); \
+ y##A = _mm_unpacklo_epi32(z##A, z##B); \
+ y##B = _mm_unpacklo_epi32(z##C, z##D); \
+ y##C = _mm_unpackhi_epi32(z##A, z##B); \
+ y##D = _mm_unpackhi_epi32(z##C, z##D); \
+ z##A = _mm_unpacklo_epi64(y##A, y##B); \
+ z##B = _mm_unpackhi_epi64(y##A, y##B); \
+ z##C = _mm_unpacklo_epi64(y##C, y##D); \
+ z##D = _mm_unpackhi_epi64(y##C, y##D); \
+ y##A = _mm_xor_si128(z##A, _mm_loadu_si128((__m128i *) (m + 0))); \
+ _mm_storeu_si128((__m128i *) (c + 0), y##A); \
+ y##B = _mm_xor_si128(z##B, _mm_loadu_si128((__m128i *) (m + 64))); \
+ _mm_storeu_si128((__m128i *) (c + 64), y##B); \
+ y##C = _mm_xor_si128(z##C, _mm_loadu_si128((__m128i *) (m + 128))); \
+ _mm_storeu_si128((__m128i *) (c + 128), y##C); \
+ y##D = _mm_xor_si128(z##D, _mm_loadu_si128((__m128i *) (m + 192))); \
+ _mm_storeu_si128((__m128i *) (c + 192), y##D)
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D)
+
+ ONEQUAD(0, 1, 2, 3);
+ m += 16;
+ c += 16;
+ ONEQUAD(4, 5, 6, 7);
+ m += 16;
+ c += 16;
+ ONEQUAD(8, 9, 10, 11);
+ m += 16;
+ c += 16;
+ ONEQUAD(12, 13, 14, 15);
+ m -= 48;
+ c -= 48;
+
+#undef ONEQUAD
+#undef ONEQUAD_TRANSPOSE
+#undef ONEQUAD_EXTRACT
+#undef ONEQUAD_SHUFFLE
+
+ bytes -= 256;
+ c += 256;
+ m += 256;
+ }
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h
new file mode 100644
index 0000000000..467a961299
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h
@@ -0,0 +1,476 @@
+if (bytes >= 512) {
+ __m256i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14,
+ y15;
+
+ /* the naive way seems as fast (if not a bit faster) than the vector way */
+ __m256i z0 = _mm256_set1_epi32(x[0]);
+ __m256i z5 = _mm256_set1_epi32(x[1]);
+ __m256i z10 = _mm256_set1_epi32(x[2]);
+ __m256i z15 = _mm256_set1_epi32(x[3]);
+ __m256i z12 = _mm256_set1_epi32(x[4]);
+ __m256i z1 = _mm256_set1_epi32(x[5]);
+ __m256i z6 = _mm256_set1_epi32(x[6]);
+ __m256i z11 = _mm256_set1_epi32(x[7]);
+ __m256i z8; /* useless */
+ __m256i z13 = _mm256_set1_epi32(x[9]);
+ __m256i z2 = _mm256_set1_epi32(x[10]);
+ __m256i z7 = _mm256_set1_epi32(x[11]);
+ __m256i z4 = _mm256_set1_epi32(x[12]);
+ __m256i z9; /* useless */
+ __m256i z14 = _mm256_set1_epi32(x[14]);
+ __m256i z3 = _mm256_set1_epi32(x[15]);
+
+ __m256i orig0 = z0;
+ __m256i orig1 = z1;
+ __m256i orig2 = z2;
+ __m256i orig3 = z3;
+ __m256i orig4 = z4;
+ __m256i orig5 = z5;
+ __m256i orig6 = z6;
+ __m256i orig7 = z7;
+ __m256i orig8;
+ __m256i orig9;
+ __m256i orig10 = z10;
+ __m256i orig11 = z11;
+ __m256i orig12 = z12;
+ __m256i orig13 = z13;
+ __m256i orig14 = z14;
+ __m256i orig15 = z15;
+
+ uint32_t in8;
+ uint32_t in9;
+ int i;
+
+ while (bytes >= 512) {
+ /* vector implementation for z8 and z9 */
+ /* faster than the naive version for 8 blocks */
+ const __m256i addv8 = _mm256_set_epi64x(3, 2, 1, 0);
+ const __m256i addv9 = _mm256_set_epi64x(7, 6, 5, 4);
+ const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0);
+
+ __m256i t8, t9;
+ uint64_t in89;
+
+ in8 = x[8];
+ in9 = x[13]; /* see arrays above for the address translation */
+ in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32);
+
+ z8 = z9 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in89));
+
+ t8 = _mm256_add_epi64(addv8, z8);
+ t9 = _mm256_add_epi64(addv9, z9);
+
+ z8 = _mm256_unpacklo_epi32(t8, t9);
+ z9 = _mm256_unpackhi_epi32(t8, t9);
+
+ t8 = _mm256_unpacklo_epi32(z8, z9);
+ t9 = _mm256_unpackhi_epi32(z8, z9);
+
+ /* required because unpack* are intra-lane */
+ z8 = _mm256_permutevar8x32_epi32(t8, permute);
+ z9 = _mm256_permutevar8x32_epi32(t9, permute);
+
+ orig8 = z8;
+ orig9 = z9;
+
+ in89 += 8;
+
+ x[8] = in89 & 0xFFFFFFFF;
+ x[13] = (in89 >> 32) & 0xFFFFFFFF;
+
+ z5 = orig5;
+ z10 = orig10;
+ z15 = orig15;
+ z14 = orig14;
+ z3 = orig3;
+ z6 = orig6;
+ z11 = orig11;
+ z1 = orig1;
+
+ z7 = orig7;
+ z13 = orig13;
+ z2 = orig2;
+ z9 = orig9;
+ z0 = orig0;
+ z12 = orig12;
+ z4 = orig4;
+ z8 = orig8;
+
+ for (i = 0; i < ROUNDS; i += 2) {
+ /* the inner loop is a direct translation (regexp search/replace)
+ * from the amd64-xmm6 ASM */
+ __m256i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13,
+ r14, r15;
+
+ y4 = z12;
+ y4 = _mm256_add_epi32(y4, z0);
+ r4 = y4;
+ y4 = _mm256_slli_epi32(y4, 7);
+ z4 = _mm256_xor_si256(z4, y4);
+ r4 = _mm256_srli_epi32(r4, 25);
+ z4 = _mm256_xor_si256(z4, r4);
+
+ y9 = z1;
+ y9 = _mm256_add_epi32(y9, z5);
+ r9 = y9;
+ y9 = _mm256_slli_epi32(y9, 7);
+ z9 = _mm256_xor_si256(z9, y9);
+ r9 = _mm256_srli_epi32(r9, 25);
+ z9 = _mm256_xor_si256(z9, r9);
+
+ y8 = z0;
+ y8 = _mm256_add_epi32(y8, z4);
+ r8 = y8;
+ y8 = _mm256_slli_epi32(y8, 9);
+ z8 = _mm256_xor_si256(z8, y8);
+ r8 = _mm256_srli_epi32(r8, 23);
+ z8 = _mm256_xor_si256(z8, r8);
+
+ y13 = z5;
+ y13 = _mm256_add_epi32(y13, z9);
+ r13 = y13;
+ y13 = _mm256_slli_epi32(y13, 9);
+ z13 = _mm256_xor_si256(z13, y13);
+ r13 = _mm256_srli_epi32(r13, 23);
+ z13 = _mm256_xor_si256(z13, r13);
+
+ y12 = z4;
+ y12 = _mm256_add_epi32(y12, z8);
+ r12 = y12;
+ y12 = _mm256_slli_epi32(y12, 13);
+ z12 = _mm256_xor_si256(z12, y12);
+ r12 = _mm256_srli_epi32(r12, 19);
+ z12 = _mm256_xor_si256(z12, r12);
+
+ y1 = z9;
+ y1 = _mm256_add_epi32(y1, z13);
+ r1 = y1;
+ y1 = _mm256_slli_epi32(y1, 13);
+ z1 = _mm256_xor_si256(z1, y1);
+ r1 = _mm256_srli_epi32(r1, 19);
+ z1 = _mm256_xor_si256(z1, r1);
+
+ y0 = z8;
+ y0 = _mm256_add_epi32(y0, z12);
+ r0 = y0;
+ y0 = _mm256_slli_epi32(y0, 18);
+ z0 = _mm256_xor_si256(z0, y0);
+ r0 = _mm256_srli_epi32(r0, 14);
+ z0 = _mm256_xor_si256(z0, r0);
+
+ y5 = z13;
+ y5 = _mm256_add_epi32(y5, z1);
+ r5 = y5;
+ y5 = _mm256_slli_epi32(y5, 18);
+ z5 = _mm256_xor_si256(z5, y5);
+ r5 = _mm256_srli_epi32(r5, 14);
+ z5 = _mm256_xor_si256(z5, r5);
+
+ y14 = z6;
+ y14 = _mm256_add_epi32(y14, z10);
+ r14 = y14;
+ y14 = _mm256_slli_epi32(y14, 7);
+ z14 = _mm256_xor_si256(z14, y14);
+ r14 = _mm256_srli_epi32(r14, 25);
+ z14 = _mm256_xor_si256(z14, r14);
+
+ y3 = z11;
+ y3 = _mm256_add_epi32(y3, z15);
+ r3 = y3;
+ y3 = _mm256_slli_epi32(y3, 7);
+ z3 = _mm256_xor_si256(z3, y3);
+ r3 = _mm256_srli_epi32(r3, 25);
+ z3 = _mm256_xor_si256(z3, r3);
+
+ y2 = z10;
+ y2 = _mm256_add_epi32(y2, z14);
+ r2 = y2;
+ y2 = _mm256_slli_epi32(y2, 9);
+ z2 = _mm256_xor_si256(z2, y2);
+ r2 = _mm256_srli_epi32(r2, 23);
+ z2 = _mm256_xor_si256(z2, r2);
+
+ y7 = z15;
+ y7 = _mm256_add_epi32(y7, z3);
+ r7 = y7;
+ y7 = _mm256_slli_epi32(y7, 9);
+ z7 = _mm256_xor_si256(z7, y7);
+ r7 = _mm256_srli_epi32(r7, 23);
+ z7 = _mm256_xor_si256(z7, r7);
+
+ y6 = z14;
+ y6 = _mm256_add_epi32(y6, z2);
+ r6 = y6;
+ y6 = _mm256_slli_epi32(y6, 13);
+ z6 = _mm256_xor_si256(z6, y6);
+ r6 = _mm256_srli_epi32(r6, 19);
+ z6 = _mm256_xor_si256(z6, r6);
+
+ y11 = z3;
+ y11 = _mm256_add_epi32(y11, z7);
+ r11 = y11;
+ y11 = _mm256_slli_epi32(y11, 13);
+ z11 = _mm256_xor_si256(z11, y11);
+ r11 = _mm256_srli_epi32(r11, 19);
+ z11 = _mm256_xor_si256(z11, r11);
+
+ y10 = z2;
+ y10 = _mm256_add_epi32(y10, z6);
+ r10 = y10;
+ y10 = _mm256_slli_epi32(y10, 18);
+ z10 = _mm256_xor_si256(z10, y10);
+ r10 = _mm256_srli_epi32(r10, 14);
+ z10 = _mm256_xor_si256(z10, r10);
+
+ y1 = z3;
+ y1 = _mm256_add_epi32(y1, z0);
+ r1 = y1;
+ y1 = _mm256_slli_epi32(y1, 7);
+ z1 = _mm256_xor_si256(z1, y1);
+ r1 = _mm256_srli_epi32(r1, 25);
+ z1 = _mm256_xor_si256(z1, r1);
+
+ y15 = z7;
+ y15 = _mm256_add_epi32(y15, z11);
+ r15 = y15;
+ y15 = _mm256_slli_epi32(y15, 18);
+ z15 = _mm256_xor_si256(z15, y15);
+ r15 = _mm256_srli_epi32(r15, 14);
+ z15 = _mm256_xor_si256(z15, r15);
+
+ y6 = z4;
+ y6 = _mm256_add_epi32(y6, z5);
+ r6 = y6;
+ y6 = _mm256_slli_epi32(y6, 7);
+ z6 = _mm256_xor_si256(z6, y6);
+ r6 = _mm256_srli_epi32(r6, 25);
+ z6 = _mm256_xor_si256(z6, r6);
+
+ y2 = z0;
+ y2 = _mm256_add_epi32(y2, z1);
+ r2 = y2;
+ y2 = _mm256_slli_epi32(y2, 9);
+ z2 = _mm256_xor_si256(z2, y2);
+ r2 = _mm256_srli_epi32(r2, 23);
+ z2 = _mm256_xor_si256(z2, r2);
+
+ y7 = z5;
+ y7 = _mm256_add_epi32(y7, z6);
+ r7 = y7;
+ y7 = _mm256_slli_epi32(y7, 9);
+ z7 = _mm256_xor_si256(z7, y7);
+ r7 = _mm256_srli_epi32(r7, 23);
+ z7 = _mm256_xor_si256(z7, r7);
+
+ y3 = z1;
+ y3 = _mm256_add_epi32(y3, z2);
+ r3 = y3;
+ y3 = _mm256_slli_epi32(y3, 13);
+ z3 = _mm256_xor_si256(z3, y3);
+ r3 = _mm256_srli_epi32(r3, 19);
+ z3 = _mm256_xor_si256(z3, r3);
+
+ y4 = z6;
+ y4 = _mm256_add_epi32(y4, z7);
+ r4 = y4;
+ y4 = _mm256_slli_epi32(y4, 13);
+ z4 = _mm256_xor_si256(z4, y4);
+ r4 = _mm256_srli_epi32(r4, 19);
+ z4 = _mm256_xor_si256(z4, r4);
+
+ y0 = z2;
+ y0 = _mm256_add_epi32(y0, z3);
+ r0 = y0;
+ y0 = _mm256_slli_epi32(y0, 18);
+ z0 = _mm256_xor_si256(z0, y0);
+ r0 = _mm256_srli_epi32(r0, 14);
+ z0 = _mm256_xor_si256(z0, r0);
+
+ y5 = z7;
+ y5 = _mm256_add_epi32(y5, z4);
+ r5 = y5;
+ y5 = _mm256_slli_epi32(y5, 18);
+ z5 = _mm256_xor_si256(z5, y5);
+ r5 = _mm256_srli_epi32(r5, 14);
+ z5 = _mm256_xor_si256(z5, r5);
+
+ y11 = z9;
+ y11 = _mm256_add_epi32(y11, z10);
+ r11 = y11;
+ y11 = _mm256_slli_epi32(y11, 7);
+ z11 = _mm256_xor_si256(z11, y11);
+ r11 = _mm256_srli_epi32(r11, 25);
+ z11 = _mm256_xor_si256(z11, r11);
+
+ y12 = z14;
+ y12 = _mm256_add_epi32(y12, z15);
+ r12 = y12;
+ y12 = _mm256_slli_epi32(y12, 7);
+ z12 = _mm256_xor_si256(z12, y12);
+ r12 = _mm256_srli_epi32(r12, 25);
+ z12 = _mm256_xor_si256(z12, r12);
+
+ y8 = z10;
+ y8 = _mm256_add_epi32(y8, z11);
+ r8 = y8;
+ y8 = _mm256_slli_epi32(y8, 9);
+ z8 = _mm256_xor_si256(z8, y8);
+ r8 = _mm256_srli_epi32(r8, 23);
+ z8 = _mm256_xor_si256(z8, r8);
+
+ y13 = z15;
+ y13 = _mm256_add_epi32(y13, z12);
+ r13 = y13;
+ y13 = _mm256_slli_epi32(y13, 9);
+ z13 = _mm256_xor_si256(z13, y13);
+ r13 = _mm256_srli_epi32(r13, 23);
+ z13 = _mm256_xor_si256(z13, r13);
+
+ y9 = z11;
+ y9 = _mm256_add_epi32(y9, z8);
+ r9 = y9;
+ y9 = _mm256_slli_epi32(y9, 13);
+ z9 = _mm256_xor_si256(z9, y9);
+ r9 = _mm256_srli_epi32(r9, 19);
+ z9 = _mm256_xor_si256(z9, r9);
+
+ y14 = z12;
+ y14 = _mm256_add_epi32(y14, z13);
+ r14 = y14;
+ y14 = _mm256_slli_epi32(y14, 13);
+ z14 = _mm256_xor_si256(z14, y14);
+ r14 = _mm256_srli_epi32(r14, 19);
+ z14 = _mm256_xor_si256(z14, r14);
+
+ y10 = z8;
+ y10 = _mm256_add_epi32(y10, z9);
+ r10 = y10;
+ y10 = _mm256_slli_epi32(y10, 18);
+ z10 = _mm256_xor_si256(z10, y10);
+ r10 = _mm256_srli_epi32(r10, 14);
+ z10 = _mm256_xor_si256(z10, r10);
+
+ y15 = z13;
+ y15 = _mm256_add_epi32(y15, z14);
+ r15 = y15;
+ y15 = _mm256_slli_epi32(y15, 18);
+ z15 = _mm256_xor_si256(z15, y15);
+ r15 = _mm256_srli_epi32(r15, 14);
+ z15 = _mm256_xor_si256(z15, r15);
+ }
+
+/* store data ; this macro first transpose data in-registers, and then store
+ * them in memory. much faster with icc. */
+#define ONEQUAD_TRANSPOSE(A, B, C, D) \
+ { \
+ __m128i t0, t1, t2, t3; \
+ z##A = _mm256_add_epi32(z##A, orig##A); \
+ z##B = _mm256_add_epi32(z##B, orig##B); \
+ z##C = _mm256_add_epi32(z##C, orig##C); \
+ z##D = _mm256_add_epi32(z##D, orig##D); \
+ y##A = _mm256_unpacklo_epi32(z##A, z##B); \
+ y##B = _mm256_unpacklo_epi32(z##C, z##D); \
+ y##C = _mm256_unpackhi_epi32(z##A, z##B); \
+ y##D = _mm256_unpackhi_epi32(z##C, z##D); \
+ z##A = _mm256_unpacklo_epi64(y##A, y##B); \
+ z##B = _mm256_unpackhi_epi64(y##A, y##B); \
+ z##C = _mm256_unpacklo_epi64(y##C, y##D); \
+ z##D = _mm256_unpackhi_epi64(y##C, y##D); \
+ t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 0), \
+ _mm_loadu_si128((__m128i*) (m + 0))); \
+ _mm_storeu_si128((__m128i*) (c + 0), t0); \
+ t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 0), \
+ _mm_loadu_si128((__m128i*) (m + 64))); \
+ _mm_storeu_si128((__m128i*) (c + 64), t1); \
+ t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 0), \
+ _mm_loadu_si128((__m128i*) (m + 128))); \
+ _mm_storeu_si128((__m128i*) (c + 128), t2); \
+ t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 0), \
+ _mm_loadu_si128((__m128i*) (m + 192))); \
+ _mm_storeu_si128((__m128i*) (c + 192), t3); \
+ t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 1), \
+ _mm_loadu_si128((__m128i*) (m + 256))); \
+ _mm_storeu_si128((__m128i*) (c + 256), t0); \
+ t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 1), \
+ _mm_loadu_si128((__m128i*) (m + 320))); \
+ _mm_storeu_si128((__m128i*) (c + 320), t1); \
+ t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 1), \
+ _mm_loadu_si128((__m128i*) (m + 384))); \
+ _mm_storeu_si128((__m128i*) (c + 384), t2); \
+ t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 1), \
+ _mm_loadu_si128((__m128i*) (m + 448))); \
+ _mm_storeu_si128((__m128i*) (c + 448), t3); \
+ }
+
+#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D)
+
+#define ONEQUAD_UNPCK(A, B, C, D) \
+ { \
+ z##A = _mm256_add_epi32(z##A, orig##A); \
+ z##B = _mm256_add_epi32(z##B, orig##B); \
+ z##C = _mm256_add_epi32(z##C, orig##C); \
+ z##D = _mm256_add_epi32(z##D, orig##D); \
+ y##A = _mm256_unpacklo_epi32(z##A, z##B); \
+ y##B = _mm256_unpacklo_epi32(z##C, z##D); \
+ y##C = _mm256_unpackhi_epi32(z##A, z##B); \
+ y##D = _mm256_unpackhi_epi32(z##C, z##D); \
+ z##A = _mm256_unpacklo_epi64(y##A, y##B); \
+ z##B = _mm256_unpackhi_epi64(y##A, y##B); \
+ z##C = _mm256_unpacklo_epi64(y##C, y##D); \
+ z##D = _mm256_unpackhi_epi64(y##C, y##D); \
+ }
+
+#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \
+ { \
+ ONEQUAD_UNPCK(A, B, C, D); \
+ ONEQUAD_UNPCK(A2, B2, C2, D2); \
+ y##A = _mm256_permute2x128_si256(z##A, z##A2, 0x20); \
+ y##A2 = _mm256_permute2x128_si256(z##A, z##A2, 0x31); \
+ y##B = _mm256_permute2x128_si256(z##B, z##B2, 0x20); \
+ y##B2 = _mm256_permute2x128_si256(z##B, z##B2, 0x31); \
+ y##C = _mm256_permute2x128_si256(z##C, z##C2, 0x20); \
+ y##C2 = _mm256_permute2x128_si256(z##C, z##C2, 0x31); \
+ y##D = _mm256_permute2x128_si256(z##D, z##D2, 0x20); \
+ y##D2 = _mm256_permute2x128_si256(z##D, z##D2, 0x31); \
+ y##A = _mm256_xor_si256(y##A, _mm256_loadu_si256((__m256i*) (m + 0))); \
+ y##B = \
+ _mm256_xor_si256(y##B, _mm256_loadu_si256((__m256i*) (m + 64))); \
+ y##C = \
+ _mm256_xor_si256(y##C, _mm256_loadu_si256((__m256i*) (m + 128))); \
+ y##D = \
+ _mm256_xor_si256(y##D, _mm256_loadu_si256((__m256i*) (m + 192))); \
+ y##A2 = \
+ _mm256_xor_si256(y##A2, _mm256_loadu_si256((__m256i*) (m + 256))); \
+ y##B2 = \
+ _mm256_xor_si256(y##B2, _mm256_loadu_si256((__m256i*) (m + 320))); \
+ y##C2 = \
+ _mm256_xor_si256(y##C2, _mm256_loadu_si256((__m256i*) (m + 384))); \
+ y##D2 = \
+ _mm256_xor_si256(y##D2, _mm256_loadu_si256((__m256i*) (m + 448))); \
+ _mm256_storeu_si256((__m256i*) (c + 0), y##A); \
+ _mm256_storeu_si256((__m256i*) (c + 64), y##B); \
+ _mm256_storeu_si256((__m256i*) (c + 128), y##C); \
+ _mm256_storeu_si256((__m256i*) (c + 192), y##D); \
+ _mm256_storeu_si256((__m256i*) (c + 256), y##A2); \
+ _mm256_storeu_si256((__m256i*) (c + 320), y##B2); \
+ _mm256_storeu_si256((__m256i*) (c + 384), y##C2); \
+ _mm256_storeu_si256((__m256i*) (c + 448), y##D2); \
+ }
+
+ ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7);
+ m += 32;
+ c += 32;
+ ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15);
+ m -= 32;
+ c -= 32;
+
+#undef ONEQUAD
+#undef ONEQUAD_TRANSPOSE
+#undef ONEQUAD_UNPCK
+#undef ONEOCTO
+
+ bytes -= 512;
+ c += 512;
+ m += 512;
+ }
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c b/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c
new file mode 100644
index 0000000000..bfdfeedba3
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c
@@ -0,0 +1,106 @@
+/*
+version 20140420
+D. J. Bernstein
+Public domain.
+*/
+
+#include <stdint.h>
+
+#include "crypto_core_salsa2012.h"
+#include "crypto_stream_salsa2012.h"
+#include "utils.h"
+
+int
+crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!clen) {
+ return 0;
+ }
+ for (i = 0; i < 32; ++i) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; ++i) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; ++i) {
+ in[i] = 0;
+ }
+ while (clen >= 64) {
+ crypto_core_salsa2012(c, in, kcopy, NULL);
+ u = 1;
+ for (i = 8; i < 16; ++i) {
+ u += (unsigned int)in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ clen -= 64;
+ c += 64;
+ }
+ if (clen) {
+ crypto_core_salsa2012(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int)clen; ++i) {
+ c[i] = block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
+
+int
+crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!mlen) {
+ return 0;
+ }
+ for (i = 0; i < 32; ++i) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; ++i) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; ++i) {
+ in[i] = 0;
+ }
+ while (mlen >= 64) {
+ crypto_core_salsa2012(block, in, kcopy, NULL);
+ for (i = 0; i < 64; ++i) {
+ c[i] = m[i] ^ block[i];
+ }
+ u = 1;
+ for (i = 8; i < 16; ++i) {
+ u += (unsigned int)in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ mlen -= 64;
+ c += 64;
+ m += 64;
+ }
+ if (mlen) {
+ crypto_core_salsa2012(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int)mlen; ++i) {
+ c[i] = m[i] ^ block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c b/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c
new file mode 100644
index 0000000000..d0cc0f68ee
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c
@@ -0,0 +1,26 @@
+#include "crypto_stream_salsa2012.h"
+#include "randombytes.h"
+
+size_t
+crypto_stream_salsa2012_keybytes(void)
+{
+ return crypto_stream_salsa2012_KEYBYTES;
+}
+
+size_t
+crypto_stream_salsa2012_noncebytes(void)
+{
+ return crypto_stream_salsa2012_NONCEBYTES;
+}
+
+size_t
+crypto_stream_salsa2012_messagebytes_max(void)
+{
+ return crypto_stream_salsa2012_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_salsa2012_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c b/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c
new file mode 100644
index 0000000000..7ec0c4e78e
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c
@@ -0,0 +1,106 @@
+/*
+version 20140420
+D. J. Bernstein
+Public domain.
+*/
+
+#include <stdint.h>
+
+#include "crypto_core_salsa208.h"
+#include "crypto_stream_salsa208.h"
+#include "utils.h"
+
+int
+crypto_stream_salsa208(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!clen) {
+ return 0;
+ }
+ for (i = 0; i < 32; ++i) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; ++i) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; ++i) {
+ in[i] = 0;
+ }
+ while (clen >= 64) {
+ crypto_core_salsa208(c, in, kcopy, NULL);
+ u = 1;
+ for (i = 8; i < 16; ++i) {
+ u += (unsigned int)in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ clen -= 64;
+ c += 64;
+ }
+ if (clen) {
+ crypto_core_salsa208(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int)clen; ++i) {
+ c[i] = block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
+
+int
+crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ unsigned char in[16];
+ unsigned char block[64];
+ unsigned char kcopy[32];
+ unsigned int i;
+ unsigned int u;
+
+ if (!mlen) {
+ return 0;
+ }
+ for (i = 0; i < 32; ++i) {
+ kcopy[i] = k[i];
+ }
+ for (i = 0; i < 8; ++i) {
+ in[i] = n[i];
+ }
+ for (i = 8; i < 16; ++i) {
+ in[i] = 0;
+ }
+ while (mlen >= 64) {
+ crypto_core_salsa208(block, in, kcopy, NULL);
+ for (i = 0; i < 64; ++i) {
+ c[i] = m[i] ^ block[i];
+ }
+ u = 1;
+ for (i = 8; i < 16; ++i) {
+ u += (unsigned int)in[i];
+ in[i] = u;
+ u >>= 8;
+ }
+ mlen -= 64;
+ c += 64;
+ m += 64;
+ }
+ if (mlen) {
+ crypto_core_salsa208(block, in, kcopy, NULL);
+ for (i = 0; i < (unsigned int)mlen; ++i) {
+ c[i] = m[i] ^ block[i];
+ }
+ }
+ sodium_memzero(block, sizeof block);
+ sodium_memzero(kcopy, sizeof kcopy);
+
+ return 0;
+}
diff --git a/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c b/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c
new file mode 100644
index 0000000000..b79bda5ec2
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c
@@ -0,0 +1,26 @@
+#include "crypto_stream_salsa208.h"
+#include "randombytes.h"
+
+size_t
+crypto_stream_salsa208_keybytes(void)
+{
+ return crypto_stream_salsa208_KEYBYTES;
+}
+
+size_t
+crypto_stream_salsa208_noncebytes(void)
+{
+ return crypto_stream_salsa208_NONCEBYTES;
+}
+
+size_t
+crypto_stream_salsa208_messagebytes_max(void)
+{
+ return crypto_stream_salsa208_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_salsa208_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c
new file mode 100644
index 0000000000..8b1bc09abd
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c
@@ -0,0 +1,69 @@
+
+#include <stdlib.h>
+
+#include "crypto_core_hchacha20.h"
+#include "crypto_stream_chacha20.h"
+#include "crypto_stream_xchacha20.h"
+#include "private/common.h"
+#include "randombytes.h"
+
+size_t
+crypto_stream_xchacha20_keybytes(void)
+{
+ return crypto_stream_xchacha20_KEYBYTES;
+}
+
+size_t
+crypto_stream_xchacha20_noncebytes(void)
+{
+ return crypto_stream_xchacha20_NONCEBYTES;
+}
+
+size_t
+crypto_stream_xchacha20_messagebytes_max(void)
+{
+ return crypto_stream_xchacha20_MESSAGEBYTES_MAX;
+}
+
+int
+crypto_stream_xchacha20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
+
+ crypto_core_hchacha20(k2, n, k, NULL);
+ COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES <= sizeof k2);
+ COMPILER_ASSERT(crypto_stream_chacha20_NONCEBYTES ==
+ crypto_stream_xchacha20_NONCEBYTES -
+ crypto_core_hchacha20_INPUTBYTES);
+
+ return crypto_stream_chacha20(c, clen, n + crypto_core_hchacha20_INPUTBYTES,
+ k2);
+}
+
+int
+crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ uint64_t ic, const unsigned char *k)
+{
+ unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
+
+ crypto_core_hchacha20(k2, n, k, NULL);
+ return crypto_stream_chacha20_xor_ic(
+ c, m, mlen, n + crypto_core_hchacha20_INPUTBYTES, ic, k2);
+}
+
+int
+crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_stream_xchacha20_xor_ic(c, m, mlen, n, 0U, k);
+}
+
+void
+crypto_stream_xchacha20_keygen(
+ unsigned char k[crypto_stream_xchacha20_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_xchacha20_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c b/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c
new file mode 100644
index 0000000000..dc831a94d8
--- /dev/null
+++ b/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c
@@ -0,0 +1,66 @@
+#include "crypto_core_hsalsa20.h"
+#include "crypto_stream_salsa20.h"
+#include "crypto_stream_xsalsa20.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+{
+ unsigned char subkey[32];
+ int ret;
+
+ crypto_core_hsalsa20(subkey, n, k, NULL);
+ ret = crypto_stream_salsa20(c, clen, n + 16, subkey);
+ sodium_memzero(subkey, sizeof subkey);
+
+ return ret;
+}
+
+int
+crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ uint64_t ic, const unsigned char *k)
+{
+ unsigned char subkey[32];
+ int ret;
+
+ crypto_core_hsalsa20(subkey, n, k, NULL);
+ ret = crypto_stream_salsa20_xor_ic(c, m, mlen, n + 16, ic, subkey);
+ sodium_memzero(subkey, sizeof subkey);
+
+ return ret;
+}
+
+int
+crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+{
+ return crypto_stream_xsalsa20_xor_ic(c, m, mlen, n, 0ULL, k);
+}
+
+size_t
+crypto_stream_xsalsa20_keybytes(void)
+{
+ return crypto_stream_xsalsa20_KEYBYTES;
+}
+
+size_t
+crypto_stream_xsalsa20_noncebytes(void)
+{
+ return crypto_stream_xsalsa20_NONCEBYTES;
+}
+
+size_t
+crypto_stream_xsalsa20_messagebytes_max(void)
+{
+ return crypto_stream_xsalsa20_MESSAGEBYTES_MAX;
+}
+
+void
+crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES])
+{
+ randombytes_buf(k, crypto_stream_xsalsa20_KEYBYTES);
+}
diff --git a/libs/libsodium/src/crypto_verify/sodium/verify.c b/libs/libsodium/src/crypto_verify/sodium/verify.c
new file mode 100644
index 0000000000..ffebf220a0
--- /dev/null
+++ b/libs/libsodium/src/crypto_verify/sodium/verify.c
@@ -0,0 +1,98 @@
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "crypto_verify_16.h"
+#include "crypto_verify_32.h"
+#include "crypto_verify_64.h"
+
+size_t
+crypto_verify_16_bytes(void)
+{
+ return crypto_verify_16_BYTES;
+}
+
+size_t
+crypto_verify_32_bytes(void)
+{
+ return crypto_verify_32_BYTES;
+}
+
+size_t
+crypto_verify_64_bytes(void)
+{
+ return crypto_verify_64_BYTES;
+}
+
+#if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__)
+
+# ifdef __GNUC__
+# pragma GCC target("sse2")
+# endif
+# include <emmintrin.h>
+
+static inline int
+crypto_verify_n(const unsigned char *x_, const unsigned char *y_,
+ const int n)
+{
+ const __m128i zero = _mm_setzero_si128();
+ volatile __m128i v1, v2, z;
+ volatile int m;
+ int i;
+
+ const volatile __m128i *volatile x =
+ (const volatile __m128i *volatile) (const void *) x_;
+ const volatile __m128i *volatile y =
+ (const volatile __m128i *volatile) (const void *) y_;
+ v1 = _mm_loadu_si128((const __m128i *) &x[0]);
+ v2 = _mm_loadu_si128((const __m128i *) &y[0]);
+ z = _mm_xor_si128(v1, v2);
+ for (i = 1; i < n / 16; i++) {
+ v1 = _mm_loadu_si128((const __m128i *) &x[i]);
+ v2 = _mm_loadu_si128((const __m128i *) &y[i]);
+ z = _mm_or_si128(z, _mm_xor_si128(v1, v2));
+ }
+ m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero));
+ v1 = zero; v2 = zero; z = zero;
+
+ return (int) (((uint32_t) m + 1U) >> 16) - 1;
+}
+
+#else
+
+static inline int
+crypto_verify_n(const unsigned char *x_, const unsigned char *y_,
+ const int n)
+{
+ const volatile unsigned char *volatile x =
+ (const volatile unsigned char *volatile) x_;
+ const volatile unsigned char *volatile y =
+ (const volatile unsigned char *volatile) y_;
+ volatile uint_fast16_t d = 0U;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ d |= x[i] ^ y[i];
+ }
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+
+#endif
+
+int
+crypto_verify_16(const unsigned char *x, const unsigned char *y)
+{
+ return crypto_verify_n(x, y, crypto_verify_16_BYTES);
+}
+
+int
+crypto_verify_32(const unsigned char *x, const unsigned char *y)
+{
+ return crypto_verify_n(x, y, crypto_verify_32_BYTES);
+}
+
+int
+crypto_verify_64(const unsigned char *x, const unsigned char *y)
+{
+ return crypto_verify_n(x, y, crypto_verify_64_BYTES);
+}
diff --git a/libs/libsodium/src/include/Makefile.am b/libs/libsodium/src/include/Makefile.am
new file mode 100644
index 0000000000..b70c22b39b
--- /dev/null
+++ b/libs/libsodium/src/include/Makefile.am
@@ -0,0 +1,75 @@
+
+SODIUM_EXPORT = \
+ sodium.h \
+ sodium/core.h \
+ sodium/crypto_aead_aes256gcm.h \
+ sodium/crypto_aead_chacha20poly1305.h \
+ sodium/crypto_aead_xchacha20poly1305.h \
+ sodium/crypto_auth.h \
+ sodium/crypto_auth_hmacsha256.h \
+ sodium/crypto_auth_hmacsha512.h \
+ sodium/crypto_auth_hmacsha512256.h \
+ sodium/crypto_box.h \
+ sodium/crypto_box_curve25519xchacha20poly1305.h \
+ sodium/crypto_box_curve25519xsalsa20poly1305.h \
+ sodium/crypto_core_ed25519.h \
+ sodium/crypto_core_hchacha20.h \
+ sodium/crypto_core_hsalsa20.h \
+ sodium/crypto_core_salsa20.h \
+ sodium/crypto_core_salsa2012.h \
+ sodium/crypto_core_salsa208.h \
+ sodium/crypto_generichash.h \
+ sodium/crypto_generichash_blake2b.h \
+ sodium/crypto_hash.h \
+ sodium/crypto_hash_sha256.h \
+ sodium/crypto_hash_sha512.h \
+ sodium/crypto_kdf.h \
+ sodium/crypto_kdf_blake2b.h \
+ sodium/crypto_kx.h \
+ sodium/crypto_onetimeauth.h \
+ sodium/crypto_onetimeauth_poly1305.h \
+ sodium/crypto_pwhash.h \
+ sodium/crypto_pwhash_argon2i.h \
+ sodium/crypto_pwhash_argon2id.h \
+ sodium/crypto_pwhash_scryptsalsa208sha256.h \
+ sodium/crypto_scalarmult.h \
+ sodium/crypto_scalarmult_curve25519.h \
+ sodium/crypto_scalarmult_ed25519.h \
+ sodium/crypto_secretbox.h \
+ sodium/crypto_secretbox_xchacha20poly1305.h \
+ sodium/crypto_secretbox_xsalsa20poly1305.h \
+ sodium/crypto_secretstream_xchacha20poly1305.h \
+ sodium/crypto_shorthash.h \
+ sodium/crypto_shorthash_siphash24.h \
+ sodium/crypto_sign.h \
+ sodium/crypto_sign_ed25519.h \
+ sodium/crypto_sign_edwards25519sha512batch.h \
+ sodium/crypto_stream.h \
+ sodium/crypto_stream_chacha20.h \
+ sodium/crypto_stream_salsa20.h \
+ sodium/crypto_stream_salsa2012.h \
+ sodium/crypto_stream_salsa208.h \
+ sodium/crypto_stream_xchacha20.h \
+ sodium/crypto_stream_xsalsa20.h \
+ sodium/crypto_verify_16.h \
+ sodium/crypto_verify_32.h \
+ sodium/crypto_verify_64.h \
+ sodium/export.h \
+ sodium/randombytes.h \
+ sodium/randombytes_salsa20_random.h \
+ sodium/randombytes_sysrandom.h \
+ sodium/runtime.h \
+ sodium/utils.h
+
+if NATIVECLIENT
+SODIUM_EXPORT += \
+ sodium/randombytes_nativeclient.h
+endif
+
+EXTRA_SRC = $(SODIUM_EXPORT) \
+ sodium/version.h.in
+
+nobase_include_HEADERS = $(SODIUM_EXPORT)
+
+nobase_nodist_include_HEADERS = \
+ sodium/version.h
diff --git a/libs/libsodium/src/include/sodium.h b/libs/libsodium/src/include/sodium.h
new file mode 100644
index 0000000000..e7b1af46f0
--- /dev/null
+++ b/libs/libsodium/src/include/sodium.h
@@ -0,0 +1,70 @@
+
+#ifndef sodium_H
+#define sodium_H
+
+#include "sodium/version.h"
+
+#include "sodium/core.h"
+#include "sodium/crypto_aead_aes256gcm.h"
+#include "sodium/crypto_aead_chacha20poly1305.h"
+#include "sodium/crypto_aead_xchacha20poly1305.h"
+#include "sodium/crypto_auth.h"
+#include "sodium/crypto_auth_hmacsha256.h"
+#include "sodium/crypto_auth_hmacsha512.h"
+#include "sodium/crypto_auth_hmacsha512256.h"
+#include "sodium/crypto_box.h"
+#include "sodium/crypto_box_curve25519xsalsa20poly1305.h"
+#include "sodium/crypto_core_hsalsa20.h"
+#include "sodium/crypto_core_hchacha20.h"
+#include "sodium/crypto_core_salsa20.h"
+#include "sodium/crypto_core_salsa2012.h"
+#include "sodium/crypto_core_salsa208.h"
+#include "sodium/crypto_generichash.h"
+#include "sodium/crypto_generichash_blake2b.h"
+#include "sodium/crypto_hash.h"
+#include "sodium/crypto_hash_sha256.h"
+#include "sodium/crypto_hash_sha512.h"
+#include "sodium/crypto_kdf.h"
+#include "sodium/crypto_kdf_blake2b.h"
+#include "sodium/crypto_kx.h"
+#include "sodium/crypto_onetimeauth.h"
+#include "sodium/crypto_onetimeauth_poly1305.h"
+#include "sodium/crypto_pwhash.h"
+#include "sodium/crypto_pwhash_argon2i.h"
+#include "sodium/crypto_scalarmult.h"
+#include "sodium/crypto_scalarmult_curve25519.h"
+#include "sodium/crypto_secretbox.h"
+#include "sodium/crypto_secretbox_xsalsa20poly1305.h"
+#include "sodium/crypto_secretstream_xchacha20poly1305.h"
+#include "sodium/crypto_shorthash.h"
+#include "sodium/crypto_shorthash_siphash24.h"
+#include "sodium/crypto_sign.h"
+#include "sodium/crypto_sign_ed25519.h"
+#include "sodium/crypto_stream.h"
+#include "sodium/crypto_stream_chacha20.h"
+#include "sodium/crypto_stream_salsa20.h"
+#include "sodium/crypto_stream_xsalsa20.h"
+#include "sodium/crypto_verify_16.h"
+#include "sodium/crypto_verify_32.h"
+#include "sodium/crypto_verify_64.h"
+#include "sodium/randombytes.h"
+#ifdef __native_client__
+# include "sodium/randombytes_nativeclient.h"
+#endif
+#include "sodium/randombytes_salsa20_random.h"
+#include "sodium/randombytes_sysrandom.h"
+#include "sodium/runtime.h"
+#include "sodium/utils.h"
+
+#ifndef SODIUM_LIBRARY_MINIMAL
+# include "sodium/crypto_box_curve25519xchacha20poly1305.h"
+# include "sodium/crypto_core_ed25519.h"
+# include "sodium/crypto_scalarmult_ed25519.h"
+# include "sodium/crypto_secretbox_xchacha20poly1305.h"
+# include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
+# include "sodium/crypto_stream_salsa2012.h"
+# include "sodium/crypto_stream_salsa208.h"
+# include "sodium/crypto_stream_xchacha20.h"
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/core.h b/libs/libsodium/src/include/sodium/core.h
new file mode 100644
index 0000000000..dd088d2cae
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/core.h
@@ -0,0 +1,28 @@
+
+#ifndef sodium_core_H
+#define sodium_core_H
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+int sodium_init(void)
+ __attribute__ ((warn_unused_result));
+
+/* ---- */
+
+SODIUM_EXPORT
+int sodium_set_misuse_handler(void (*handler)(void));
+
+SODIUM_EXPORT
+void sodium_misuse(void)
+ __attribute__ ((noreturn));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h
new file mode 100644
index 0000000000..46a3800f37
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h
@@ -0,0 +1,171 @@
+#ifndef crypto_aead_aes256gcm_H
+#define crypto_aead_aes256gcm_H
+
+/*
+ * WARNING: Despite being the most popular AEAD construction due to its
+ * use in TLS, safely using AES-GCM in a different context is tricky.
+ *
+ * No more than ~ 350 GB of input data should be encrypted with a given key.
+ * This is for ~ 16 KB messages -- Actual figures vary according to
+ * message sizes.
+ *
+ * In addition, nonces are short and repeated nonces would totally destroy
+ * the security of this scheme.
+ *
+ * Nonces should thus come from atomic counters, which can be difficult to
+ * set up in a distributed environment.
+ *
+ * Unless you absolutely need AES-GCM, use crypto_aead_xchacha20poly1305_ietf_*()
+ * instead. It doesn't have any of these limitations.
+ * Or, if you don't need to authenticate additional data, just stick to
+ * crypto_secretbox().
+ */
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_is_available(void);
+
+#define crypto_aead_aes256gcm_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_keybytes(void);
+
+#define crypto_aead_aes256gcm_NSECBYTES 0U
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_nsecbytes(void);
+
+#define crypto_aead_aes256gcm_NPUBBYTES 12U
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_npubbytes(void);
+
+#define crypto_aead_aes256gcm_ABYTES 16U
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_abytes(void);
+
+#define crypto_aead_aes256gcm_MESSAGEBYTES_MAX \
+ SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aes256gcm_ABYTES, \
+ (16ULL * ((1ULL << 32) - 2ULL)) - crypto_aead_aes256gcm_ABYTES)
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_messagebytes_max(void);
+
+typedef CRYPTO_ALIGN(16) unsigned char crypto_aead_aes256gcm_state[512];
+
+SODIUM_EXPORT
+size_t crypto_aead_aes256gcm_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* -- Precomputation interface -- */
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_);
+
+SODIUM_EXPORT
+int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const crypto_aead_aes256gcm_state *ctx_)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h
new file mode 100644
index 0000000000..a575ec7173
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h
@@ -0,0 +1,174 @@
+#ifndef crypto_aead_chacha20poly1305_H
+#define crypto_aead_chacha20poly1305_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+/* -- IETF ChaCha20-Poly1305 construction with a 96-bit nonce and a 32-bit internal counter -- */
+
+#define crypto_aead_chacha20poly1305_ietf_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_ietf_keybytes(void);
+
+#define crypto_aead_chacha20poly1305_ietf_NSECBYTES 0U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_ietf_nsecbytes(void);
+
+#define crypto_aead_chacha20poly1305_ietf_NPUBBYTES 12U
+
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void);
+
+#define crypto_aead_chacha20poly1305_ietf_ABYTES 16U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_ietf_abytes(void);
+
+#define crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX \
+ SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ietf_ABYTES, \
+ (64ULL * (1ULL << 32) - 64ULL) - crypto_aead_chacha20poly1305_ietf_ABYTES)
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_ietf_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]);
+
+/* -- Original ChaCha20-Poly1305 construction with a 64-bit nonce and a 64-bit internal counter -- */
+
+#define crypto_aead_chacha20poly1305_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_keybytes(void);
+
+#define crypto_aead_chacha20poly1305_NSECBYTES 0U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_nsecbytes(void);
+
+#define crypto_aead_chacha20poly1305_NPUBBYTES 8U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_npubbytes(void);
+
+#define crypto_aead_chacha20poly1305_ABYTES 16U
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_abytes(void);
+
+#define crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX \
+ (SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ABYTES)
+SODIUM_EXPORT
+size_t crypto_aead_chacha20poly1305_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]);
+
+/* Aliases */
+
+#define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES
+#define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_ietf_NSECBYTES
+#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES
+#define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ietf_ABYTES
+#define crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h
new file mode 100644
index 0000000000..99692aae9a
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h
@@ -0,0 +1,97 @@
+#ifndef crypto_aead_xchacha20poly1305_H
+#define crypto_aead_xchacha20poly1305_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void);
+
+#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U
+SODIUM_EXPORT
+size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void);
+
+#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U
+SODIUM_EXPORT
+size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void);
+
+#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U
+SODIUM_EXPORT
+size_t crypto_aead_xchacha20poly1305_ietf_abytes(void);
+
+#define crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX \
+ (SODIUM_SIZE_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES)
+SODIUM_EXPORT
+size_t crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c,
+ unsigned long long *clen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
+ unsigned long long *mlen_p,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
+ unsigned char *mac,
+ unsigned long long *maclen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
+ unsigned char *nsec,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *mac,
+ const unsigned char *ad,
+ unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]);
+
+/* Aliases */
+
+#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES
+#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES
+#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
+#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES
+#define crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_auth.h b/libs/libsodium/src/include/sodium/crypto_auth.h
new file mode 100644
index 0000000000..7174e7bced
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_auth.h
@@ -0,0 +1,44 @@
+#ifndef crypto_auth_H
+#define crypto_auth_H
+
+#include <stddef.h>
+
+#include "crypto_auth_hmacsha512256.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
+SODIUM_EXPORT
+size_t crypto_auth_bytes(void);
+
+#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_auth_keybytes(void);
+
+#define crypto_auth_PRIMITIVE "hmacsha512256"
+SODIUM_EXPORT
+const char *crypto_auth_primitive(void);
+
+SODIUM_EXPORT
+int crypto_auth(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_auth_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h
new file mode 100644
index 0000000000..deec5266e6
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h
@@ -0,0 +1,68 @@
+#ifndef crypto_auth_hmacsha256_H
+#define crypto_auth_hmacsha256_H
+
+#include <stddef.h>
+#include "crypto_hash_sha256.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_auth_hmacsha256_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha256_bytes(void);
+
+#define crypto_auth_hmacsha256_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha256_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha256(unsigned char *out,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha256_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct crypto_auth_hmacsha256_state {
+ crypto_hash_sha256_state ictx;
+ crypto_hash_sha256_state octx;
+} crypto_auth_hmacsha256_state;
+
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha256_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
+ const unsigned char *key,
+ size_t keylen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
+ unsigned char *out);
+
+
+SODIUM_EXPORT
+void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h
new file mode 100644
index 0000000000..77a55fbc00
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h
@@ -0,0 +1,67 @@
+#ifndef crypto_auth_hmacsha512_H
+#define crypto_auth_hmacsha512_H
+
+#include <stddef.h>
+#include "crypto_hash_sha512.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_auth_hmacsha512_BYTES 64U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512_bytes(void);
+
+#define crypto_auth_hmacsha512_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512(unsigned char *out,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct crypto_auth_hmacsha512_state {
+ crypto_hash_sha512_state ictx;
+ crypto_hash_sha512_state octx;
+} crypto_auth_hmacsha512_state;
+
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
+ const unsigned char *key,
+ size_t keylen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
+ unsigned char *out);
+
+SODIUM_EXPORT
+void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h
new file mode 100644
index 0000000000..4842f3debc
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h
@@ -0,0 +1,62 @@
+#ifndef crypto_auth_hmacsha512256_H
+#define crypto_auth_hmacsha512256_H
+
+#include <stddef.h>
+#include "crypto_auth_hmacsha512.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_auth_hmacsha512256_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512256_bytes(void);
+
+#define crypto_auth_hmacsha512256_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512256_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen,const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512256_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* ------------------------------------------------------------------------- */
+
+typedef crypto_auth_hmacsha512_state crypto_auth_hmacsha512256_state;
+
+SODIUM_EXPORT
+size_t crypto_auth_hmacsha512256_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
+ const unsigned char *key,
+ size_t keylen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
+ unsigned char *out);
+
+SODIUM_EXPORT
+void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_box.h b/libs/libsodium/src/include/sodium/crypto_box.h
new file mode 100644
index 0000000000..99ee19a8f6
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_box.h
@@ -0,0 +1,173 @@
+#ifndef crypto_box_H
+#define crypto_box_H
+
+/*
+ * THREAD SAFETY: crypto_box_keypair() is thread-safe,
+ * provided that sodium_init() was called before.
+ *
+ * Other functions are always thread-safe.
+ */
+
+#include <stddef.h>
+
+#include "crypto_box_curve25519xsalsa20poly1305.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_box_SEEDBYTES crypto_box_curve25519xsalsa20poly1305_SEEDBYTES
+SODIUM_EXPORT
+size_t crypto_box_seedbytes(void);
+
+#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
+SODIUM_EXPORT
+size_t crypto_box_publickeybytes(void);
+
+#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
+SODIUM_EXPORT
+size_t crypto_box_secretkeybytes(void);
+
+#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
+SODIUM_EXPORT
+size_t crypto_box_noncebytes(void);
+
+#define crypto_box_MACBYTES crypto_box_curve25519xsalsa20poly1305_MACBYTES
+SODIUM_EXPORT
+size_t crypto_box_macbytes(void);
+
+#define crypto_box_MESSAGEBYTES_MAX crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX
+SODIUM_EXPORT
+size_t crypto_box_messagebytes_max(void);
+
+#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
+SODIUM_EXPORT
+const char *crypto_box_primitive(void);
+
+SODIUM_EXPORT
+int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed);
+
+SODIUM_EXPORT
+int crypto_box_keypair(unsigned char *pk, unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_box_easy(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_open_easy(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_detached(unsigned char *c, unsigned char *mac,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *n, const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_open_detached(unsigned char *m, const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+/* -- Precomputation interface -- */
+
+#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
+SODIUM_EXPORT
+size_t crypto_box_beforenmbytes(void);
+
+SODIUM_EXPORT
+int crypto_box_beforenm(unsigned char *k, const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* -- Ephemeral SK interface -- */
+
+#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_box_sealbytes(void);
+
+SODIUM_EXPORT
+int crypto_box_seal(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *pk);
+
+SODIUM_EXPORT
+int crypto_box_seal_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *pk, const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+/* -- NaCl compatibility interface ; Requires padding -- */
+
+#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+SODIUM_EXPORT
+size_t crypto_box_zerobytes(void);
+
+#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
+SODIUM_EXPORT
+size_t crypto_box_boxzerobytes(void);
+
+SODIUM_EXPORT
+int crypto_box(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *pk, const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_afternm(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_open_afternm(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h
new file mode 100644
index 0000000000..c1cf756687
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h
@@ -0,0 +1,159 @@
+
+#ifndef crypto_box_curve25519xchacha20poly1305_H
+#define crypto_box_curve25519xchacha20poly1305_H
+
+#include <stddef.h>
+#include "crypto_stream_xchacha20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_box_curve25519xchacha20poly1305_SEEDBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_seedbytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_publickeybytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_secretkeybytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_beforenmbytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_noncebytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_MACBYTES 16U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_macbytes(void);
+
+#define crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX \
+ (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_box_curve25519xchacha20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk,
+ unsigned char *sk,
+ const unsigned char *seed);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk,
+ unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_easy(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_detached(unsigned char *c,
+ unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char *m,
+ const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+/* -- Precomputation interface -- */
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char *c,
+ unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char *m,
+ const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+/* -- Ephemeral SK interface -- */
+
+#define crypto_box_curve25519xchacha20poly1305_SEALBYTES \
+ (crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES + \
+ crypto_box_curve25519xchacha20poly1305_MACBYTES)
+
+SODIUM_EXPORT
+size_t crypto_box_curve25519xchacha20poly1305_sealbytes(void);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h
new file mode 100644
index 0000000000..c5b15f42e4
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h
@@ -0,0 +1,109 @@
+#ifndef crypto_box_curve25519xsalsa20poly1305_H
+#define crypto_box_curve25519xsalsa20poly1305_H
+
+#include <stddef.h>
+#include "crypto_stream_xsalsa20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_box_curve25519xsalsa20poly1305_SEEDBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_seedbytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 32U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_noncebytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_MACBYTES 16U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_macbytes(void);
+
+/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */
+#define crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX \
+ (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_box_curve25519xsalsa20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk,
+ unsigned char *sk,
+ const unsigned char *seed);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk,
+ unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+/* -- NaCl compatibility interface ; Requires padding -- */
+
+#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 16U
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void);
+
+#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES \
+ (crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \
+ crypto_box_curve25519xsalsa20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *pk,
+ const unsigned char *sk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_ed25519.h b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h
new file mode 100644
index 0000000000..1536294b21
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h
@@ -0,0 +1,37 @@
+#ifndef crypto_core_ed25519_H
+#define crypto_core_ed25519_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_ed25519_BYTES 32
+SODIUM_EXPORT
+size_t crypto_core_ed25519_bytes(void);
+
+#define crypto_core_ed25519_UNIFORMBYTES 32
+SODIUM_EXPORT
+size_t crypto_core_ed25519_uniformbytes(void);
+
+SODIUM_EXPORT
+int crypto_core_ed25519_is_valid_point(const unsigned char *p);
+
+SODIUM_EXPORT
+int crypto_core_ed25519_add(unsigned char *r,
+ const unsigned char *p, const unsigned char *q);
+
+SODIUM_EXPORT
+int crypto_core_ed25519_sub(unsigned char *r,
+ const unsigned char *p, const unsigned char *q);
+
+SODIUM_EXPORT
+int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h b/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h
new file mode 100644
index 0000000000..05e5670c10
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h
@@ -0,0 +1,35 @@
+#ifndef crypto_core_hchacha20_H
+#define crypto_core_hchacha20_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_hchacha20_OUTPUTBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_hchacha20_outputbytes(void);
+
+#define crypto_core_hchacha20_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_hchacha20_inputbytes(void);
+
+#define crypto_core_hchacha20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_hchacha20_keybytes(void);
+
+#define crypto_core_hchacha20_CONSTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_hchacha20_constbytes(void);
+
+SODIUM_EXPORT
+int crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h b/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h
new file mode 100644
index 0000000000..82e475b8f6
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h
@@ -0,0 +1,35 @@
+#ifndef crypto_core_hsalsa20_H
+#define crypto_core_hsalsa20_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_hsalsa20_OUTPUTBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_hsalsa20_outputbytes(void);
+
+#define crypto_core_hsalsa20_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_hsalsa20_inputbytes(void);
+
+#define crypto_core_hsalsa20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_hsalsa20_keybytes(void);
+
+#define crypto_core_hsalsa20_CONSTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_hsalsa20_constbytes(void);
+
+SODIUM_EXPORT
+int crypto_core_hsalsa20(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa20.h b/libs/libsodium/src/include/sodium/crypto_core_salsa20.h
new file mode 100644
index 0000000000..160cc56d2c
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_salsa20.h
@@ -0,0 +1,35 @@
+#ifndef crypto_core_salsa20_H
+#define crypto_core_salsa20_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_salsa20_OUTPUTBYTES 64U
+SODIUM_EXPORT
+size_t crypto_core_salsa20_outputbytes(void);
+
+#define crypto_core_salsa20_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa20_inputbytes(void);
+
+#define crypto_core_salsa20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_salsa20_keybytes(void);
+
+#define crypto_core_salsa20_CONSTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa20_constbytes(void);
+
+SODIUM_EXPORT
+int crypto_core_salsa20(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h b/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h
new file mode 100644
index 0000000000..bdd5f9fdbb
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h
@@ -0,0 +1,35 @@
+#ifndef crypto_core_salsa2012_H
+#define crypto_core_salsa2012_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_salsa2012_OUTPUTBYTES 64U
+SODIUM_EXPORT
+size_t crypto_core_salsa2012_outputbytes(void);
+
+#define crypto_core_salsa2012_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa2012_inputbytes(void);
+
+#define crypto_core_salsa2012_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_salsa2012_keybytes(void);
+
+#define crypto_core_salsa2012_CONSTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa2012_constbytes(void);
+
+SODIUM_EXPORT
+int crypto_core_salsa2012(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa208.h b/libs/libsodium/src/include/sodium/crypto_core_salsa208.h
new file mode 100644
index 0000000000..876bda8936
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_core_salsa208.h
@@ -0,0 +1,39 @@
+#ifndef crypto_core_salsa208_H
+#define crypto_core_salsa208_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_core_salsa208_OUTPUTBYTES 64U
+SODIUM_EXPORT
+size_t crypto_core_salsa208_outputbytes(void)
+ __attribute__ ((deprecated));
+
+#define crypto_core_salsa208_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa208_inputbytes(void)
+ __attribute__ ((deprecated));
+
+#define crypto_core_salsa208_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_core_salsa208_keybytes(void)
+ __attribute__ ((deprecated));
+
+#define crypto_core_salsa208_CONSTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_core_salsa208_constbytes(void)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+int crypto_core_salsa208(unsigned char *out, const unsigned char *in,
+ const unsigned char *k, const unsigned char *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_generichash.h b/libs/libsodium/src/include/sodium/crypto_generichash.h
new file mode 100644
index 0000000000..2398fb9dbb
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_generichash.h
@@ -0,0 +1,75 @@
+#ifndef crypto_generichash_H
+#define crypto_generichash_H
+
+#include <stddef.h>
+
+#include "crypto_generichash_blake2b.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_generichash_BYTES_MIN crypto_generichash_blake2b_BYTES_MIN
+SODIUM_EXPORT
+size_t crypto_generichash_bytes_min(void);
+
+#define crypto_generichash_BYTES_MAX crypto_generichash_blake2b_BYTES_MAX
+SODIUM_EXPORT
+size_t crypto_generichash_bytes_max(void);
+
+#define crypto_generichash_BYTES crypto_generichash_blake2b_BYTES
+SODIUM_EXPORT
+size_t crypto_generichash_bytes(void);
+
+#define crypto_generichash_KEYBYTES_MIN crypto_generichash_blake2b_KEYBYTES_MIN
+SODIUM_EXPORT
+size_t crypto_generichash_keybytes_min(void);
+
+#define crypto_generichash_KEYBYTES_MAX crypto_generichash_blake2b_KEYBYTES_MAX
+SODIUM_EXPORT
+size_t crypto_generichash_keybytes_max(void);
+
+#define crypto_generichash_KEYBYTES crypto_generichash_blake2b_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_generichash_keybytes(void);
+
+#define crypto_generichash_PRIMITIVE "blake2b"
+SODIUM_EXPORT
+const char *crypto_generichash_primitive(void);
+
+typedef crypto_generichash_blake2b_state crypto_generichash_state;
+
+SODIUM_EXPORT
+size_t crypto_generichash_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_generichash(unsigned char *out, size_t outlen,
+ const unsigned char *in, unsigned long long inlen,
+ const unsigned char *key, size_t keylen);
+
+SODIUM_EXPORT
+int crypto_generichash_init(crypto_generichash_state *state,
+ const unsigned char *key,
+ const size_t keylen, const size_t outlen);
+
+SODIUM_EXPORT
+int crypto_generichash_update(crypto_generichash_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_generichash_final(crypto_generichash_state *state,
+ unsigned char *out, const size_t outlen);
+
+SODIUM_EXPORT
+void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h
new file mode 100644
index 0000000000..9326a04ad1
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h
@@ -0,0 +1,117 @@
+#ifndef crypto_generichash_blake2b_H
+#define crypto_generichash_blake2b_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# pragma pack(1)
+#else
+# pragma pack(push, 1)
+#endif
+
+typedef struct CRYPTO_ALIGN(64) crypto_generichash_blake2b_state {
+ uint64_t h[8];
+ uint64_t t[2];
+ uint64_t f[2];
+ uint8_t buf[2 * 128];
+ size_t buflen;
+ uint8_t last_node;
+} crypto_generichash_blake2b_state;
+
+#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# pragma pack()
+#else
+# pragma pack(pop)
+#endif
+
+#define crypto_generichash_blake2b_BYTES_MIN 16U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_bytes_min(void);
+
+#define crypto_generichash_blake2b_BYTES_MAX 64U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_bytes_max(void);
+
+#define crypto_generichash_blake2b_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_bytes(void);
+
+#define crypto_generichash_blake2b_KEYBYTES_MIN 16U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_keybytes_min(void);
+
+#define crypto_generichash_blake2b_KEYBYTES_MAX 64U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_keybytes_max(void);
+
+#define crypto_generichash_blake2b_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_keybytes(void);
+
+#define crypto_generichash_blake2b_SALTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_saltbytes(void);
+
+#define crypto_generichash_blake2b_PERSONALBYTES 16U
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_personalbytes(void);
+
+SODIUM_EXPORT
+size_t crypto_generichash_blake2b_statebytes(void);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b(unsigned char *out, size_t outlen,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *key, size_t keylen);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *key,
+ size_t keylen,
+ const unsigned char *salt,
+ const unsigned char *personal);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state,
+ const unsigned char *key,
+ const size_t keylen, const size_t outlen);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b_init_salt_personal(crypto_generichash_blake2b_state *state,
+ const unsigned char *key,
+ const size_t keylen, const size_t outlen,
+ const unsigned char *salt,
+ const unsigned char *personal);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state,
+ unsigned char *out,
+ const size_t outlen);
+
+SODIUM_EXPORT
+void crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_hash.h b/libs/libsodium/src/include/sodium/crypto_hash.h
new file mode 100644
index 0000000000..302ed5c5ea
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_hash.h
@@ -0,0 +1,40 @@
+#ifndef crypto_hash_H
+#define crypto_hash_H
+
+/*
+ * WARNING: Unless you absolutely need to use SHA512 for interoperatibility,
+ * purposes, you might want to consider crypto_generichash() instead.
+ * Unlike SHA512, crypto_generichash() is not vulnerable to length
+ * extension attacks.
+ */
+
+#include <stddef.h>
+
+#include "crypto_hash_sha512.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_hash_BYTES crypto_hash_sha512_BYTES
+SODIUM_EXPORT
+size_t crypto_hash_bytes(void);
+
+SODIUM_EXPORT
+int crypto_hash(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen);
+
+#define crypto_hash_PRIMITIVE "sha512"
+SODIUM_EXPORT
+const char *crypto_hash_primitive(void)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha256.h b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h
new file mode 100644
index 0000000000..f64d16e0e5
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h
@@ -0,0 +1,57 @@
+#ifndef crypto_hash_sha256_H
+#define crypto_hash_sha256_H
+
+/*
+ * WARNING: Unless you absolutely need to use SHA256 for interoperatibility,
+ * purposes, you might want to consider crypto_generichash() instead.
+ * Unlike SHA256, crypto_generichash() is not vulnerable to length
+ * extension attacks.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef struct crypto_hash_sha256_state {
+ uint32_t state[8];
+ uint64_t count;
+ uint8_t buf[64];
+} crypto_hash_sha256_state;
+
+SODIUM_EXPORT
+size_t crypto_hash_sha256_statebytes(void);
+
+#define crypto_hash_sha256_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_hash_sha256_bytes(void);
+
+SODIUM_EXPORT
+int crypto_hash_sha256(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_hash_sha256_init(crypto_hash_sha256_state *state);
+
+SODIUM_EXPORT
+int crypto_hash_sha256_update(crypto_hash_sha256_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_hash_sha256_final(crypto_hash_sha256_state *state,
+ unsigned char *out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha512.h b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h
new file mode 100644
index 0000000000..6b0330f14f
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h
@@ -0,0 +1,57 @@
+#ifndef crypto_hash_sha512_H
+#define crypto_hash_sha512_H
+
+/*
+ * WARNING: Unless you absolutely need to use SHA512 for interoperatibility,
+ * purposes, you might want to consider crypto_generichash() instead.
+ * Unlike SHA512, crypto_generichash() is not vulnerable to length
+ * extension attacks.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef struct crypto_hash_sha512_state {
+ uint64_t state[8];
+ uint64_t count[2];
+ uint8_t buf[128];
+} crypto_hash_sha512_state;
+
+SODIUM_EXPORT
+size_t crypto_hash_sha512_statebytes(void);
+
+#define crypto_hash_sha512_BYTES 64U
+SODIUM_EXPORT
+size_t crypto_hash_sha512_bytes(void);
+
+SODIUM_EXPORT
+int crypto_hash_sha512(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_hash_sha512_init(crypto_hash_sha512_state *state);
+
+SODIUM_EXPORT
+int crypto_hash_sha512_update(crypto_hash_sha512_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_hash_sha512_final(crypto_hash_sha512_state *state,
+ unsigned char *out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_kdf.h b/libs/libsodium/src/include/sodium/crypto_kdf.h
new file mode 100644
index 0000000000..52e496a744
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_kdf.h
@@ -0,0 +1,51 @@
+#ifndef crypto_kdf_H
+#define crypto_kdf_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "crypto_kdf_blake2b.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_kdf_BYTES_MIN crypto_kdf_blake2b_BYTES_MIN
+SODIUM_EXPORT
+size_t crypto_kdf_bytes_min(void);
+
+#define crypto_kdf_BYTES_MAX crypto_kdf_blake2b_BYTES_MAX
+SODIUM_EXPORT
+size_t crypto_kdf_bytes_max(void);
+
+#define crypto_kdf_CONTEXTBYTES crypto_kdf_blake2b_CONTEXTBYTES
+SODIUM_EXPORT
+size_t crypto_kdf_contextbytes(void);
+
+#define crypto_kdf_KEYBYTES crypto_kdf_blake2b_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_kdf_keybytes(void);
+
+#define crypto_kdf_PRIMITIVE "blake2b"
+SODIUM_EXPORT
+const char *crypto_kdf_primitive(void)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len,
+ uint64_t subkey_id,
+ const char ctx[crypto_kdf_CONTEXTBYTES],
+ const unsigned char key[crypto_kdf_KEYBYTES]);
+
+SODIUM_EXPORT
+void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h
new file mode 100644
index 0000000000..5480ebe82f
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h
@@ -0,0 +1,42 @@
+#ifndef crypto_kdf_blake2b_H
+#define crypto_kdf_blake2b_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "crypto_kdf_blake2b.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_kdf_blake2b_BYTES_MIN 16
+SODIUM_EXPORT
+size_t crypto_kdf_blake2b_bytes_min(void);
+
+#define crypto_kdf_blake2b_BYTES_MAX 64
+SODIUM_EXPORT
+size_t crypto_kdf_blake2b_bytes_max(void);
+
+#define crypto_kdf_blake2b_CONTEXTBYTES 8
+SODIUM_EXPORT
+size_t crypto_kdf_blake2b_contextbytes(void);
+
+#define crypto_kdf_blake2b_KEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kdf_blake2b_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len,
+ uint64_t subkey_id,
+ const char ctx[crypto_kdf_blake2b_CONTEXTBYTES],
+ const unsigned char key[crypto_kdf_blake2b_KEYBYTES]);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_kx.h b/libs/libsodium/src/include/sodium/crypto_kx.h
new file mode 100644
index 0000000000..d1fce90da5
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_kx.h
@@ -0,0 +1,64 @@
+#ifndef crypto_kx_H
+#define crypto_kx_H
+
+#include <stddef.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_kx_PUBLICKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_publickeybytes(void);
+
+#define crypto_kx_SECRETKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_secretkeybytes(void);
+
+#define crypto_kx_SEEDBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_seedbytes(void);
+
+#define crypto_kx_SESSIONKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_sessionkeybytes(void);
+
+#define crypto_kx_PRIMITIVE "x25519blake2b"
+SODIUM_EXPORT
+const char *crypto_kx_primitive(void);
+
+SODIUM_EXPORT
+int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char seed[crypto_kx_SEEDBYTES]);
+
+SODIUM_EXPORT
+int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES]);
+
+SODIUM_EXPORT
+int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h
new file mode 100644
index 0000000000..5951c5b82d
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h
@@ -0,0 +1,62 @@
+#ifndef crypto_onetimeauth_H
+#define crypto_onetimeauth_H
+
+#include <stddef.h>
+
+#include "crypto_onetimeauth_poly1305.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef crypto_onetimeauth_poly1305_state crypto_onetimeauth_state;
+
+SODIUM_EXPORT
+size_t crypto_onetimeauth_statebytes(void);
+
+#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
+SODIUM_EXPORT
+size_t crypto_onetimeauth_bytes(void);
+
+#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_onetimeauth_keybytes(void);
+
+#define crypto_onetimeauth_PRIMITIVE "poly1305"
+SODIUM_EXPORT
+const char *crypto_onetimeauth_primitive(void);
+
+SODIUM_EXPORT
+int crypto_onetimeauth(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
+ const unsigned char *key);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_final(crypto_onetimeauth_state *state,
+ unsigned char *out);
+
+SODIUM_EXPORT
+void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h
new file mode 100644
index 0000000000..4b89c4f019
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h
@@ -0,0 +1,67 @@
+#ifndef crypto_onetimeauth_poly1305_H
+#define crypto_onetimeauth_poly1305_H
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#include "export.h"
+
+typedef struct CRYPTO_ALIGN(16) crypto_onetimeauth_poly1305_state {
+ unsigned char opaque[256];
+} crypto_onetimeauth_poly1305_state;
+
+SODIUM_EXPORT
+size_t crypto_onetimeauth_poly1305_statebytes(void);
+
+#define crypto_onetimeauth_poly1305_BYTES 16U
+SODIUM_EXPORT
+size_t crypto_onetimeauth_poly1305_bytes(void);
+
+#define crypto_onetimeauth_poly1305_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_onetimeauth_poly1305_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_poly1305(unsigned char *out,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_poly1305_verify(const unsigned char *h,
+ const unsigned char *in,
+ unsigned long long inlen,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *key);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state,
+ const unsigned char *in,
+ unsigned long long inlen);
+
+SODIUM_EXPORT
+int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state,
+ unsigned char *out);
+
+SODIUM_EXPORT
+void crypto_onetimeauth_poly1305_keygen(unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash.h b/libs/libsodium/src/include/sodium/crypto_pwhash.h
new file mode 100644
index 0000000000..2c76461f44
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_pwhash.h
@@ -0,0 +1,147 @@
+#ifndef crypto_pwhash_H
+#define crypto_pwhash_H
+
+#include <stddef.h>
+
+#include "crypto_pwhash_argon2i.h"
+#include "crypto_pwhash_argon2id.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_pwhash_ALG_ARGON2I13 crypto_pwhash_argon2i_ALG_ARGON2I13
+SODIUM_EXPORT
+int crypto_pwhash_alg_argon2i13(void);
+
+#define crypto_pwhash_ALG_ARGON2ID13 crypto_pwhash_argon2id_ALG_ARGON2ID13
+SODIUM_EXPORT
+int crypto_pwhash_alg_argon2id13(void);
+
+#define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2ID13
+SODIUM_EXPORT
+int crypto_pwhash_alg_default(void);
+
+#define crypto_pwhash_BYTES_MIN crypto_pwhash_argon2id_BYTES_MIN
+SODIUM_EXPORT
+size_t crypto_pwhash_bytes_min(void);
+
+#define crypto_pwhash_BYTES_MAX crypto_pwhash_argon2id_BYTES_MAX
+SODIUM_EXPORT
+size_t crypto_pwhash_bytes_max(void);
+
+#define crypto_pwhash_PASSWD_MIN crypto_pwhash_argon2id_PASSWD_MIN
+SODIUM_EXPORT
+size_t crypto_pwhash_passwd_min(void);
+
+#define crypto_pwhash_PASSWD_MAX crypto_pwhash_argon2id_PASSWD_MAX
+SODIUM_EXPORT
+size_t crypto_pwhash_passwd_max(void);
+
+#define crypto_pwhash_SALTBYTES crypto_pwhash_argon2id_SALTBYTES
+SODIUM_EXPORT
+size_t crypto_pwhash_saltbytes(void);
+
+#define crypto_pwhash_STRBYTES crypto_pwhash_argon2id_STRBYTES
+SODIUM_EXPORT
+size_t crypto_pwhash_strbytes(void);
+
+#define crypto_pwhash_STRPREFIX crypto_pwhash_argon2id_STRPREFIX
+SODIUM_EXPORT
+const char *crypto_pwhash_strprefix(void);
+
+#define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_argon2id_OPSLIMIT_MIN
+SODIUM_EXPORT
+size_t crypto_pwhash_opslimit_min(void);
+
+#define crypto_pwhash_OPSLIMIT_MAX crypto_pwhash_argon2id_OPSLIMIT_MAX
+SODIUM_EXPORT
+size_t crypto_pwhash_opslimit_max(void);
+
+#define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_argon2id_MEMLIMIT_MIN
+SODIUM_EXPORT
+size_t crypto_pwhash_memlimit_min(void);
+
+#define crypto_pwhash_MEMLIMIT_MAX crypto_pwhash_argon2id_MEMLIMIT_MAX
+SODIUM_EXPORT
+size_t crypto_pwhash_memlimit_max(void);
+
+#define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
+SODIUM_EXPORT
+size_t crypto_pwhash_opslimit_interactive(void);
+
+#define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
+SODIUM_EXPORT
+size_t crypto_pwhash_memlimit_interactive(void);
+
+#define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2id_OPSLIMIT_MODERATE
+SODIUM_EXPORT
+size_t crypto_pwhash_opslimit_moderate(void);
+
+#define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2id_MEMLIMIT_MODERATE
+SODIUM_EXPORT
+size_t crypto_pwhash_memlimit_moderate(void);
+
+#define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
+SODIUM_EXPORT
+size_t crypto_pwhash_opslimit_sensitive(void);
+
+#define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE
+SODIUM_EXPORT
+size_t crypto_pwhash_memlimit_sensitive(void);
+
+/*
+ * With this function, do not forget to store all parameters, including the
+ * algorithm identifier in order to produce deterministic output.
+ * The crypto_pwhash_* definitions, including crypto_pwhash_ALG_DEFAULT,
+ * may change.
+ */
+SODIUM_EXPORT
+int crypto_pwhash(unsigned char * const out, unsigned long long outlen,
+ const char * const passwd, unsigned long long passwdlen,
+ const unsigned char * const salt,
+ unsigned long long opslimit, size_t memlimit, int alg)
+ __attribute__ ((warn_unused_result));
+
+/*
+ * The output string already includes all the required parameters, including
+ * the algorithm identifier. The string is all that has to be stored in
+ * order to verify a password.
+ */
+SODIUM_EXPORT
+int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES],
+ const char * const passwd, unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES],
+ const char * const passwd, unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit, int alg)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+#define crypto_pwhash_PRIMITIVE "argon2i"
+SODIUM_EXPORT
+const char *crypto_pwhash_primitive(void)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h
new file mode 100644
index 0000000000..8e4c1c3531
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h
@@ -0,0 +1,122 @@
+#ifndef crypto_pwhash_argon2i_H
+#define crypto_pwhash_argon2i_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_pwhash_argon2i_ALG_ARGON2I13 1
+SODIUM_EXPORT
+int crypto_pwhash_argon2i_alg_argon2i13(void);
+
+#define crypto_pwhash_argon2i_BYTES_MIN 16U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_bytes_min(void);
+
+#define crypto_pwhash_argon2i_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U)
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_bytes_max(void);
+
+#define crypto_pwhash_argon2i_PASSWD_MIN 0U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_passwd_min(void);
+
+#define crypto_pwhash_argon2i_PASSWD_MAX 4294967295U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_passwd_max(void);
+
+#define crypto_pwhash_argon2i_SALTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_saltbytes(void);
+
+#define crypto_pwhash_argon2i_STRBYTES 128U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_strbytes(void);
+
+#define crypto_pwhash_argon2i_STRPREFIX "$argon2i$"
+SODIUM_EXPORT
+const char *crypto_pwhash_argon2i_strprefix(void);
+
+#define crypto_pwhash_argon2i_OPSLIMIT_MIN 3U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_opslimit_min(void);
+
+#define crypto_pwhash_argon2i_OPSLIMIT_MAX 4294967295U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_opslimit_max(void);
+
+#define crypto_pwhash_argon2i_MEMLIMIT_MIN 8192U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_memlimit_min(void);
+
+#define crypto_pwhash_argon2i_MEMLIMIT_MAX \
+ ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U)
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_memlimit_max(void);
+
+#define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_opslimit_interactive(void);
+
+#define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_memlimit_interactive(void);
+
+#define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_opslimit_moderate(void);
+
+#define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_memlimit_moderate(void);
+
+#define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_opslimit_sensitive(void);
+
+#define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2i_memlimit_sensitive(void);
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2i(unsigned char * const out,
+ unsigned long long outlen,
+ const char * const passwd,
+ unsigned long long passwdlen,
+ const unsigned char * const salt,
+ unsigned long long opslimit, size_t memlimit,
+ int alg)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h
new file mode 100644
index 0000000000..51b17aa8e3
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h
@@ -0,0 +1,122 @@
+#ifndef crypto_pwhash_argon2id_H
+#define crypto_pwhash_argon2id_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_pwhash_argon2id_ALG_ARGON2ID13 2
+SODIUM_EXPORT
+int crypto_pwhash_argon2id_alg_argon2id13(void);
+
+#define crypto_pwhash_argon2id_BYTES_MIN 16U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_bytes_min(void);
+
+#define crypto_pwhash_argon2id_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U)
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_bytes_max(void);
+
+#define crypto_pwhash_argon2id_PASSWD_MIN 0U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_passwd_min(void);
+
+#define crypto_pwhash_argon2id_PASSWD_MAX 4294967295U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_passwd_max(void);
+
+#define crypto_pwhash_argon2id_SALTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_saltbytes(void);
+
+#define crypto_pwhash_argon2id_STRBYTES 128U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_strbytes(void);
+
+#define crypto_pwhash_argon2id_STRPREFIX "$argon2id$"
+SODIUM_EXPORT
+const char *crypto_pwhash_argon2id_strprefix(void);
+
+#define crypto_pwhash_argon2id_OPSLIMIT_MIN 1U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_opslimit_min(void);
+
+#define crypto_pwhash_argon2id_OPSLIMIT_MAX 4294967295U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_opslimit_max(void);
+
+#define crypto_pwhash_argon2id_MEMLIMIT_MIN 8192U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_memlimit_min(void);
+
+#define crypto_pwhash_argon2id_MEMLIMIT_MAX \
+ ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U)
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_memlimit_max(void);
+
+#define crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE 2U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_opslimit_interactive(void);
+
+#define crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE 67108864U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_memlimit_interactive(void);
+
+#define crypto_pwhash_argon2id_OPSLIMIT_MODERATE 3U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_opslimit_moderate(void);
+
+#define crypto_pwhash_argon2id_MEMLIMIT_MODERATE 268435456U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_memlimit_moderate(void);
+
+#define crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE 4U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_opslimit_sensitive(void);
+
+#define crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE 1073741824U
+SODIUM_EXPORT
+size_t crypto_pwhash_argon2id_memlimit_sensitive(void);
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2id(unsigned char * const out,
+ unsigned long long outlen,
+ const char * const passwd,
+ unsigned long long passwdlen,
+ const unsigned char * const salt,
+ unsigned long long opslimit, size_t memlimit,
+ int alg)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen,
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES],
+ unsigned long long opslimit, size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h
new file mode 100644
index 0000000000..951b87b962
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h
@@ -0,0 +1,120 @@
+#ifndef crypto_pwhash_scryptsalsa208sha256_H
+#define crypto_pwhash_scryptsalsa208sha256_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_pwhash_scryptsalsa208sha256_BYTES_MIN 16U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_bytes_min(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_BYTES_MAX \
+ SODIUM_MIN(SODIUM_SIZE_MAX, 0x1fffffffe0ULL)
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_bytes_max(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN 0U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_passwd_min(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_passwd_max(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$"
+SODIUM_EXPORT
+const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_opslimit_min(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX 4294967295U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_opslimit_max(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_memlimit_min(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX \
+ SODIUM_MIN(SIZE_MAX, 68719476736ULL)
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_memlimit_max(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void);
+
+#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U
+SODIUM_EXPORT
+size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void);
+
+SODIUM_EXPORT
+int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
+ unsigned long long outlen,
+ const char * const passwd,
+ unsigned long long passwdlen,
+ const unsigned char * const salt,
+ unsigned long long opslimit,
+ size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen,
+ unsigned long long opslimit,
+ size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ const char * const passwd,
+ unsigned long long passwdlen)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
+ const uint8_t * salt, size_t saltlen,
+ uint64_t N, uint32_t r, uint32_t p,
+ uint8_t * buf, size_t buflen)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
+ unsigned long long opslimit,
+ size_t memlimit)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult.h b/libs/libsodium/src/include/sodium/crypto_scalarmult.h
new file mode 100644
index 0000000000..f7fa6f8f39
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_scalarmult.h
@@ -0,0 +1,45 @@
+#ifndef crypto_scalarmult_H
+#define crypto_scalarmult_H
+
+#include <stddef.h>
+
+#include "crypto_scalarmult_curve25519.h"
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
+SODIUM_EXPORT
+size_t crypto_scalarmult_bytes(void);
+
+#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
+SODIUM_EXPORT
+size_t crypto_scalarmult_scalarbytes(void);
+
+#define crypto_scalarmult_PRIMITIVE "curve25519"
+SODIUM_EXPORT
+const char *crypto_scalarmult_primitive(void);
+
+SODIUM_EXPORT
+int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
+
+/*
+ * NOTE: Do not use the result of this function directly.
+ *
+ * Hash the result with the public keys in order to compute a shared
+ * secret key: H(q || client_pk || server_pk)
+ *
+ * Or unless this is not an option, use the crypto_kx() API instead.
+ */
+SODIUM_EXPORT
+int crypto_scalarmult(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h
new file mode 100644
index 0000000000..ae85eadc22
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h
@@ -0,0 +1,40 @@
+#ifndef crypto_scalarmult_curve25519_H
+#define crypto_scalarmult_curve25519_H
+
+#include <stddef.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_scalarmult_curve25519_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_scalarmult_curve25519_bytes(void);
+
+#define crypto_scalarmult_curve25519_SCALARBYTES 32U
+SODIUM_EXPORT
+size_t crypto_scalarmult_curve25519_scalarbytes(void);
+
+/*
+ * NOTE: Do not use the result of this function directly.
+ *
+ * Hash the result with the public keys in order to compute a shared
+ * secret key: H(q || client_pk || server_pk)
+ *
+ * Or unless this is not an option, use the crypto_kx() API instead.
+ */
+SODIUM_EXPORT
+int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h
new file mode 100644
index 0000000000..3d51235112
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h
@@ -0,0 +1,41 @@
+
+#ifndef crypto_scalarmult_ed25519_H
+#define crypto_scalarmult_ed25519_H
+
+#include <stddef.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_scalarmult_ed25519_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_scalarmult_ed25519_bytes(void);
+
+#define crypto_scalarmult_ed25519_SCALARBYTES 32U
+SODIUM_EXPORT
+size_t crypto_scalarmult_ed25519_scalarbytes(void);
+
+/*
+ * NOTE: Do not use the result of this function directly.
+ *
+ * Hash the result with the public keys in order to compute a shared
+ * secret key: H(q || client_pk || server_pk)
+ *
+ * Or unless this is not an option, use the crypto_kx() API instead.
+ */
+SODIUM_EXPORT
+int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
+ const unsigned char *p)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox.h b/libs/libsodium/src/include/sodium/crypto_secretbox.h
new file mode 100644
index 0000000000..55e94a0292
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_secretbox.h
@@ -0,0 +1,91 @@
+#ifndef crypto_secretbox_H
+#define crypto_secretbox_H
+
+#include <stddef.h>
+
+#include "crypto_secretbox_xsalsa20poly1305.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_secretbox_keybytes(void);
+
+#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
+SODIUM_EXPORT
+size_t crypto_secretbox_noncebytes(void);
+
+#define crypto_secretbox_MACBYTES crypto_secretbox_xsalsa20poly1305_MACBYTES
+SODIUM_EXPORT
+size_t crypto_secretbox_macbytes(void);
+
+#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
+SODIUM_EXPORT
+const char *crypto_secretbox_primitive(void);
+
+#define crypto_secretbox_MESSAGEBYTES_MAX crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX
+SODIUM_EXPORT
+size_t crypto_secretbox_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_open_detached(unsigned char *m,
+ const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]);
+
+/* -- NaCl compatibility interface ; Requires padding -- */
+
+#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
+SODIUM_EXPORT
+size_t crypto_secretbox_zerobytes(void);
+
+#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
+SODIUM_EXPORT
+size_t crypto_secretbox_boxzerobytes(void);
+
+SODIUM_EXPORT
+int crypto_secretbox(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_open(unsigned char *m, const unsigned char *c,
+ unsigned long long clen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h
new file mode 100644
index 0000000000..2919da161c
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h
@@ -0,0 +1,68 @@
+#ifndef crypto_secretbox_xchacha20poly1305_H
+#define crypto_secretbox_xchacha20poly1305_H
+
+#include <stddef.h>
+#include "crypto_stream_xchacha20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_secretbox_xchacha20poly1305_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_secretbox_xchacha20poly1305_keybytes(void);
+
+#define crypto_secretbox_xchacha20poly1305_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_secretbox_xchacha20poly1305_noncebytes(void);
+
+#define crypto_secretbox_xchacha20poly1305_MACBYTES 16U
+SODIUM_EXPORT
+size_t crypto_secretbox_xchacha20poly1305_macbytes(void);
+
+#define crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX \
+ (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_secretbox_xchacha20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_secretbox_xchacha20poly1305_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_secretbox_xchacha20poly1305_easy(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_secretbox_xchacha20poly1305_detached(unsigned char *c,
+ unsigned char *mac,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m,
+ const unsigned char *c,
+ const unsigned char *mac,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h
new file mode 100644
index 0000000000..4b8c7c8ea2
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h
@@ -0,0 +1,67 @@
+#ifndef crypto_secretbox_xsalsa20poly1305_H
+#define crypto_secretbox_xsalsa20poly1305_H
+
+#include <stddef.h>
+#include "crypto_stream_xsalsa20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_keybytes(void);
+
+#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void);
+
+#define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_macbytes(void);
+
+/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */
+#define crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX \
+ (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_secretbox_xsalsa20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_secretbox_xsalsa20poly1305(unsigned char *c,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m,
+ const unsigned char *c,
+ unsigned long long clen,
+ const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]);
+
+/* -- NaCl compatibility interface ; Requires padding -- */
+
+#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void);
+
+#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \
+ (crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \
+ crypto_secretbox_xsalsa20poly1305_MACBYTES)
+SODIUM_EXPORT
+size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h
new file mode 100644
index 0000000000..7d3fa2a9e3
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h
@@ -0,0 +1,102 @@
+#ifndef crypto_secretstream_xchacha20poly1305_H
+#define crypto_secretstream_xchacha20poly1305_H
+
+#include <stddef.h>
+
+#include "crypto_aead_xchacha20poly1305.h"
+#include "crypto_stream_chacha20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_secretstream_xchacha20poly1305_ABYTES \
+ (1U + crypto_aead_xchacha20poly1305_ietf_ABYTES)
+SODIUM_EXPORT
+size_t crypto_secretstream_xchacha20poly1305_abytes(void);
+
+#define crypto_secretstream_xchacha20poly1305_HEADERBYTES \
+ crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
+SODIUM_EXPORT
+size_t crypto_secretstream_xchacha20poly1305_headerbytes(void);
+
+#define crypto_secretstream_xchacha20poly1305_KEYBYTES \
+ crypto_aead_xchacha20poly1305_ietf_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_secretstream_xchacha20poly1305_keybytes(void);
+
+#define crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX \
+ SODIUM_MIN(SODIUM_SIZE_MAX, ((1ULL << 32) - 2ULL) * 64ULL)
+SODIUM_EXPORT
+size_t crypto_secretstream_xchacha20poly1305_messagebytes_max(void);
+
+#define crypto_secretstream_xchacha20poly1305_TAG_MESSAGE 0x00
+SODIUM_EXPORT
+unsigned char crypto_secretstream_xchacha20poly1305_tag_message(void);
+
+#define crypto_secretstream_xchacha20poly1305_TAG_PUSH 0x01
+SODIUM_EXPORT
+unsigned char crypto_secretstream_xchacha20poly1305_tag_push(void);
+
+#define crypto_secretstream_xchacha20poly1305_TAG_REKEY 0x02
+SODIUM_EXPORT
+unsigned char crypto_secretstream_xchacha20poly1305_tag_rekey(void);
+
+#define crypto_secretstream_xchacha20poly1305_TAG_FINAL \
+ (crypto_secretstream_xchacha20poly1305_TAG_PUSH | \
+ crypto_secretstream_xchacha20poly1305_TAG_REKEY)
+SODIUM_EXPORT
+unsigned char crypto_secretstream_xchacha20poly1305_tag_final(void);
+
+typedef struct crypto_secretstream_xchacha20poly1305_state {
+ unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES];
+ unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES];
+ unsigned char _pad[8];
+} crypto_secretstream_xchacha20poly1305_state;
+
+SODIUM_EXPORT
+size_t crypto_secretstream_xchacha20poly1305_statebytes(void);
+
+SODIUM_EXPORT
+void crypto_secretstream_xchacha20poly1305_keygen
+ (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
+
+SODIUM_EXPORT
+int crypto_secretstream_xchacha20poly1305_init_push
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
+ const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
+
+SODIUM_EXPORT
+int crypto_secretstream_xchacha20poly1305_push
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char *c, unsigned long long *clen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *ad, unsigned long long adlen, unsigned char tag);
+
+SODIUM_EXPORT
+int crypto_secretstream_xchacha20poly1305_init_pull
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ const unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
+ const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
+
+SODIUM_EXPORT
+int crypto_secretstream_xchacha20poly1305_pull
+ (crypto_secretstream_xchacha20poly1305_state *state,
+ unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p,
+ const unsigned char *c, unsigned long long clen,
+ const unsigned char *ad, unsigned long long adlen);
+
+SODIUM_EXPORT
+void crypto_secretstream_xchacha20poly1305_rekey
+ (crypto_secretstream_xchacha20poly1305_state *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash.h b/libs/libsodium/src/include/sodium/crypto_shorthash.h
new file mode 100644
index 0000000000..a498808247
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_shorthash.h
@@ -0,0 +1,39 @@
+#ifndef crypto_shorthash_H
+#define crypto_shorthash_H
+
+#include <stddef.h>
+
+#include "crypto_shorthash_siphash24.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_shorthash_BYTES crypto_shorthash_siphash24_BYTES
+SODIUM_EXPORT
+size_t crypto_shorthash_bytes(void);
+
+#define crypto_shorthash_KEYBYTES crypto_shorthash_siphash24_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_shorthash_keybytes(void);
+
+#define crypto_shorthash_PRIMITIVE "siphash24"
+SODIUM_EXPORT
+const char *crypto_shorthash_primitive(void);
+
+SODIUM_EXPORT
+int crypto_shorthash(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h
new file mode 100644
index 0000000000..745ed48fae
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h
@@ -0,0 +1,48 @@
+#ifndef crypto_shorthash_siphash24_H
+#define crypto_shorthash_siphash24_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+/* -- 64-bit output -- */
+
+#define crypto_shorthash_siphash24_BYTES 8U
+SODIUM_EXPORT
+size_t crypto_shorthash_siphash24_bytes(void);
+
+#define crypto_shorthash_siphash24_KEYBYTES 16U
+SODIUM_EXPORT
+size_t crypto_shorthash_siphash24_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+
+#ifndef SODIUM_LIBRARY_MINIMAL
+/* -- 128-bit output -- */
+
+#define crypto_shorthash_siphashx24_BYTES 16U
+SODIUM_EXPORT
+size_t crypto_shorthash_siphashx24_bytes(void);
+
+#define crypto_shorthash_siphashx24_KEYBYTES 16U
+SODIUM_EXPORT
+size_t crypto_shorthash_siphashx24_keybytes(void);
+
+SODIUM_EXPORT
+int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in,
+ unsigned long long inlen, const unsigned char *k);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_sign.h b/libs/libsodium/src/include/sodium/crypto_sign.h
new file mode 100644
index 0000000000..85aff0c9db
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_sign.h
@@ -0,0 +1,103 @@
+#ifndef crypto_sign_H
+#define crypto_sign_H
+
+/*
+ * THREAD SAFETY: crypto_sign_keypair() is thread-safe,
+ * provided that sodium_init() was called before.
+ *
+ * Other functions, including crypto_sign_seed_keypair() are always thread-safe.
+ */
+
+#include <stddef.h>
+
+#include "crypto_sign_ed25519.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef crypto_sign_ed25519ph_state crypto_sign_state;
+
+SODIUM_EXPORT
+size_t crypto_sign_statebytes(void);
+
+#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
+SODIUM_EXPORT
+size_t crypto_sign_bytes(void);
+
+#define crypto_sign_SEEDBYTES crypto_sign_ed25519_SEEDBYTES
+SODIUM_EXPORT
+size_t crypto_sign_seedbytes(void);
+
+#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
+SODIUM_EXPORT
+size_t crypto_sign_publickeybytes(void);
+
+#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
+SODIUM_EXPORT
+size_t crypto_sign_secretkeybytes(void);
+
+#define crypto_sign_MESSAGEBYTES_MAX crypto_sign_ed25519_MESSAGEBYTES_MAX
+SODIUM_EXPORT
+size_t crypto_sign_messagebytes_max(void);
+
+#define crypto_sign_PRIMITIVE "ed25519"
+SODIUM_EXPORT
+const char *crypto_sign_primitive(void);
+
+SODIUM_EXPORT
+int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed);
+
+SODIUM_EXPORT
+int crypto_sign_keypair(unsigned char *pk, unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p,
+ const unsigned char *sm, unsigned long long smlen,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_verify_detached(const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_sign_init(crypto_sign_state *state);
+
+SODIUM_EXPORT
+int crypto_sign_update(crypto_sign_state *state,
+ const unsigned char *m, unsigned long long mlen);
+
+SODIUM_EXPORT
+int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig,
+ unsigned long long *siglen_p,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_final_verify(crypto_sign_state *state, unsigned char *sig,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h
new file mode 100644
index 0000000000..38d2b9dd63
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h
@@ -0,0 +1,114 @@
+#ifndef crypto_sign_ed25519_H
+#define crypto_sign_ed25519_H
+
+#include <stddef.h>
+#include "crypto_hash_sha512.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef struct crypto_sign_ed25519ph_state {
+ crypto_hash_sha512_state hs;
+} crypto_sign_ed25519ph_state;
+
+SODIUM_EXPORT
+size_t crypto_sign_ed25519ph_statebytes(void);
+
+#define crypto_sign_ed25519_BYTES 64U
+SODIUM_EXPORT
+size_t crypto_sign_ed25519_bytes(void);
+
+#define crypto_sign_ed25519_SEEDBYTES 32U
+SODIUM_EXPORT
+size_t crypto_sign_ed25519_seedbytes(void);
+
+#define crypto_sign_ed25519_PUBLICKEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_sign_ed25519_publickeybytes(void);
+
+#define crypto_sign_ed25519_SECRETKEYBYTES (32U + 32U)
+SODIUM_EXPORT
+size_t crypto_sign_ed25519_secretkeybytes(void);
+
+#define crypto_sign_ed25519_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_ed25519_BYTES)
+SODIUM_EXPORT
+size_t crypto_sign_ed25519_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p,
+ const unsigned char *sm, unsigned long long smlen,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_detached(unsigned char *sig,
+ unsigned long long *siglen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_verify_detached(const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk,
+ const unsigned char *ed25519_pk)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
+ const unsigned char *ed25519_sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state,
+ const unsigned char *m,
+ unsigned long long mlen);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state,
+ unsigned char *sig,
+ unsigned long long *siglen_p,
+ const unsigned char *sk);
+
+SODIUM_EXPORT
+int crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state,
+ unsigned char *sig,
+ const unsigned char *pk)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h b/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h
new file mode 100644
index 0000000000..4bb9192470
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h
@@ -0,0 +1,55 @@
+#ifndef crypto_sign_edwards25519sha512batch_H
+#define crypto_sign_edwards25519sha512batch_H
+
+/*
+ * WARNING: This construction was a prototype, which should not be used
+ * any more in new projects.
+ *
+ * crypto_sign_edwards25519sha512batch is provided for applications
+ * initially built with NaCl, but as recommended by the author of this
+ * construction, new applications should use ed25519 instead.
+ *
+ * In Sodium, you should use the high-level crypto_sign_*() functions instead.
+ */
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_sign_edwards25519sha512batch_BYTES 64U
+#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U
+#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U)
+#define crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_edwards25519sha512batch_BYTES)
+
+SODIUM_EXPORT
+int crypto_sign_edwards25519sha512batch(unsigned char *sm,
+ unsigned long long *smlen_p,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *sk)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+int crypto_sign_edwards25519sha512batch_open(unsigned char *m,
+ unsigned long long *mlen_p,
+ const unsigned char *sm,
+ unsigned long long smlen,
+ const unsigned char *pk)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk,
+ unsigned char *sk)
+ __attribute__ ((deprecated));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream.h b/libs/libsodium/src/include/sodium/crypto_stream.h
new file mode 100644
index 0000000000..d288f0b6dd
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream.h
@@ -0,0 +1,56 @@
+#ifndef crypto_stream_H
+#define crypto_stream_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+
+#include "crypto_stream_xsalsa20.h"
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
+SODIUM_EXPORT
+size_t crypto_stream_keybytes(void);
+
+#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
+SODIUM_EXPORT
+size_t crypto_stream_noncebytes(void);
+
+#define crypto_stream_MESSAGEBYTES_MAX crypto_stream_xsalsa20_MESSAGEBYTES_MAX
+SODIUM_EXPORT
+size_t crypto_stream_messagebytes_max(void);
+
+#define crypto_stream_PRIMITIVE "xsalsa20"
+SODIUM_EXPORT
+const char *crypto_stream_primitive(void);
+
+SODIUM_EXPORT
+int crypto_stream(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h b/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h
new file mode 100644
index 0000000000..d3e2b234ef
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h
@@ -0,0 +1,98 @@
+#ifndef crypto_stream_chacha20_H
+#define crypto_stream_chacha20_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_chacha20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_keybytes(void);
+
+#define crypto_stream_chacha20_NONCEBYTES 8U
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_noncebytes(void);
+
+#define crypto_stream_chacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_messagebytes_max(void);
+
+/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */
+
+SODIUM_EXPORT
+int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]);
+
+/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */
+
+#define crypto_stream_chacha20_ietf_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_ietf_keybytes(void);
+
+#define crypto_stream_chacha20_ietf_NONCEBYTES 12U
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_ietf_noncebytes(void);
+
+#define crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX \
+ SODIUM_MIN(SODIUM_SIZE_MAX, 64ULL * (1ULL << 32))
+SODIUM_EXPORT
+size_t crypto_stream_chacha20_ietf_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint32_t ic,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]);
+
+/* Aliases */
+
+#define crypto_stream_chacha20_IETF_KEYBYTES crypto_stream_chacha20_ietf_KEYBYTES
+#define crypto_stream_chacha20_IETF_NONCEBYTES crypto_stream_chacha20_ietf_NONCEBYTES
+#define crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h
new file mode 100644
index 0000000000..0c7688c736
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h
@@ -0,0 +1,57 @@
+#ifndef crypto_stream_salsa20_H
+#define crypto_stream_salsa20_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_salsa20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_salsa20_keybytes(void);
+
+#define crypto_stream_salsa20_NONCEBYTES 8U
+SODIUM_EXPORT
+size_t crypto_stream_salsa20_noncebytes(void);
+
+#define crypto_stream_salsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_stream_salsa20_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_stream_salsa20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h
new file mode 100644
index 0000000000..c93d1c81f8
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h
@@ -0,0 +1,50 @@
+#ifndef crypto_stream_salsa2012_H
+#define crypto_stream_salsa2012_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_salsa2012_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_salsa2012_keybytes(void);
+
+#define crypto_stream_salsa2012_NONCEBYTES 8U
+SODIUM_EXPORT
+size_t crypto_stream_salsa2012_noncebytes(void);
+
+#define crypto_stream_salsa2012_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_stream_salsa2012_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h
new file mode 100644
index 0000000000..653f6504bd
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h
@@ -0,0 +1,56 @@
+#ifndef crypto_stream_salsa208_H
+#define crypto_stream_salsa208_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_salsa208_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_salsa208_keybytes(void)
+ __attribute__ ((deprecated));
+
+#define crypto_stream_salsa208_NONCEBYTES 8U
+SODIUM_EXPORT
+size_t crypto_stream_salsa208_noncebytes(void)
+ __attribute__ ((deprecated));
+
+#define crypto_stream_salsa208_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+ SODIUM_EXPORT
+size_t crypto_stream_salsa208_messagebytes_max(void)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+int crypto_stream_salsa208(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k)
+ __attribute__ ((deprecated));
+
+SODIUM_EXPORT
+void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES])
+ __attribute__ ((deprecated));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h b/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h
new file mode 100644
index 0000000000..cf0407ffa7
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h
@@ -0,0 +1,57 @@
+#ifndef crypto_stream_xchacha20_H
+#define crypto_stream_xchacha20_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_xchacha20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_xchacha20_keybytes(void);
+
+#define crypto_stream_xchacha20_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_stream_xchacha20_noncebytes(void);
+
+#define crypto_stream_xchacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_stream_xchacha20_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h b/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h
new file mode 100644
index 0000000000..cb4c44a8b8
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h
@@ -0,0 +1,57 @@
+#ifndef crypto_stream_xsalsa20_H
+#define crypto_stream_xsalsa20_H
+
+/*
+ * WARNING: This is just a stream cipher. It is NOT authenticated encryption.
+ * While it provides some protection against eavesdropping, it does NOT
+ * provide any security against active attacks.
+ * Unless you know what you're doing, what you are looking for is probably
+ * the crypto_box functions.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_stream_xsalsa20_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_stream_xsalsa20_keybytes(void);
+
+#define crypto_stream_xsalsa20_NONCEBYTES 24U
+SODIUM_EXPORT
+size_t crypto_stream_xsalsa20_noncebytes(void);
+
+#define crypto_stream_xsalsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX
+SODIUM_EXPORT
+size_t crypto_stream_xsalsa20_messagebytes_max(void);
+
+SODIUM_EXPORT
+int crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen,
+ const unsigned char *n, const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *n,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+int crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *n, uint64_t ic,
+ const unsigned char *k);
+
+SODIUM_EXPORT
+void crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_verify_16.h b/libs/libsodium/src/include/sodium/crypto_verify_16.h
new file mode 100644
index 0000000000..5e9eeabee8
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_verify_16.h
@@ -0,0 +1,23 @@
+#ifndef crypto_verify_16_H
+#define crypto_verify_16_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_verify_16_BYTES 16U
+SODIUM_EXPORT
+size_t crypto_verify_16_bytes(void);
+
+SODIUM_EXPORT
+int crypto_verify_16(const unsigned char *x, const unsigned char *y)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_verify_32.h b/libs/libsodium/src/include/sodium/crypto_verify_32.h
new file mode 100644
index 0000000000..281b5a1bb7
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_verify_32.h
@@ -0,0 +1,23 @@
+#ifndef crypto_verify_32_H
+#define crypto_verify_32_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_verify_32_BYTES 32U
+SODIUM_EXPORT
+size_t crypto_verify_32_bytes(void);
+
+SODIUM_EXPORT
+int crypto_verify_32(const unsigned char *x, const unsigned char *y)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/crypto_verify_64.h b/libs/libsodium/src/include/sodium/crypto_verify_64.h
new file mode 100644
index 0000000000..0dc7c304a9
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/crypto_verify_64.h
@@ -0,0 +1,23 @@
+#ifndef crypto_verify_64_H
+#define crypto_verify_64_H
+
+#include <stddef.h>
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define crypto_verify_64_BYTES 64U
+SODIUM_EXPORT
+size_t crypto_verify_64_bytes(void);
+
+SODIUM_EXPORT
+int crypto_verify_64(const unsigned char *x, const unsigned char *y)
+ __attribute__ ((warn_unused_result));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/export.h b/libs/libsodium/src/include/sodium/export.h
new file mode 100644
index 0000000000..0f624ae3c5
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/export.h
@@ -0,0 +1,53 @@
+
+#ifndef sodium_export_H
+#define sodium_export_H
+
+#ifndef __GNUC__
+# ifdef __attribute__
+# undef __attribute__
+# endif
+# define __attribute__(a)
+#endif
+
+#ifdef SODIUM_STATIC
+# define SODIUM_EXPORT
+# define SODIUM_EXPORT_WEAK
+#else
+# if defined(_MSC_VER)
+# ifdef SODIUM_DLL_EXPORT
+# define SODIUM_EXPORT __declspec(dllexport)
+# else
+# define SODIUM_EXPORT __declspec(dllimport)
+# endif
+# else
+# if defined(__SUNPRO_C)
+# ifndef __GNU_C__
+# define SODIUM_EXPORT __attribute__ (visibility(__global))
+# else
+# define SODIUM_EXPORT __attribute__ __global
+# endif
+# elif defined(_MSG_VER)
+# define SODIUM_EXPORT extern __declspec(dllexport)
+# else
+# define SODIUM_EXPORT __attribute__ ((visibility ("default")))
+# endif
+# endif
+# if defined(__ELF__) && !defined(SODIUM_DISABLE_WEAK_FUNCTIONS)
+# define SODIUM_EXPORT_WEAK SODIUM_EXPORT __attribute__((weak))
+# else
+# define SODIUM_EXPORT_WEAK SODIUM_EXPORT
+# endif
+#endif
+
+#ifndef CRYPTO_ALIGN
+# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# define CRYPTO_ALIGN(x) __declspec(align(x))
+# else
+# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
+# endif
+#endif
+
+#define SODIUM_MIN(A, B) ((A) < (B) ? (A) : (B))
+#define SODIUM_SIZE_MAX SODIUM_MIN(UINT64_MAX, SIZE_MAX)
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/private/common.h b/libs/libsodium/src/include/sodium/private/common.h
new file mode 100644
index 0000000000..954d02ccd7
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/common.h
@@ -0,0 +1,246 @@
+#ifndef common_H
+#define common_H 1
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1])
+
+#ifdef HAVE_TI_MODE
+# if defined(__SIZEOF_INT128__)
+typedef unsigned __int128 uint128_t;
+# else
+typedef unsigned uint128_t __attribute__((mode(TI)));
+# endif
+#endif
+
+#define ROTL32(X, B) rotl32((X), (B))
+static inline uint32_t
+rotl32(const uint32_t x, const int b)
+{
+ return (x << b) | (x >> (32 - b));
+}
+
+#define ROTL64(X, B) rotl64((X), (B))
+static inline uint64_t
+rotl64(const uint64_t x, const int b)
+{
+ return (x << b) | (x >> (64 - b));
+}
+
+#define ROTR32(X, B) rotr32((X), (B))
+static inline uint32_t
+rotr32(const uint32_t x, const int b)
+{
+ return (x >> b) | (x << (32 - b));
+}
+
+#define ROTR64(X, B) rotr64((X), (B))
+static inline uint64_t
+rotr64(const uint64_t x, const int b)
+{
+ return (x >> b) | (x << (64 - b));
+}
+
+#define LOAD64_LE(SRC) load64_le(SRC)
+static inline uint64_t
+load64_le(const uint8_t src[8])
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ uint64_t w;
+ memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint64_t w = (uint64_t) src[0];
+ w |= (uint64_t) src[1] << 8;
+ w |= (uint64_t) src[2] << 16;
+ w |= (uint64_t) src[3] << 24;
+ w |= (uint64_t) src[4] << 32;
+ w |= (uint64_t) src[5] << 40;
+ w |= (uint64_t) src[6] << 48;
+ w |= (uint64_t) src[7] << 56;
+ return w;
+#endif
+}
+
+#define STORE64_LE(DST, W) store64_le((DST), (W))
+static inline void
+store64_le(uint8_t dst[8], uint64_t w)
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ memcpy(dst, &w, sizeof w);
+#else
+ dst[0] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[4] = (uint8_t) w; w >>= 8;
+ dst[5] = (uint8_t) w; w >>= 8;
+ dst[6] = (uint8_t) w; w >>= 8;
+ dst[7] = (uint8_t) w;
+#endif
+}
+
+#define LOAD32_LE(SRC) load32_le(SRC)
+static inline uint32_t
+load32_le(const uint8_t src[4])
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ uint32_t w;
+ memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint32_t w = (uint32_t) src[0];
+ w |= (uint32_t) src[1] << 8;
+ w |= (uint32_t) src[2] << 16;
+ w |= (uint32_t) src[3] << 24;
+ return w;
+#endif
+}
+
+#define STORE32_LE(DST, W) store32_le((DST), (W))
+static inline void
+store32_le(uint8_t dst[4], uint32_t w)
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ memcpy(dst, &w, sizeof w);
+#else
+ dst[0] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w;
+#endif
+}
+
+/* ----- */
+
+#define LOAD64_BE(SRC) load64_be(SRC)
+static inline uint64_t
+load64_be(const uint8_t src[8])
+{
+#ifdef NATIVE_BIG_ENDIAN
+ uint64_t w;
+ memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint64_t w = (uint64_t) src[7];
+ w |= (uint64_t) src[6] << 8;
+ w |= (uint64_t) src[5] << 16;
+ w |= (uint64_t) src[4] << 24;
+ w |= (uint64_t) src[3] << 32;
+ w |= (uint64_t) src[2] << 40;
+ w |= (uint64_t) src[1] << 48;
+ w |= (uint64_t) src[0] << 56;
+ return w;
+#endif
+}
+
+#define STORE64_BE(DST, W) store64_be((DST), (W))
+static inline void
+store64_be(uint8_t dst[8], uint64_t w)
+{
+#ifdef NATIVE_BIG_ENDIAN
+ memcpy(dst, &w, sizeof w);
+#else
+ dst[7] = (uint8_t) w; w >>= 8;
+ dst[6] = (uint8_t) w; w >>= 8;
+ dst[5] = (uint8_t) w; w >>= 8;
+ dst[4] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[0] = (uint8_t) w;
+#endif
+}
+
+#define LOAD32_BE(SRC) load32_be(SRC)
+static inline uint32_t
+load32_be(const uint8_t src[4])
+{
+#ifdef NATIVE_BIG_ENDIAN
+ uint32_t w;
+ memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint32_t w = (uint32_t) src[3];
+ w |= (uint32_t) src[2] << 8;
+ w |= (uint32_t) src[1] << 16;
+ w |= (uint32_t) src[0] << 24;
+ return w;
+#endif
+}
+
+#define STORE32_BE(DST, W) store32_be((DST), (W))
+static inline void
+store32_be(uint8_t dst[4], uint32_t w)
+{
+#ifdef NATIVE_BIG_ENDIAN
+ memcpy(dst, &w, sizeof w);
+#else
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[0] = (uint8_t) w;
+#endif
+}
+
+#define XOR_BUF(OUT, IN, N) xor_buf((OUT), (IN), (N))
+static inline void
+xor_buf(unsigned char *out, const unsigned char *in, size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ out[i] ^= in[i];
+ }
+}
+
+#ifndef __GNUC__
+# ifdef __attribute__
+# undef __attribute__
+# endif
+# define __attribute__(a)
+#endif
+
+#ifndef CRYPTO_ALIGN
+# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# define CRYPTO_ALIGN(x) __declspec(align(x))
+# else
+# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
+# endif
+#endif
+
+#if defined(_MSC_VER) && \
+ (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86))
+
+# include <intrin.h>
+
+# define HAVE_INTRIN_H 1
+# define HAVE_MMINTRIN_H 1
+# define HAVE_EMMINTRIN_H 1
+# define HAVE_PMMINTRIN_H 1
+# define HAVE_TMMINTRIN_H 1
+# define HAVE_SMMINTRIN_H 1
+# define HAVE_AVXINTRIN_H 1
+# if _MSC_VER >= 1600
+# define HAVE_WMMINTRIN_H 1
+# endif
+# if _MSC_VER >= 1700 && defined(_M_X64)
+# define HAVE_AVX2INTRIN_H 1
+# endif
+#elif defined(HAVE_INTRIN_H)
+# include <intrin.h>
+#endif
+
+#ifdef HAVE_LIBCTGRIND
+extern void ct_poison (const void *, size_t);
+extern void ct_unpoison(const void *, size_t);
+# define POISON(X, L) ct_poison((X), (L))
+# define UNPOISON(X, L) ct_unpoison((X), (L))
+#else
+# define POISON(X, L) (void) 0
+# define UNPOISON(X, L) (void) 0
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h
new file mode 100644
index 0000000000..42fcd98139
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h
@@ -0,0 +1,125 @@
+#ifndef ed25519_ref10_H
+#define ed25519_ref10_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ fe means field element.
+ Here the field is \Z/(2^255-19).
+ */
+
+#ifdef HAVE_TI_MODE
+typedef uint64_t fe25519[5];
+#else
+typedef int32_t fe25519[10];
+#endif
+
+void fe25519_invert(fe25519 out, const fe25519 z);
+void fe25519_frombytes(fe25519 h, const unsigned char *s);
+void fe25519_tobytes(unsigned char *s, const fe25519 h);
+
+#ifdef HAVE_TI_MODE
+# include "ed25519_ref10_fe_51.h"
+#else
+# include "ed25519_ref10_fe_25_5.h"
+#endif
+
+
+/*
+ ge means group element.
+
+ Here the group is the set of pairs (x,y) of field elements
+ satisfying -x^2 + y^2 = 1 + d x^2y^2
+ where d = -121665/121666.
+
+ Representations:
+ ge25519_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
+ ge25519_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
+ ge25519_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
+ ge25519_precomp (Duif): (y+x,y-x,2dxy)
+ */
+
+typedef struct {
+ fe25519 X;
+ fe25519 Y;
+ fe25519 Z;
+} ge25519_p2;
+
+typedef struct {
+ fe25519 X;
+ fe25519 Y;
+ fe25519 Z;
+ fe25519 T;
+} ge25519_p3;
+
+typedef struct {
+ fe25519 X;
+ fe25519 Y;
+ fe25519 Z;
+ fe25519 T;
+} ge25519_p1p1;
+
+typedef struct {
+ fe25519 yplusx;
+ fe25519 yminusx;
+ fe25519 xy2d;
+} ge25519_precomp;
+
+typedef struct {
+ fe25519 YplusX;
+ fe25519 YminusX;
+ fe25519 Z;
+ fe25519 T2d;
+} ge25519_cached;
+
+void ge25519_tobytes(unsigned char *s, const ge25519_p2 *h);
+
+void ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h);
+
+int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s);
+
+int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s);
+
+void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p);
+
+void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p);
+
+void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p);
+
+void ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q);
+
+void ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q);
+
+void ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a);
+
+void ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a,
+ const ge25519_p3 *A,
+ const unsigned char *b);
+
+void ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a,
+ const ge25519_p3 *p);
+
+int ge25519_is_canonical(const unsigned char *s);
+
+int ge25519_is_on_curve(const ge25519_p3 *p);
+
+int ge25519_is_on_main_subgroup(const ge25519_p3 *p);
+
+int ge25519_has_small_order(const unsigned char s[32]);
+
+void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]);
+
+/*
+ The set of scalars is \Z/l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+ */
+
+void sc25519_reduce(unsigned char *s);
+
+void sc25519_muladd(unsigned char *s, const unsigned char *a,
+ const unsigned char *b, const unsigned char *c);
+
+int sc25519_is_canonical(const unsigned char *s);
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h
new file mode 100644
index 0000000000..5a0b6148b7
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h
@@ -0,0 +1,1050 @@
+#include <string.h>
+
+#include "private/common.h"
+#include "utils.h"
+
+/*
+ h = 0
+ */
+
+static inline void
+fe25519_0(fe25519 h)
+{
+ memset(&h[0], 0, 10 * sizeof h[0]);
+}
+
+/*
+ h = 1
+ */
+
+static inline void
+fe25519_1(fe25519 h)
+{
+ h[0] = 1;
+ h[1] = 0;
+ memset(&h[2], 0, 8 * sizeof h[0]);
+}
+
+/*
+ h = f + g
+ Can overlap h with f or g.
+ *
+ Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+
+static inline void
+fe25519_add(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ int32_t h0 = f[0] + g[0];
+ int32_t h1 = f[1] + g[1];
+ int32_t h2 = f[2] + g[2];
+ int32_t h3 = f[3] + g[3];
+ int32_t h4 = f[4] + g[4];
+ int32_t h5 = f[5] + g[5];
+ int32_t h6 = f[6] + g[6];
+ int32_t h7 = f[7] + g[7];
+ int32_t h8 = f[8] + g[8];
+ int32_t h9 = f[9] + g[9];
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/*
+ h = f - g
+ Can overlap h with f or g.
+ *
+ Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+
+static void
+fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ int32_t h0 = f[0] - g[0];
+ int32_t h1 = f[1] - g[1];
+ int32_t h2 = f[2] - g[2];
+ int32_t h3 = f[3] - g[3];
+ int32_t h4 = f[4] - g[4];
+ int32_t h5 = f[5] - g[5];
+ int32_t h6 = f[6] - g[6];
+ int32_t h7 = f[7] - g[7];
+ int32_t h8 = f[8] - g[8];
+ int32_t h9 = f[9] - g[9];
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/*
+ h = -f
+ *
+ Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ */
+
+static inline void
+fe25519_neg(fe25519 h, const fe25519 f)
+{
+ int32_t h0 = -f[0];
+ int32_t h1 = -f[1];
+ int32_t h2 = -f[2];
+ int32_t h3 = -f[3];
+ int32_t h4 = -f[4];
+ int32_t h5 = -f[5];
+ int32_t h6 = -f[6];
+ int32_t h7 = -f[7];
+ int32_t h8 = -f[8];
+ int32_t h9 = -f[9];
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
+
+/*
+ Replace (f,g) with (g,g) if b == 1;
+ replace (f,g) with (f,g) if b == 0.
+ *
+ Preconditions: b in {0,1}.
+ */
+
+static void
+fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b)
+{
+ const uint32_t mask = (uint32_t) (-(int32_t) b);
+
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ int32_t x0 = f0 ^ g[0];
+ int32_t x1 = f1 ^ g[1];
+ int32_t x2 = f2 ^ g[2];
+ int32_t x3 = f3 ^ g[3];
+ int32_t x4 = f4 ^ g[4];
+ int32_t x5 = f5 ^ g[5];
+ int32_t x6 = f6 ^ g[6];
+ int32_t x7 = f7 ^ g[7];
+ int32_t x8 = f8 ^ g[8];
+ int32_t x9 = f9 ^ g[9];
+
+ x0 &= mask;
+ x1 &= mask;
+ x2 &= mask;
+ x3 &= mask;
+ x4 &= mask;
+ x5 &= mask;
+ x6 &= mask;
+ x7 &= mask;
+ x8 &= mask;
+ x9 &= mask;
+
+ f[0] = f0 ^ x0;
+ f[1] = f1 ^ x1;
+ f[2] = f2 ^ x2;
+ f[3] = f3 ^ x3;
+ f[4] = f4 ^ x4;
+ f[5] = f5 ^ x5;
+ f[6] = f6 ^ x6;
+ f[7] = f7 ^ x7;
+ f[8] = f8 ^ x8;
+ f[9] = f9 ^ x9;
+}
+
+static void
+fe25519_cswap(fe25519 f, fe25519 g, unsigned int b)
+{
+ const uint32_t mask = (uint32_t) (-(int64_t) b);
+
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ int32_t g0 = g[0];
+ int32_t g1 = g[1];
+ int32_t g2 = g[2];
+ int32_t g3 = g[3];
+ int32_t g4 = g[4];
+ int32_t g5 = g[5];
+ int32_t g6 = g[6];
+ int32_t g7 = g[7];
+ int32_t g8 = g[8];
+ int32_t g9 = g[9];
+
+ int32_t x0 = f0 ^ g0;
+ int32_t x1 = f1 ^ g1;
+ int32_t x2 = f2 ^ g2;
+ int32_t x3 = f3 ^ g3;
+ int32_t x4 = f4 ^ g4;
+ int32_t x5 = f5 ^ g5;
+ int32_t x6 = f6 ^ g6;
+ int32_t x7 = f7 ^ g7;
+ int32_t x8 = f8 ^ g8;
+ int32_t x9 = f9 ^ g9;
+
+ x0 &= mask;
+ x1 &= mask;
+ x2 &= mask;
+ x3 &= mask;
+ x4 &= mask;
+ x5 &= mask;
+ x6 &= mask;
+ x7 &= mask;
+ x8 &= mask;
+ x9 &= mask;
+
+ f[0] = f0 ^ x0;
+ f[1] = f1 ^ x1;
+ f[2] = f2 ^ x2;
+ f[3] = f3 ^ x3;
+ f[4] = f4 ^ x4;
+ f[5] = f5 ^ x5;
+ f[6] = f6 ^ x6;
+ f[7] = f7 ^ x7;
+ f[8] = f8 ^ x8;
+ f[9] = f9 ^ x9;
+
+ g[0] = g0 ^ x0;
+ g[1] = g1 ^ x1;
+ g[2] = g2 ^ x2;
+ g[3] = g3 ^ x3;
+ g[4] = g4 ^ x4;
+ g[5] = g5 ^ x5;
+ g[6] = g6 ^ x6;
+ g[7] = g7 ^ x7;
+ g[8] = g8 ^ x8;
+ g[9] = g9 ^ x9;
+}
+
+/*
+ h = f
+ */
+
+static inline void
+fe25519_copy(fe25519 h, const fe25519 f)
+{
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ h[0] = f0;
+ h[1] = f1;
+ h[2] = f2;
+ h[3] = f3;
+ h[4] = f4;
+ h[5] = f5;
+ h[6] = f6;
+ h[7] = f7;
+ h[8] = f8;
+ h[9] = f9;
+}
+
+/*
+ return 1 if f is in {1,3,5,...,q-2}
+ return 0 if f is in {0,2,4,...,q-1}
+
+ Preconditions:
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+
+static inline int
+fe25519_isnegative(const fe25519 f)
+{
+ unsigned char s[32];
+
+ fe25519_tobytes(s, f);
+
+ return s[0] & 1;
+}
+
+/*
+ return 1 if f == 0
+ return 0 if f != 0
+
+ Preconditions:
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ */
+
+static inline int
+fe25519_iszero(const fe25519 f)
+{
+ unsigned char s[32];
+
+ fe25519_tobytes(s, f);
+
+ return sodium_is_zero(s, 32);
+}
+
+/*
+ h = f * g
+ Can overlap h with f or g.
+ *
+ Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ */
+
+/*
+ Notes on implementation strategy:
+ *
+ Using schoolbook multiplication.
+ Karatsuba would save a little in some cost models.
+ *
+ Most multiplications by 2 and 19 are 32-bit precomputations;
+ cheaper than 64-bit postcomputations.
+ *
+ There is one remaining multiplication by 19 in the carry chain;
+ one *19 precomputation can be merged into this,
+ but the resulting data flow is considerably less clean.
+ *
+ There are 12 carries below.
+ 10 of them are 2-way parallelizable and vectorizable.
+ Can get away with 11 carries, but then data flow is much deeper.
+ *
+ With tighter constraints on inputs can squeeze carries into int32.
+ */
+
+static void
+fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ int32_t g0 = g[0];
+ int32_t g1 = g[1];
+ int32_t g2 = g[2];
+ int32_t g3 = g[3];
+ int32_t g4 = g[4];
+ int32_t g5 = g[5];
+ int32_t g6 = g[6];
+ int32_t g7 = g[7];
+ int32_t g8 = g[8];
+ int32_t g9 = g[9];
+
+ int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
+ int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
+ int32_t g3_19 = 19 * g3;
+ int32_t g4_19 = 19 * g4;
+ int32_t g5_19 = 19 * g5;
+ int32_t g6_19 = 19 * g6;
+ int32_t g7_19 = 19 * g7;
+ int32_t g8_19 = 19 * g8;
+ int32_t g9_19 = 19 * g9;
+ int32_t f1_2 = 2 * f1;
+ int32_t f3_2 = 2 * f3;
+ int32_t f5_2 = 2 * f5;
+ int32_t f7_2 = 2 * f7;
+ int32_t f9_2 = 2 * f9;
+
+ int64_t f0g0 = f0 * (int64_t) g0;
+ int64_t f0g1 = f0 * (int64_t) g1;
+ int64_t f0g2 = f0 * (int64_t) g2;
+ int64_t f0g3 = f0 * (int64_t) g3;
+ int64_t f0g4 = f0 * (int64_t) g4;
+ int64_t f0g5 = f0 * (int64_t) g5;
+ int64_t f0g6 = f0 * (int64_t) g6;
+ int64_t f0g7 = f0 * (int64_t) g7;
+ int64_t f0g8 = f0 * (int64_t) g8;
+ int64_t f0g9 = f0 * (int64_t) g9;
+ int64_t f1g0 = f1 * (int64_t) g0;
+ int64_t f1g1_2 = f1_2 * (int64_t) g1;
+ int64_t f1g2 = f1 * (int64_t) g2;
+ int64_t f1g3_2 = f1_2 * (int64_t) g3;
+ int64_t f1g4 = f1 * (int64_t) g4;
+ int64_t f1g5_2 = f1_2 * (int64_t) g5;
+ int64_t f1g6 = f1 * (int64_t) g6;
+ int64_t f1g7_2 = f1_2 * (int64_t) g7;
+ int64_t f1g8 = f1 * (int64_t) g8;
+ int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
+ int64_t f2g0 = f2 * (int64_t) g0;
+ int64_t f2g1 = f2 * (int64_t) g1;
+ int64_t f2g2 = f2 * (int64_t) g2;
+ int64_t f2g3 = f2 * (int64_t) g3;
+ int64_t f2g4 = f2 * (int64_t) g4;
+ int64_t f2g5 = f2 * (int64_t) g5;
+ int64_t f2g6 = f2 * (int64_t) g6;
+ int64_t f2g7 = f2 * (int64_t) g7;
+ int64_t f2g8_19 = f2 * (int64_t) g8_19;
+ int64_t f2g9_19 = f2 * (int64_t) g9_19;
+ int64_t f3g0 = f3 * (int64_t) g0;
+ int64_t f3g1_2 = f3_2 * (int64_t) g1;
+ int64_t f3g2 = f3 * (int64_t) g2;
+ int64_t f3g3_2 = f3_2 * (int64_t) g3;
+ int64_t f3g4 = f3 * (int64_t) g4;
+ int64_t f3g5_2 = f3_2 * (int64_t) g5;
+ int64_t f3g6 = f3 * (int64_t) g6;
+ int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
+ int64_t f3g8_19 = f3 * (int64_t) g8_19;
+ int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
+ int64_t f4g0 = f4 * (int64_t) g0;
+ int64_t f4g1 = f4 * (int64_t) g1;
+ int64_t f4g2 = f4 * (int64_t) g2;
+ int64_t f4g3 = f4 * (int64_t) g3;
+ int64_t f4g4 = f4 * (int64_t) g4;
+ int64_t f4g5 = f4 * (int64_t) g5;
+ int64_t f4g6_19 = f4 * (int64_t) g6_19;
+ int64_t f4g7_19 = f4 * (int64_t) g7_19;
+ int64_t f4g8_19 = f4 * (int64_t) g8_19;
+ int64_t f4g9_19 = f4 * (int64_t) g9_19;
+ int64_t f5g0 = f5 * (int64_t) g0;
+ int64_t f5g1_2 = f5_2 * (int64_t) g1;
+ int64_t f5g2 = f5 * (int64_t) g2;
+ int64_t f5g3_2 = f5_2 * (int64_t) g3;
+ int64_t f5g4 = f5 * (int64_t) g4;
+ int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
+ int64_t f5g6_19 = f5 * (int64_t) g6_19;
+ int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
+ int64_t f5g8_19 = f5 * (int64_t) g8_19;
+ int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
+ int64_t f6g0 = f6 * (int64_t) g0;
+ int64_t f6g1 = f6 * (int64_t) g1;
+ int64_t f6g2 = f6 * (int64_t) g2;
+ int64_t f6g3 = f6 * (int64_t) g3;
+ int64_t f6g4_19 = f6 * (int64_t) g4_19;
+ int64_t f6g5_19 = f6 * (int64_t) g5_19;
+ int64_t f6g6_19 = f6 * (int64_t) g6_19;
+ int64_t f6g7_19 = f6 * (int64_t) g7_19;
+ int64_t f6g8_19 = f6 * (int64_t) g8_19;
+ int64_t f6g9_19 = f6 * (int64_t) g9_19;
+ int64_t f7g0 = f7 * (int64_t) g0;
+ int64_t f7g1_2 = f7_2 * (int64_t) g1;
+ int64_t f7g2 = f7 * (int64_t) g2;
+ int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
+ int64_t f7g4_19 = f7 * (int64_t) g4_19;
+ int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
+ int64_t f7g6_19 = f7 * (int64_t) g6_19;
+ int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
+ int64_t f7g8_19 = f7 * (int64_t) g8_19;
+ int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
+ int64_t f8g0 = f8 * (int64_t) g0;
+ int64_t f8g1 = f8 * (int64_t) g1;
+ int64_t f8g2_19 = f8 * (int64_t) g2_19;
+ int64_t f8g3_19 = f8 * (int64_t) g3_19;
+ int64_t f8g4_19 = f8 * (int64_t) g4_19;
+ int64_t f8g5_19 = f8 * (int64_t) g5_19;
+ int64_t f8g6_19 = f8 * (int64_t) g6_19;
+ int64_t f8g7_19 = f8 * (int64_t) g7_19;
+ int64_t f8g8_19 = f8 * (int64_t) g8_19;
+ int64_t f8g9_19 = f8 * (int64_t) g9_19;
+ int64_t f9g0 = f9 * (int64_t) g0;
+ int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
+ int64_t f9g2_19 = f9 * (int64_t) g2_19;
+ int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
+ int64_t f9g4_19 = f9 * (int64_t) g4_19;
+ int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
+ int64_t f9g6_19 = f9 * (int64_t) g6_19;
+ int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
+ int64_t f9g8_19 = f9 * (int64_t) g8_19;
+ int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
+
+ int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 +
+ f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
+ int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 +
+ f7g4_19 + f8g3_19 + f9g2_19;
+ int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 +
+ f7g5_38 + f8g4_19 + f9g3_38;
+ int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 +
+ f7g6_19 + f8g5_19 + f9g4_19;
+ int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 +
+ f7g7_38 + f8g6_19 + f9g5_38;
+ int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 +
+ f8g7_19 + f9g6_19;
+ int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 +
+ f7g9_38 + f8g8_19 + f9g7_38;
+ int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 +
+ f8g9_19 + f9g8_19;
+ int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 +
+ f8g0 + f9g9_38;
+ int64_t h9 =
+ f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0;
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ /*
+ |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
+ i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
+ |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
+ i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
+ */
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+ /* |h0| <= 2^25 */
+ /* |h4| <= 2^25 */
+ /* |h1| <= 1.71*2^59 */
+ /* |h5| <= 1.71*2^59 */
+
+ carry1 = (h1 + (int64_t)(1L << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((uint64_t) 1L << 25);
+ carry5 = (h5 + (int64_t)(1L << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((uint64_t) 1L << 25);
+ /* |h1| <= 2^24; from now on fits into int32 */
+ /* |h5| <= 2^24; from now on fits into int32 */
+ /* |h2| <= 1.41*2^60 */
+ /* |h6| <= 1.41*2^60 */
+
+ carry2 = (h2 + (int64_t)(1L << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((uint64_t) 1L << 26);
+ carry6 = (h6 + (int64_t)(1L << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((uint64_t) 1L << 26);
+ /* |h2| <= 2^25; from now on fits into int32 unchanged */
+ /* |h6| <= 2^25; from now on fits into int32 unchanged */
+ /* |h3| <= 1.71*2^59 */
+ /* |h7| <= 1.71*2^59 */
+
+ carry3 = (h3 + (int64_t)(1L << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((uint64_t) 1L << 25);
+ carry7 = (h7 + (int64_t)(1L << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((uint64_t) 1L << 25);
+ /* |h3| <= 2^24; from now on fits into int32 unchanged */
+ /* |h7| <= 2^24; from now on fits into int32 unchanged */
+ /* |h4| <= 1.72*2^34 */
+ /* |h8| <= 1.41*2^60 */
+
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+ carry8 = (h8 + (int64_t)(1L << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((uint64_t) 1L << 26);
+ /* |h4| <= 2^25; from now on fits into int32 unchanged */
+ /* |h8| <= 2^25; from now on fits into int32 unchanged */
+ /* |h5| <= 1.01*2^24 */
+ /* |h9| <= 1.71*2^59 */
+
+ carry9 = (h9 + (int64_t)(1L << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 * ((uint64_t) 1L << 25);
+ /* |h9| <= 2^24; from now on fits into int32 unchanged */
+ /* |h0| <= 1.1*2^39 */
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+ /* |h0| <= 2^25; from now on fits into int32 unchanged */
+ /* |h1| <= 1.01*2^24 */
+
+ h[0] = (int32_t) h0;
+ h[1] = (int32_t) h1;
+ h[2] = (int32_t) h2;
+ h[3] = (int32_t) h3;
+ h[4] = (int32_t) h4;
+ h[5] = (int32_t) h5;
+ h[6] = (int32_t) h6;
+ h[7] = (int32_t) h7;
+ h[8] = (int32_t) h8;
+ h[9] = (int32_t) h9;
+}
+
+/*
+ h = f * f
+ Can overlap h with f.
+ *
+ Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ */
+
+static void
+fe25519_sq(fe25519 h, const fe25519 f)
+{
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ int32_t f0_2 = 2 * f0;
+ int32_t f1_2 = 2 * f1;
+ int32_t f2_2 = 2 * f2;
+ int32_t f3_2 = 2 * f3;
+ int32_t f4_2 = 2 * f4;
+ int32_t f5_2 = 2 * f5;
+ int32_t f6_2 = 2 * f6;
+ int32_t f7_2 = 2 * f7;
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+
+ int64_t f0f0 = f0 * (int64_t) f0;
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+ int64_t f2f2 = f2 * (int64_t) f2;
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+ int64_t f4f4 = f4 * (int64_t) f4;
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
+
+ int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
+ int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
+ int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
+ int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
+ int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
+ int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
+ int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
+ int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
+ int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
+ int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+
+ carry1 = (h1 + (int64_t)(1L << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((uint64_t) 1L << 25);
+ carry5 = (h5 + (int64_t)(1L << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((uint64_t) 1L << 25);
+
+ carry2 = (h2 + (int64_t)(1L << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((uint64_t) 1L << 26);
+ carry6 = (h6 + (int64_t)(1L << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((uint64_t) 1L << 26);
+
+ carry3 = (h3 + (int64_t)(1L << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((uint64_t) 1L << 25);
+ carry7 = (h7 + (int64_t)(1L << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((uint64_t) 1L << 25);
+
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+ carry8 = (h8 + (int64_t)(1L << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((uint64_t) 1L << 26);
+
+ carry9 = (h9 + (int64_t)(1L << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 * ((uint64_t) 1L << 25);
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+
+ h[0] = (int32_t) h0;
+ h[1] = (int32_t) h1;
+ h[2] = (int32_t) h2;
+ h[3] = (int32_t) h3;
+ h[4] = (int32_t) h4;
+ h[5] = (int32_t) h5;
+ h[6] = (int32_t) h6;
+ h[7] = (int32_t) h7;
+ h[8] = (int32_t) h8;
+ h[9] = (int32_t) h9;
+}
+
+/*
+ h = 2 * f * f
+ Can overlap h with f.
+ *
+ Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ */
+
+static void
+fe25519_sq2(fe25519 h, const fe25519 f)
+{
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+
+ int32_t f0_2 = 2 * f0;
+ int32_t f1_2 = 2 * f1;
+ int32_t f2_2 = 2 * f2;
+ int32_t f3_2 = 2 * f3;
+ int32_t f4_2 = 2 * f4;
+ int32_t f5_2 = 2 * f5;
+ int32_t f6_2 = 2 * f6;
+ int32_t f7_2 = 2 * f7;
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+
+ int64_t f0f0 = f0 * (int64_t) f0;
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+ int64_t f2f2 = f2 * (int64_t) f2;
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+ int64_t f4f4 = f4 * (int64_t) f4;
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
+
+ int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
+ int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
+ int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
+ int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
+ int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
+ int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
+ int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
+ int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
+ int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
+ int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
+
+ int64_t carry0;
+ int64_t carry1;
+ int64_t carry2;
+ int64_t carry3;
+ int64_t carry4;
+ int64_t carry5;
+ int64_t carry6;
+ int64_t carry7;
+ int64_t carry8;
+ int64_t carry9;
+
+ h0 += h0;
+ h1 += h1;
+ h2 += h2;
+ h3 += h3;
+ h4 += h4;
+ h5 += h5;
+ h6 += h6;
+ h7 += h7;
+ h8 += h8;
+ h9 += h9;
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+
+ carry1 = (h1 + (int64_t)(1L << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((uint64_t) 1L << 25);
+ carry5 = (h5 + (int64_t)(1L << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((uint64_t) 1L << 25);
+
+ carry2 = (h2 + (int64_t)(1L << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((uint64_t) 1L << 26);
+ carry6 = (h6 + (int64_t)(1L << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((uint64_t) 1L << 26);
+
+ carry3 = (h3 + (int64_t)(1L << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((uint64_t) 1L << 25);
+ carry7 = (h7 + (int64_t)(1L << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((uint64_t) 1L << 25);
+
+ carry4 = (h4 + (int64_t)(1L << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((uint64_t) 1L << 26);
+ carry8 = (h8 + (int64_t)(1L << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((uint64_t) 1L << 26);
+
+ carry9 = (h9 + (int64_t)(1L << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 * ((uint64_t) 1L << 25);
+
+ carry0 = (h0 + (int64_t)(1L << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((uint64_t) 1L << 26);
+
+ h[0] = (int32_t) h0;
+ h[1] = (int32_t) h1;
+ h[2] = (int32_t) h2;
+ h[3] = (int32_t) h3;
+ h[4] = (int32_t) h4;
+ h[5] = (int32_t) h5;
+ h[6] = (int32_t) h6;
+ h[7] = (int32_t) h7;
+ h[8] = (int32_t) h8;
+ h[9] = (int32_t) h9;
+}
+
+static void
+fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n)
+{
+ int64_t sn = (int64_t) n;
+ int32_t f0 = f[0];
+ int32_t f1 = f[1];
+ int32_t f2 = f[2];
+ int32_t f3 = f[3];
+ int32_t f4 = f[4];
+ int32_t f5 = f[5];
+ int32_t f6 = f[6];
+ int32_t f7 = f[7];
+ int32_t f8 = f[8];
+ int32_t f9 = f[9];
+ int64_t h0 = f0 * sn;
+ int64_t h1 = f1 * sn;
+ int64_t h2 = f2 * sn;
+ int64_t h3 = f3 * sn;
+ int64_t h4 = f4 * sn;
+ int64_t h5 = f5 * sn;
+ int64_t h6 = f6 * sn;
+ int64_t h7 = f7 * sn;
+ int64_t h8 = f8 * sn;
+ int64_t h9 = f9 * sn;
+ int64_t carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7,
+ carry8, carry9;
+
+ carry9 = (h9 + ((int64_t) 1 << 24)) >> 25;
+ h0 += carry9 * 19;
+ h9 -= carry9 * ((int64_t) 1 << 25);
+ carry1 = (h1 + ((int64_t) 1 << 24)) >> 25;
+ h2 += carry1;
+ h1 -= carry1 * ((int64_t) 1 << 25);
+ carry3 = (h3 + ((int64_t) 1 << 24)) >> 25;
+ h4 += carry3;
+ h3 -= carry3 * ((int64_t) 1 << 25);
+ carry5 = (h5 + ((int64_t) 1 << 24)) >> 25;
+ h6 += carry5;
+ h5 -= carry5 * ((int64_t) 1 << 25);
+ carry7 = (h7 + ((int64_t) 1 << 24)) >> 25;
+ h8 += carry7;
+ h7 -= carry7 * ((int64_t) 1 << 25);
+
+ carry0 = (h0 + ((int64_t) 1 << 25)) >> 26;
+ h1 += carry0;
+ h0 -= carry0 * ((int64_t) 1 << 26);
+ carry2 = (h2 + ((int64_t) 1 << 25)) >> 26;
+ h3 += carry2;
+ h2 -= carry2 * ((int64_t) 1 << 26);
+ carry4 = (h4 + ((int64_t) 1 << 25)) >> 26;
+ h5 += carry4;
+ h4 -= carry4 * ((int64_t) 1 << 26);
+ carry6 = (h6 + ((int64_t) 1 << 25)) >> 26;
+ h7 += carry6;
+ h6 -= carry6 * ((int64_t) 1 << 26);
+ carry8 = (h8 + ((int64_t) 1 << 25)) >> 26;
+ h9 += carry8;
+ h8 -= carry8 * ((int64_t) 1 << 26);
+
+ h[0] = (int32_t) h0;
+ h[1] = (int32_t) h1;
+ h[2] = (int32_t) h2;
+ h[3] = (int32_t) h3;
+ h[4] = (int32_t) h4;
+ h[5] = (int32_t) h5;
+ h[6] = (int32_t) h6;
+ h[7] = (int32_t) h7;
+ h[8] = (int32_t) h8;
+ h[9] = (int32_t) h9;
+}
diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h
new file mode 100644
index 0000000000..3a30f30148
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h
@@ -0,0 +1,518 @@
+#include <string.h>
+
+#include "private/common.h"
+#include "utils.h"
+
+/*
+ h = 0
+ */
+
+static inline void
+fe25519_0(fe25519 h)
+{
+ memset(&h[0], 0, 5 * sizeof h[0]);
+}
+
+/*
+ h = 1
+ */
+
+static inline void
+fe25519_1(fe25519 h)
+{
+ h[0] = 1;
+ memset(&h[1], 0, 4 * sizeof h[0]);
+}
+
+/*
+ h = f + g
+ Can overlap h with f or g.
+ */
+
+static inline void
+fe25519_add(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ uint64_t h0 = f[0] + g[0];
+ uint64_t h1 = f[1] + g[1];
+ uint64_t h2 = f[2] + g[2];
+ uint64_t h3 = f[3] + g[3];
+ uint64_t h4 = f[4] + g[4];
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+}
+
+/*
+ h = f - g
+ */
+
+static void
+fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint64_t h0, h1, h2, h3, h4;
+
+ h0 = g[0];
+ h1 = g[1];
+ h2 = g[2];
+ h3 = g[3];
+ h4 = g[4];
+
+ h1 += h0 >> 51;
+ h0 &= mask;
+ h2 += h1 >> 51;
+ h1 &= mask;
+ h3 += h2 >> 51;
+ h2 &= mask;
+ h4 += h3 >> 51;
+ h3 &= mask;
+ h0 += 19ULL * (h4 >> 51);
+ h4 &= mask;
+
+ h0 = (f[0] + 0xfffffffffffdaULL) - h0;
+ h1 = (f[1] + 0xffffffffffffeULL) - h1;
+ h2 = (f[2] + 0xffffffffffffeULL) - h2;
+ h3 = (f[3] + 0xffffffffffffeULL) - h3;
+ h4 = (f[4] + 0xffffffffffffeULL) - h4;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+}
+
+/*
+ h = -f
+ */
+
+static inline void
+fe25519_neg(fe25519 h, const fe25519 f)
+{
+ fe25519 zero;
+
+ fe25519_0(zero);
+ fe25519_sub(h, zero, f);
+}
+
+/*
+ Replace (f,g) with (g,g) if b == 1;
+ replace (f,g) with (f,g) if b == 0.
+ *
+ Preconditions: b in {0,1}.
+ */
+
+static void
+fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b)
+{
+ const uint64_t mask = (uint64_t) (-(int64_t) b);
+
+ uint64_t f0 = f[0];
+ uint64_t f1 = f[1];
+ uint64_t f2 = f[2];
+ uint64_t f3 = f[3];
+ uint64_t f4 = f[4];
+
+ uint64_t x0 = f0 ^ g[0];
+ uint64_t x1 = f1 ^ g[1];
+ uint64_t x2 = f2 ^ g[2];
+ uint64_t x3 = f3 ^ g[3];
+ uint64_t x4 = f4 ^ g[4];
+
+ x0 &= mask;
+ x1 &= mask;
+ x2 &= mask;
+ x3 &= mask;
+ x4 &= mask;
+
+ f[0] = f0 ^ x0;
+ f[1] = f1 ^ x1;
+ f[2] = f2 ^ x2;
+ f[3] = f3 ^ x3;
+ f[4] = f4 ^ x4;
+}
+
+/*
+Replace (f,g) with (g,f) if b == 1;
+replace (f,g) with (f,g) if b == 0.
+
+Preconditions: b in {0,1}.
+*/
+
+static void
+fe25519_cswap(fe25519 f, fe25519 g, unsigned int b)
+{
+ const uint64_t mask = (uint64_t) (-(int64_t) b);
+
+ uint64_t f0 = f[0];
+ uint64_t f1 = f[1];
+ uint64_t f2 = f[2];
+ uint64_t f3 = f[3];
+ uint64_t f4 = f[4];
+
+ uint64_t g0 = g[0];
+ uint64_t g1 = g[1];
+ uint64_t g2 = g[2];
+ uint64_t g3 = g[3];
+ uint64_t g4 = g[4];
+
+ uint64_t x0 = f0 ^ g0;
+ uint64_t x1 = f1 ^ g1;
+ uint64_t x2 = f2 ^ g2;
+ uint64_t x3 = f3 ^ g3;
+ uint64_t x4 = f4 ^ g4;
+
+ x0 &= mask;
+ x1 &= mask;
+ x2 &= mask;
+ x3 &= mask;
+ x4 &= mask;
+
+ f[0] = f0 ^ x0;
+ f[1] = f1 ^ x1;
+ f[2] = f2 ^ x2;
+ f[3] = f3 ^ x3;
+ f[4] = f4 ^ x4;
+
+ g[0] = g0 ^ x0;
+ g[1] = g1 ^ x1;
+ g[2] = g2 ^ x2;
+ g[3] = g3 ^ x3;
+ g[4] = g4 ^ x4;
+}
+
+/*
+ h = f
+ */
+
+static inline void
+fe25519_copy(fe25519 h, const fe25519 f)
+{
+ uint64_t f0 = f[0];
+ uint64_t f1 = f[1];
+ uint64_t f2 = f[2];
+ uint64_t f3 = f[3];
+ uint64_t f4 = f[4];
+
+ h[0] = f0;
+ h[1] = f1;
+ h[2] = f2;
+ h[3] = f3;
+ h[4] = f4;
+}
+
+/*
+ return 1 if f is in {1,3,5,...,q-2}
+ return 0 if f is in {0,2,4,...,q-1}
+ */
+
+static inline int
+fe25519_isnegative(const fe25519 f)
+{
+ unsigned char s[32];
+
+ fe25519_tobytes(s, f);
+
+ return s[0] & 1;
+}
+
+/*
+ return 1 if f == 0
+ return 0 if f != 0
+ */
+
+static inline int
+fe25519_iszero(const fe25519 f)
+{
+ unsigned char s[32];
+
+ fe25519_tobytes(s, f);
+
+ return sodium_is_zero(s, 32);
+}
+
+/*
+ h = f * g
+ Can overlap h with f or g.
+ */
+
+static void
+fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint128_t r0, r1, r2, r3, r4, carry;
+ uint64_t f0, f1, f2, f3, f4;
+ uint64_t f1_19, f2_19, f3_19, f4_19;
+ uint64_t g0, g1, g2, g3, g4;
+ uint64_t r00, r01, r02, r03, r04;
+
+ f0 = f[0];
+ f1 = f[1];
+ f2 = f[2];
+ f3 = f[3];
+ f4 = f[4];
+
+ g0 = g[0];
+ g1 = g[1];
+ g2 = g[2];
+ g3 = g[3];
+ g4 = g[4];
+
+ f1_19 = 19ULL * f1;
+ f2_19 = 19ULL * f2;
+ f3_19 = 19ULL * f3;
+ f4_19 = 19ULL * f4;
+
+ r0 = ((uint128_t) f0 ) * ((uint128_t) g0);
+ r0 += ((uint128_t) f1_19) * ((uint128_t) g4);
+ r0 += ((uint128_t) f2_19) * ((uint128_t) g3);
+ r0 += ((uint128_t) f3_19) * ((uint128_t) g2);
+ r0 += ((uint128_t) f4_19) * ((uint128_t) g1);
+
+ r1 = ((uint128_t) f0 ) * ((uint128_t) g1);
+ r1 += ((uint128_t) f1 ) * ((uint128_t) g0);
+ r1 += ((uint128_t) f2_19) * ((uint128_t) g4);
+ r1 += ((uint128_t) f3_19) * ((uint128_t) g3);
+ r1 += ((uint128_t) f4_19) * ((uint128_t) g2);
+
+ r2 = ((uint128_t) f0 ) * ((uint128_t) g2);
+ r2 += ((uint128_t) f1 ) * ((uint128_t) g1);
+ r2 += ((uint128_t) f2 ) * ((uint128_t) g0);
+ r2 += ((uint128_t) f3_19) * ((uint128_t) g4);
+ r2 += ((uint128_t) f4_19) * ((uint128_t) g3);
+
+ r3 = ((uint128_t) f0 ) * ((uint128_t) g3);
+ r3 += ((uint128_t) f1 ) * ((uint128_t) g2);
+ r3 += ((uint128_t) f2 ) * ((uint128_t) g1);
+ r3 += ((uint128_t) f3 ) * ((uint128_t) g0);
+ r3 += ((uint128_t) f4_19) * ((uint128_t) g4);
+
+ r4 = ((uint128_t) f0 ) * ((uint128_t) g4);
+ r4 += ((uint128_t) f1 ) * ((uint128_t) g3);
+ r4 += ((uint128_t) f2 ) * ((uint128_t) g2);
+ r4 += ((uint128_t) f3 ) * ((uint128_t) g1);
+ r4 += ((uint128_t) f4 ) * ((uint128_t) g0);
+
+ r00 = ((uint64_t) r0) & mask;
+ carry = r0 >> 51;
+ r1 += carry;
+ r01 = ((uint64_t) r1) & mask;
+ carry = r1 >> 51;
+ r2 += carry;
+ r02 = ((uint64_t) r2) & mask;
+ carry = r2 >> 51;
+ r3 += carry;
+ r03 = ((uint64_t) r3) & mask;
+ carry = r3 >> 51;
+ r4 += carry;
+ r04 = ((uint64_t) r4) & mask;
+ carry = r4 >> 51;
+ r00 += 19ULL * (uint64_t) carry;
+ carry = r00 >> 51;
+ r00 &= mask;
+ r01 += (uint64_t) carry;
+ carry = r01 >> 51;
+ r01 &= mask;
+ r02 += (uint64_t) carry;
+
+ h[0] = r00;
+ h[1] = r01;
+ h[2] = r02;
+ h[3] = r03;
+ h[4] = r04;
+}
+
+/*
+ h = f * f
+ Can overlap h with f.
+ */
+
+static void
+fe25519_sq(fe25519 h, const fe25519 f)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint128_t r0, r1, r2, r3, r4, carry;
+ uint64_t f0, f1, f2, f3, f4;
+ uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19;
+ uint64_t r00, r01, r02, r03, r04;
+
+ f0 = f[0];
+ f1 = f[1];
+ f2 = f[2];
+ f3 = f[3];
+ f4 = f[4];
+
+ f0_2 = f0 << 1;
+ f1_2 = f1 << 1;
+
+ f1_38 = 38ULL * f1;
+ f2_38 = 38ULL * f2;
+ f3_38 = 38ULL * f3;
+
+ f3_19 = 19ULL * f3;
+ f4_19 = 19ULL * f4;
+
+ r0 = ((uint128_t) f0 ) * ((uint128_t) f0);
+ r0 += ((uint128_t) f1_38) * ((uint128_t) f4);
+ r0 += ((uint128_t) f2_38) * ((uint128_t) f3);
+
+ r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1);
+ r1 += ((uint128_t) f2_38) * ((uint128_t) f4);
+ r1 += ((uint128_t) f3_19) * ((uint128_t) f3);
+
+ r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2);
+ r2 += ((uint128_t) f1 ) * ((uint128_t) f1);
+ r2 += ((uint128_t) f3_38) * ((uint128_t) f4);
+
+ r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3);
+ r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2);
+ r3 += ((uint128_t) f4_19) * ((uint128_t) f4);
+
+ r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4);
+ r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3);
+ r4 += ((uint128_t) f2 ) * ((uint128_t) f2);
+
+ r00 = ((uint64_t) r0) & mask;
+ carry = r0 >> 51;
+ r1 += carry;
+ r01 = ((uint64_t) r1) & mask;
+ carry = r1 >> 51;
+ r2 += carry;
+ r02 = ((uint64_t) r2) & mask;
+ carry = r2 >> 51;
+ r3 += carry;
+ r03 = ((uint64_t) r3) & mask;
+ carry = r3 >> 51;
+ r4 += carry;
+ r04 = ((uint64_t) r4) & mask;
+ carry = r4 >> 51;
+ r00 += 19ULL * (uint64_t) carry;
+ carry = r00 >> 51;
+ r00 &= mask;
+ r01 += (uint64_t) carry;
+ carry = r01 >> 51;
+ r01 &= mask;
+ r02 += (uint64_t) carry;
+
+ h[0] = r00;
+ h[1] = r01;
+ h[2] = r02;
+ h[3] = r03;
+ h[4] = r04;
+}
+
+/*
+ h = 2 * f * f
+ Can overlap h with f.
+*/
+
+static void
+fe25519_sq2(fe25519 h, const fe25519 f)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint128_t r0, r1, r2, r3, r4, carry;
+ uint64_t f0, f1, f2, f3, f4;
+ uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19;
+ uint64_t r00, r01, r02, r03, r04;
+
+ f0 = f[0];
+ f1 = f[1];
+ f2 = f[2];
+ f3 = f[3];
+ f4 = f[4];
+
+ f0_2 = f0 << 1;
+ f1_2 = f1 << 1;
+
+ f1_38 = 38ULL * f1;
+ f2_38 = 38ULL * f2;
+ f3_38 = 38ULL * f3;
+
+ f3_19 = 19ULL * f3;
+ f4_19 = 19ULL * f4;
+
+ r0 = ((uint128_t) f0 ) * ((uint128_t) f0);
+ r0 += ((uint128_t) f1_38) * ((uint128_t) f4);
+ r0 += ((uint128_t) f2_38) * ((uint128_t) f3);
+
+ r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1);
+ r1 += ((uint128_t) f2_38) * ((uint128_t) f4);
+ r1 += ((uint128_t) f3_19) * ((uint128_t) f3);
+
+ r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2);
+ r2 += ((uint128_t) f1 ) * ((uint128_t) f1);
+ r2 += ((uint128_t) f3_38) * ((uint128_t) f4);
+
+ r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3);
+ r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2);
+ r3 += ((uint128_t) f4_19) * ((uint128_t) f4);
+
+ r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4);
+ r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3);
+ r4 += ((uint128_t) f2 ) * ((uint128_t) f2);
+
+ r0 <<= 1;
+ r1 <<= 1;
+ r2 <<= 1;
+ r3 <<= 1;
+ r4 <<= 1;
+
+ r00 = ((uint64_t) r0) & mask;
+ carry = r0 >> 51;
+ r1 += carry;
+ r01 = ((uint64_t) r1) & mask;
+ carry = r1 >> 51;
+ r2 += carry;
+ r02 = ((uint64_t) r2) & mask;
+ carry = r2 >> 51;
+ r3 += carry;
+ r03 = ((uint64_t) r3) & mask;
+ carry = r3 >> 51;
+ r4 += carry;
+ r04 = ((uint64_t) r4) & mask;
+ carry = r4 >> 51;
+ r00 += 19ULL * (uint64_t) carry;
+ carry = r00 >> 51;
+ r00 &= mask;
+ r01 += (uint64_t) carry;
+ carry = r01 >> 51;
+ r01 &= mask;
+ r02 += (uint64_t) carry;
+
+ h[0] = r00;
+ h[1] = r01;
+ h[2] = r02;
+ h[3] = r03;
+ h[4] = r04;
+}
+
+static void
+fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n)
+{
+ const uint64_t mask = 0x7ffffffffffffULL;
+ uint128_t a;
+ uint128_t sn = (uint128_t) n;
+ uint64_t h0, h1, h2, h3, h4;
+
+ a = f[0] * sn;
+ h0 = ((uint64_t) a) & mask;
+ a = f[1] * sn + ((uint64_t) (a >> 51));
+ h1 = ((uint64_t) a) & mask;
+ a = f[2] * sn + ((uint64_t) (a >> 51));
+ h2 = ((uint64_t) a) & mask;
+ a = f[3] * sn + ((uint64_t) (a >> 51));
+ h3 = ((uint64_t) a) & mask;
+ a = f[4] * sn + ((uint64_t) (a >> 51));
+ h4 = ((uint64_t) a) & mask;
+
+ h0 += (a >> 51) * 19ULL;
+
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+}
diff --git a/libs/libsodium/src/include/sodium/private/implementations.h b/libs/libsodium/src/include/sodium/private/implementations.h
new file mode 100644
index 0000000000..c7237f851d
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/implementations.h
@@ -0,0 +1,11 @@
+#ifndef implementations_H
+#define implementations_H
+
+int _crypto_generichash_blake2b_pick_best_implementation(void);
+int _crypto_onetimeauth_poly1305_pick_best_implementation(void);
+int _crypto_pwhash_argon2_pick_best_implementation(void);
+int _crypto_scalarmult_curve25519_pick_best_implementation(void);
+int _crypto_stream_chacha20_pick_best_implementation(void);
+int _crypto_stream_salsa20_pick_best_implementation(void);
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/private/mutex.h b/libs/libsodium/src/include/sodium/private/mutex.h
new file mode 100644
index 0000000000..322b6742b2
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/mutex.h
@@ -0,0 +1,7 @@
+#ifndef mutex_H
+#define mutex_H 1
+
+extern int sodium_crit_enter(void);
+extern int sodium_crit_leave(void);
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/private/sse2_64_32.h b/libs/libsodium/src/include/sodium/private/sse2_64_32.h
new file mode 100644
index 0000000000..d0455b41b4
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/private/sse2_64_32.h
@@ -0,0 +1,50 @@
+#ifndef sse2_64_32_H
+#define sse2_64_32_H 1
+
+#include "common.h"
+
+#ifdef HAVE_INTRIN_H
+# include <intrin.h>
+#endif
+
+#if defined(HAVE_EMMINTRIN_H) && \
+ !(defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || \
+ defined(_M_X64) || defined(_M_AMD64))
+
+# include <emmintrin.h>
+# include <stdint.h>
+
+# ifndef _mm_set_epi64x
+# define _mm_set_epi64x(Q0, Q1) sodium__mm_set_epi64x((Q0), (Q1))
+static inline __m128i
+sodium__mm_set_epi64x(int64_t q1, int64_t q0)
+{
+ union { int64_t as64; int32_t as32[2]; } x0, x1;
+ x0.as64 = q0; x1.as64 = q1;
+ return _mm_set_epi32(x1.as32[1], x1.as32[0], x0.as32[1], x0.as32[0]);
+}
+# endif
+
+# ifndef _mm_set1_epi64x
+# define _mm_set1_epi64x(Q) sodium__mm_set1_epi64x(Q)
+static inline __m128i
+sodium__mm_set1_epi64x(int64_t q)
+{
+ return _mm_set_epi64x(q, q);
+}
+# endif
+
+# ifndef _mm_cvtsi64_si128
+# define _mm_cvtsi64_si128(Q) sodium__mm_cvtsi64_si128(Q)
+static inline __m128i
+sodium__mm_cvtsi64_si128(int64_t q)
+{
+ union { int64_t as64; int32_t as32[2]; } x;
+ x.as64 = q;
+ return _mm_setr_epi32(x.as32[0], x.as32[1], 0, 0);
+}
+# endif
+
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/randombytes.h b/libs/libsodium/src/include/sodium/randombytes.h
new file mode 100644
index 0000000000..d19f684ed6
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/randombytes.h
@@ -0,0 +1,68 @@
+
+#ifndef randombytes_H
+#define randombytes_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/types.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+typedef struct randombytes_implementation {
+ const char *(*implementation_name)(void); /* required */
+ uint32_t (*random)(void); /* required */
+ void (*stir)(void); /* optional */
+ uint32_t (*uniform)(const uint32_t upper_bound); /* optional, a default implementation will be used if NULL */
+ void (*buf)(void * const buf, const size_t size); /* required */
+ int (*close)(void); /* optional */
+} randombytes_implementation;
+
+#define randombytes_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 0xffffffffUL)
+
+#define randombytes_SEEDBYTES 32U
+SODIUM_EXPORT
+size_t randombytes_seedbytes(void);
+
+SODIUM_EXPORT
+void randombytes_buf(void * const buf, const size_t size);
+
+SODIUM_EXPORT
+void randombytes_buf_deterministic(void * const buf, const size_t size,
+ const unsigned char seed[randombytes_SEEDBYTES]);
+
+SODIUM_EXPORT
+uint32_t randombytes_random(void);
+
+SODIUM_EXPORT
+uint32_t randombytes_uniform(const uint32_t upper_bound);
+
+SODIUM_EXPORT
+void randombytes_stir(void);
+
+SODIUM_EXPORT
+int randombytes_close(void);
+
+SODIUM_EXPORT
+int randombytes_set_implementation(randombytes_implementation *impl);
+
+SODIUM_EXPORT
+const char *randombytes_implementation_name(void);
+
+/* -- NaCl compatibility interface -- */
+
+SODIUM_EXPORT
+void randombytes(unsigned char * const buf, const unsigned long long buf_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/randombytes_nativeclient.h b/libs/libsodium/src/include/sodium/randombytes_nativeclient.h
new file mode 100644
index 0000000000..5158d8c3c3
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/randombytes_nativeclient.h
@@ -0,0 +1,23 @@
+
+#ifndef randombytes_nativeclient_H
+#define randombytes_nativeclient_H
+
+#ifdef __native_client__
+
+# include "export.h"
+# include "randombytes.h"
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+SODIUM_EXPORT
+extern struct randombytes_implementation randombytes_nativeclient_implementation;
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h b/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h
new file mode 100644
index 0000000000..4deae15b6d
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h
@@ -0,0 +1,19 @@
+
+#ifndef randombytes_salsa20_random_H
+#define randombytes_salsa20_random_H
+
+#include "export.h"
+#include "randombytes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+extern struct randombytes_implementation randombytes_salsa20_implementation;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/randombytes_sysrandom.h b/libs/libsodium/src/include/sodium/randombytes_sysrandom.h
new file mode 100644
index 0000000000..9e27b674c7
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/randombytes_sysrandom.h
@@ -0,0 +1,19 @@
+
+#ifndef randombytes_sysrandom_H
+#define randombytes_sysrandom_H
+
+#include "export.h"
+#include "randombytes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+extern struct randombytes_implementation randombytes_sysrandom_implementation;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/runtime.h b/libs/libsodium/src/include/sodium/runtime.h
new file mode 100644
index 0000000000..7f15d58e7c
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/runtime.h
@@ -0,0 +1,52 @@
+
+#ifndef sodium_runtime_H
+#define sodium_runtime_H
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_neon(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_sse2(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_sse3(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_ssse3(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_sse41(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_avx(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_avx2(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_avx512f(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_pclmul(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_aesni(void);
+
+SODIUM_EXPORT_WEAK
+int sodium_runtime_has_rdrand(void);
+
+/* ------------------------------------------------------------------------- */
+
+int _sodium_runtime_get_cpu_features(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/utils.h b/libs/libsodium/src/include/sodium/utils.h
new file mode 100644
index 0000000000..46eb331cfd
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/utils.h
@@ -0,0 +1,170 @@
+
+#ifndef sodium_utils_H
+#define sodium_utils_H
+
+#include <stddef.h>
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SODIUM_C99
+# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+# define SODIUM_C99(X)
+# else
+# define SODIUM_C99(X) X
+# endif
+#endif
+
+SODIUM_EXPORT
+void sodium_memzero(void * const pnt, const size_t len);
+
+SODIUM_EXPORT
+void sodium_stackzero(const size_t len);
+
+/*
+ * WARNING: sodium_memcmp() must be used to verify if two secret keys
+ * are equal, in constant time.
+ * It returns 0 if the keys are equal, and -1 if they differ.
+ * This function is not designed for lexicographical comparisons.
+ */
+SODIUM_EXPORT
+int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len)
+ __attribute__ ((warn_unused_result));
+
+/*
+ * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_
+ * It is suitable for lexicographical comparisons, or to compare nonces
+ * and counters stored in little-endian format.
+ * However, it is slower than sodium_memcmp().
+ */
+SODIUM_EXPORT
+int sodium_compare(const unsigned char *b1_, const unsigned char *b2_,
+ size_t len)
+ __attribute__ ((warn_unused_result));
+
+SODIUM_EXPORT
+int sodium_is_zero(const unsigned char *n, const size_t nlen);
+
+SODIUM_EXPORT
+void sodium_increment(unsigned char *n, const size_t nlen);
+
+SODIUM_EXPORT
+void sodium_add(unsigned char *a, const unsigned char *b, const size_t len);
+
+SODIUM_EXPORT
+char *sodium_bin2hex(char * const hex, const size_t hex_maxlen,
+ const unsigned char * const bin, const size_t bin_len);
+
+SODIUM_EXPORT
+int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
+ const char * const hex, const size_t hex_len,
+ const char * const ignore, size_t * const bin_len,
+ const char ** const hex_end);
+
+#define sodium_base64_VARIANT_ORIGINAL 1
+#define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3
+#define sodium_base64_VARIANT_URLSAFE 5
+#define sodium_base64_VARIANT_URLSAFE_NO_PADDING 7
+
+/*
+ * Computes the required length to encode BIN_LEN bytes as a base64 string
+ * using the given variant. The computed length includes a trailing \0.
+ */
+#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \
+ (((BIN_LEN) / 3U) * 4U + \
+ ((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \
+ (4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + 1U)
+
+SODIUM_EXPORT
+size_t sodium_base64_encoded_len(const size_t bin_len, const int variant);
+
+SODIUM_EXPORT
+char *sodium_bin2base64(char * const b64, const size_t b64_maxlen,
+ const unsigned char * const bin, const size_t bin_len,
+ const int variant);
+
+SODIUM_EXPORT
+int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
+ const char * const b64, const size_t b64_len,
+ const char * const ignore, size_t * const bin_len,
+ const char ** const b64_end, const int variant);
+
+SODIUM_EXPORT
+int sodium_mlock(void * const addr, const size_t len);
+
+SODIUM_EXPORT
+int sodium_munlock(void * const addr, const size_t len);
+
+/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose
+ * allocation functions.
+ *
+ * They return a pointer to a region filled with 0xd0 bytes, immediately
+ * followed by a guard page.
+ * As a result, accessing a single byte after the requested allocation size
+ * will intentionally trigger a segmentation fault.
+ *
+ * A canary and an additional guard page placed before the beginning of the
+ * region may also kill the process if a buffer underflow is detected.
+ *
+ * The memory layout is:
+ * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)]
+ * With the layout of the unprotected pages being:
+ * [optional padding][16-bytes canary][user region]
+ *
+ * However:
+ * - These functions are significantly slower than standard functions
+ * - Each allocation requires 3 or 4 additional pages
+ * - The returned address will not be aligned if the allocation size is not
+ * a multiple of the required alignment. For this reason, these functions
+ * are designed to store data, such as secret keys and messages.
+ *
+ * sodium_malloc() can be used to allocate any libsodium data structure.
+ *
+ * The crypto_generichash_state structure is packed and its length is
+ * either 357 or 361 bytes. For this reason, when using sodium_malloc() to
+ * allocate a crypto_generichash_state structure, padding must be added in
+ * order to ensure proper alignment. crypto_generichash_statebytes()
+ * returns the rounded up structure size, and should be prefered to sizeof():
+ * state = sodium_malloc(crypto_generichash_statebytes());
+ */
+
+SODIUM_EXPORT
+void *sodium_malloc(const size_t size)
+ __attribute__ ((malloc));
+
+SODIUM_EXPORT
+void *sodium_allocarray(size_t count, size_t size)
+ __attribute__ ((malloc));
+
+SODIUM_EXPORT
+void sodium_free(void *ptr);
+
+SODIUM_EXPORT
+int sodium_mprotect_noaccess(void *ptr);
+
+SODIUM_EXPORT
+int sodium_mprotect_readonly(void *ptr);
+
+SODIUM_EXPORT
+int sodium_mprotect_readwrite(void *ptr);
+
+SODIUM_EXPORT
+int sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
+ size_t unpadded_buflen, size_t blocksize, size_t max_buflen);
+
+SODIUM_EXPORT
+int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
+ size_t padded_buflen, size_t blocksize);
+
+/* -------- */
+
+int _sodium_alloc_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/include/sodium/version.h b/libs/libsodium/src/include/sodium/version.h
new file mode 100644
index 0000000000..56ec2b9550
--- /dev/null
+++ b/libs/libsodium/src/include/sodium/version.h
@@ -0,0 +1,32 @@
+
+#ifndef sodium_version_H
+#define sodium_version_H
+
+#include "export.h"
+
+#define SODIUM_VERSION_STRING "1.0.16"
+
+#define SODIUM_LIBRARY_VERSION_MAJOR 10
+#define SODIUM_LIBRARY_VERSION_MINOR 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+const char *sodium_version_string(void);
+
+SODIUM_EXPORT
+int sodium_library_version_major(void);
+
+SODIUM_EXPORT
+int sodium_library_version_minor(void);
+
+SODIUM_EXPORT
+int sodium_library_minimal(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c
new file mode 100644
index 0000000000..85ffa9b29b
--- /dev/null
+++ b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c
@@ -0,0 +1,61 @@
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __native_client__
+# include <irt.h>
+
+# include "core.h"
+# include "utils.h"
+# include "randombytes.h"
+# include "randombytes_nativeclient.h"
+
+static void
+randombytes_nativeclient_buf(void * const buf, const size_t size)
+{
+ unsigned char *buf_ = (unsigned char *) buf;
+ struct nacl_irt_random rand_intf;
+ size_t readnb = (size_t) 0U;
+ size_t toread = size;
+
+ if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &rand_intf,
+ sizeof rand_intf) != sizeof rand_intf) {
+ sodium_misuse();
+ }
+ while (toread > (size_t) 0U) {
+ if (rand_intf.get_random_bytes(buf_, size, &readnb) != 0 ||
+ readnb > size) {
+ sodium_misuse();
+ }
+ toread -= readnb;
+ buf_ += readnb;
+ }
+}
+
+static uint32_t
+randombytes_nativeclient_random(void)
+{
+ uint32_t r;
+
+ randombytes_nativeclient_buf(&r, sizeof r);
+
+ return r;
+}
+
+static const char *
+randombytes_nativeclient_implementation_name(void)
+{
+ return "nativeclient";
+}
+
+struct randombytes_implementation randombytes_nativeclient_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_nativeclient_implementation_name,
+ SODIUM_C99(.random =) randombytes_nativeclient_random,
+ SODIUM_C99(.stir =) NULL,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_nativeclient_buf,
+ SODIUM_C99(.close =) NULL
+};
+
+#endif
diff --git a/libs/libsodium/src/randombytes/randombytes.c b/libs/libsodium/src/randombytes/randombytes.c
new file mode 100644
index 0000000000..708616b8aa
--- /dev/null
+++ b/libs/libsodium/src/randombytes/randombytes.c
@@ -0,0 +1,206 @@
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#ifdef __EMSCRIPTEN__
+# include <emscripten.h>
+#endif
+
+#include "core.h"
+#include "crypto_stream_chacha20.h"
+#include "randombytes.h"
+#ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION
+# include "randombytes_default.h"
+#else
+# ifdef __native_client__
+# include "randombytes_nativeclient.h"
+# else
+# include "randombytes_sysrandom.h"
+# endif
+#endif
+#include "private/common.h"
+
+/* C++Builder defines a "random" macro */
+#undef random
+
+static const randombytes_implementation *implementation;
+
+#ifndef RANDOMBYTES_DEFAULT_IMPLEMENTATION
+# ifdef __EMSCRIPTEN__
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL
+# else
+# ifdef __native_client__
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_nativeclient_implementation;
+# else
+# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation;
+# endif
+# endif
+#endif
+
+static void
+randombytes_init_if_needed(void)
+{
+ if (implementation == NULL) {
+ implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION;
+ randombytes_stir();
+ }
+}
+
+int
+randombytes_set_implementation(randombytes_implementation *impl)
+{
+ implementation = impl;
+
+ return 0;
+}
+
+const char *
+randombytes_implementation_name(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ return implementation->implementation_name();
+#else
+ return "js";
+#endif
+}
+
+uint32_t
+randombytes_random(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ return implementation->random();
+#else
+ return EM_ASM_INT_V({
+ return Module.getRandomValue();
+ });
+#endif
+}
+
+void
+randombytes_stir(void)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (implementation->stir != NULL) {
+ implementation->stir();
+ }
+#else
+ EM_ASM({
+ if (Module.getRandomValue === undefined) {
+ try {
+ var window_ = 'object' === typeof window ? window : self;
+ var crypto_ = typeof window_.crypto !== 'undefined' ? window_.crypto : window_.msCrypto;
+ var randomValuesStandard = function() {
+ var buf = new Uint32Array(1);
+ crypto_.getRandomValues(buf);
+ return buf[0] >>> 0;
+ };
+ randomValuesStandard();
+ Module.getRandomValue = randomValuesStandard;
+ } catch (e) {
+ try {
+ var crypto = require('crypto');
+ var randomValueNodeJS = function() {
+ var buf = crypto.randomBytes(4);
+ return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
+ };
+ randomValueNodeJS();
+ Module.getRandomValue = randomValueNodeJS;
+ } catch (e) {
+ throw 'No secure random number generator found';
+ }
+ }
+ }
+ });
+#endif
+}
+
+uint32_t
+randombytes_uniform(const uint32_t upper_bound)
+{
+ uint32_t min;
+ uint32_t r;
+
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (implementation->uniform != NULL) {
+ return implementation->uniform(upper_bound);
+ }
+#endif
+ if (upper_bound < 2) {
+ return 0;
+ }
+ min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */
+ do {
+ r = randombytes_random();
+ } while (r < min);
+ /* r is now clamped to a set whose size mod upper_bound == 0
+ * the worst case (2**31+1) requires ~ 2 attempts */
+
+ return r % upper_bound;
+}
+
+void
+randombytes_buf(void * const buf, const size_t size)
+{
+#ifndef __EMSCRIPTEN__
+ randombytes_init_if_needed();
+ if (size > (size_t) 0U) {
+ implementation->buf(buf, size);
+ }
+#else
+ unsigned char *p = (unsigned char *) buf;
+ size_t i;
+
+ for (i = (size_t) 0U; i < size; i++) {
+ p[i] = (unsigned char) randombytes_random();
+ }
+#endif
+}
+
+void
+randombytes_buf_deterministic(void * const buf, const size_t size,
+ const unsigned char seed[randombytes_SEEDBYTES])
+{
+ static const unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES] = {
+ 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G'
+ };
+
+ COMPILER_ASSERT(randombytes_SEEDBYTES == crypto_stream_chacha20_ietf_KEYBYTES);
+#if SIZE_MAX > 0x4000000000ULL
+ COMPILER_ASSERT(randombytes_BYTES_MAX <= 0x4000000000ULL);
+ if (size > 0x4000000000ULL) {
+ sodium_misuse();
+ }
+#endif
+ crypto_stream_chacha20_ietf((unsigned char *) buf, (unsigned long long) size,
+ nonce, seed);
+}
+
+size_t
+randombytes_seedbytes(void)
+{
+ return randombytes_SEEDBYTES;
+}
+
+int
+randombytes_close(void)
+{
+ if (implementation != NULL && implementation->close != NULL) {
+ return implementation->close();
+ }
+ return 0;
+}
+
+void
+randombytes(unsigned char * const buf, const unsigned long long buf_len)
+{
+ assert(buf_len <= SIZE_MAX);
+ randombytes_buf(buf, (size_t) buf_len);
+}
diff --git a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c
new file mode 100644
index 0000000000..79916eabc0
--- /dev/null
+++ b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c
@@ -0,0 +1,564 @@
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(_MSC_VER) && !defined(__BORLANDC__)
+# include <unistd.h>
+#endif
+
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/stat.h>
+# include <sys/time.h>
+#endif
+#ifdef __linux__
+# ifdef __dietlibc__
+# define _LINUX_SOURCE
+# else
+# include <sys/syscall.h>
+# endif
+# include <poll.h>
+#endif
+#ifdef HAVE_RDRAND
+# pragma GCC target("rdrnd")
+# include <immintrin.h>
+#endif
+
+#include "core.h"
+#include "crypto_core_salsa20.h"
+#include "crypto_stream_salsa20.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "randombytes_salsa20_random.h"
+#include "runtime.h"
+#include "utils.h"
+
+#ifdef _WIN32
+# include <windows.h>
+# include <sys/timeb.h>
+# define RtlGenRandom SystemFunction036
+# if defined(__cplusplus)
+extern "C"
+# endif
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+# pragma comment(lib, "advapi32.lib")
+# ifdef __BORLANDC__
+# define _ftime ftime
+# define _timeb timeb
+# endif
+#endif
+
+#define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES
+
+#if defined(__OpenBSD__) || defined(__CloudABI__)
+# define HAVE_SAFE_ARC4RANDOM 1
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX (SIZE_MAX / 2 - 1)
+#endif
+#ifndef S_ISNAM
+# ifdef __COMPCERT__
+# define S_ISNAM(X) 1
+# else
+# define S_ISNAM(X) 0
+# endif
+#endif
+
+#ifndef TLS
+# ifdef _WIN32
+# define TLS __declspec(thread)
+# else
+# define TLS
+# endif
+#endif
+
+typedef struct Salsa20RandomGlobal_ {
+ int initialized;
+ int random_data_source_fd;
+ int getrandom_available;
+ int rdrand_available;
+#ifdef HAVE_GETPID
+ pid_t pid;
+#endif
+} Salsa20RandomGlobal;
+
+typedef struct Salsa20Random_ {
+ int initialized;
+ size_t rnd32_outleft;
+ unsigned char key[crypto_stream_salsa20_KEYBYTES];
+ unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE];
+ uint64_t nonce;
+} Salsa20Random;
+
+static Salsa20RandomGlobal global = {
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.random_data_source_fd =) -1
+};
+
+static TLS Salsa20Random stream = {
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.rnd32_outleft =) (size_t) 0U
+};
+
+
+/*
+ * Get a high-resolution timestamp, as a uint64_t value
+ */
+
+#ifdef _WIN32
+static uint64_t
+sodium_hrtime(void)
+{
+ struct _timeb tb;
+# pragma warning(push)
+# pragma warning(disable: 4996)
+ _ftime(&tb);
+# pragma warning(pop)
+ return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
+}
+
+#else /* _WIN32 */
+
+static uint64_t
+sodium_hrtime(void)
+{
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
+}
+#endif
+
+/*
+ * Initialize the entropy source
+ */
+
+#ifdef _WIN32
+
+static void
+randombytes_salsa20_random_init(void)
+{
+ stream.nonce = sodium_hrtime();
+ assert(stream.nonce != (uint64_t) 0U);
+ global.rdrand_available = sodium_runtime_has_rdrand();
+}
+
+#else /* _WIN32 */
+
+static ssize_t
+safe_read(const int fd, void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ ssize_t readnb;
+
+ assert(size > (size_t) 0U);
+ assert(size <= SSIZE_MAX);
+ do {
+ while ((readnb = read(fd, buf, size)) < (ssize_t) 0 &&
+ (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */
+ if (readnb < (ssize_t) 0) {
+ return readnb; /* LCOV_EXCL_LINE */
+ }
+ if (readnb == (ssize_t) 0) {
+ break; /* LCOV_EXCL_LINE */
+ }
+ size -= (size_t) readnb;
+ buf += readnb;
+ } while (size > (ssize_t) 0);
+
+ return (ssize_t) (buf - (unsigned char *) buf_);
+}
+
+# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
+static int
+randombytes_block_on_dev_random(void)
+{
+ struct pollfd pfd;
+ int fd;
+ int pret;
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd == -1) {
+ return 0;
+ }
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ do {
+ pret = poll(&pfd, 1, -1);
+ } while (pret < 0 && (errno == EINTR || errno == EAGAIN));
+ if (pret != 1) {
+ (void) close(fd);
+ errno = EIO;
+ return -1;
+ }
+ return close(fd);
+}
+# endif
+
+# ifndef HAVE_SAFE_ARC4RANDOM
+static int
+randombytes_salsa20_random_random_dev_open(void)
+{
+/* LCOV_EXCL_START */
+ struct stat st;
+ static const char *devices[] = {
+# ifndef USE_BLOCKING_RANDOM
+ "/dev/urandom",
+# endif
+ "/dev/random", NULL
+ };
+ const char **device = devices;
+ int fd;
+
+# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
+ if (randombytes_block_on_dev_random() != 0) {
+ return -1;
+ }
+# endif
+ do {
+ fd = open(*device, O_RDONLY);
+ if (fd != -1) {
+ if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) {
+# if defined(F_SETFD) && defined(FD_CLOEXEC)
+ (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+# endif
+ return fd;
+ }
+ (void) close(fd);
+ } else if (errno == EINTR) {
+ continue;
+ }
+ device++;
+ } while (*device != NULL);
+
+ errno = EIO;
+ return -1;
+/* LCOV_EXCL_STOP */
+}
+# endif
+
+# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom))
+static int
+_randombytes_linux_getrandom(void * const buf, const size_t size)
+{
+ int readnb;
+
+ assert(size <= 256U);
+ do {
+# ifdef __dietlibc__
+ readnb = getrandom(buf, size, 0);
+# else
+ readnb = syscall(SYS_getrandom, buf, (int) size, 0);
+# endif
+ } while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
+
+ return (readnb == (int) size) - 1;
+}
+
+static int
+randombytes_linux_getrandom(void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ size_t chunk_size = 256U;
+
+ do {
+ if (size < chunk_size) {
+ chunk_size = size;
+ assert(chunk_size > (size_t) 0U);
+ }
+ if (_randombytes_linux_getrandom(buf, chunk_size) != 0) {
+ return -1;
+ }
+ size -= chunk_size;
+ buf += chunk_size;
+ } while (size > (size_t) 0U);
+
+ return 0;
+}
+# endif
+
+static void
+randombytes_salsa20_random_init(void)
+{
+ const int errno_save = errno;
+
+ stream.nonce = sodium_hrtime();
+ global.rdrand_available = sodium_runtime_has_rdrand();
+ assert(stream.nonce != (uint64_t) 0U);
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ errno = errno_save;
+# else
+
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+ {
+ unsigned char fodder[16];
+
+ if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
+ global.getrandom_available = 1;
+ errno = errno_save;
+ return;
+ }
+ global.getrandom_available = 0;
+ }
+# endif /* SYS_getrandom */
+
+ if ((global.random_data_source_fd =
+ randombytes_salsa20_random_random_dev_open()) == -1) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ errno = errno_save;
+# endif /* HAVE_SAFE_ARC4RANDOM */
+}
+
+#endif /* _WIN32 */
+
+/*
+ * (Re)seed the generator using the entropy source
+ */
+
+static void
+randombytes_salsa20_random_stir(void)
+{
+ unsigned char m0[crypto_stream_salsa20_KEYBYTES +
+ crypto_stream_salsa20_NONCEBYTES];
+
+ memset(stream.rnd32, 0, sizeof stream.rnd32);
+ stream.rnd32_outleft = (size_t) 0U;
+ if (global.initialized == 0) {
+ randombytes_salsa20_random_init();
+ global.initialized = 1;
+ }
+#ifdef HAVE_GETPID
+ global.pid = getpid();
+#endif
+
+#ifndef _WIN32
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ arc4random_buf(m0, sizeof m0);
+# elif defined(SYS_getrandom) && defined(__NR_getrandom)
+ if (global.getrandom_available != 0) {
+ if (randombytes_linux_getrandom(m0, sizeof m0) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ } else if (global.random_data_source_fd == -1 ||
+ safe_read(global.random_data_source_fd, m0,
+ sizeof m0) != (ssize_t) sizeof m0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# else
+ if (global.random_data_source_fd == -1 ||
+ safe_read(global.random_data_source_fd, m0,
+ sizeof m0) != (ssize_t) sizeof m0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+# endif
+
+#else /* _WIN32 */
+ if (! RtlGenRandom((PVOID) m0, (ULONG) sizeof m0)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+
+ crypto_stream_salsa20(stream.key, sizeof stream.key,
+ m0 + crypto_stream_salsa20_KEYBYTES, m0);
+ sodium_memzero(m0, sizeof m0);
+ stream.initialized = 1;
+}
+
+/*
+ * Reseed the generator if it hasn't been initialized yet
+ */
+
+static void
+randombytes_salsa20_random_stir_if_needed(void)
+{
+#ifdef HAVE_GETPID
+ if (stream.initialized == 0) {
+ randombytes_salsa20_random_stir();
+ } else if (global.pid != getpid()) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#else
+ if (stream.initialized == 0) {
+ randombytes_salsa20_random_stir();
+ }
+#endif
+}
+
+/*
+ * Close the stream, free global resources
+ */
+
+#ifdef _WIN32
+static int
+randombytes_salsa20_random_close(void)
+{
+ int ret = -1;
+
+ if (global.initialized != 0) {
+ global.initialized = 0;
+ ret = 0;
+ }
+ sodium_memzero(&stream, sizeof stream);
+
+ return ret;
+}
+#else
+static int
+randombytes_salsa20_random_close(void)
+{
+ int ret = -1;
+
+ if (global.random_data_source_fd != -1 &&
+ close(global.random_data_source_fd) == 0) {
+ global.random_data_source_fd = -1;
+ global.initialized = 0;
+# ifdef HAVE_GETPID
+ global.pid = (pid_t) 0;
+# endif
+ ret = 0;
+ }
+
+# ifdef HAVE_SAFE_ARC4RANDOM
+ ret = 0;
+# endif
+
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+ if (global.getrandom_available != 0) {
+ ret = 0;
+ }
+# endif
+
+ sodium_memzero(&stream, sizeof stream);
+
+ return ret;
+}
+#endif
+
+/*
+ * RDRAND is only used to mitigate prediction if a key is compromised
+ */
+
+static void
+randombytes_salsa20_random_xorhwrand(void)
+{
+/* LCOV_EXCL_START */
+#ifdef HAVE_RDRAND
+ unsigned int r;
+
+ if (global.rdrand_available == 0) {
+ return;
+ }
+ (void) _rdrand32_step(&r);
+ * (uint32_t *) (void *)
+ &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r;
+#endif
+/* LCOV_EXCL_STOP */
+}
+
+/*
+ * XOR the key with another same-length secret
+ */
+
+static inline void
+randombytes_salsa20_random_xorkey(const unsigned char * const mix)
+{
+ unsigned char *key = stream.key;
+ size_t i;
+
+ for (i = (size_t) 0U; i < sizeof stream.key; i++) {
+ key[i] ^= mix[i];
+ }
+}
+
+/*
+ * Put `size` random bytes into `buf` and overwrite the key
+ */
+
+static void
+randombytes_salsa20_random_buf(void * const buf, const size_t size)
+{
+ size_t i;
+ int ret;
+
+ randombytes_salsa20_random_stir_if_needed();
+ COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES);
+#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX)
+# if SIZE_MAX > ULONG_LONG_MAX
+ /* coverity[result_independent_of_operands] */
+ assert(size <= ULONG_LONG_MAX);
+# endif
+#endif
+ ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size,
+ (unsigned char *) &stream.nonce, stream.key);
+ assert(ret == 0);
+ for (i = 0U; i < sizeof size; i++) {
+ stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i];
+ }
+ randombytes_salsa20_random_xorhwrand();
+ stream.nonce++;
+ crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key,
+ (unsigned char *) &stream.nonce, stream.key);
+}
+
+/*
+ * Pop a 32-bit value from the random pool
+ *
+ * Overwrite the key after the pool gets refilled.
+ */
+
+static uint32_t
+randombytes_salsa20_random(void)
+{
+ uint32_t val;
+ int ret;
+
+ COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val));
+ COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key))
+ % sizeof val == (size_t) 0U);
+ if (stream.rnd32_outleft <= (size_t) 0U) {
+ randombytes_salsa20_random_stir_if_needed();
+ COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES);
+ ret = crypto_stream_salsa20((unsigned char *) stream.rnd32,
+ (unsigned long long) sizeof stream.rnd32,
+ (unsigned char *) &stream.nonce,
+ stream.key);
+ assert(ret == 0);
+ stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key);
+ randombytes_salsa20_random_xorhwrand();
+ randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]);
+ memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key);
+ stream.nonce++;
+ }
+ stream.rnd32_outleft -= sizeof val;
+ memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val);
+ memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val);
+
+ return val;
+}
+
+static const char *
+randombytes_salsa20_implementation_name(void)
+{
+ return "salsa20";
+}
+
+struct randombytes_implementation randombytes_salsa20_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_salsa20_implementation_name,
+ SODIUM_C99(.random =) randombytes_salsa20_random,
+ SODIUM_C99(.stir =) randombytes_salsa20_random_stir,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_salsa20_random_buf,
+ SODIUM_C99(.close =) randombytes_salsa20_random_close
+};
diff --git a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c
new file mode 100644
index 0000000000..f4dec08f5b
--- /dev/null
+++ b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c
@@ -0,0 +1,382 @@
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#ifndef _WIN32
+# include <sys/stat.h>
+# include <sys/time.h>
+#endif
+#ifdef __linux__
+# ifdef __dietlibc__
+# define _LINUX_SOURCE
+# else
+# include <sys/syscall.h>
+# endif
+# include <poll.h>
+#endif
+
+#include "core.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "randombytes_sysrandom.h"
+#include "utils.h"
+
+#ifdef _WIN32
+/* `RtlGenRandom` is used over `CryptGenRandom` on Microsoft Windows based systems:
+ * - `CryptGenRandom` requires pulling in `CryptoAPI` which causes unnecessary
+ * memory overhead if this API is not being used for other purposes
+ * - `RtlGenRandom` is thus called directly instead. A detailed explanation
+ * can be found here: https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+ *
+ * In spite of the disclaimer on the `RtlGenRandom` documentation page that was
+ * written back in the Windows XP days, this function is here to stay. The CRT
+ * function `rand_s()` directly depends on it, so touching it would break many
+ * applications released since Windows XP.
+ *
+ * Also note that Rust, Firefox and BoringSSL (thus, Google Chrome and everything
+ * based on Chromium) also depend on it, and that libsodium allows the RNG to be
+ * replaced without patching nor recompiling the library.
+ */
+# include <windows.h>
+# define RtlGenRandom SystemFunction036
+# if defined(__cplusplus)
+extern "C"
+# endif
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+# pragma comment(lib, "advapi32.lib")
+#endif
+
+#if defined(__OpenBSD__) || defined(__CloudABI__)
+# define HAVE_SAFE_ARC4RANDOM 1
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX (SIZE_MAX / 2 - 1)
+#endif
+
+#ifdef HAVE_SAFE_ARC4RANDOM
+
+static uint32_t
+randombytes_sysrandom(void)
+{
+ return arc4random();
+}
+
+static void
+randombytes_sysrandom_stir(void)
+{
+}
+
+static void
+randombytes_sysrandom_buf(void * const buf, const size_t size)
+{
+ arc4random_buf(buf, size);
+}
+
+static int
+randombytes_sysrandom_close(void)
+{
+ return 0;
+}
+
+#else /* __OpenBSD__ */
+
+typedef struct SysRandom_ {
+ int random_data_source_fd;
+ int initialized;
+ int getrandom_available;
+} SysRandom;
+
+static SysRandom stream = {
+ SODIUM_C99(.random_data_source_fd =) -1,
+ SODIUM_C99(.initialized =) 0,
+ SODIUM_C99(.getrandom_available =) 0
+};
+
+#ifndef _WIN32
+static ssize_t
+safe_read(const int fd, void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ ssize_t readnb;
+
+ assert(size > (size_t) 0U);
+ assert(size <= SSIZE_MAX);
+ do {
+ while ((readnb = read(fd, buf, size)) < (ssize_t) 0 &&
+ (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */
+ if (readnb < (ssize_t) 0) {
+ return readnb; /* LCOV_EXCL_LINE */
+ }
+ if (readnb == (ssize_t) 0) {
+ break; /* LCOV_EXCL_LINE */
+ }
+ size -= (size_t) readnb;
+ buf += readnb;
+ } while (size > (ssize_t) 0);
+
+ return (ssize_t) (buf - (unsigned char *) buf_);
+}
+#endif
+
+#ifndef _WIN32
+# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
+static int
+randombytes_block_on_dev_random(void)
+{
+ struct pollfd pfd;
+ int fd;
+ int pret;
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd == -1) {
+ return 0;
+ }
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ do {
+ pret = poll(&pfd, 1, -1);
+ } while (pret < 0 && (errno == EINTR || errno == EAGAIN));
+ if (pret != 1) {
+ (void) close(fd);
+ errno = EIO;
+ return -1;
+ }
+ return close(fd);
+}
+# endif
+
+static int
+randombytes_sysrandom_random_dev_open(void)
+{
+/* LCOV_EXCL_START */
+ struct stat st;
+ static const char *devices[] = {
+# ifndef USE_BLOCKING_RANDOM
+ "/dev/urandom",
+# endif
+ "/dev/random", NULL
+ };
+ const char **device = devices;
+ int fd;
+
+# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
+ if (randombytes_block_on_dev_random() != 0) {
+ return -1;
+ }
+# endif
+ do {
+ fd = open(*device, O_RDONLY);
+ if (fd != -1) {
+ if (fstat(fd, &st) == 0 &&
+# ifdef __COMPCERT__
+ 1
+# elif defined(S_ISNAM)
+ (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
+# else
+ S_ISCHR(st.st_mode)
+# endif
+ ) {
+# if defined(F_SETFD) && defined(FD_CLOEXEC)
+ (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+# endif
+ return fd;
+ }
+ (void) close(fd);
+ } else if (errno == EINTR) {
+ continue;
+ }
+ device++;
+ } while (*device != NULL);
+
+ errno = EIO;
+ return -1;
+/* LCOV_EXCL_STOP */
+}
+
+# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom))
+static int
+_randombytes_linux_getrandom(void * const buf, const size_t size)
+{
+ int readnb;
+
+ assert(size <= 256U);
+ do {
+# ifdef __dietlibc__
+ readnb = getrandom(buf, size, 0);
+# else
+ readnb = syscall(SYS_getrandom, buf, (int) size, 0);
+# endif
+ } while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
+
+ return (readnb == (int) size) - 1;
+}
+
+static int
+randombytes_linux_getrandom(void * const buf_, size_t size)
+{
+ unsigned char *buf = (unsigned char *) buf_;
+ size_t chunk_size = 256U;
+
+ do {
+ if (size < chunk_size) {
+ chunk_size = size;
+ assert(chunk_size > (size_t) 0U);
+ }
+ if (_randombytes_linux_getrandom(buf, chunk_size) != 0) {
+ return -1;
+ }
+ size -= chunk_size;
+ buf += chunk_size;
+ } while (size > (size_t) 0U);
+
+ return 0;
+}
+# endif
+
+static void
+randombytes_sysrandom_init(void)
+{
+ const int errno_save = errno;
+
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+ {
+ unsigned char fodder[16];
+
+ if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
+ stream.getrandom_available = 1;
+ errno = errno_save;
+ return;
+ }
+ stream.getrandom_available = 0;
+ }
+# endif
+
+ if ((stream.random_data_source_fd =
+ randombytes_sysrandom_random_dev_open()) == -1) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ errno = errno_save;
+}
+
+#else /* _WIN32 */
+
+static void
+randombytes_sysrandom_init(void)
+{
+}
+#endif
+
+static void
+randombytes_sysrandom_stir(void)
+{
+ if (stream.initialized == 0) {
+ randombytes_sysrandom_init();
+ stream.initialized = 1;
+ }
+}
+
+static void
+randombytes_sysrandom_stir_if_needed(void)
+{
+ if (stream.initialized == 0) {
+ randombytes_sysrandom_stir();
+ }
+}
+
+static int
+randombytes_sysrandom_close(void)
+{
+ int ret = -1;
+
+#ifndef _WIN32
+ if (stream.random_data_source_fd != -1 &&
+ close(stream.random_data_source_fd) == 0) {
+ stream.random_data_source_fd = -1;
+ stream.initialized = 0;
+ ret = 0;
+ }
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+ if (stream.getrandom_available != 0) {
+ ret = 0;
+ }
+# endif
+#else /* _WIN32 */
+ if (stream.initialized != 0) {
+ stream.initialized = 0;
+ ret = 0;
+ }
+#endif
+ return ret;
+}
+
+static void
+randombytes_sysrandom_buf(void * const buf, const size_t size)
+{
+ randombytes_sysrandom_stir_if_needed();
+#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX)
+# if SIZE_MAX > ULONG_LONG_MAX
+ /* coverity[result_independent_of_operands] */
+ assert(size <= ULONG_LONG_MAX);
+# endif
+#endif
+#ifndef _WIN32
+# if defined(SYS_getrandom) && defined(__NR_getrandom)
+ if (stream.getrandom_available != 0) {
+ if (randombytes_linux_getrandom(buf, size) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return;
+ }
+# endif
+ if (stream.random_data_source_fd == -1 ||
+ safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#else
+ COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL);
+ if (size > (size_t) 0xffffffffUL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (! RtlGenRandom((PVOID) buf, (ULONG) size)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+}
+
+static uint32_t
+randombytes_sysrandom(void)
+{
+ uint32_t r;
+
+ randombytes_sysrandom_buf(&r, sizeof r);
+
+ return r;
+}
+
+#endif /* __OpenBSD__ */
+
+static const char *
+randombytes_sysrandom_implementation_name(void)
+{
+ return "sysrandom";
+}
+
+struct randombytes_implementation randombytes_sysrandom_implementation = {
+ SODIUM_C99(.implementation_name =) randombytes_sysrandom_implementation_name,
+ SODIUM_C99(.random =) randombytes_sysrandom,
+ SODIUM_C99(.stir =) randombytes_sysrandom_stir,
+ SODIUM_C99(.uniform =) NULL,
+ SODIUM_C99(.buf =) randombytes_sysrandom_buf,
+ SODIUM_C99(.close =) randombytes_sysrandom_close
+};
diff --git a/libs/libsodium/src/sodium/codecs.c b/libs/libsodium/src/sodium/codecs.c
new file mode 100644
index 0000000000..77fa464cc4
--- /dev/null
+++ b/libs/libsodium/src/sodium/codecs.c
@@ -0,0 +1,333 @@
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "utils.h"
+
+/* Derived from original code by CodesInChaos */
+char *
+sodium_bin2hex(char *const hex, const size_t hex_maxlen,
+ const unsigned char *const bin, const size_t bin_len)
+{
+ size_t i = (size_t) 0U;
+ unsigned int x;
+ int b;
+ int c;
+
+ if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ while (i < bin_len) {
+ c = bin[i] & 0xf;
+ b = bin[i] >> 4;
+ x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 |
+ (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U));
+ hex[i * 2U] = (char) x;
+ x >>= 8;
+ hex[i * 2U + 1U] = (char) x;
+ i++;
+ }
+ hex[i * 2U] = 0U;
+
+ return hex;
+}
+
+int
+sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen,
+ const char *const hex, const size_t hex_len,
+ const char *const ignore, size_t *const bin_len,
+ const char **const hex_end)
+{
+ size_t bin_pos = (size_t) 0U;
+ size_t hex_pos = (size_t) 0U;
+ int ret = 0;
+ unsigned char c;
+ unsigned char c_acc = 0U;
+ unsigned char c_alpha0, c_alpha;
+ unsigned char c_num0, c_num;
+ unsigned char c_val;
+ unsigned char state = 0U;
+
+ while (hex_pos < hex_len) {
+ c = (unsigned char) hex[hex_pos];
+ c_num = c ^ 48U;
+ c_num0 = (c_num - 10U) >> 8;
+ c_alpha = (c & ~32U) - 55U;
+ c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
+ if ((c_num0 | c_alpha0) == 0U) {
+ if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) {
+ hex_pos++;
+ continue;
+ }
+ break;
+ }
+ c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
+ if (bin_pos >= bin_maxlen) {
+ ret = -1;
+ errno = ERANGE;
+ break;
+ }
+ if (state == 0U) {
+ c_acc = c_val * 16U;
+ } else {
+ bin[bin_pos++] = c_acc | c_val;
+ }
+ state = ~state;
+ hex_pos++;
+ }
+ if (state != 0U) {
+ hex_pos--;
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (ret != 0) {
+ bin_pos = (size_t) 0U;
+ }
+ if (hex_end != NULL) {
+ *hex_end = &hex[hex_pos];
+ } else if (hex_pos != hex_len) {
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (bin_len != NULL) {
+ *bin_len = bin_pos;
+ }
+ return ret;
+}
+
+/*
+ * Some macros for constant-time comparisons. These work over values in
+ * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
+ *
+ * Original code by Thomas Pornin.
+ */
+#define EQ(x, y) \
+ ((((0U - ((unsigned int) (x) ^ (unsigned int) (y))) >> 8) & 0xFF) ^ 0xFF)
+#define GT(x, y) ((((unsigned int) (y) - (unsigned int) (x)) >> 8) & 0xFF)
+#define GE(x, y) (GT(y, x) ^ 0xFF)
+#define LT(x, y) GT(y, x)
+#define LE(x, y) GE(y, x)
+
+static int
+b64_byte_to_char(unsigned int x)
+{
+ return (LT(x, 26) & (x + 'A')) |
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
+ (EQ(x, 63) & '/');
+}
+
+static unsigned int
+b64_char_to_byte(int c)
+{
+ const unsigned int x =
+ (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
+ (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
+ (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
+ (EQ(c, '/') & 63);
+
+ return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
+}
+
+static int
+b64_byte_to_urlsafe_char(unsigned int x)
+{
+ return (LT(x, 26) & (x + 'A')) |
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '-') |
+ (EQ(x, 63) & '_');
+}
+
+static unsigned int
+b64_urlsafe_char_to_byte(int c)
+{
+ const unsigned x =
+ (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
+ (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
+ (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '-') & 62) |
+ (EQ(c, '_') & 63);
+
+ return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
+}
+
+
+#define VARIANT_NO_PADDING_MASK 0x2U
+#define VARIANT_URLSAFE_MASK 0x4U
+
+static void
+sodium_base64_check_variant(const int variant)
+{
+ if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) {
+ sodium_misuse();
+ }
+}
+
+size_t
+sodium_base64_encoded_len(const size_t bin_len, const int variant)
+{
+ sodium_base64_check_variant(variant);
+
+ return sodium_base64_ENCODED_LEN(bin_len, variant);
+}
+
+char *
+sodium_bin2base64(char * const b64, const size_t b64_maxlen,
+ const unsigned char * const bin, const size_t bin_len,
+ const int variant)
+{
+ size_t acc_len = (size_t) 0;
+ size_t b64_len;
+ size_t b64_pos = (size_t) 0;
+ size_t bin_pos = (size_t) 0;
+ size_t nibbles;
+ size_t remainder;
+ unsigned int acc = 0U;
+
+ sodium_base64_check_variant(variant);
+ nibbles = bin_len / 3;
+ remainder = bin_len - 3 * nibbles;
+ b64_len = nibbles * 4;
+ if (remainder != 0) {
+ if ((((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) {
+ b64_len += 4;
+ } else {
+ b64_len += 2 + (remainder >> 1);
+ }
+ }
+ if (b64_maxlen <= b64_len) {
+ sodium_misuse();
+ }
+ if ((((unsigned int) variant) & VARIANT_URLSAFE_MASK) != 0U) {
+ while (bin_pos < bin_len) {
+ acc = (acc << 8) + bin[bin_pos++];
+ acc_len += 8;
+ while (acc_len >= 6) {
+ acc_len -= 6;
+ b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc >> acc_len) & 0x3F);
+ }
+ }
+ if (acc_len > 0) {
+ b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc << (6 - acc_len)) & 0x3F);
+ }
+ } else {
+ while (bin_pos < bin_len) {
+ acc = (acc << 8) + bin[bin_pos++];
+ acc_len += 8;
+ while (acc_len >= 6) {
+ acc_len -= 6;
+ b64[b64_pos++] = (char) b64_byte_to_char((acc >> acc_len) & 0x3F);
+ }
+ }
+ if (acc_len > 0) {
+ b64[b64_pos++] = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
+ }
+ }
+ assert(b64_pos <= b64_len);
+ while (b64_pos < b64_len) {
+ b64[b64_pos++] = '=';
+ }
+ do {
+ b64[b64_pos++] = 0U;
+ } while (b64_pos < b64_maxlen);
+
+ return b64;
+}
+
+static int
+_sodium_base642bin_skip_padding(const char * const b64, const size_t b64_len,
+ size_t * const b64_pos_p,
+ const char * const ignore, size_t padding_len)
+{
+ int c;
+
+ while (padding_len > 0) {
+ if (*b64_pos_p >= b64_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ c = b64[*b64_pos_p];
+ if (c == '=') {
+ padding_len--;
+ } else if (ignore == NULL || strchr(ignore, c) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ (*b64_pos_p)++;
+ }
+ return 0;
+}
+
+int
+sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
+ const char * const b64, const size_t b64_len,
+ const char * const ignore, size_t * const bin_len,
+ const char ** const b64_end, const int variant)
+{
+ size_t acc_len = (size_t) 0;
+ size_t b64_pos = (size_t) 0;
+ size_t bin_pos = (size_t) 0;
+ int is_urlsafe;
+ int ret = 0;
+ unsigned int acc = 0U;
+ unsigned int d;
+ char c;
+
+ sodium_base64_check_variant(variant);
+ is_urlsafe = ((unsigned int) variant) & VARIANT_URLSAFE_MASK;
+ while (b64_pos < b64_len) {
+ c = b64[b64_pos];
+ if (is_urlsafe) {
+ d = b64_urlsafe_char_to_byte(c);
+ } else {
+ d = b64_char_to_byte(c);
+ }
+ if (d == 0xFF) {
+ if (ignore != NULL && strchr(ignore, c) != NULL) {
+ b64_pos++;
+ continue;
+ }
+ break;
+ }
+ acc = (acc << 6) + d;
+ acc_len += 6;
+ if (acc_len >= 8) {
+ acc_len -= 8;
+ if (bin_pos >= bin_maxlen) {
+ errno = ERANGE;
+ ret = -1;
+ break;
+ }
+ bin[bin_pos++] = (acc >> acc_len) & 0xFF;
+ }
+ b64_pos++;
+ }
+ if (acc_len > 4U || (acc & ((1U << acc_len) - 1U)) != 0U) {
+ ret = -1;
+ } else if (ret == 0 &&
+ (((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) {
+ ret = _sodium_base642bin_skip_padding(b64, b64_len, &b64_pos, ignore,
+ acc_len / 2);
+ }
+ if (ret != 0) {
+ bin_pos = (size_t) 0U;
+ } else if (ignore != NULL) {
+ while (b64_pos < b64_len && strchr(ignore, b64[b64_pos]) != NULL) {
+ b64_pos++;
+ }
+ }
+ if (b64_end != NULL) {
+ *b64_end = &b64[b64_pos];
+ } else if (b64_pos != b64_len) {
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (bin_len != NULL) {
+ *bin_len = bin_pos;
+ }
+ return ret;
+}
diff --git a/libs/libsodium/src/sodium/core.c b/libs/libsodium/src/sodium/core.c
new file mode 100644
index 0000000000..1ac29d09c8
--- /dev/null
+++ b/libs/libsodium/src/sodium/core.c
@@ -0,0 +1,231 @@
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef _WIN32
+# include <windows.h>
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+#endif
+
+#include "core.h"
+#include "crypto_generichash.h"
+#include "crypto_onetimeauth.h"
+#include "crypto_scalarmult.h"
+#include "crypto_stream_chacha20.h"
+#include "crypto_stream_salsa20.h"
+#include "randombytes.h"
+#include "runtime.h"
+#include "utils.h"
+#include "private/implementations.h"
+#include "private/mutex.h"
+
+#if !defined(_MSC_VER) && 0
+# warning *** This is unstable, untested, development code.
+# warning It might not compile. It might not work as expected.
+# warning It might be totally insecure.
+# warning Do not use this in production.
+# warning Use releases available at https://download.libsodium.org/libsodium/releases/ instead.
+# warning Alternatively, use the "stable" branch in the git repository.
+#endif
+
+#if !defined(_MSC_VER) && (!defined(CONFIGURED) || CONFIGURED != 1)
+# warning *** The library is being compiled using an undocumented method.
+# warning This is not supported. It has not been tested, it might not
+# warning work as expected, and performance is likely to be suboptimal.
+#endif
+
+static volatile int initialized;
+static volatile int locked;
+
+int
+sodium_init(void)
+{
+ if (sodium_crit_enter() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (initialized != 0) {
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 1;
+ }
+ _sodium_runtime_get_cpu_features();
+ randombytes_stir();
+ _sodium_alloc_init();
+ _crypto_pwhash_argon2_pick_best_implementation();
+ _crypto_generichash_blake2b_pick_best_implementation();
+ _crypto_onetimeauth_poly1305_pick_best_implementation();
+ _crypto_scalarmult_curve25519_pick_best_implementation();
+ _crypto_stream_chacha20_pick_best_implementation();
+ _crypto_stream_salsa20_pick_best_implementation();
+ initialized = 1;
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+#ifdef _WIN32
+
+static CRITICAL_SECTION _sodium_lock;
+static volatile LONG _sodium_lock_initialized;
+
+int
+_sodium_crit_init(void)
+{
+ LONG status = 0L;
+
+ while ((status = InterlockedCompareExchange(&_sodium_lock_initialized,
+ 1L, 0L)) == 1L) {
+ Sleep(0);
+ }
+
+ switch (status) {
+ case 0L:
+ InitializeCriticalSection(&_sodium_lock);
+ return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1;
+ case 2L:
+ return 0;
+ default: /* should never be reached */
+ return -1;
+ }
+}
+
+int
+sodium_crit_enter(void)
+{
+ if (_sodium_crit_init() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ EnterCriticalSection(&_sodium_lock);
+ assert(locked == 0);
+ locked = 1;
+
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ if (locked == 0) {
+# ifdef EPERM
+ errno = EPERM;
+# endif
+ return -1;
+ }
+ locked = 0;
+ LeaveCriticalSection(&_sodium_lock);
+
+ return 0;
+}
+
+#elif defined(HAVE_PTHREAD) && !defined(__EMSCRIPTEN__)
+
+static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER;
+
+int
+sodium_crit_enter(void)
+{
+ int ret;
+
+ if ((ret = pthread_mutex_lock(&_sodium_lock)) == 0) {
+ assert(locked == 0);
+ locked = 1;
+ }
+ return ret;
+}
+
+int
+sodium_crit_leave(void)
+{
+ int ret;
+
+ if (locked == 0) {
+# ifdef EPERM
+ errno = EPERM;
+# endif
+ return -1;
+ }
+ locked = 0;
+
+ return pthread_mutex_unlock(&_sodium_lock);
+}
+
+#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) && !defined(__native_client__)
+
+static volatile int _sodium_lock;
+
+int
+sodium_crit_enter(void)
+{
+# ifdef HAVE_NANOSLEEP
+ struct timespec q;
+ memset(&q, 0, sizeof q);
+# endif
+ while (__sync_lock_test_and_set(&_sodium_lock, 1) != 0) {
+# ifdef HAVE_NANOSLEEP
+ (void) nanosleep(&q, NULL);
+# elif defined(__x86_64__) || defined(__i386__)
+ __asm__ __volatile__ ("pause");
+# endif
+ }
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ __sync_lock_release(&_sodium_lock);
+
+ return 0;
+}
+
+#else
+
+int
+sodium_crit_enter(void)
+{
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ return 0;
+}
+
+#endif
+
+static void (*_misuse_handler)(void);
+
+void
+sodium_misuse(void)
+{
+ void (*handler)(void);
+
+ (void) sodium_crit_leave();
+ if (sodium_crit_enter() == 0) {
+ handler = _misuse_handler;
+ if (handler != NULL) {
+ handler();
+ }
+ }
+/* LCOV_EXCL_START */
+ abort();
+}
+/* LCOV_EXCL_STOP */
+
+int
+sodium_set_misuse_handler(void (*handler)(void))
+{
+ if (sodium_crit_enter() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ _misuse_handler = handler;
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
diff --git a/libs/libsodium/src/sodium/runtime.c b/libs/libsodium/src/sodium/runtime.c
new file mode 100644
index 0000000000..ba1000f4dc
--- /dev/null
+++ b/libs/libsodium/src/sodium/runtime.c
@@ -0,0 +1,286 @@
+#include <stddef.h>
+#include <stdint.h>
+#ifdef HAVE_ANDROID_GETCPUFEATURES
+# include <cpu-features.h>
+#endif
+
+#include "private/common.h"
+#include "runtime.h"
+
+typedef struct CPUFeatures_ {
+ int initialized;
+ int has_neon;
+ int has_sse2;
+ int has_sse3;
+ int has_ssse3;
+ int has_sse41;
+ int has_avx;
+ int has_avx2;
+ int has_avx512f;
+ int has_pclmul;
+ int has_aesni;
+ int has_rdrand;
+} CPUFeatures;
+
+static CPUFeatures _cpu_features;
+
+#define CPUID_EBX_AVX2 0x00000020
+#define CPUID_EBX_AVX512F 0x00010000
+
+#define CPUID_ECX_SSE3 0x00000001
+#define CPUID_ECX_PCLMUL 0x00000002
+#define CPUID_ECX_SSSE3 0x00000200
+#define CPUID_ECX_SSE41 0x00080000
+#define CPUID_ECX_AESNI 0x02000000
+#define CPUID_ECX_XSAVE 0x04000000
+#define CPUID_ECX_OSXSAVE 0x08000000
+#define CPUID_ECX_AVX 0x10000000
+#define CPUID_ECX_RDRAND 0x40000000
+
+#define CPUID_EDX_SSE2 0x04000000
+
+#define XCR0_SSE 0x00000002
+#define XCR0_AVX 0x00000004
+
+static int
+_sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features)
+{
+#ifndef __arm__
+ cpu_features->has_neon = 0;
+ return -1;
+#else
+# ifdef __APPLE__
+# ifdef __ARM_NEON__
+ cpu_features->has_neon = 1;
+# else
+ cpu_features->has_neon = 0;
+# endif
+# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \
+ defined(ANDROID_CPU_ARM_FEATURE_NEON)
+ cpu_features->has_neon =
+ (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0;
+# else
+ cpu_features->has_neon = 0;
+# endif
+ return 0;
+#endif
+}
+
+static void
+_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type)
+{
+#if defined(_MSC_VER) && \
+ (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86))
+ __cpuid((int *) cpu_info, cpu_info_type);
+#elif defined(HAVE_CPUID)
+ cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
+# ifdef __i386__
+ __asm__ __volatile__(
+ "pushfl; pushfl; "
+ "popl %0; "
+ "movl %0, %1; xorl %2, %0; "
+ "pushl %0; "
+ "popfl; pushfl; popl %0; popfl"
+ : "=&r"(cpu_info[0]), "=&r"(cpu_info[1])
+ : "i"(0x200000));
+ if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) {
+ return; /* LCOV_EXCL_LINE */
+ }
+# endif
+# ifdef __i386__
+ __asm__ __volatile__("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1"
+ : "=a"(cpu_info[0]), "=&r"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# elif defined(__x86_64__)
+ __asm__ __volatile__("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1"
+ : "=a"(cpu_info[0]), "=&r"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# else
+ __asm__ __volatile__("cpuid"
+ : "=a"(cpu_info[0]), "=b"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# endif
+#else
+ (void) cpu_info_type;
+ cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
+#endif
+}
+
+static int
+_sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features)
+{
+ unsigned int cpu_info[4];
+ unsigned int id;
+
+ _cpuid(cpu_info, 0x0);
+ if ((id = cpu_info[0]) == 0U) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ _cpuid(cpu_info, 0x00000001);
+#ifdef HAVE_EMMINTRIN_H
+ cpu_features->has_sse2 = ((cpu_info[3] & CPUID_EDX_SSE2) != 0x0);
+#else
+ cpu_features->has_sse2 = 0;
+#endif
+
+#ifdef HAVE_PMMINTRIN_H
+ cpu_features->has_sse3 = ((cpu_info[2] & CPUID_ECX_SSE3) != 0x0);
+#else
+ cpu_features->has_sse3 = 0;
+#endif
+
+#ifdef HAVE_TMMINTRIN_H
+ cpu_features->has_ssse3 = ((cpu_info[2] & CPUID_ECX_SSSE3) != 0x0);
+#else
+ cpu_features->has_ssse3 = 0;
+#endif
+
+#ifdef HAVE_SMMINTRIN_H
+ cpu_features->has_sse41 = ((cpu_info[2] & CPUID_ECX_SSE41) != 0x0);
+#else
+ cpu_features->has_sse41 = 0;
+#endif
+
+ cpu_features->has_avx = 0;
+#ifdef HAVE_AVXINTRIN_H
+ if ((cpu_info[2] & (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) ==
+ (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) {
+ uint32_t xcr0 = 0U;
+# if defined(HAVE__XGETBV) || \
+ (defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && _MSC_FULL_VER >= 160040219)
+ xcr0 = (uint32_t) _xgetbv(0);
+# elif defined(_MSC_VER) && defined(_M_IX86)
+ __asm {
+ xor ecx, ecx
+ _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
+ mov xcr0, eax
+ }
+# elif defined(HAVE_AVX_ASM)
+ __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */
+ : "=a"(xcr0)
+ : "c"((uint32_t) 0U)
+ : "%edx");
+# endif
+ if ((xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX)) {
+ cpu_features->has_avx = 1;
+ }
+ }
+#endif
+
+ cpu_features->has_avx2 = 0;
+#ifdef HAVE_AVX2INTRIN_H
+ if (cpu_features->has_avx) {
+ unsigned int cpu_info7[4];
+
+ _cpuid(cpu_info7, 0x00000007);
+ cpu_features->has_avx2 = ((cpu_info7[1] & CPUID_EBX_AVX2) != 0x0);
+ }
+#endif
+
+ cpu_features->has_avx512f = 0;
+#ifdef HAVE_AVX512FINTRIN_H
+ if (cpu_features->has_avx2) {
+ unsigned int cpu_info7[4];
+
+ _cpuid(cpu_info7, 0x00000007);
+ cpu_features->has_avx512f = ((cpu_info7[1] & CPUID_EBX_AVX512F) != 0x0);
+ }
+#endif
+
+#ifdef HAVE_WMMINTRIN_H
+ cpu_features->has_pclmul = ((cpu_info[2] & CPUID_ECX_PCLMUL) != 0x0);
+ cpu_features->has_aesni = ((cpu_info[2] & CPUID_ECX_AESNI) != 0x0);
+#else
+ cpu_features->has_pclmul = 0;
+ cpu_features->has_aesni = 0;
+#endif
+
+#ifdef HAVE_RDRAND
+ cpu_features->has_rdrand = ((cpu_info[2] & CPUID_ECX_RDRAND) != 0x0);
+#else
+ cpu_features->has_rdrand = 0;
+#endif
+
+ return 0;
+}
+
+int
+_sodium_runtime_get_cpu_features(void)
+{
+ int ret = -1;
+
+ ret &= _sodium_runtime_arm_cpu_features(&_cpu_features);
+ ret &= _sodium_runtime_intel_cpu_features(&_cpu_features);
+ _cpu_features.initialized = 1;
+
+ return ret;
+}
+
+int
+sodium_runtime_has_neon(void)
+{
+ return _cpu_features.has_neon;
+}
+
+int
+sodium_runtime_has_sse2(void)
+{
+ return _cpu_features.has_sse2;
+}
+
+int
+sodium_runtime_has_sse3(void)
+{
+ return _cpu_features.has_sse3;
+}
+
+int
+sodium_runtime_has_ssse3(void)
+{
+ return _cpu_features.has_ssse3;
+}
+
+int
+sodium_runtime_has_sse41(void)
+{
+ return _cpu_features.has_sse41;
+}
+
+int
+sodium_runtime_has_avx(void)
+{
+ return _cpu_features.has_avx;
+}
+
+int
+sodium_runtime_has_avx2(void)
+{
+ return _cpu_features.has_avx2;
+}
+
+int
+sodium_runtime_has_avx512f(void)
+{
+ return _cpu_features.has_avx512f;
+}
+
+int
+sodium_runtime_has_pclmul(void)
+{
+ return _cpu_features.has_pclmul;
+}
+
+int
+sodium_runtime_has_aesni(void)
+{
+ return _cpu_features.has_aesni;
+}
+
+int
+sodium_runtime_has_rdrand(void)
+{
+ return _cpu_features.has_rdrand;
+}
diff --git a/libs/libsodium/src/sodium/utils.c b/libs/libsodium/src/sodium/utils.c
new file mode 100644
index 0000000000..85aad29200
--- /dev/null
+++ b/libs/libsodium/src/sodium/utils.c
@@ -0,0 +1,737 @@
+#ifndef __STDC_WANT_LIB_EXT1__
+# define __STDC_WANT_LIB_EXT1__ 1
+#endif
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# include <wincrypt.h>
+#else
+# include <unistd.h>
+#endif
+
+#ifndef HAVE_C_VARARRAYS
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# elif !defined(alloca)
+# if defined(__GNUC__)
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+# endif
+#endif
+
+#include "core.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#ifndef ENOSYS
+# define ENOSYS ENXIO
+#endif
+
+#if defined(_WIN32) && \
+ (!defined(WINAPI_FAMILY) || WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
+# define WINAPI_DESKTOP
+#endif
+
+#define CANARY_SIZE 16U
+#define GARBAGE_VALUE 0xdb
+
+#ifndef MAP_NOCORE
+# define MAP_NOCORE 0
+#endif
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+#if defined(WINAPI_DESKTOP) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || \
+ defined(HAVE_POSIX_MEMALIGN)
+# define HAVE_ALIGNED_MALLOC
+#endif
+#if defined(HAVE_MPROTECT) && \
+ !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE))
+# undef HAVE_MPROTECT
+#endif
+#if defined(HAVE_ALIGNED_MALLOC) && \
+ (defined(WINAPI_DESKTOP) || defined(HAVE_MPROTECT))
+# define HAVE_PAGE_PROTECTION
+#endif
+#if !defined(MADV_DODUMP) && defined(MADV_CORE)
+# define MADV_DODUMP MADV_CORE
+# define MADV_DONTDUMP MADV_NOCORE
+#endif
+
+static size_t page_size;
+static unsigned char canary[CANARY_SIZE];
+
+/* LCOV_EXCL_START */
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt,
+ const size_t len)
+{
+ (void) pnt; /* LCOV_EXCL_LINE */
+ (void) len; /* LCOV_EXCL_LINE */
+}
+#endif
+/* LCOV_EXCL_STOP */
+
+void
+sodium_memzero(void *const pnt, const size_t len)
+{
+#ifdef _WIN32
+ SecureZeroMemory(pnt, len);
+#elif defined(HAVE_MEMSET_S)
+ if (len > 0U && memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#elif defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(pnt, len);
+#elif HAVE_WEAK_SYMBOLS
+ memset(pnt, 0, len);
+ _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len);
+# ifdef HAVE_AMD64_ASM
+ __asm__ __volatile__ ("" : : "p"(pnt));
+# endif
+#else
+ volatile unsigned char *volatile pnt_ =
+ (volatile unsigned char *volatile) pnt;
+ size_t i = (size_t) 0U;
+
+ while (i < len) {
+ pnt_[i++] = 0U;
+ }
+#endif
+}
+
+void
+sodium_stackzero(const size_t len)
+{
+#ifdef HAVE_C_VARARRAYS
+ unsigned char fodder[len];
+ sodium_memzero(fodder, len);
+#elif HAVE_ALLOCA
+ sodium_memzero(alloca(len), len);
+#endif
+}
+
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len)
+{
+ (void) b1;
+ (void) b2;
+ (void) len;
+}
+#endif
+
+int
+sodium_memcmp(const void *const b1_, const void *const b2_, size_t len)
+{
+#ifdef HAVE_WEAK_SYMBOLS
+ const unsigned char *b1 = (const unsigned char *) b1_;
+ const unsigned char *b2 = (const unsigned char *) b2_;
+#else
+ const volatile unsigned char *volatile b1 =
+ (const volatile unsigned char *volatile) b1_;
+ const volatile unsigned char *volatile b2 =
+ (const volatile unsigned char *volatile) b2_;
+#endif
+ size_t i;
+ volatile unsigned char d = 0U;
+
+#if HAVE_WEAK_SYMBOLS
+ _sodium_dummy_symbol_to_prevent_memcmp_lto(b1, b2, len);
+#endif
+ for (i = 0U; i < len; i++) {
+ d |= b1[i] ^ b2[i];
+ }
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len)
+{
+ (void) b1;
+ (void) b2;
+ (void) len;
+}
+#endif
+
+int
+sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len)
+{
+#ifdef HAVE_WEAK_SYMBOLS
+ const unsigned char *b1 = b1_;
+ const unsigned char *b2 = b2_;
+#else
+ const volatile unsigned char *volatile b1 =
+ (const volatile unsigned char *volatile) b1_;
+ const volatile unsigned char *volatile b2 =
+ (const volatile unsigned char *volatile) b2_;
+#endif
+ size_t i;
+ volatile unsigned char gt = 0U;
+ volatile unsigned char eq = 1U;
+ uint16_t x1, x2;
+
+#if HAVE_WEAK_SYMBOLS
+ _sodium_dummy_symbol_to_prevent_compare_lto(b1, b2, len);
+#endif
+ i = len;
+ while (i != 0U) {
+ i--;
+ x1 = b1[i];
+ x2 = b2[i];
+ gt |= ((x2 - x1) >> 8) & eq;
+ eq &= ((x2 ^ x1) - 1) >> 8;
+ }
+ return (int) (gt + gt + eq) - 1;
+}
+
+int
+sodium_is_zero(const unsigned char *n, const size_t nlen)
+{
+ size_t i;
+ volatile unsigned char d = 0U;
+
+ for (i = 0U; i < nlen; i++) {
+ d |= n[i];
+ }
+ return 1 & ((d - 1) >> 8);
+}
+
+void
+sodium_increment(unsigned char *n, const size_t nlen)
+{
+ size_t i = 0U;
+ uint_fast16_t c = 1U;
+
+#ifdef HAVE_AMD64_ASM
+ uint64_t t64, t64_2;
+ uint32_t t32;
+
+ if (nlen == 12U) {
+ __asm__ __volatile__(
+ "xorq %[t64], %[t64] \n"
+ "xorl %[t32], %[t32] \n"
+ "stc \n"
+ "adcq %[t64], (%[out]) \n"
+ "adcl %[t32], 8(%[out]) \n"
+ : [t64] "=&r"(t64), [t32] "=&r"(t32)
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ } else if (nlen == 24U) {
+ __asm__ __volatile__(
+ "movq $1, %[t64] \n"
+ "xorq %[t64_2], %[t64_2] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcq %[t64_2], 8(%[out]) \n"
+ "adcq %[t64_2], 16(%[out]) \n"
+ : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2)
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ } else if (nlen == 8U) {
+ __asm__ __volatile__("incq (%[out]) \n"
+ :
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ }
+#endif
+ for (; i < nlen; i++) {
+ c += (uint_fast16_t) n[i];
+ n[i] = (unsigned char) c;
+ c >>= 8;
+ }
+}
+
+void
+sodium_add(unsigned char *a, const unsigned char *b, const size_t len)
+{
+ size_t i = 0U;
+ uint_fast16_t c = 0U;
+
+#ifdef HAVE_AMD64_ASM
+ uint64_t t64, t64_2, t64_3;
+ uint32_t t32;
+
+ if (len == 12U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "movl 8(%[in]), %[t32] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcl %[t32], 8(%[out]) \n"
+ : [t64] "=&r"(t64), [t32] "=&r"(t32)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ } else if (len == 24U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "movq 8(%[in]), %[t64_2] \n"
+ "movq 16(%[in]), %[t64_3] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcq %[t64_2], 8(%[out]) \n"
+ "adcq %[t64_3], 16(%[out]) \n"
+ : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2), [t64_3] "=&r"(t64_3)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ } else if (len == 8U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "addq %[t64], (%[out]) \n"
+ : [t64] "=&r"(t64)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ }
+#endif
+ for (; i < len; i++) {
+ c += (uint_fast16_t) a[i] + (uint_fast16_t) b[i];
+ a[i] = (unsigned char) c;
+ c >>= 8;
+ }
+}
+
+int
+_sodium_alloc_init(void)
+{
+#ifdef HAVE_ALIGNED_MALLOC
+# if defined(_SC_PAGESIZE)
+ long page_size_ = sysconf(_SC_PAGESIZE);
+ if (page_size_ > 0L) {
+ page_size = (size_t) page_size_;
+ }
+# elif defined(WINAPI_DESKTOP)
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ page_size = (size_t) si.dwPageSize;
+# endif
+ if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+ randombytes_buf(canary, sizeof canary);
+
+ return 0;
+}
+
+int
+sodium_mlock(void *const addr, const size_t len)
+{
+#if defined(MADV_DONTDUMP) && defined(HAVE_MADVISE)
+ (void) madvise(addr, len, MADV_DONTDUMP);
+#endif
+#ifdef HAVE_MLOCK
+ return mlock(addr, len);
+#elif defined(WINAPI_DESKTOP)
+ return -(VirtualLock(addr, len) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int
+sodium_munlock(void *const addr, const size_t len)
+{
+ sodium_memzero(addr, len);
+#if defined(MADV_DODUMP) && defined(HAVE_MADVISE)
+ (void) madvise(addr, len, MADV_DODUMP);
+#endif
+#ifdef HAVE_MLOCK
+ return munlock(addr, len);
+#elif defined(WINAPI_DESKTOP)
+ return -(VirtualUnlock(addr, len) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_noaccess(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_NONE);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_readonly(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_READ);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_readwrite(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_READ | PROT_WRITE);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+#ifdef HAVE_ALIGNED_MALLOC
+
+__attribute__((noreturn)) static void
+_out_of_bounds(void)
+{
+# ifdef SIGSEGV
+ raise(SIGSEGV);
+# elif defined(SIGKILL)
+ raise(SIGKILL);
+# endif
+ abort(); /* not something we want any higher-level API to catch */
+} /* LCOV_EXCL_LINE */
+
+static inline size_t
+_page_round(const size_t size)
+{
+ const size_t page_mask = page_size - 1U;
+
+ return (size + page_mask) & ~page_mask;
+}
+
+static __attribute__((malloc)) unsigned char *
+_alloc_aligned(const size_t size)
+{
+ void *ptr;
+
+# if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) ==
+ MAP_FAILED) {
+ ptr = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+# elif defined(HAVE_POSIX_MEMALIGN)
+ if (posix_memalign(&ptr, page_size, size) != 0) {
+ ptr = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+# elif defined(WINAPI_DESKTOP)
+ ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+# else
+# error Bug
+# endif
+ return (unsigned char *) ptr;
+}
+
+static void
+_free_aligned(unsigned char *const ptr, const size_t size)
+{
+# if defined(MAP_ANON) && defined(HAVE_MMAP)
+ (void) munmap(ptr, size);
+# elif defined(HAVE_POSIX_MEMALIGN)
+ free(ptr);
+# elif defined(WINAPI_DESKTOP)
+ VirtualFree(ptr, 0U, MEM_RELEASE);
+# else
+# error Bug
+#endif
+}
+
+static unsigned char *
+_unprotected_ptr_from_user_ptr(void *const ptr)
+{
+ uintptr_t unprotected_ptr_u;
+ unsigned char *canary_ptr;
+ size_t page_mask;
+
+ canary_ptr = ((unsigned char *) ptr) - sizeof canary;
+ page_mask = page_size - 1U;
+ unprotected_ptr_u = ((uintptr_t) canary_ptr & (uintptr_t) ~page_mask);
+ if (unprotected_ptr_u <= page_size * 2U) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return (unsigned char *) unprotected_ptr_u;
+}
+
+#endif /* HAVE_ALIGNED_MALLOC */
+
+#ifndef HAVE_ALIGNED_MALLOC
+static __attribute__((malloc)) void *
+_sodium_malloc(const size_t size)
+{
+ return malloc(size > (size_t) 0U ? size : (size_t) 1U);
+}
+#else
+static __attribute__((malloc)) void *
+_sodium_malloc(const size_t size)
+{
+ void *user_ptr;
+ unsigned char *base_ptr;
+ unsigned char *canary_ptr;
+ unsigned char *unprotected_ptr;
+ size_t size_with_canary;
+ size_t total_size;
+ size_t unprotected_size;
+
+ if (size >= (size_t) SIZE_MAX - page_size * 4U) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ if (page_size <= sizeof canary || page_size < sizeof unprotected_size) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ size_with_canary = (sizeof canary) + size;
+ unprotected_size = _page_round(size_with_canary);
+ total_size = page_size + page_size + unprotected_size + page_size;
+ if ((base_ptr = _alloc_aligned(total_size)) == NULL) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ unprotected_ptr = base_ptr + page_size * 2U;
+ _mprotect_noaccess(base_ptr + page_size, page_size);
+# ifndef HAVE_PAGE_PROTECTION
+ memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary);
+# endif
+ _mprotect_noaccess(unprotected_ptr + unprotected_size, page_size);
+ sodium_mlock(unprotected_ptr, unprotected_size);
+ canary_ptr =
+ unprotected_ptr + _page_round(size_with_canary) - size_with_canary;
+ user_ptr = canary_ptr + sizeof canary;
+ memcpy(canary_ptr, canary, sizeof canary);
+ memcpy(base_ptr, &unprotected_size, sizeof unprotected_size);
+ _mprotect_readonly(base_ptr, page_size);
+ assert(_unprotected_ptr_from_user_ptr(user_ptr) == unprotected_ptr);
+
+ return user_ptr;
+}
+#endif /* !HAVE_ALIGNED_MALLOC */
+
+__attribute__((malloc)) void *
+sodium_malloc(const size_t size)
+{
+ void *ptr;
+
+ if ((ptr = _sodium_malloc(size)) == NULL) {
+ return NULL;
+ }
+ memset(ptr, (int) GARBAGE_VALUE, size);
+
+ return ptr;
+}
+
+__attribute__((malloc)) void *
+sodium_allocarray(size_t count, size_t size)
+{
+ size_t total_size;
+
+ if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ total_size = count * size;
+
+ return sodium_malloc(total_size);
+}
+
+#ifndef HAVE_ALIGNED_MALLOC
+void
+sodium_free(void *ptr)
+{
+ free(ptr);
+}
+#else
+void
+sodium_free(void *ptr)
+{
+ unsigned char *base_ptr;
+ unsigned char *canary_ptr;
+ unsigned char *unprotected_ptr;
+ size_t total_size;
+ size_t unprotected_size;
+
+ if (ptr == NULL) {
+ return;
+ }
+ canary_ptr = ((unsigned char *) ptr) - sizeof canary;
+ unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
+ base_ptr = unprotected_ptr - page_size * 2U;
+ memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
+ total_size = page_size + page_size + unprotected_size + page_size;
+ _mprotect_readwrite(base_ptr, total_size);
+ if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) {
+ _out_of_bounds();
+ }
+# ifndef HAVE_PAGE_PROTECTION
+ if (sodium_memcmp(unprotected_ptr + unprotected_size, canary,
+ sizeof canary) != 0) {
+ _out_of_bounds();
+ }
+# endif
+ sodium_munlock(unprotected_ptr, unprotected_size);
+ _free_aligned(base_ptr, total_size);
+}
+#endif /* HAVE_ALIGNED_MALLOC */
+
+#ifndef HAVE_PAGE_PROTECTION
+static int
+_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
+{
+ (void) ptr;
+ (void) cb;
+ errno = ENOSYS;
+ return -1;
+}
+#else
+static int
+_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
+{
+ unsigned char *base_ptr;
+ unsigned char *unprotected_ptr;
+ size_t unprotected_size;
+
+ unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
+ base_ptr = unprotected_ptr - page_size * 2U;
+ memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
+
+ return cb(unprotected_ptr, unprotected_size);
+}
+#endif
+
+int
+sodium_mprotect_noaccess(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_noaccess);
+}
+
+int
+sodium_mprotect_readonly(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_readonly);
+}
+
+int
+sodium_mprotect_readwrite(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_readwrite);
+}
+
+int
+sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
+ size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
+{
+ unsigned char *tail;
+ size_t i;
+ size_t xpadlen;
+ size_t xpadded_len;
+ volatile unsigned char mask;
+ unsigned char barrier_mask;
+
+ if (blocksize <= 0U) {
+ return -1;
+ }
+ xpadlen = blocksize - 1U;
+ if ((blocksize & (blocksize - 1U)) == 0U) {
+ xpadlen -= unpadded_buflen & (blocksize - 1U);
+ } else {
+ xpadlen -= unpadded_buflen % blocksize;
+ }
+ if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) {
+ sodium_misuse();
+ }
+ xpadded_len = unpadded_buflen + xpadlen;
+ if (xpadded_len >= max_buflen) {
+ return -1;
+ }
+ tail = &buf[xpadded_len];
+ if (padded_buflen_p != NULL) {
+ *padded_buflen_p = xpadded_len + 1U;
+ }
+ mask = 0U;
+ for (i = 0; i < blocksize; i++) {
+ barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> 8);
+ tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask);
+ mask |= barrier_mask;
+ }
+ return 0;
+}
+
+int
+sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
+ size_t padded_buflen, size_t blocksize)
+{
+ const unsigned char *tail;
+ unsigned char acc = 0U;
+ unsigned char c;
+ unsigned char valid = 0U;
+ volatile size_t pad_len = 0U;
+ size_t i;
+ size_t is_barrier;
+
+ if (padded_buflen < blocksize || blocksize <= 0U) {
+ return -1;
+ }
+ tail = &buf[padded_buflen - 1U];
+
+ for (i = 0U; i < blocksize; i++) {
+ c = tail[-i];
+ is_barrier =
+ (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U;
+ acc |= c;
+ pad_len |= i & (1U + ~is_barrier);
+ valid |= (unsigned char) is_barrier;
+ }
+ *unpadded_buflen_p = padded_buflen - 1U - pad_len;
+
+ return (int) (valid - 1U);
+}
diff --git a/libs/libsodium/src/sodium/version.c b/libs/libsodium/src/sodium/version.c
new file mode 100644
index 0000000000..4e584a6ea0
--- /dev/null
+++ b/libs/libsodium/src/sodium/version.c
@@ -0,0 +1,30 @@
+
+#include "version.h"
+
+const char *
+sodium_version_string(void)
+{
+ return SODIUM_VERSION_STRING;
+}
+
+int
+sodium_library_version_major(void)
+{
+ return SODIUM_LIBRARY_VERSION_MAJOR;
+}
+
+int
+sodium_library_version_minor(void)
+{
+ return SODIUM_LIBRARY_VERSION_MINOR;
+}
+
+int
+sodium_library_minimal(void)
+{
+#ifdef SODIUM_LIBRARY_MINIMAL
+ return 1;
+#else
+ return 0;
+#endif
+}
diff --git a/libs/libsodium/src/stdafx.cxx b/libs/libsodium/src/stdafx.cxx
new file mode 100644
index 0000000000..1647228cd0
--- /dev/null
+++ b/libs/libsodium/src/stdafx.cxx
@@ -0,0 +1,2 @@
+
+#include "stdafx.h" \ No newline at end of file
diff --git a/libs/libsodium/src/stdafx.h b/libs/libsodium/src/stdafx.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/libs/libsodium/src/stdafx.h
diff --git a/libs/pthreads/docs/ANNOUNCE b/libs/pthreads/docs/ANNOUNCE
new file mode 100644
index 0000000000..950c86ff03
--- /dev/null
+++ b/libs/pthreads/docs/ANNOUNCE
@@ -0,0 +1,483 @@
+PTHREADS-WIN32 RELEASE 2.9.0 (2012-05-25)
+-----------------------------------------
+Web Site: http://sourceware.org/pthreads-win32/
+FTP Site: ftp://sourceware.org/pub/pthreads-win32
+Maintainer: Ross Johnson <ross.johnson@loungebythelake.net>
+
+
+We are pleased to announce the availability of a new release of
+Pthreads-win32, an Open Source Software implementation of the
+Threads component of the POSIX 1003.1 2001 Standard for Microsoft's
+Win32 environment. Some functions from other sections of POSIX
+1003.1 2001 are also supported including semaphores and scheduling
+functions.
+
+Some common non-portable functions are also implemented for
+additional compatibility, as are a few functions specific
+to pthreads-win32 for easier integration with Win32 applications.
+
+Pthreads-win32 is free software, distributed under the GNU Lesser
+General Public License (LGPL).
+
+
+Acknowledgements
+----------------
+This library is based originally on a Win32 pthreads
+implementation contributed by John Bossom.
+
+The implementation of Condition Variables uses algorithms developed
+by Alexander Terekhov and Louis Thomas.
+
+The implementation of POSIX mutexes has been improved by Thomas Pfaff
+and later by Alexander Terekhov.
+
+The implementation of Spinlocks and Barriers was contributed
+by Ross Johnson.
+
+The implementation of read/write locks was contributed by
+Aurelio Medina and improved by Alexander Terekhov.
+
+Many others have contributed significant time and effort to solve crutial
+problems in order to make the library workable, robust and reliable.
+
+Thanks to Xavier Leroy for granting permission to use and modify his
+LinuxThreads manual pages.
+
+Thanks to The Open Group for making the Single Unix Specification
+publicly available - many of the manual pages included in the package
+were extracted from it.
+
+There is also a separate CONTRIBUTORS file. This file and others are
+on the web site:
+
+ http://sourceware.org/pthreads-win32
+
+As much as possible, the ChangeLog file acknowledges contributions to the
+code base in more detail.
+
+
+Changes since the last release
+------------------------------
+These are now documented in the NEWS file.
+See the ChangeLog file also.
+
+
+Known Bugs
+----------
+These are now documented in the BUGS file.
+
+
+Level of standards conformance
+------------------------------
+
+The following POSIX 1003.1 2001 options are defined and set to 200112L:
+
+ _POSIX_THREADS
+ _POSIX_THREAD_SAFE_FUNCTIONS
+ _POSIX_THREAD_ATTR_STACKSIZE
+ _POSIX_THREAD_PRIORITY_SCHEDULING
+ _POSIX_SEMAPHORES
+ _POSIX_READER_WRITER_LOCKS
+ _POSIX_SPIN_LOCKS
+ _POSIX_BARRIERS
+
+
+The following POSIX 1003.1 2001 options are defined and set to -1:
+
+ _POSIX_THREAD_ATTR_STACKADDR
+ _POSIX_THREAD_PRIO_INHERIT
+ _POSIX_THREAD_PRIO_PROTECT
+ _POSIX_THREAD_PROCESS_SHARED
+
+
+The following POSIX 1003.1 2001 limits are defined and set:
+
+ _POSIX_THREAD_THREADS_MAX
+ _POSIX_SEM_VALUE_MAX
+ _POSIX_SEM_NSEMS_MAX
+ _POSIX_THREAD_KEYS_MAX
+ _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+ PTHREAD_STACK_MIN
+ PTHREAD_THREADS_MAX
+ SEM_VALUE_MAX
+ SEM_NSEMS_MAX
+ PTHREAD_KEYS_MAX
+ PTHREAD_DESTRUCTOR_ITERATIONS
+
+
+The following functions are implemented:
+
+ ---------------------------
+ PThreads
+ ---------------------------
+ pthread_attr_init
+ pthread_attr_destroy
+ pthread_attr_getdetachstate
+ pthread_attr_getstackaddr
+ pthread_attr_getstacksize
+ pthread_attr_setdetachstate
+ pthread_attr_setstackaddr
+ pthread_attr_setstacksize
+
+ pthread_create
+ pthread_detach
+ pthread_equal
+ pthread_exit
+ pthread_join
+ pthread_once
+ pthread_self
+
+ pthread_cancel
+ pthread_cleanup_pop
+ pthread_cleanup_push
+ pthread_setcancelstate
+ pthread_setcanceltype
+ pthread_testcancel
+
+ ---------------------------
+ Thread Specific Data
+ ---------------------------
+ pthread_key_create
+ pthread_key_delete
+ pthread_setspecific
+ pthread_getspecific
+
+ ---------------------------
+ Mutexes
+ ---------------------------
+ pthread_mutexattr_init
+ pthread_mutexattr_destroy
+ pthread_mutexattr_getpshared
+ pthread_mutexattr_setpshared
+ pthread_mutexattr_gettype
+ pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT
+ PTHREAD_MUTEX_NORMAL
+ PTHREAD_MUTEX_ERRORCHECK
+ PTHREAD_MUTEX_RECURSIVE )
+ pthread_mutexattr_getrobust
+ pthread_mutexattr_setrobust (values: PTHREAD_MUTEX_STALLED
+ PTHREAD_MUTEX_ROBUST)
+ pthread_mutex_init
+ pthread_mutex_destroy
+ pthread_mutex_lock
+ pthread_mutex_trylock
+ pthread_mutex_timedlock
+ pthread_mutex_unlock
+ pthread_mutex_consistent
+
+ ---------------------------
+ Condition Variables
+ ---------------------------
+ pthread_condattr_init
+ pthread_condattr_destroy
+ pthread_condattr_getpshared
+ pthread_condattr_setpshared
+
+ pthread_cond_init
+ pthread_cond_destroy
+ pthread_cond_wait
+ pthread_cond_timedwait
+ pthread_cond_signal
+ pthread_cond_broadcast
+
+ ---------------------------
+ Read/Write Locks
+ ---------------------------
+ pthread_rwlock_init
+ pthread_rwlock_destroy
+ pthread_rwlock_tryrdlock
+ pthread_rwlock_trywrlock
+ pthread_rwlock_rdlock
+ pthread_rwlock_timedrdlock
+ pthread_rwlock_rwlock
+ pthread_rwlock_timedwrlock
+ pthread_rwlock_unlock
+ pthread_rwlockattr_init
+ pthread_rwlockattr_destroy
+ pthread_rwlockattr_getpshared
+ pthread_rwlockattr_setpshared
+
+ ---------------------------
+ Spin Locks
+ ---------------------------
+ pthread_spin_init
+ pthread_spin_destroy
+ pthread_spin_lock
+ pthread_spin_unlock
+ pthread_spin_trylock
+
+ ---------------------------
+ Barriers
+ ---------------------------
+ pthread_barrier_init
+ pthread_barrier_destroy
+ pthread_barrier_wait
+ pthread_barrierattr_init
+ pthread_barrierattr_destroy
+ pthread_barrierattr_getpshared
+ pthread_barrierattr_setpshared
+
+ ---------------------------
+ Semaphores
+ ---------------------------
+ sem_init
+ sem_destroy
+ sem_post
+ sem_wait
+ sem_trywait
+ sem_timedwait
+ sem_getvalue (# free if +ve, # of waiters if -ve)
+ sem_open (returns an error ENOSYS)
+ sem_close (returns an error ENOSYS)
+ sem_unlink (returns an error ENOSYS)
+
+ ---------------------------
+ RealTime Scheduling
+ ---------------------------
+ pthread_attr_getschedparam
+ pthread_attr_setschedparam
+ pthread_attr_getinheritsched
+ pthread_attr_setinheritsched
+ pthread_attr_getschedpolicy (only supports SCHED_OTHER)
+ pthread_attr_setschedpolicy (only supports SCHED_OTHER)
+ pthread_getschedparam
+ pthread_setschedparam
+ pthread_getconcurrency
+ pthread_setconcurrency
+ pthread_attr_getscope
+ pthread_attr_setscope (only supports PTHREAD_SCOPE_SYSTEM)
+ sched_get_priority_max
+ sched_get_priority_min
+ sched_rr_get_interval (returns an error ENOTSUP)
+ sched_setscheduler (only supports SCHED_OTHER)
+ sched_getscheduler (only supports SCHED_OTHER)
+ sched_yield
+
+ ---------------------------
+ Signals
+ ---------------------------
+ pthread_sigmask
+ pthread_kill (only supports zero sig value,
+ for thread validity checking)
+
+ ---------------------------
+ Non-portable routines (see the README.NONPORTABLE file for usage)
+ ---------------------------
+ pthread_getw32threadhandle_np
+ pthread_timechange_handler_np
+ pthread_delay_np
+ pthread_getunique_np
+ pthread_mutexattr_getkind_np
+ pthread_mutexattr_setkind_np (types: PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ADAPTIVE_NP,
+ PTHREAD_MUTEX_TIMED_NP)
+ pthread_num_processors_np
+ (The following four routines may be required when linking statically.
+ The process_* routines should not be needed for MSVC or GCC.)
+ pthread_win32_process_attach_np
+ pthread_win32_process_detach_np
+ (The following routines should only be needed to manage implicit
+ POSIX handles i.e. when Win native threads call POSIX thread routines
+ (other than pthread_create))
+ pthread_win32_thread_attach_np
+ pthread_win32_thread_detach_np
+
+ ---------------------------
+ Static Initializers
+ ---------------------------
+ PTHREAD_ONCE_INIT
+ PTHREAD_MUTEX_INITIALIZER
+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+ PTHREAD_COND_INITIALIZER
+ PTHREAD_RWLOCK_INITIALIZER
+ PTHREAD_SPINLOCK_INITIALIZER
+
+
+The library includes two non-API functions for creating cancellation
+points in applications and libraries:
+
+ pthreadCancelableWait
+ pthreadCancelableTimedWait
+
+
+The following functions are not implemented:
+
+ ---------------------------
+ RealTime Scheduling
+ ---------------------------
+ pthread_mutex_getprioceiling
+ pthread_mutex_setprioceiling
+ pthread_mutex_attr_getprioceiling
+ pthread_mutex_attr_getprotocol
+ pthread_mutex_attr_setprioceiling
+ pthread_mutex_attr_setprotocol
+
+ ---------------------------
+ Fork Handlers
+ ---------------------------
+ pthread_atfork
+
+ ---------------------------
+ Stdio
+ ---------------------------
+ flockfile
+ ftrylockfile
+ funlockfile
+ getc_unlocked
+ getchar_unlocked
+ putc_unlocked
+ putchar_unlocked
+
+ ---------------------------
+ Thread-Safe C Runtime Library
+ ---------------------------
+ readdir_r
+ getgrgid_r
+ getgrnam_r
+ getpwuid_r
+ getpwnam_r
+
+ ---------------------------
+ Signals
+ ---------------------------
+ sigtimedwait
+ sigwait
+ sigwaitinfo
+
+ ---------------------------
+ General
+ ---------------------------
+ sysconf
+
+ ---------------------------
+ Thread-Safe C Runtime Library (macros)
+ ---------------------------
+ strtok_r
+ asctime_r
+ ctime_r
+ gmtime_r
+ localtime_r
+ rand_r
+
+
+Availability
+------------
+
+The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header
+files (pthread.h, semaphore.h, sched.h) are available along with the
+complete source code.
+
+The source code can be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32
+
+and as individual source code files at
+
+ ftp://sources.redhat.com/pub/pthreads-win32/source
+
+The pre-built DLL, export libraries and include files can be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
+
+
+
+Mailing List
+------------
+
+There is a mailing list for discussing pthreads on Win32. To join,
+send email to:
+
+ pthreads-win32-subscribe@sourceware.cygnus.com
+
+
+Application Development Environments
+------------------------------------
+
+See the README file for more information.
+
+MSVC:
+MSVC using SEH works. Distribute pthreadVSE.dll with your application.
+MSVC using C++ EH works. Distribute pthreadVCE.dll with your application.
+MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application.
+
+
+Mingw32:
+See the FAQ, Questions 6 and 10.
+
+Mingw using C++ EH works. Distribute pthreadGCE.dll with your application.
+Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application.
+
+
+Cygwin: (http://sourceware.cygnus.com/cygwin/)
+Developers using Cygwin do not need pthreads-win32 since it has POSIX threads
+support. Refer to its documentation for details and extent.
+
+
+UWIN:
+UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32
+doesn't currently support UWIN (and vice versa), but that may change in the
+future.
+
+Generally:
+For convenience, the following pre-built files are available on the FTP site
+(see Availability above):
+
+ pthread.h - for POSIX threads
+ semaphore.h - for POSIX semaphores
+ sched.h - for POSIX scheduling
+ pthreadVCE.dll - built with MSVC++ compiler using C++ EH
+ pthreadVCE.lib
+ pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp
+ pthreadVC.lib
+ pthreadVSE.dll - built with MSVC compiler using SEH
+ pthreadVSE.lib
+ pthreadGCE.dll - built with Mingw32 G++ 2.95.2-1
+ pthreadGC.dll - built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp
+ libpthreadGCE.a - derived from pthreadGCE.dll
+ libpthreadGC.a - derived from pthreadGC.dll
+ gcc.dll - needed if distributing applications that use
+ pthreadGCE.dll (but see the FAQ Q 10 for the latest
+ related information)
+
+These are the only files you need in order to build POSIX threads
+applications for Win32 using either MSVC or Mingw32.
+
+See the FAQ file in the source tree for additional information.
+
+
+Documentation
+-------------
+
+For the authoritative reference, see the online POSIX
+standard reference at:
+
+ http://www.OpenGroup.org
+
+For POSIX Thread API programming, several reference books are
+available:
+
+ Programming with POSIX Threads
+ David R. Butenhof
+ Addison-Wesley (pub)
+
+ Pthreads Programming
+ By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell
+ O'Reilly (pub)
+
+On the web: see the links at the bottom of the pthreads-win32 site:
+
+ http://sources.redhat.com/pthreads-win32/
+
+ Currently, there is no documentation included in the package apart
+ from the copious comments in the source code.
+
+
+
+Enjoy!
+
+Ross Johnson
diff --git a/libs/pthreads/docs/BUGS b/libs/pthreads/docs/BUGS
new file mode 100644
index 0000000000..285ba4eb98
--- /dev/null
+++ b/libs/pthreads/docs/BUGS
@@ -0,0 +1,141 @@
+----------
+Known bugs
+----------
+
+1. Not strictly a bug, more of a gotcha.
+
+ Under MS VC++ (only tested with version 6.0), a term_func
+ set via the standard C++ set_terminate() function causes the
+ application to abort.
+
+ Notes from the MSVC++ manual:
+ 1) A term_func() should call exit(), otherwise
+ abort() will be called on return to the caller.
+ A call to abort() raises SIGABRT and the default signal handler
+ for all signals terminates the calling program with
+ exit code 3.
+ 2) A term_func() must not throw an exception. Therefore
+ term_func() should not call pthread_exit(), which
+ works by throwing an exception (pthreadVCE or pthreadVSE)
+ or by calling longjmp (pthreadVC).
+
+ Workaround: avoid using pthread_exit() in C++ applications. Exit
+ threads by dropping through the end of the thread routine.
+
+2. Cancellation problems in C++ builds
+ - Milan Gardian
+
+ [Note: It's not clear if this problem isn't simply due to the context
+ switch in pthread_cancel() which occurs unless the QueueUserAPCEx
+ library and driver are installed and used. Just like setjmp/longjmp,
+ this is probably not going to work well in C++. In any case, unless for
+ some very unusual reason you really must use the C++ build then please
+ use the C build pthreadVC2.dll or pthreadGC2.dll, i.e. for C++
+ applications.]
+
+ This is suspected to be a compiler bug in VC6.0, and also seen in
+ VC7.0 and VS .NET 2003. The GNU C++ compiler does not have a problem
+ with this, and it has been reported that the Intel C++ 8.1 compiler
+ and Visual C++ 2005 Express Edition Beta2 pass tests\semaphore4.c
+ (which exposes the bug).
+
+ Workaround [rpj - 2 Feb 2002]
+ -----------------------------
+ [Please note: this workaround did not solve a similar problem in
+ snapshot-2004-11-03 or later, even though similar symptoms were seen.
+ tests\semaphore4.c fails in that snapshot for the VCE version of the
+ DLL.]
+
+ The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK,
+ but if you want to use inlining optimisation you can be much more
+ specific about where it's switched off and on by using a pragma.
+
+ So the inlining optimisation is interfering with the way that cleanup
+ handlers are run. It appears to relate to auto-inlining of class methods
+ since this is the only auto inlining that is performed at /O1 optimisation
+ (functions with the "inline" qualifier are also inlined, but the problem
+ doesn't appear to involve any such functions in the library or testsuite).
+
+ In order to confirm the inlining culprit, the following use of pragmas
+ eliminate the problem but I don't know how to make it transparent, putting
+ it in, say, pthread.h where pthread_cleanup_push defined as a macro.
+
+ #pragma inline_depth(0)
+ pthread_cleanup_push(handlerFunc, (void *) &arg);
+
+ /* ... */
+
+ pthread_cleanup_pop(0);
+ #pragma inline_depth()
+
+ Note the empty () pragma value after the pop macro. This resets depth to the
+ default. Or you can specify a non-zero depth here.
+
+ The pragma is also needed (and now used) within the library itself wherever
+ cleanup handlers are used (condvar.c and rwlock.c).
+
+ Use of these pragmas allows compiler optimisations /O1 and /O2 to be
+ used for either or both the library and applications.
+
+ Experimenting further, I found that wrapping the actual cleanup handler
+ function with #pragma auto_inline(off|on) does NOT work.
+
+ MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive,
+ however, later versions may. This form is embeddable inside #define
+ macros, which would be ideal because it would mean that it could be added
+ to the push/pop macro definitions in pthread.h and hidden from the
+ application programmer.
+
+ [/rpj]
+
+ Original problem description
+ ----------------------------
+
+ The cancellation (actually, cleanup-after-cancel) tests fail when using VC
+ (professional) optimisation switches (/O1 or /O2) in pthreads library. I
+ have not investigated which concrete optimisation technique causes this
+ problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a
+ summary of builds and corresponding failures:
+
+ * pthreads VSE (optimised tests): OK
+ * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime)
+
+ * pthreads VSE (DLL in CRT, optimised tests): OK
+ * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test
+ (runtime)
+
+ Please note that while in VSE version of the pthreads library the
+ optimisation does not really have any impact on the tests (they pass OK), in
+ VCE version addition of optimisation (/O2 in this case) causes the tests to
+ fail uniformly - either in "cleanup0" or "cleanup1" test cases.
+
+ Please note that all the tests above use default pthreads DLL (no
+ optimisations, linked with either static or DLL CRT, based on test type).
+ Therefore the problem lies not within the pthreads DLL but within the
+ compiled client code (the application using pthreads -> involvement of
+ "pthread.h").
+
+ I think the message of this section is that usage of VCE version of pthreads
+ in applications relying on cancellation/cleanup AND using optimisations for
+ creation of production code is highly unreliable for the current version of
+ the pthreads library.
+
+3. The Borland Builder 5.5 version of the library produces memory read exceptions
+in some tests.
+
+4. pthread_barrier_wait() can deadlock if the number of potential calling
+threads for a particular barrier is greater than the barrier count parameter
+given to pthread_barrier_init() for that barrier.
+
+This is due to the very lightweight implementation of pthread-win32 barriers.
+To cope with more than "count" possible waiters, barriers must effectively
+implement all the same safeguards as condition variables, making them much
+"heavier" than at present.
+
+The workaround is to ensure that no more than "count" threads attempt to wait
+at the barrier.
+
+5. Canceling a thread blocked on pthread_once appears not to work in the MSVC++
+version of the library "pthreadVCE.dll". The test case "once3.c" hangs. I have no
+clues on this at present. All other versions pass this test ok - pthreadsVC.dll,
+pthreadsVSE.dll, pthreadsGC.dll and pthreadsGCE.dll.
diff --git a/libs/pthreads/docs/Bmakefile b/libs/pthreads/docs/Bmakefile
new file mode 100644
index 0000000000..ea25dec4fd
--- /dev/null
+++ b/libs/pthreads/docs/Bmakefile
@@ -0,0 +1,268 @@
+# This makefile is compatible with BCB make. Use "make -fBMakefile" to compile.
+#
+# The variables $DLLDEST and $LIBDEST hold the destination directories for the
+# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
+#
+# Currently only the recommended pthreadBC.dll is built by this makefile.
+#
+
+
+DLL_VER = 2
+
+DEVROOT = .
+
+DLLDEST = $(DEVROOT)\DLL
+LIBDEST = $(DEVROOT)\DLL
+
+DLLS = pthreadBC$(DLL_VER).dll
+
+OPTIM = /O2
+
+RC = brcc32
+RCFLAGS = -i.
+
+CFLAGS = /q /I. /D_WIN32_WINNT=0x400 /DHAVE_PTW32_CONFIG_H=1 /4 /tWD /tWM \
+ /w-aus /w-asc /w-par
+
+#C cleanup code
+BCFLAGS = $(PTW32_FLAGS) $(CFLAGS)
+
+# Agregate modules for inlinability
+DLL_OBJS = \
+ attr.obj \
+ barrier.obj \
+ cancel.obj \
+ cleanup.obj \
+ condvar.obj \
+ create.obj \
+ dll.obj \
+ errno.obj \
+ exit.obj \
+ fork.obj \
+ global.obj \
+ misc.obj \
+ mutex.obj \
+ nonportable.obj \
+ private.obj \
+ rwlock.obj \
+ sched.obj \
+ semaphore.obj \
+ signal.obj \
+ spin.obj \
+ sync.obj \
+ tsd.obj
+
+INCL = config.h implement.h semaphore.h pthread.h need_errno.h
+
+ATTR_SRCS = \
+ pthread_attr_init.c \
+ pthread_attr_destroy.c \
+ pthread_attr_getdetachstate.c \
+ pthread_attr_setdetachstate.c \
+ pthread_attr_getstackaddr.c \
+ pthread_attr_setstackaddr.c \
+ pthread_attr_getstacksize.c \
+ pthread_attr_setstacksize.c \
+ pthread_attr_getscope.c \
+ pthread_attr_setscope.c
+
+BARRIER_SRCS = \
+ pthread_barrier_init.c \
+ pthread_barrier_destroy.c \
+ pthread_barrier_wait.c \
+ pthread_barrierattr_init.c \
+ pthread_barrierattr_destroy.c \
+ pthread_barrierattr_setpshared.c \
+ pthread_barrierattr_getpshared.c
+
+CANCEL_SRCS = \
+ pthread_setcancelstate.c \
+ pthread_setcanceltype.c \
+ pthread_testcancel.c \
+ pthread_cancel.c
+
+CONDVAR_SRCS = \
+ ptw32_cond_check_need_init.c \
+ pthread_condattr_destroy.c \
+ pthread_condattr_getpshared.c \
+ pthread_condattr_init.c \
+ pthread_condattr_setpshared.c \
+ pthread_cond_destroy.c \
+ pthread_cond_init.c \
+ pthread_cond_signal.c \
+ pthread_cond_wait.c
+
+EXIT_SRCS = \
+ pthread_exit.c
+
+MISC_SRCS = \
+ pthread_equal.c \
+ pthread_getconcurrency.c \
+ pthread_once.c \
+ pthread_self.c \
+ pthread_setconcurrency.c \
+ ptw32_calloc.c \
+ ptw32_MCS_lock.c \
+ ptw32_new.c \
+ w32_CancelableWait.c
+
+MUTEX_SRCS = \
+ ptw32_mutex_check_need_init.c \
+ pthread_mutex_init.c \
+ pthread_mutex_destroy.c \
+ pthread_mutexattr_init.c \
+ pthread_mutexattr_destroy.c \
+ pthread_mutexattr_getpshared.c \
+ pthread_mutexattr_setpshared.c \
+ pthread_mutexattr_settype.c \
+ pthread_mutexattr_gettype.c \
+ pthread_mutexattr_setrobust.c \
+ pthread_mutexattr_getrobust.c \
+ pthread_mutex_lock.c \
+ pthread_mutex_timedlock.c \
+ pthread_mutex_unlock.c \
+ pthread_mutex_trylock.c \
+ pthread_mutex_consistent.c
+
+NONPORTABLE_SRCS = \
+ pthread_mutexattr_setkind_np.c \
+ pthread_mutexattr_getkind_np.c \
+ pthread_getw32threadhandle_np.c \
+ pthread_delay_np.c \
+ pthread_num_processors_np.c \
+ pthread_win32_attach_detach_np.c \
+ pthread_timechange_handler_np.c
+
+PRIVATE_SRCS = \
+ ptw32_is_attr.c \
+ ptw32_processInitialize.c \
+ ptw32_processTerminate.c \
+ ptw32_threadStart.c \
+ ptw32_threadDestroy.c \
+ ptw32_tkAssocCreate.c \
+ ptw32_tkAssocDestroy.c \
+ ptw32_callUserDestroyRoutines.c \
+ ptw32_timespec.c \
+ ptw32_relmillisecs.c \
+ ptw32_throw.c \
+ ptw32_getprocessors.c
+
+RWLOCK_SRCS = \
+ ptw32_rwlock_check_need_init.c \
+ ptw32_rwlock_cancelwrwait.c \
+ pthread_rwlock_init.c \
+ pthread_rwlock_destroy.c \
+ pthread_rwlockattr_init.c \
+ pthread_rwlockattr_destroy.c \
+ pthread_rwlockattr_getpshared.c \
+ pthread_rwlockattr_setpshared.c \
+ pthread_rwlock_rdlock.c \
+ pthread_rwlock_timedrdlock.c \
+ pthread_rwlock_wrlock.c \
+ pthread_rwlock_timedwrlock.c \
+ pthread_rwlock_unlock.c \
+ pthread_rwlock_tryrdlock.c \
+ pthread_rwlock_trywrlock.c
+
+SCHED_SRCS = \
+ pthread_attr_setschedpolicy.c \
+ pthread_attr_getschedpolicy.c \
+ pthread_attr_setschedparam.c \
+ pthread_attr_getschedparam.c \
+ pthread_attr_setinheritsched.c \
+ pthread_attr_getinheritsched.c \
+ pthread_setschedparam.c \
+ pthread_getschedparam.c \
+ sched_get_priority_max.c \
+ sched_get_priority_min.c \
+ sched_setscheduler.c \
+ sched_getscheduler.c \
+ sched_yield.c
+
+SEMAPHORE_SRCS = \
+ sem_init.c \
+ sem_destroy.c \
+ sem_trywait.c \
+ sem_timedwait.c \
+ sem_wait.c \
+ sem_post.c \
+ sem_post_multiple.c \
+ sem_getvalue.c \
+ sem_open.c \
+ sem_close.c \
+ sem_unlink.c
+
+SPIN_SRCS = \
+ ptw32_spinlock_check_need_init.c \
+ pthread_spin_init.c \
+ pthread_spin_destroy.c \
+ pthread_spin_lock.c \
+ pthread_spin_unlock.c \
+ pthread_spin_trylock.c
+
+SYNC_SRCS = \
+ pthread_detach.c \
+ pthread_join.c
+
+TSD_SRCS = \
+ pthread_key_create.c \
+ pthread_key_delete.c \
+ pthread_setspecific.c \
+ pthread_getspecific.c
+
+
+all: clean $(DLLS)
+
+realclean: clean
+ if exist pthread*.dll del pthread*.dll
+ if exist pthread*.lib del pthread*.lib
+ if exist *.stamp del *.stamp
+
+clean:
+ if exist *.obj del *.obj
+ if exist *.ilk del *.ilk
+ if exist *.ilc del *.ilc
+ if exist *.ild del *.ild
+ if exist *.ilf del *.ilf
+ if exist *.ils del *.ils
+ if exist *.tds del *.tds
+ if exist *.pdb del *.pdb
+ if exist *.exp del *.exp
+ if exist *.map del *.map
+ if exist *.o del *.o
+ if exist *.i del *.i
+ if exist *.res del *.res
+
+
+install: $(DLLS)
+ copy pthread*.dll $(DLLDEST)
+ copy pthread*.lib $(LIBDEST)
+
+$(DLLS): $(DLL_OBJS) version.res
+ ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \
+ $@, ,\
+ cw32mti.lib import32.lib, ,\
+ version.res
+
+.c.obj:
+ $(CC) $(OPTIM) $(BCFLAGS) -c $<
+
+.rc.res:
+ $(RC) $(RCFLAGS) $<
+
+attr.obj: attr.c $(ATTR_SRCS) $(INCL)
+barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.obj: exit.c $(EXIT_SRCS) $(INCL)
+misc.obj: misc.c $(MISC_SRCS) $(INCL)
+mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.obj: private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.obj: sched.c $(SCHED_SRCS) $(INCL)
+semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.obj: spin.c $(SPIN_SRCS) $(INCL)
+sync.obj: sync.c $(SYNC_SRCS) $(INCL)
+tsd.obj: tsd.c $(TSD_SRCS) $(INCL)
+version.res: version.rc $(INCL)
diff --git a/libs/pthreads/docs/CONTRIBUTORS b/libs/pthreads/docs/CONTRIBUTORS
new file mode 100644
index 0000000000..da31ff266c
--- /dev/null
+++ b/libs/pthreads/docs/CONTRIBUTORS
@@ -0,0 +1,140 @@
+Contributors (in approximate order of appearance)
+
+[See also the ChangeLog file where individuals are
+attributed in log entries. Likewise in the FAQ file.]
+
+Ben Elliston bje at cygnus dot com
+ Initiated the project;
+ setup the project infrastructure (CVS, web page, etc.);
+ early prototype routines.
+Ross Johnson Ross dot Johnson at dot homemail dot com dot au
+ early prototype routines;
+ ongoing project coordination/maintenance;
+ implementation of spin locks and barriers;
+ various enhancements;
+ bug fixes;
+ documentation;
+ testsuite.
+Robert Colquhoun rjc at trump dot net dot au
+ Early bug fixes.
+John E. Bossom John dot Bossom at cognos dot com
+ Contributed substantial original working implementation;
+ bug fixes;
+ ongoing guidance and standards interpretation.
+Anders Norlander anorland at hem2 dot passagen dot se
+ Early enhancements and runtime checking for supported
+ Win32 routines.
+Tor Lillqvist tml at iki dot fi
+ General enhancements;
+ early bug fixes to condition variables.
+Scott Lightner scott at curriculum dot com
+ Bug fix.
+Kevin Ruland Kevin dot Ruland at anheuser-busch dot com
+ Various bug fixes.
+Mike Russo miker at eai dot com
+ Bug fix.
+Mark E. Armstrong avail at pacbell dot net
+ Bug fixes.
+Lorin Hochstein lmh at xiphos dot ca
+ general bug fixes; bug fixes to condition variables.
+Peter Slacik Peter dot Slacik at tatramed dot sk
+ Bug fixes.
+Mumit Khan khan at xraylith dot wisc dot edu
+ Fixes to work with Mingw32.
+Milan Gardian mg at tatramed dot sk
+ Bug fixes and reports/analyses of obscure problems.
+Aurelio Medina aureliom at crt dot com
+ First implementation of read-write locks.
+Graham Dumpleton Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au
+ Bug fix in condition variables.
+Tristan Savatier tristan at mpegtv dot com
+ WinCE port.
+Erik Hensema erik at hensema dot xs4all dot nl
+ Bug fixes.
+Rich Peters rpeters at micro-magic dot com
+Todd Owen towen at lucidcalm dot dropbear dot id dot au
+ Bug fixes to dll loading.
+Jason Nye jnye at nbnet dot nb dot ca
+ Implementation of async cancelation.
+Fred Forester fforest at eticomm dot net
+Kevin D. Clark kclark at cabletron dot com
+David Baggett dmb at itasoftware dot com
+ Bug fixes.
+Paul Redondo paul at matchvision dot com
+Scott McCaskill scott at 3dfx dot com
+ Bug fixes.
+Jef Gearhart jgearhart at tpssys dot com
+ Bug fix.
+Arthur Kantor akantor at bexusa dot com
+ Mutex enhancements.
+Steven Reddie smr at essemer dot com dot au
+ Bug fix.
+Alexander Terekhov TEREKHOV at de dot ibm dot com
+ Re-implemented and improved read-write locks;
+ (with Louis Thomas) re-implemented and improved
+ condition variables;
+ enhancements to semaphores;
+ enhancements to mutexes;
+ new mutex implementation in 'futex' style;
+ suggested a robust implementation of pthread_once
+ similar to that implemented by V.Kliathcko;
+ system clock change handling re CV timeouts;
+ bug fixes.
+Thomas Pfaff tpfaff at gmx dot net
+ Changes to make C version usable with C++ applications;
+ re-implemented mutex routines to avoid Win32 mutexes
+ and TryEnterCriticalSection;
+ procedure to fix Mingw32 thread-safety issues.
+Franco Bez franco dot bez at gmx dot de
+ procedure to fix Mingw32 thread-safety issues.
+Louis Thomas lthomas at arbitrade dot com
+ (with Alexander Terekhov) re-implemented and improved
+ condition variables.
+David Korn dgk at research dot att dot com
+ Ported to UWIN.
+Phil Frisbie, Jr. phil at hawksoft dot com
+ Bug fix.
+Ralf Brese Ralf dot Brese at pdb4 dot siemens dot de
+ Bug fix.
+prionx at juno dot com prionx at juno dot com
+ Bug fixes.
+Max Woodbury mtew at cds dot duke dot edu
+ POSIX versioning conditionals;
+ reduced namespace pollution;
+ idea to separate routines to reduce statically
+ linked image sizes.
+Rob Fanner rfanner at stonethree dot com
+ Bug fix.
+Michael Johnson michaelj at maine dot rr dot com
+ Bug fix.
+Nicolas Barry boozai at yahoo dot com
+ Bug fixes.
+Piet van Bruggen pietvb at newbridges dot nl
+ Bug fix.
+Makoto Kato raven at oldskool dot jp
+ AMD64 port.
+Panagiotis E. Hadjidoukas peh at hpclab dot ceid dot upatras dot gr
+ phadjido at cs dot uoi dot gr
+ Contributed the QueueUserAPCEx package which
+ makes preemptive async cancelation possible.
+Will Bryant will dot bryant at ecosm dot com
+ Borland compiler patch and makefile.
+Anuj Goyal anuj dot goyal at gmail dot com
+ Port to Digital Mars compiler.
+Gottlob Frege gottlobfrege at gmail dot com
+ re-implemented pthread_once (version 2)
+ (pthread_once cancellation added by rpj).
+Vladimir Kliatchko vladimir at kliatchko dot com
+ reimplemented pthread_once with the same form
+ as described by A.Terekhov (later version 2);
+ implementation of MCS (Mellor-Crummey/Scott) locks.
+Ramiro Polla ramiro.polla at gmail dot com
+ static library auto init/cleanup on application
+ start/exit via RT hooks (MSC and GCC compilers only).
+Daniel Richard G. skunk at iSKUNK dot org
+ Patches and cleanups for x86 and x64, particularly
+ across a range of MS build environments.
+John Kamp john dot kamp at globalgraphics dot com
+ Patches to fix various problems on x64; brutal testing
+ particularly using high memory run environments.
+
diff --git a/libs/pthreads/docs/COPYING b/libs/pthreads/docs/COPYING
new file mode 100644
index 0000000000..5cfea0d0ed
--- /dev/null
+++ b/libs/pthreads/docs/COPYING
@@ -0,0 +1,150 @@
+ pthreads-win32 - a POSIX threads library for Microsoft Windows
+
+
+This file is Copyrighted
+------------------------
+
+ This file is covered under the following Copyright:
+
+ Copyright (C) 2001,2006 Ross P. Johnson
+ All rights reserved.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Pthreads-win32 is covered by the GNU Lesser General Public License
+------------------------------------------------------------------
+
+ Pthreads-win32 is open software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation version 2.1 of the
+ License.
+
+ Pthreads-win32 is several binary link libraries, several modules,
+ associated interface definition files and scripts used to control
+ its compilation and installation.
+
+ Pthreads-win32 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ A copy of the GNU Lesser General Public License is distributed with
+ pthreads-win32 under the filename:
+
+ COPYING.LIB
+
+ You should have received a copy of the version 2.1 GNU Lesser General
+ Public License with pthreads-win32; if not, write to:
+
+ Free Software Foundation, Inc.
+ 59 Temple Place
+ Suite 330
+ Boston, MA 02111-1307
+ USA
+
+ The contact addresses for pthreads-win32 is as follows:
+
+ Web: http://sources.redhat.com/pthreads-win32
+ Email: Ross Johnson
+ Please use: Firstname.Lastname@homemail.com.au
+
+
+
+Pthreads-win32 copyrights and exception files
+---------------------------------------------
+
+ With the exception of the files listed below, Pthreads-win32
+ is covered under the following GNU Lesser General Public License
+ Copyrights:
+
+ Pthreads-win32 - POSIX Threads Library for Win32
+ Copyright(C) 1998 John E. Bossom
+ Copyright(C) 1999,2006 Pthreads-win32 contributors
+
+ The current list of contributors is contained
+ in the file CONTRIBUTORS included with the source
+ code distribution. The current list of CONTRIBUTORS
+ can also be seen at the following WWW location:
+ http://sources.redhat.com/pthreads-win32/contributors.html
+
+ Contact Email: Ross Johnson
+ Please use: Firstname.Lastname@homemail.com.au
+
+ These files are not covered under one of the Copyrights listed above:
+
+ COPYING
+ COPYING.LIB
+ tests/rwlock7.c
+
+ This file, COPYING, is distributed under the Copyright found at the
+ top of this file. It is important to note that you may distribute
+ verbatim copies of this file but you may not modify this file.
+
+ The file COPYING.LIB, which contains a copy of the version 2.1
+ GNU Lesser General Public License, is itself copyrighted by the
+ Free Software Foundation, Inc. Please note that the Free Software
+ Foundation, Inc. does NOT have a copyright over Pthreads-win32,
+ only the COPYING.LIB that is supplied with pthreads-win32.
+
+ The file tests/rwlock7.c is derived from code written by
+ Dave Butenhof for his book 'Programming With POSIX(R) Threads'.
+ The original code was obtained by free download from his website
+ http://home.earthlink.net/~anneart/family/Threads/source.html
+ and did not contain a copyright or author notice. It is assumed to
+ be freely distributable.
+
+ In all cases one may use and distribute these exception files freely.
+ And because one may freely distribute the LGPL covered files, the
+ entire pthreads-win32 source may be freely used and distributed.
+
+
+
+General Copyleft and License info
+---------------------------------
+
+ For general information on Copylefts, see:
+
+ http://www.gnu.org/copyleft/
+
+ For information on GNU Lesser General Public Licenses, see:
+
+ http://www.gnu.org/copyleft/lesser.html
+ http://www.gnu.org/copyleft/lesser.txt
+
+
+Why pthreads-win32 did not use the GNU General Public License
+-------------------------------------------------------------
+
+ The goal of the pthreads-win32 project has been to
+ provide a quality and complete implementation of the POSIX
+ threads API for Microsoft Windows within the limits imposed
+ by virtue of it being a stand-alone library and not
+ linked directly to other POSIX compliant libraries. For
+ example, some functions and features, such as those based
+ on POSIX signals, are missing.
+
+ Pthreads-win32 is a library, available in several different
+ versions depending on supported compilers, and may be used
+ as a dynamically linked module or a statically linked set of
+ binary modules. It is not an application on it's own.
+
+ It was fully intended that pthreads-win32 be usable with
+ commercial software not covered by either the GPL or the LGPL
+ licenses. Pthreads-win32 has many contributors to it's
+ code base, many of whom have done so because they have
+ used the library in commercial or proprietry software
+ projects.
+
+ Releasing pthreads-win32 under the LGPL ensures that the
+ library can be used widely, while at the same time ensures
+ that bug fixes and improvements to the pthreads-win32 code
+ itself is returned to benefit all current and future users
+ of the library.
+
+ Although pthreads-win32 makes it possible for applications
+ that use POSIX threads to be ported to Win32 platforms, the
+ broader goal of the project is to encourage the use of open
+ standards, and in particular, to make it just a little easier
+ for developers writing Win32 applications to consider
+ widening the potential market for their products.
diff --git a/libs/pthreads/docs/ChangeLog b/libs/pthreads/docs/ChangeLog
new file mode 100644
index 0000000000..42abcc457a
--- /dev/null
+++ b/libs/pthreads/docs/ChangeLog
@@ -0,0 +1,5211 @@
+2012-03-18 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * create.c (pthread_create): add __cdecl attribute to thread routine
+ arg
+ * implement.h (pthread_key_t): add __cdecl attribute to destructor
+ element
+ (ThreadParms): likewise for start element
+ * pthread.h (pthread_create): add __cdecl to prototype start arg
+ (pthread_once): likewise for init_routine arg
+ (pthread_key_create): likewise for destructor arg
+ (ptw32_cleanup_push): replace type of routine arg with previously
+ defined ptw32_cleanup_callback_t
+ * pthread_key_create.c: add __cdecl attribute to destructor arg
+ * pthread_once.c: add __cdecl attribute to init_routine arg
+ * ptw32_threadStart.c (start): add __cdecl to start variable type
+
+
+2011-07-06 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * pthread_cond_wait.c (pragma inline_depth): this is almost redundant
+ now nevertheless fixed thei controlling MSC_VER from "< 800" to
+ "< 1400" (i.e. any prior to VC++ 8.0).
+ * pthread_once.ci (pragma inline_depth): Likewise.
+ * pthread_rwlock_timedwrlock.ci (pragma inline_depth): Likewise.
+ * pthread_rwlock_wrlock.ci (pragma inline_depth): Likewise.
+ * sem_timedwait.ci (pragma inline_depth): Likewise.
+ * sem_wait.ci (pragma inline_depth): Likewise.
+
+2011-07-05 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * pthread_win32_attach_detach_np.c: Use strncat_s if available
+ to removei a compile warning; MingW supports this routine but we
+ continue to use strncat anyway there because it is secure if
+ given the correct parameters; fix strncat param 3 to avoid
+ buffer overrun exploitation potential.
+
+2011-07-03 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * pthread_spin_unlock.c (EPERM): Return success if unlocking a lock
+ that is not locked, because single CPU machines wrap a
+ PTHREAD_MUTEX_NORMAL mutex, which returns success in this case.
+ * pthread_win32_attach_detach_np.c (QUSEREX.DLL): Load from an
+ absolute path only which must be the Windows System folder.
+
+2011-07-03 Daniel Richard G. <skunk at iskunk dot org>
+
+ * Makefile (_WIN32_WINNT): Removed; duplicate definition in
+ implement.h; more cleanup and enhancements.
+
+2011-07-02 Daniel Richard G. <skunk at iskunk dot org>
+
+ * Makefile: Cleanups and implovements.
+ * ptw32_MCS_locks.c: Casting fixes.
+ * implement.h: Interlocked call and argument casting macro fixes
+ to support older and newer build environments.
+
+2011-07-01 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * *.[ch] (PTW32_INTERLOCKED_*): Redo 23 and 64 bit versions of these
+ macros and re-apply in code to undo the incorrect changes from
+ 2011-06-29; remove some size_t casts which should not be required
+ and may be problematic.a
+ There are now two sets of macros:
+ PTW32_INTERLOCKED_*_LONG which work only on 32 bit integer variables;
+ PTW32_INTERLOCKED_*_SIZE which work on size_t integer variables, i.e.
+ LONG for 32 bit systems and LONGLONG for 64 bit systems.
+ * implement.h (MCS locks): nextFlag and waitFlag are now HANDLE type.
+ * ptw32_MCS_locks.c: Likewise.
+ * pthread.h (#include <setjmp.h>): Removed.
+ * ptw32_throw.c (#include <setjmp.h>): Added.
+ * ptw32_threadStart.c (#include <setjmp.h>): Added.
+ * implement.h (#include <setjmp.h>): Added.
+
+2011-06-30 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * pthread_once.c: Tighten 'if' statement casting; fix interlocked
+ pointer cast for 64 bit compatibility (missed yesterday); remove
+ the superfluous static cleanup routine and call the release routine
+ directly if popped.
+ * create.c (stackSize): Now type size_t.
+ * pthread.h (struct ptw32_thread_t_): Rearrange to fix element alignments.
+
+2011-06-29 Daniel Richard G. <skunk at iskunk dot org>
+
+ * ptw32_relmillisecs.c (ftime):
+ _ftime64_s() is only available in MSVC 2005 or later;
+ _ftime64() is available in MinGW or MSVC 2002 or later;
+ _ftime() is always available.
+ * pthread.h (long long): Not defined in older MSVC 6.
+ * implement.h (long long): Likewise.
+ * pthread_getunique_np.c (long long): Likewise.
+
+2011-06-29 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * *.[ch] (PTW32_INTERLOCKED_*): These macros should now work for
+ both 32 and 64 bit builds. The MingW versions are all inlined asm
+ while the MSVC versions expand to their Interlocked* or Interlocked*64
+ counterparts appropriately. The argument type have also been changed
+ to cast to the appropriate value or pointer size for the architecture.
+
+2011-05-29 Ross Johnson <ross dot johnson at homemail dot com dot au>
+
+ * *.[ch] (#ifdef): Extended cleanup to whole project.
+
+2011-05-29 Daniel Richard G. <skunk at iskunk dot org>
+
+ * Makefile (CC): Define CC to allow use of other compatible
+ compilers such as the Intel compilter icl.
+ * implement.h (#if): Fix forms like #if HAVE_SOMETHING.
+ * pthread.h: Likewise.
+ * sched.h: Likewise; PTW32_LEVEL_* becomes PTW32_SCHED_LEVEL_*.
+ * semaphore.h: Likewise.
+
+2011-05-11 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * ptw32_callUserDestroyRoutines.c (terminate): Altered includes
+ to match ptw32_threadStart.c.
+ * GNUmakefile (GCE-inlined-debug, DOPT): Fixed.
+
+2011-04-31 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * (robust mutexes): Added this API. The API is not
+ mandatory for implementations that don't support PROCESS_SHARED
+ mutexes, nevertheless it was considered useful both functionally
+ and for source-level compatibility.
+
+2011-03-26 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * pthread_getunique_np.c: New non-POSIX interface for compatibility
+ with some other implementations; returns a 64 bit sequence number
+ that is unique to each thread in the process.
+ * pthread.h (pthread_getunique_np): Added.
+ * global.c: Add global sequence counter for above.
+ * implement.h: Likewise.
+
+2011-03-25 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * (cancelLock): Convert to an MCS lock and rename to stateLock.
+ * (threadLock): Likewise.
+ * (keyLock): Likewise.
+ * pthread_mutex*.c: First working robust mutexes.
+
+2011-03-11 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * implement.h (PTW32_INTERLOCKED_*CREMENT macros): increment/decrement
+ using ++/-- instead of add/subtract 1.
+ * ptw32_MCS_lock.c: Make casts consistent.
+
+2011-03-09 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * implement.h (ptw32_thread_t_): Add process unique sequence number.
+ * global.c: Replace global Critical Section objects with MCS
+ queue locks.
+ * implement.h: Likewise.
+ * pthread_cond_destroy.c: Likewise.
+ * pthread_cond_init.c: Likewise.
+ * pthread_detach.c: Likewise.
+ * pthread_join.c: Likewise.
+ * pthread_kill.c: Likewise.
+ * pthread_mutex_destroy.c: Likewise.
+ * pthread_rwlock_destroy.c: Likewise.
+ * pthread_spin_destroy.c: Likewise.
+ * pthread_timechange_handler_np.c: Likewise.
+ * ptw32_cond_check_need_init.c: Likewise.
+ * ptw32_mutex_check_need_init.c: Likewise.
+ * ptw32_processInitialize.c: Likewise.
+ * ptw32_processTerminate.c: Likewise.
+ * ptw32_reuse.c: Likewise.
+ * ptw32_rwlock_check_need_init.c: Likewise.
+ * ptw32_spinlock_check_need_init.c: Likewise.
+
+2011-03-06 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * several (MINGW64): Cast and call fixups for 64 bit compatibility;
+ clean build via x86_64-w64-mingw32 cross toolchain on Linux i686
+ targeting x86_64 win64.
+ * ptw32_threadStart.c (ptw32_threadStart): Routine no longer attempts
+ to pass [unexpected C++] exceptions out of scope but ends the thread
+ normally setting EINTR as the exit status.
+ * ptw32_throw.c: Fix C++ exception throwing warnings; ignore
+ informational warning.
+ * implement.h: Likewise with the corresponding header definition.
+
+2011-03-04 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * implement.h (PTW32_INTERLOCKED_*): Mingw32 does not provide
+ the __sync_* intrinsics so implemented them here as macro
+ assembler routines. MSVS Interlocked* are emmitted as intrinsics
+ wherever possible, so we want mingw to match it; Extended to
+ include all interlocked routines used by the library; implemented
+ x86_64 versions also.
+ * ptw32_InterlockedCompareExchange.c: No code remaining here.
+ * ptw32_MCS_lock.c: Converted interlocked calls to use new macros.
+ * pthread_barrier_wait.c: Likewise.
+ * pthread_once.c: Likewise.
+ * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Name changed to
+ ptw32_mcs_node_transfer.
+
+2011-02-28 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * ptw32_relmillisecs.c: If possible, use _ftime64_s or _ftime64
+ before resorting to _ftime.
+
+2011-02-27 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * sched_setscheduler.c: Ensure the handle is closed after use.
+ * sched_getscheduler.c: Likewise.
+ * pthread.h: Remove POSIX compatibility macros; don't define
+ timespec if already defined.
+ * context.h: Changes for 64 bit.
+ * pthread_cancel.c: Likewise.
+ * pthread_exit.c: Likewise.
+ * pthread_spin_destroy.c: Likewise.
+ * pthread_timechange_handler_np.c: Likewise.
+ * ptw32_MCS_lock.c: Likewise; some of these changes may
+ not be compatible with pre Windows 2000 systems; reverse the order of
+ the includes.
+ * ptw32_threadStart.c: Likewise.
+ * ptw32_throw.c: Likewise.
+
+2011-02-13 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * pthread_self: Add comment re returning 'nil' value to
+ indicate failure only to win32 threads that call us.
+ * pthread_attr_setstackaddr: Fix comments; note this
+ function and it's compliment are now removed from SUSv4.
+
+2011-02-12 Ross Johnson <ross.johnson at homemail.com.au>
+
+ README.NONPORTABLE: Record a description of an obvious
+ method for nulling/comparing/hashing pthread_t using a
+ union; plus and investigation of a change of type for
+ pthread_t (to a union) to neutralise any padding bits and
+ bytes if they occur in pthread_t (the current pthread_t struct
+ does not contain padding AFAIK, but porting the library to a
+ future architecture may introduce them). Padding affects
+ byte-by-byte copies and compare operations.
+
+2010-11-16 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * ChangeLog: Add this entry ;-)
+ Restore entries from 2007 through 2009 that went missing
+ at the last update.
+
+2010-06-19 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Fix variable
+ names to avoid using C++ keyword ("new").
+ * implement.h (ptw32_mcs_node_substitute): Likewise.
+ * pthread_barrier_wait.c: Fix signed/unsigned comparison warning.
+
+2010-06-18 Ramiro Polla <ramiro.polla at gmail.com >
+
+ * autostatic.c: New file; call pthread_win32_process_*()
+ libary init/cleanup routines automatically on application start
+ when statically linked.
+ * pthread.c (autostatic.c): Included.
+ * pthread.h (declspec): Remove import/export defines if compiler
+ is MINGW.
+ * sched.h (declspec): Likewise.
+ * semaphore.h (declspec): Likewise.
+ * need_errno.h (declspec): Likewise.
+ * Makefile (autostatic.obj): Add for small static builds.
+ * GNUmakefile (autostatic.o): Likewise.
+ * NEWS (Version 2.9.0): Add changes.
+ * README.NONPORTABLE (pthread_win32_process_*): Update
+ description.
+
+2010-06-15 Ramiro Polla <ramiro.polla at gmail.com >
+
+ * Makefile: Remove linkage with the winsock library by default.
+ * GNUmakefile: Likewise.
+ * pthread_getspecific.c: Likewise by removing calls to WSA
+ functions.
+ * config.h (RETAIN_WSALASTERROR): Can be defined if necessary.
+
+2010-01-26 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): New routine
+ to allow relocating the lock owners thread-local node to somewhere
+ else, e.g. to global space so that another thread can release the
+ lock. Used in pthread_barrier_wait.
+ (ptw32_mcs_lock_try_acquire): New routine.
+ * pthread_barrier_init: Only one semaphore is used now.
+ * pthread_barrier_wait: Added an MCS guard lock with the last thread
+ to leave the barrier releasing the lock. This removes a deadlock bug
+ observed when there are greater than barrier-count threads
+ attempting to cross.
+ * pthread_barrier_destroy: Added an MCS guard lock.
+
+2009-03-03 Stephan O'Farrill <stephan dot ofarrill at gmail dot com>
+
+ * pthread_attr_getschedpolicy.c: Add "const" to function parameter
+ in accordance with SUSv3 (POSIX).
+ * pthread_attr_getinheritsched.c: Likewise.
+ * pthread_mutexattr_gettype.c: Likewise.
+
+2008-06-06 Robert Kindred <RKindred at SwRI dot edu>
+
+ * ptw32_throw.c (ptw32_throw): Remove possible reference to NULL
+ pointer. (At the same time made the switch block conditionally
+ included only if exitCode is needed - RPJ.)
+ * pthread_testcancel.c (pthread_testcancel): Remove duplicate and
+ misplaced pthread_mutex_unlock().
+
+2008-02-21 Sebastian Gottschalk <seppig_relay at gmx dot de>
+
+ * pthread_attr_getdetachstate.c (pthread_attr_getdetachstate):
+ Remove potential and superfluous null pointer assignment.
+
+2007-11-22 Ivan Pizhenko <ivanp4 at ua dot fm>
+
+ * pthread.h (gmtime_r): gmtime returns 0 if tm represents a time
+ prior to 1/1/1970. Notice this to prevent raising an exception.
+ * pthread.h (localtime_r): Likewise for localtime.
+
+2007-07-14 Marcel Ruff <mr at marcelruff dot info>
+
+ * errno.c (_errno): Fix test for pthread_self() success.
+ * need_errno.h: Remove unintentional line wrap from #if line.
+
+2007-07-14 Mike Romanchuk <mromanchuk at empirix dot com>
+
+ * pthread.h (timespec): Fix tv_sec type.
+
+2007-01-07 Sinan Kaya <sinan.kaya at siemens dot com>
+
+ * need_errno.h: Fix declaration of _errno - the local version of
+ _errno() is used, e.g. by WinCE.
+
+2007-01-06 Ross Johnson <ross.johnson at homemail dot com dot au>
+
+ * ptw32_semwait.c: Add check for invalid sem_t after acquiring the
+ sem_t state guard mutex and before affecting changes to sema state.
+
+2007-01-06 Marcel Ruff <mr at marcelruff dot info>
+
+ * error.c: Fix reference to pthread handle exitStatus member for
+ builds that use NEED_ERRNO (i.e. WINCE).
+ * context.h: Add support for ARM processor (WinCE).
+ * mutex.c (process.h): Exclude for WINCE.
+ * create.c: Likewise.
+ * exit.c: Likewise.
+ * implement.h: Likewise.
+ * pthread_detach.c (signal.h): Exclude for WINCE.
+ * pthread_join.c: Likewise.
+ * pthread_kill.c: Likewise.
+ * pthread_rwlock_init.c (errno.h): Remove - included by pthread.h.
+ * pthread_rwlock_destroy.c: Likewise.
+ * pthread_rwlock_rdlock.c: Likewise.
+ * pthread_rwlock_timedrdlock.c: Likewise.
+ * pthread_rwlock_timedwrlock.c: Likewise.
+ * pthread_rwlock_tryrdlock.c: Likewise.
+ * pthread_rwlock_trywrlock.c: likewise.
+ * pthread_rwlock_unlock.c: Likewise.
+ * pthread_rwlock_wrlock.c: Likewise.
+ * pthread_rwlockattr_destroy.c: Likewise.
+ * pthread_rwlockattr_getpshared.c: Likewise.
+ * pthread_rwlockattr_init.c: Likewise.
+ * pthread_rwlockattr_setpshared.c: Likewise.
+
+2007-01-06 Romano Paolo Tenca <rotenca at telvia dot it>
+
+ * pthread_cond_destroy.c: Replace sem_wait() with non-cancelable
+ ptw32_semwait() since pthread_cond_destroy() is not a cancelation
+ point.
+ * implement.h (ptw32_spinlock_check_need_init): Add prototype.
+ * ptw32_MCS_lock.c: Reverse order of includes.
+
+2007-01-06 Eric Berge <eric dot berge at quantum dot com>
+
+ * pthread_cond_destroy.c: Add LeaveCriticalSection before returning
+ after errors.
+
+2007-01-04 Ross Johnson <ross.johnson at homemail dot com dot au>
+
+ * ptw32_InterlockedCompareExchange.c: Conditionally skip for
+ Win64 as not required.
+ * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np):
+ Test for InterlockedCompareExchange is not required for Win64.
+ * context.h: New file. Included by pthread_cancel.h and any tests
+ that need it (e.g. context1.c).
+ * pthread_cancel.c: Architecture-dependent context macros moved
+ to context.h.
+
+2007-01-04 Kip Streithorst <KSTREITH at ball dot com>
+
+ * implement.h (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Add Win64
+ support.
+
+2006-12-20 Ross Johnson <ross.johnson at homemail.com.au>
+
+ * sem_destroy.c: Fix the race involving invalidation of the sema;
+ fix incorrect return of EBUSY resulting from the mutex trylock
+ on the private mutex guard.
+ * sem_wait.c: Add check for invalid sem_t after acquiring the
+ sem_t state guard mutex and before affecting changes to sema state.
+ * sem_trywait.c: Likewise.
+ * sem_timedwait.c: Likewise.
+ * sem_getvalue.c: Likewise.
+ * sem_post.c: Similar.
+ * sem_post_multiple.c: Likewise.
+ * sem_init.c: Set max Win32 semaphore count to SEM_VALUE_MAX (was
+ _POSIX_SEM_VALUE_MAX, which is a lower value - the minimum).
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np):
+ Load COREDLL.DLL under WINCE to check existence of
+ InterlockedCompareExchange() routine. This used to be done to test
+ for TryEnterCriticalSection() but was removed when this was no
+ longer needed.
+
+2006-01-25 Prashant Thakre <prashant.thakre at gmail.com>
+
+ * pthread_cancel.c: Added _M_IA64 register context support.
+
+2005-05-13 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread_kill.c (pthread_kill): Remove check for Win32 thread
+ priority (to confirm HANDLE validity). Useless since thread HANDLEs
+ a not recycle-unique.
+
+2005-05-30 Vladimir Kliatchko <vladimir at kliatchko.com>
+
+ * pthread_once.c: Re-implement using an MCS queue-based lock. The form
+ of pthread_once is as proposed by Alexander Terekhov (see entry of
+ 2005-03-13). The MCS lock implementation does not require a unique
+ 'name' to identify the lock between threads. Attempts to get the Event
+ or Semaphore based versions of pthread_once to a satisfactory level
+ of robustness have thus far failed. The last problem (avoiding races
+ involving non recycle-unique Win32 HANDLEs) was giving everyone
+ grey hair trying to solve it.
+
+ * ptw32_MCS_lock.c: New MCS queue-based lock implementation. These
+ locks are efficient: they have very low overhead in the uncontended case;
+ are efficient in contention and minimise cache-coherence updates in
+ managing the user level FIFO queue; do not require an ABI change in the
+ library.
+
+2005-05-27 Alexander Gottwald <alexander.gottwald at s1999.tu-chemnitz.de>
+
+ * pthread.h: Some things, like HANDLE, were only defined if
+ PTW32_LEVEL was >= 3. They should always be defined.
+
+2005-05-25 Vladimir Kliatchko <vladimir at kliatchko.com>
+
+ * pthread_once.c: Eliminate all priority operations and other
+ complexity by replacing the event with a semaphore. The advantage
+ of the change is the ability to release just one waiter if the
+ init_routine thread is cancelled yet still release all waiters when
+ done. Simplify once_control state checks to improve efficiency
+ further.
+
+2005-05-24 Mikael Magnusson <mikaelmagnusson at glocalnet.net>
+
+ * GNUmakefile: Patched to allow cross-compile with mingw32 on Linux.
+ It uses macros instead of referencing dlltool, gcc and g++ directly;
+ added a call to ranlib. For example the GC static library can be
+ built with:
+ make CC=i586-mingw32msvc-gcc RC=i586-mingw32msvc-windres \
+ RANLIB=i586-mingw32msvc-ranlib clean GC-static
+
+2005-05-13 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
+ Move on-exit-only stuff from ptw32_threadDestroy() to here.
+ * ptw32_threadDestroy.c: It's purpose is now only to reclaim thread
+ resources for detached threads, or via pthread_join() or
+ pthread_detach() on joinable threads.
+ * ptw32_threadStart.c: Calling user destruct routines has moved to
+ pthread_win32_thread_detach_np(); call pthread_win32_thread_detach_np()
+ directly if statically linking, otherwise do so via dllMain; store
+ thread return value in thread struct for all cases, including
+ cancellation and exception exits; thread abnormal exits go via
+ pthread_win32_thread_detach_np.
+ * pthread_join.c (pthread_join): Don't try to get return code from
+ Win32 thread - always get it from he thread struct.
+ * pthread_detach.c (pthread_detach): reduce extent of the thread
+ existence check since we now don't care if the Win32 thread HANDLE has
+ been closed; reclaim thread resources if the thread has exited already.
+ * ptw32_throw.c (ptw32_throw): For Win32 threads that are not implicit,
+ only Call thread cleanup if statically linking, otherwise leave it to
+ dllMain.
+ * sem_post.c (_POSIX_SEM_VALUE_MAX): Change to SEM_VALUE_MAX.
+ * sem_post_multiple.c: Likewise.
+ * sem_init.c: Likewise.
+
+2005-05-10 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread_join.c (pthread_join): Add missing check for thread ID
+ reference count in thread existence test; reduce extent of the
+ existence test since we don't care if the Win32 thread HANDLE has
+ been closed.
+
+2005-05-09 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * ptw32_callUserDestroyRoutines.c: Run destructor process (i.e.
+ loop over all keys calling destructors) up to
+ PTHREAD_DESTRUCTOR_ITERATIONS times if TSD value isn't NULL yet;
+ modify assoc management.
+ * pthread_key_delete.c: Modify assoc management.
+ * ptw32_tkAssocDestroy.c: Fix error in assoc removal from chains.
+ * pthread.h
+ (_POSIX_THREAD_DESTRUCTOR_ITERATIONS): Define to value specified by
+ POSIX.
+ (_POSIX_THREAD_KEYS_MAX): Define to value specified by POSIX.
+ (PTHREAD_KEYS_MAX): Redefine [upward] to minimum required by POSIX.
+ (SEM_NSEMS_MAX): Define to implementation value.
+ (SEM_VALUE_MAX): Define to implementation value.
+ (_POSIX_SEM_NSEMS_MAX): Redefine to value specified by POSIX.
+ (_POSIX_SEM_VALUE_MAX): Redefine to value specified by POSIX.
+
+2005-05-06 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * signal.c (sigwait): Add a cancellation point to this otherwise
+ no-op.
+ * sem_init.c (sem_init): Check for and return ERANGE error.
+ * sem_post.c (sem_post): Likewise.
+ * sem_post_multiple.c (sem_post_multiple): Likewise.
+ * manual (directory): Added; see ChangeLog inside.
+
+2005-05-02 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * implement.h (struct pthread_key_t_): Change threadsLock to keyLock
+ so as not to be confused with the per thread lock 'threadlock';
+ change all references to it.
+ * implement.h (struct ThreadKeyAssoc): Remove lock; add prevKey
+ and prevThread pointers; re-implemented all routines that use this
+ struct. The effect of this is to save one handle per association,
+ which could potentially equal the number of keys multiplied by the
+ number of threads, accumulating over time - and to free the
+ association memory as soon as it is no longer referenced by either
+ the key or the thread. Previously, the handle and memory were
+ released only after BOTH key and thread no longer referenced the
+ association. That is, often no association resources were released
+ until the process itself exited. In addition, at least one race
+ condition has been removed - where two threads could attempt to
+ release the association resources simultaneously - one via
+ ptw32_callUserDestroyRoutines and the other via
+ pthread_key_delete.
+ - thanks to Richard Hughes at Aculab for discovering the problem.
+ * pthread_key_create.c: See above.
+ * pthread_key_delete.c: See above.
+ * pthread_setspecific.c: See above.
+ * ptw32_callUserDestroyRoutines.c: See above.
+ * ptw32_tkAssocCreate.c: See above.
+ * ptw32_tkAssocDestroy.c: See above.
+
+2005-04-27 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * sem_wait.c (ptw32_sem_wait_cleanup): after cancellation re-attempt
+ to acquire the semaphore to avoid a race with a late sem_post.
+ * sem_timedwait.c: Modify comments.
+
+2005-04-25 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * ptw32_relmillisecs.c: New module; converts future abstime to
+ milliseconds relative to 'now'.
+ * pthread_mutex_timedlock.c: Use new ptw32_relmillisecs routine in
+ place of internal code; remove the NEED_SEM code - this routine is now
+ implemented for builds that define NEED_SEM (WinCE etc)
+ * sem_timedwait.c: Likewise; after timeout or cancellation,
+ re-attempt to acquire the semaphore in case one has been posted since
+ the timeout/cancel occurred. Thanks to Stefan Mueller.
+ * Makefile: Add ptw32_relmillisecs.c module; remove
+ ptw32_{in,de}crease_semaphore.c modules.
+ * GNUmakefile: Likewise.
+ * Bmakefile: Likewise.
+
+ * sem_init.c: Re-write the NEED_SEM code to be consistent with the
+ non-NEED_SEM code, but retaining use of an event in place of the w32 sema
+ for w32 systems that don't include semaphores (WinCE);
+ the NEED_SEM versions of semaphores has been broken for a long time but is
+ now fixed and supports all of the same routines as the non-NEED_SEM case.
+ * sem_destroy.c: Likewise.
+ * sem_wait.c: Likewise.
+ * sem_post.c: Likewise.
+ * sem_post_multple.c: Likewise.
+ * implement.h: Likewise.
+ * sem_timedwait.c: Likewise; this routine is now
+ implemented for builds that define NEED_SEM (WinCE etc).
+ * sem_trywait.c: Likewise.
+ * sem_getvalue.c: Likewise.
+
+ * pthread_once.c: Yet more changes, reverting closer to Gottlob Frege's
+ first design, but retaining cancellation, priority boosting, and adding
+ preservation of W32 error codes to make pthread_once transparent to
+ GetLastError.
+
+2005-04-11 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Added priority boosting to
+ solve starvation problem after once_routine cancellation.
+ See notes in file.
+
+2005-04-06 Kevin Lussier <Kevin at codegreennetworks.com>
+
+ * Makefile: Added debug targets for all versions of the library.
+
+2005-04-01 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * GNUmakefile: Add target to build libpthreadGC1.a as a static link
+ library.
+ * Makefile: Likewise for pthreadGC1.lib.
+
+2005-04-01 Kevin Lussier <Kevin at codegreennetworks.com>
+
+ * sem_timedwait.c (sem_timedwait): Increase size of temp variables to
+ avoid int overflows for large timeout values.
+ * implement.h (int64_t): Include or define.
+
+2005-03-31 Dimitar Panayotov <develop at mail.bg>^M
+
+ * pthread.h: Fix conditional defines for static linking.
+ * sched.h: Liekwise.
+ * semaphore.h: Likewise.
+ * dll.c (PTW32_STATIC_LIB): Module is conditionally included
+ in the build.
+
+2005-03-16 Ross Johnson <ross at callisto.canberra.edu.au>^M
+
+ * pthread_setcancelstate.c: Undo the last change.
+
+2005-03-16 Ross Johnson <ross at callisto.canberra.edu.au>^M
+
+ * pthread_setcancelstate.c: Don't check for an async cancel event
+ if the library is using alertable async cancel..
+
+2005-03-14 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Downgrade interlocked operations to simple
+ memory operations where these are protected by the critical section; edit
+ comments.
+
+2005-03-13 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Completely redesigned; a change was
+ required to the ABI (pthread_once_t_), and resulting in a version
+ compatibility index increment.
+
+ NOTES:
+ The design (based on pseudo code contributed by Gottlob Frege) avoids
+ creating a kernel object if there is no contention. See URL for details:-
+ http://sources.redhat.com/ml/pthreads-win32/2005/msg00029.html
+ This uses late initialisation similar to the technique already used for
+ pthreads-win32 mutexes and semaphores (from Alexander Terekhov).
+
+ The subsequent cancelation cleanup additions (by rpj) could not be implemented
+ without sacrificing some of the efficiency in Gottlob's design. In particular,
+ although each once_control uses it's own event to block on, a global CS is
+ required to manage it - since the event must be either re-usable or
+ re-creatable under cancelation. This is not needed in the non-cancelable
+ design because it is able to mark the event as closed (forever).
+
+ When uncontested, a CS operation is equivalent to an Interlocked operation
+ in speed. So, in the final design with cancelability, an uncontested
+ once_control operation involves a minimum of five interlocked operations
+ (including the LeaveCS operation).
+
+ ALTERNATIVES:
+ An alternative design from Alexander Terekhov proposed using a named mutex,
+ as sketched below:-
+
+ if (!once_control) { // May be in TLS
+ named_mutex::guard guard(&once_control2);
+ if (!once_control2) {
+ <init>
+ once_control2 = true;
+ }
+ once_control = true;
+ }
+
+ A more detailed description of this can be found here:-
+ http://groups.yahoo.com/group/boost/message/15442
+
+ [Although the definition of a suitable PTHREAD_ONCE_INIT precludes use of the
+ TLS located flag, this is not critical.]
+
+ There are three primary concerns though:-
+ 1) The [named] mutex is 'created' even in the uncontended case.
+ 2) A system wide unique name must be generated.
+ 3) Win32 mutexes are VERY slow even in the uncontended case. An uncontested
+ Win32 mutex lock operation can be 50 (or more) times slower than an
+ uncontested EnterCS operation.
+
+ Ultimately, the named mutex trick is making use of the global locks maintained
+ by the kernel.
+
+ * pthread.h (pthread_once_t_): One flag and an event HANDLE added.
+ (PTHREAD_ONCE_INIT): Additional values included.
+
+2005-03-08 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Redesigned to elliminate potential
+ starvation problem.
+ - reported by Gottlob Frege <gottlobfrege at gmail.com>
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were
+ not closing their Win32 thread duplicate handle.
+ - reported by Dmitrii Semii <bogolt at gmail.com>
+
+2005-01-25 Ralf Kubis <RKubis at mc.com>
+
+ * Attempted acquisition of recursive mutex was causing waiting
+ threads to not be woken when the mutex is released.
+
+ * GNUmakefile (GCE): Generate correct version resource comments.
+
+2005-01-01 Konstantin Voronkov <beowinkle at yahoo.com>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): The new atomic exchange
+ mutex algorithm is known to allow a thread to steal the lock off
+ FIFO waiting threads. The next waiting FIFO thread gets a spurious
+ wake-up and must attempt to re-acquire the lock. The woken thread
+ was setting itself as the mutex's owner before the re-acquisition.
+
+2004-11-22 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Undo change
+ from 2004-11-02.
+ * Makefile (DLL_VER): Added for DLL naming suffix - see README.
+ * GNUmakefile (DLL_VER): Likewise.
+ * Wmakefile (DLL_VER): Likewise.
+ * Bmakefile (DLL_VER): Likewise.
+ * pthread.dsw (version.rc): Added to MSVS workspace.
+
+2004-11-20 Boudewijn Dekker <b.dekker at ellipsis.nl>
+
+ * pthread_getspecific.c (pthread_getspecific): Check for
+ invalid (NULL) key argument.
+
+2004-11-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * config.h (PTW32_THREAD_ID_REUSE_INCREMENT): Added to allow
+ building the library for either unique thread IDs like Solaris
+ or non-unique thread IDs like Linux; allows application developers
+ to override the library's default insensitivity to some apps
+ that may not be strictly POSIX compliant.
+ * version.rc: New resource module to encode version information
+ within the DLL.
+ * pthread.h: Added PTW32_VERSION* defines and grouped sections
+ required by resource compiler together; bulk of file is skipped
+ if RC_INVOKED. Defined some error numbers and other names for
+ Borland compiler.
+
+2004-11-02 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Lock CV mutex at
+ start of cleanup handler rather than at the end.
+ * implement.h (PTW32_THREAD_REUSE_EMPTY): Renamed from *_BOTTOM.
+ (ptw32_threadReuseBottom): New global variable.
+ * global.c (ptw32_threadReuseBottom): Declare new variable.
+ * ptw32_reuse.c (ptw32_reuse): Change reuse LIFO stack to LILO queue
+ to more evenly distribute use of reusable thread IDs; use renamed
+ PTW32_THREAD_REUSE_EMPTY.
+ * ptw32_processTerminate.c (ptw2_processTerminate): Use renamed
+ PTW32_THREAD_REUSE_EMPTY.
+
+2004-10-31 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (PThreadState): Add new state value
+ 'PThreadStateCancelPending'.
+ * pthread_testcancel.c (pthread_testcancel): Use new thread
+ 'PThreadStateCancelPending' state as short cut to avoid entering
+ kernel space via WaitForSingleObject() call. This was obviated
+ by user space sema acquisition in sem_wait() and sem_timedwait(),
+ which are also cancelation points. A call to pthread_testcancel()
+ was required, which introduced a kernel call, effectively nullifying
+ any gains made by the user space sem acquisition checks.
+ * pthread_cancel.c (pthread_cancel): Set new thread
+ 'PThreadStateCancelPending' state.
+
+2004-10-29 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (pthread_t): Renamed to ptw32_thread_t; struct contains
+ all thread state.
+ * pthread.h (ptw32_handle_t): New general purpose struct to serve
+ as a handle for various reusable object IDs - currently only used
+ by pthread_t; contains a pointer to ptw32_thread_t (thread state)
+ and a general purpose uint for use as a reuse counter or flags etc.
+ (pthread_t): typedef'ed to ptw32_handle_t; the uint is the reuse
+ counter that allows the library to maintain unique POSIX thread IDs.
+ When the pthread struct reuse stack was introduced, threads would
+ often acquire an identical ID to a previously destroyed thread. The
+ same was true for the pre-reuse stack library, by virtue of pthread_t
+ being the address of the thread struct. The new pthread_t retains
+ the reuse stack but provides virtually unique thread IDs.
+ * sem_wait.c (ptw32_sem_wait_cleanup): New routine used for
+ cancelation cleanup.
+ * sem_timedwait.c (ptw32_sem_timedwait_cleanup): Likewise.
+
+2004-10-22 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sem_init.c (sem_init): Introduce a 'lock' element in order to
+ replace the interlocked operations with conventional serialisation.
+ This is needed in order to be able to atomically modify the sema
+ value and perform Win32 sema release operations. Win32 semaphores are
+ used instead of events in order to support efficient multiple posting.
+ If the whole modify/release isn't atomic, a race between
+ sem_timedwait() and sem_post() could result in a release when there is
+ no waiting semaphore, which would cause too many threads to proceed.
+ * sem_wait.c (sem_wait): Use new 'lock'element.
+ * sem_timedwait.c (sem_timedwait): Likewise.
+ * sem_trywait.c (sem_trywait): Likewise.
+ * sem_post.c (sem_post): Likewise.
+ * sem_post_multiple.c (sem_post_multiple): Likewise.
+ * sem_getvalue.c (sem_getvalue): Likewise.
+ * ptw32_semwait.c (ptw32_semwait): Likewise.
+ * sem_destroy.c (sem_destroy): Likewise; also tightened the conditions
+ for semaphore destruction; in particular, a semaphore will not be
+ destroyed if it has waiters.
+ * sem_timedwait.c (sem_timedwait): Added cancel cleanup handler to
+ restore sema value when cancelled.
+ * sem_wait.c (sem_wait): Likewise.
+
+2004-10-21 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Must use PulseEvent()
+ rather than SetEvent() to reset the event if there are no waiters.
+
+2004-10-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sem_init.c (sem_init): New semaphore model based on the same idea
+ as mutexes, i.e. user space interlocked check to avoid
+ unnecessarily entering kernel space. Wraps the Win32 semaphore and
+ keeps it's own counter. Although the motivation to do this has existed
+ for a long time, credit goes to Alexander Terekhov for providing
+ the logic. I have deviated slightly from AT's logic to add the waiters
+ count, which has made the code more complicated by adding cancelation
+ cleanup. This also appears to have broken the VCE (C++ EH) version of
+ the library (the same problem as previously reported - see BUGS #2),
+ only apparently not fixable using the usual workaround, nor by turning
+ all optimisation off. The GCE version works fine, so it is presumed to
+ be a bug in MSVC++ 6.0. The cancelation exception is thrown and caught
+ correctly, but the cleanup class destructor is never called. The failing
+ test is tests\semaphore4.c.
+ * sem_wait.c (sem_wait): Implemented user space check model.
+ * sem_post.c (sem_post): Likewise.
+ * sem_trywait.c (sem_trywait): Likewise.
+ * sem_timedwait.c (sem_timedwait): Likewise.
+ * sem_post_multiple.c (sem_post_multiple): Likewise.
+ * sem_getvalue.c (sem_getvalue): Likewise.
+ * ptw32_semwait.c (ptw32_semwait): Likewise.
+ * implement.h (sem_t_): Add counter element.
+
+2004-10-15 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (pthread_mutex_t_): Use an event in place of
+ the POSIX semaphore.
+ * pthread_mutex_init.c: Create the event; remove semaphore init.
+ * pthread_mutex_destroy.c: Delete the event.
+ * pthread_mutex_lock.c: Replace the semaphore wait with the event wait.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_unlock.c: Set the event.
+
+2004-10-14 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): New algorithm using
+ Terekhov's xchg based variation of Drepper's cmpxchg model.
+ Theoretically, xchg uses fewer clock cycles than cmpxchg (using IA-32
+ as a reference), however, in my opinion bus locking dominates the
+ equation on smp systems, so the model with the least number of bus
+ lock operations in the execution path should win, which is Terekhov's
+ variant. On IA-32 uni-processor systems, it's faster to use the
+ CMPXCHG instruction without locking the bus than to use the XCHG
+ instruction, which always locks the bus. This makes the two variants
+ equal for the non-contended lock (fast lane) execution path on up
+ IA-32. Testing shows that the xchg variant is faster on up IA-32 as
+ well if the test forces higher lock contention frequency, even though
+ kernel calls should be dominating the times (on up IA-32, both
+ variants used CMPXCHG instructions and neither locked the bus).
+ * pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
+ * ptw32_InterlockedCompareExchange.c (ptw32_InterlockExchange): New
+ function.
+ (PTW32_INTERLOCKED_EXCHANGE): Sets up macro to use inlined
+ ptw32_InterlockedExchange.
+ * implement.h (PTW32_INTERLOCKED_EXCHANGE): Set default to
+ InterlockedExchange().
+ * Makefile: Building using /Ob2 so that asm sections within inline
+ functions are inlined.
+
+2004-10-08 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): Critical Section
+ element is no longer required.
+ * pthread_mutex_init.c (pthread_mutex_init): Likewise.
+ * pthread_mutex_lock.c (pthread_mutex_lock): New algorithm following
+ Drepper's paper at http://people.redhat.com/drepper/futex.pdf, but
+ using the existing semaphore in place of the futex described in the
+ paper. Idea suggested by Alexander Terekhov - see:
+ http://sources.redhat.com/ml/pthreads-win32/2003/msg00108.html
+ * pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
+ * pthread_barrier_wait.c (pthread_barrier_wait): Use inlined version
+ of InterlockedCompareExchange() if possible - determined at
+ build-time.
+ * pthread_spin_destroy.c pthread_spin_destroy(): Likewise.
+ * pthread_spin_lock.c pthread_spin_lock():Likewise.
+ * pthread_spin_trylock.c (pthread_spin_trylock):Likewise.
+ * pthread_spin_unlock.c (pthread_spin_unlock):Likewise.
+ * ptw32_InterlockedCompareExchange.c: Sets up macro for inlined use.
+ * implement.h (pthread_mutex_t_): Remove Critical Section element.
+ (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Set to default non-inlined
+ version of InterlockedCompareExchange().
+ * private.c: Include ptw32_InterlockedCompareExchange.c first for
+ inlining.
+ * GNUmakefile: Add commandline option to use inlined
+ InterlockedCompareExchange().
+ * Makefile: Likewise.
+
+2004-09-27 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): Separate
+ PTHREAD_MUTEX_NORMAL logic since we do not need to keep or check some
+ state required by other mutex types; do not check mutex pointer arg
+ for validity - leave this to the system since we are only checking
+ for NULL pointers. This should improve speed of NORMAL mutexes and
+ marginally improve speed of other type.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid
+ entering the critical section for the no-waiters case, with approx.
+ 30% reduction in lock/unlock overhead for this case.
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also
+ no longer keeps mutex if post-timeout second attempt succeeds - this
+ will assist applications that wish to impose strict lock deadlines,
+ rather than simply to escape from frozen locks.
+
+2004-09-09 Tristan Savatier <tristan at mpegtv.com>
+ * pthread.h (struct pthread_once_t_): Qualify the 'done' element
+ as 'volatile'.
+ * pthread_once.c: Concerned about possible race condition,
+ specifically on MPU systems re concurrent access to multibyte types.
+ [Maintainer's note: the race condition is harmless on SPU systems
+ and only a problem on MPU systems if concurrent access results in an
+ exception (presumably generated by a hardware interrupt). There are
+ other instances of similar harmless race conditions that have not
+ been identified as issues.]
+
+2004-09-09 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread.h: Declare additional types as volatile.
+
+2004-08-27 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code
+ by substituting the internal non-cancelable version of sem_wait
+ (ptw32_semwait).
+
+2004-08-25 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_join.c (pthread_join): Rewrite and re-order the conditional
+ tests in an attempt to improve efficiency and remove a race
+ condition.
+
+2004-08-23 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * create.c (pthread_create): Don't create a thread if the thread
+ id pointer location (first arg) is inaccessible. A memory
+ protection fault will result if the thread id arg isn't an accessible
+ location. This is consistent with GNU/Linux but different to
+ Solaris or MKS (and possibly others), which accept NULL as meaning
+ 'don't return the created thread's ID'. Applications that run
+ using pthreads-win32 will run on all other POSIX threads
+ implementations, at least w.r.t. this feature.
+
+ It was decided not to copy the Solaris et al behaviour because,
+ although it would have simplified some application porting (but only
+ from Solaris to Windows), the feature is not technically necessary,
+ and the alternative segfault behaviour helps avoid buggy application
+ code.
+
+2004-07-01 Anuj Goyal <anuj.goyal at gmail.com>
+
+ * builddmc.bat: New; Windows bat file to build the library.
+ * config.h (__DMC__): Support for Digital Mars compiler.
+ * create.c (__DMC__): Likewise.
+ * pthread_exit.c (__DMC__): Likewise.
+ * pthread_join.c (__DMC__): Likewise.
+ * ptw32_threadDestroy.c (__DMC__): Likewise.
+ * ptw32_threadStart.c (__DMC__): Likewise.
+ * ptw32_throw.c (__DMC__): Likewise.
+
+2004-06-29 Anuj Goyal <anuj.goyal at gmail.com>
+
+ * pthread.h (__DMC__): Initial support for Digital Mars compiler.
+
+2004-06-29 Will Bryant <will.bryant at ecosm.com>
+
+ * README.Borland: New; description of Borland changes.
+ * Bmakefile: New makefile for the Borland make utility.
+ * ptw32_InterlockedCompareExchange.c:
+ Add Borland compatible asm code.
+
+2004-06-26 Jason Bard <BardJA at Npt.NUWC.Navy.Mil>
+
+ * pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it
+ to avoid timespec struct redefined errors elsewhere in an
+ application.
+
+2004-06-21 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Mutex
+ initialiser added for compatibility with Linux threads and
+ others; currently not included in SUSV3.
+ * pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER): Likewise.
+ * pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise.
+ * pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
+
+ * ptw32_mutex_check_need_init.c (ptw32_mutex_check_need_init):
+ Add new initialisers.
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): Check for new
+ initialisers.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise.
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): Likewise.
+
+2004-05-20 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * README.NONPORTABLE: Document pthread_win32_test_features_np().
+ * FAQ: Update various answers.
+
+2004-05-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * Makefile: Don't define _WIN32_WINNT on compiler command line.
+ * GNUmakefile: Likewise.
+
+2004-05-16 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cancel.c (pthread_cancel): Adapted to use auto-detected
+ QueueUserAPCEx features at run-time.
+ (ptw32_RegisterCancelation): Drop in replacement for QueueUserAPCEx()
+ if it can't be used. Provides older style non-preemptive async
+ cancelation.
+ * pthread_win32_attach_detach_np.c (pthread_win32_attach_np):
+ Auto-detect quserex.dll and the availability of alertdrv.sys;
+ initialise and close on process attach/detach.
+ * global.c (ptw32_register_cancelation): Pointer to either
+ QueueUserAPCEx() or ptw32_RegisterCancelation() depending on
+ availability. QueueUserAPCEx makes pre-emptive async cancelation
+ possible.
+ * implement.h: Add definitions and prototypes related to QueueUserAPC.
+
+2004-05-16 Panagiotis E. Hadjidoukas <peh at hpclab.ceid.upatras.gr>
+
+ * QueueUserAPCEx (separate contributed package): Provides preemptive
+ APC feature.
+ * pthread_cancel.c (pthread_cancel): Initial integration of
+ QueueUserAPCEx into pthreads-win32 to provide true pre-emptive
+ async cancelation of threads, including blocked threads.
+
+2004-05-06 Makoto Kato <raven at oldskool.jp>
+
+ * pthread.h (DWORD_PTR): Define typedef for older MSVC.
+ * pthread_cancel.c (AMD64): Add architecture specific Context register.
+ * ptw32_getprocessors.c: Use correct types (DWORD_PTR) for mask
+ variables.
+
+2004-04-06 P. van Bruggen <pietvb at newbridges.nl>
+
+ * ptw32_threadDestroy.c: Destroy threadLock mutex to
+ close a memory leak.
+
+2004-02-13 Gustav Hallberg <gustav at virtutech.com>
+
+ * pthread_equal.c: Remove redundant equality logic.
+
+2003-12-10 Philippe Di Cristo <philipped at voicebox.com>
+
+ * sem_timedwait.c (sem_timedwait): Fix timeout calculations.
+
+2003-10-20 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_mutex_timedlock.c (ptw32_semwait): Move to individual module.
+ * ptw32_semwait.c: New module.
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Replace cancelable
+ sem_wait() call with non-cancelable ptw32_semwait() call.
+ * pthread.c (private.c): Re-order for inlining. GNU C warned that
+ function ptw32_semwait() was defined 'inline' after it was called.
+ * pthread_cond_signal.c (ptw32_cond_unblock): Likewise.
+ * pthread_delay_np.c: Disable Watcom warning with comment.
+ * *.c (process.h): Remove include from .c files. This is conditionally
+ included by the common project include files.
+
+2003-10-20 James Ewing <james.ewing at sveasoft.com>
+
+ * ptw32_getprocessors.c: Some Win32 environments don't have
+ GetProcessAffinityMask(), so always return CPU count = 1 for them.
+ * config.h (NEED_PROCESSOR_AFFINITY_MASK): Define for WinCE.
+
+2003-10-15 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * Re-indented all .c files using default GNU style to remove assorted
+ editor ugliness (used GNU indent utility in default style).
+
+2003-10-15 Alex Blanco <Alex.Blanco at motorola.com>
+
+ * sem_init.c (sem_init): Would call CreateSemaphore even if the sema
+ struct calloc failed; was not freeing calloced memory if either
+ CreateSemaphore or CreateEvent failed.
+
+2003-10-14 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread.h: Add Watcom compiler compatibility. Esssentially just add
+ the cdecl attribute to all exposed function prototypes so that Watcom
+ generates function call code compatible with non-Watcom built libraries.
+ By default, Watcom uses registers to pass function args if possible rather
+ than pushing to stack.
+ * semaphore.h: Likewise.
+ * sched.h: Likewise.
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Define with cdecl attribute
+ for Watcom compatibility. This routine is called via pthread_cleanup_push so
+ it had to match function arg definition.
+ * Wmakefile: New makefile for Watcom builds.
+
+2003-09-14 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_setschedparam.c (pthread_setschedparam): Attempt to map
+ all priority levels between max and min (as returned by
+ sched_get_priority_min/max) to reasonable Win32 priority levels - i.e.
+ levels between THREAD_PRIORITY_LOWEST/IDLE to THREAD_PRIORITY_LOWEST and
+ between THREAD_PRIORITY_HIGHEST/TIME_CRITICAL to THREAD_PRIORITY_HIGHEST
+ while others remain unchanged; record specified thread priority level
+ for return by pthread_getschedparam.
+
+ Note that, previously, specified levels not matching Win32 priority levels
+ would silently leave the current thread priority unaltered.
+
+ * pthread_getschedparam.c (pthread_getschedparam): Return the priority
+ level specified by the latest pthread_setschedparam or pthread_create rather
+ than the actual running thread priority as returned by GetThreadPriority - as
+ required by POSIX. I.e. temporary or adjusted actual priority levels are not
+ returned by this routine.
+
+ * pthread_create.c (pthread_create): For priority levels specified via
+ pthread attributes, attempt to map all priority levels between max and
+ min (as returned by sched_get_priority_min/max) to reasonable Win32
+ priority levels; record priority level given via attributes, or
+ inherited from parent thread, for later return by pthread_getschedparam.
+
+ * ptw32_new.c (ptw32_new): Initialise pthread_t_ sched_priority element.
+
+ * pthread_self.c (pthread_self): Set newly created implicit POSIX thread
+ sched_priority to Win32 thread's current actual priority. Temporarily
+ altered priorities can't be avoided in this case.
+
+ * implement.h (struct pthread_t_): Add new sched_priority element.
+
+2003-09-12 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sched_get_priority_min.c (sched_get_priority_min): On error should return -1
+ with errno set.
+ * sched_get_priority_max.c (sched_get_priority_max): Likewise.
+
+2003-09-03 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation
+ of implicit POSIX threads as well.
+
+2003-09-02 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
+ Add comment.
+
+ * pthread_exit.c (pthread_exit): Fix to recycle the POSIX thread handle in
+ addition to calling user TSD destructors. Move the implicit POSIX thread exit
+ handling to ptw32_throw to centralise the logic.
+
+ * ptw32_throw.c (ptw32_throw): Implicit POSIX threads have no point
+ to jump or throw to, so cleanup and exit the thread here in this case. For
+ processes using the C runtime, the exit code will be set to the POSIX
+ reason for the throw (i.e. PTHREAD_CANCEL or the value given to pthread_exit).
+ Note that pthread_exit() already had similar logic, which has been moved to
+ here.
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Don't close the Win32 handle
+ of implicit POSIX threads - expect this to be done by Win32?
+
+2003-09-01 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_self.c (pthread_self): The newly aquired pthread_t must be
+ assigned to the reuse stack, not freed, if the routine fails somehow.
+
+2003-08-13 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * pthread_getschedparam.c (pthread_getschedparam): An invalid thread ID
+ parameter was returning an incorrect error value; now uses a more exhaustive
+ check for validity.
+
+ * pthread_setschedparam.c (pthread_setschedparam): Likewise.
+
+ * pthread_join.c (pthread_join): Now uses a more exhaustive
+ check for validity.
+
+ * pthread_detach.c (pthread_detach): Likewise.
+
+ * pthread_cancel.c (pthread_cancel): Likewise.
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): pthread_t structs are
+ never freed - push them onto a stack for reuse.
+
+ * ptw32_new.c (ptw32_new): Check for reusable pthread_t before dynamically
+ allocating new memory for the struct.
+
+ * pthread_kill.c (pthread_kill): New file; new routine; takes only a zero
+ signal arg so that applications can check the thread arg for validity; checks
+ that the underlying Win32 thread HANDLE is valid.
+
+ * pthread.h (pthread_kill): Add prototype.
+
+ * ptw32_reuse.c (ptw32_threadReusePop): New file; new routine; pop a
+ pthread_t off the reuse stack. pthread_t_ structs that have been destroyed, i.e.
+ have exited detached or have been joined, are cleaned up and put onto a reuse
+ stack. Consequently, thread IDs are no longer freed once calloced. The library
+ will attempt to get a struct off this stack before asking the system to alloc
+ new memory when creating threads. The stack is guarded by a global mutex.
+ (ptw32_threadReusePush): New routine; push a pthread_t onto the reuse stack.
+
+ * implement.h (ptw32_threadReusePush): Add new prototype.
+ (ptw32_threadReusePop): Likewise.
+ (pthread_t): Add new element.
+
+ * ptw32_processTerminate.c (ptw32_processTerminate): Delete the thread
+ reuse lock; free all thread ID structs on the thread reuse stack.
+
+ * ptw32_processInitialize.c (ptw32_processInitialize): Initialise the
+ thread reuse lock.
+
+2003-07-19 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * GNUmakefile: modified to work under MsysDTK environment.
+ * pthread_spin_lock.c (pthread_spin_lock): Check for NULL arg.
+ * pthread_spin_unlock.c (pthread_spin_unlock): Likewise.
+ * pthread_spin_trylock.c (pthread_spin_trylock): Likewise;
+ fix incorrect pointer value if lock is dynamically initialised by
+ this function.
+ * sem_init.c (sem_init): Initialise sem_t value to quell compiler warning.
+ * sem_destroy.c (sem_destroy): Likewise.
+ * ptw32_threadStart.c (non-MSVC code sections): Include <exception> rather
+ than old-style <new.h>; fix all std:: namespace entities such as
+ std::terminate_handler instances and associated methods.
+ * ptw32_callUserDestroyRoutines.c (non-MSVC code sections): Likewise.
+
+2003-06-24 Piet van Bruggen <pietvb at newbridges.nl>
+
+ * pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the
+ spinlock struct.
+
+2003-06-22 Nicolas Barry <boozai at yahoo.com>
+
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): When called
+ with a recursive mutex that was locked by the current thread, the
+ function was failing with a success return code.
+
+2003-05-15 Steven Reddie <Steven.Reddie at ca.com>
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_process_detach_np):
+ NULLify ptw32_selfThreadKey after the thread is destroyed, otherwise
+ destructors calling pthreads routines might resurrect it again, creating
+ memory leaks. Call the underlying Win32 Tls routine directly rather than
+ pthread_setspecific().
+ (pthread_win32_thread_detach_np): Likewise.
+
+2003-05-14 Viv <vcotirlea at hotmail.com>
+
+ * pthread.dsp: Change /MT compile flag to /MD.
+
+2003-03-04 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Fix failure to
+ set ownership of mutex on second grab after abstime timeout.
+ - bug reported by Robert Strycek <strycek at posam.sk>
+
+2002-12-17 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread_mutex_lock.c (ptw32_semwait): New static routine to provide
+ a non-cancelable sem_wait() function. This is consistent with the
+ way that pthread_mutex_timedlock.c does it.
+ (pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait().
+
+2002-12-11 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK.
+ * pthread_mutex_destroy.c: Remove redundant ownership test (the
+ trylock call does this for us); do not destroy a recursively locked
+ mutex.
+
+2002-09-20 Michael Johnson <michaelj at maine.rr.com>
+
+ * pthread_cond_destroy.c (pthread_cond_destroy):
+ When two different threads exist, and one is attempting to
+ destroy a condition variable while the other is attempting to
+ initialize a condition variable that was created with
+ PTHREAD_COND_INITIALIZER, a deadlock can occur. Shrink
+ the ptw32_cond_list_lock critical section to fix it.
+
+2002-07-31 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * ptw32_threadStart.c (ptw32_threadStart): Thread cancelLock
+ destruction moved to ptw32_threadDestroy().
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Destroy
+ the thread's cancelLock. Moved here from ptw32_threadStart.c
+ to cleanup implicit threads as well.
+
+2002-07-30 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup):
+ Remove code designed to avoid/prevent spurious wakeup
+ problems. It is believed that the sem_timedwait() call
+ is consuming a CV signal that it shouldn't and this is
+ breaking the avoidance logic.
+
+2002-07-30 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * sem_timedwait.c (sem_timedwait): Tighten checks for
+ unreasonable abstime values - that would result in
+ unexpected timeout values.
+
+ * w32_CancelableWait.c (ptw32_cancelable_wait):
+ Tighten up return value checking and add comments.
+
+
+2002-06-08 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * sem_getvalue.c (sem_getvalue): Now returns a value for the
+ NEED_SEM version (i.e. earlier versions of WinCE).
+
+
+2002-06-04 Rob Fanner <rfanner at stonethree.com>
+
+ * sem_getvalue.c (sem_getvalue): The Johnson M. Hart
+ approach didn't work - we are forced to take an
+ intrusive approach. We try to decrement the sema
+ and then immediately release it again to get the
+ value. There is a small probability that this may
+ block other threads, but only momentarily.
+
+2002-06-03 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * sem_init.c (sem_init): Initialise Win32 semaphores
+ to _POSIX_SEM_VALUE_MAX (which this implementation
+ defines in pthread.h) so that sem_getvalue() can use
+ the trick described in the comments in sem_getvalue().
+ * pthread.h (_POSIX_SEM_VALUE_MAX): Defined.
+ (_POSIX_SEM_NSEMS_MAX): Defined - not used but may be
+ useful for source code portability.
+
+2002-06-03 Rob Fanner <rfanner at stonethree.com>
+
+ * sem_getvalue.c (sem_getvalue): Did not work on NT.
+ Use approach suggested by Johnson M. Hart in his book
+ "Win32 System Programming".
+
+2002-02-28 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * errno.c: Compiler directive was incorrectly including code.
+ * pthread.h: Conditionally added some #defines from config.h
+ needed when not building the library. e.g. NEED_ERRNO, NEED_SEM.
+ (PTW32_DLLPORT): Now only defined if _DLL defined.
+ (_errno): Compiler directive was incorrectly including prototype.
+ * sched.h: Conditionally added some #defines from config.h
+ needed when not building the library.
+ * semaphore.h: Replace an instance of NEED_SEM that should
+ have been NEED_ERRNO. This change currently has nil effect.
+
+ * GNUmakefile: Correct some recent changes.
+
+ * Makefile: Add rule to generate pre-processor output.
+
+2002-02-23 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread_rwlock_timedrdlock.c: New - untested.
+ * pthread_rwlock_timedwrlock.c: New - untested.
+
+ * Testsuite passed (except known MSVC++ problems)
+
+ * pthread_cond_destroy.c: Expand the time change
+ critical section to solve deadlock problem.
+
+ * pthread.c: Add all remaining C modules.
+ * pthread.h: Use dllexport/dllimport attributes on functions
+ to avoid using pthread.def.
+ * sched.h: Likewise.
+ * semaphore.h: Likewise.
+ * GNUmakefile: Add new targets for single translation
+ unit build to maximise inlining potential; generate
+ pthread.def automatically.
+ * Makefile: Likewise, but no longer uses pthread.def.
+
+2002-02-20 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread_cond_destroy.c (pthread_cond_destroy):
+ Enter the time change critical section earlier.
+
+2002-02-17 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ * Testsuite passed.
+
+ * pthread_timechange_handler_np.c: New; following
+ a suggestion from Alexander Terekhov that CVs should
+ be broadcast so that they all re-evaluate their
+ condition variables and reset a new timeout if
+ required, whenever an application receives a
+ WM_TIMECHANGE message. This message indicates that
+ the system time has been changed. Therefore, CVs
+ waiting for a timeout set as an abs_time will possibly
+ not wake up at the expected time. Some applications
+ may not be tolerant of this.
+ * pthread_cond_init.c: Add CV to linked list.
+ * pthread_cond_destroy.c: Remove CV from linked list.
+ * global.c (ptw32_cond_list_head): New variable.
+ (ptw32_cond_list_tail): New variable.
+ (ptw32_cond_list_cs): New critical section.
+ * ptw32_processInitialize (ptw32_cond_list_cs): Initialize.
+ * ptw32_processTerminate (ptw32_cond_list_cs): Delete.
+
+
+ * Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * spin.c: Split file into function segments.
+ * ptw32_spinlock_check_need_init.c: Separated routine from spin.c.
+ * pthread_spin_init.c: Likewise.
+ * pthread_spin_destroy.c: Likewise.
+ * pthread_spin_lock.c: Likewise.
+ * pthread_spin_unlock.c: Likewise.
+ * pthread_spin_trylock.c: Likewise.
+
+ * sync.c: Split file into function segments.
+ * pthread_detach.c: Separated routine from sync.c.
+ * pthread_join.c: Likewise.
+
+ * tsd.c: Split file into function segments.
+ * pthread_key_create.c: Separated routine from tsd.c.
+ * pthread_key_delete.c: Likewise.
+ * pthread_setspecific.c: Likewise.
+ * pthread_getspecific.c: Likewise.
+
+ * sched.c: Split file into function segments.
+ * pthread_attr_setschedpolicy.c: Separated routine from sched.c.
+ * pthread_attr_getschedpolicy.c: Likewise.
+ * pthread_attr_setschedparam.c: Likewise.
+ * pthread_attr_getschedparam.c: Likewise.
+ * pthread_attr_setinheritsched.c: Likewise.
+ * pthread_attr_getinheritsched.c: Likewise.
+ * pthread_setschedparam.c: Likewise.
+ * pthread_getschedparam.c: Likewise.
+ * sched_get_priority_max.c: Likewise.
+ * sched_get_priority_min.c: Likewise.
+ * sched_setscheduler.c: Likewise.
+ * sched_getscheduler.c: Likewise.
+ * sched_yield.c: Likewise.
+
+
+2002-02-16 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * mutex.c: Split file into function segments.
+ * pthread_mutexattr_destroy.c: Separated routine from mutex.c
+ * pthread_mutexattr_getpshared.c: Likewise.
+ * pthread_mutexattr_gettype.c: Likewise.
+ * pthread_mutexattr_init.c: Likewise.
+ * pthread_mutexattr_setpshared.c: Likewise.
+ * pthread_mutexattr_settype.c: Likewise.
+ * ptw32_mutex_check_need_init.c: Likewise.
+ * pthread_mutex_destroy.c: Likewise.
+ * pthread_mutex_init.c: Likewise.
+ * pthread_mutex_lock.c: Likewise.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_unlock.c: Likewise.
+
+ * private.c: Split file into function segments.
+ * ptw32_InterlockedCompareExchange.c: Separated routine from private.c
+ * ptw32_callUserDestroyRoutines.c: Likewise.
+ * ptw32_getprocessors.c: Likewise.
+ * ptw32_processInitialize.c: Likewise.
+ * ptw32_processTerminate.c: Likewise.
+ * ptw32_threadDestroy.c: Likewise.
+ * ptw32_threadStart.c: Likewise.
+ * ptw32_throw.c: Likewise.
+ * ptw32_timespec.c: Likewise.
+ * ptw32_tkAssocCreate.c: Likewise.
+ * ptw32_tkAssocDestroy.c: Likewise.
+
+ * rwlock.c: Split file into function segments.
+ * pthread_rwlockattr_destroy.c: Separated routine from rwlock.c
+ * pthread_rwlockattr_getpshared.c: Likewise.
+ * pthread_rwlockattr_init.c: Likewise.
+ * pthread_rwlockattr_setpshared.c: Likewise.
+ * ptw32_rwlock_check_need_init.c: Likewise.
+ * pthread_rwlock_destroy.c: Likewise.
+ * pthread_rwlock_init.c: Likewise.
+ * pthread_rwlock_rdlock.c: Likewise.
+ * pthread_rwlock_tryrdlock.c: Likewise.
+ * pthread_rwlock_trywrlock.c: Likewise.
+ * pthread_rwlock_unlock.c: Likewise.
+ * pthread_rwlock_wrlock.c: Likewise.
+
+2002-02-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * nonportable.c: Split file into function segments.
+ * np_delay.c: Separated routine from nonportable.c
+ * np_getw32threadhandle.c: Likewise.
+ * np_mutexattr_setkind.c: Likewise.
+ * np_mutexattr_getkind.c: Likewise.
+ * np_num_processors.c: Likewise.
+ * np_win32_attach_detach.c: Likewise.
+
+ * misc.c: Split file into function segments.
+ * pthread_equal.c: Separated routine from nonportable.c.
+ * pthread_getconcurrency.c: Likewise.
+ * pthread_once.c: Likewise.
+ * pthread_self.c: Likewise.
+ * pthread_setconcurrency.c: Likewise.
+ * ptw32_calloc.c: Likewise.
+ * ptw32_new.c: Likewise.
+ * w32_CancelableWait.c: Likewise.
+
+2002-02-09 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * condvar.c: Split file into function segments.
+ * pthread_condattr_destroy.c: Separated routine from condvar.c.
+ * pthread_condattr_getpshared.c: Likewise.
+ * pthread_condattr_init.c: Likewise.
+ * pthread_condattr_setpshared.c: Likewise.
+ * ptw32_cond_check_need_init.c: Likewise.
+ * pthread_cond_destroy.c: Likewise.
+ * pthread_cond_init.c: Likewise.
+ * pthread_cond_signal.c: Likewise.
+ * pthread_cond_wait.c: Likewise.
+
+2002-02-07 Alexander Terekhov<TEREKHOV at de.ibm.com>
+
+ * nonportable.c (pthread_delay_np): Make a true
+ cancelation point. Deferred cancels will interrupt the
+ wait.
+
+2002-02-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ * misc.c (ptw32_new): Add creation of cancelEvent so that
+ implicit POSIX threads (Win32 threads with a POSIX face)
+ are cancelable; mainly so that pthread_delay_np doesn't fail
+ if called from the main thread.
+ * create.c (pthread_create): Remove creation of cancelEvent
+ from here; now in ptw32_new().
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * barrier.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * cancel.c: Likewise.
+ * pthread_barrierattr_destroy.c: Separated routine from cancel.c.
+ * pthread_barrierattr_getpshared.c: Likewise.
+ * pthread_barrierattr_init.c: Likewise.
+ * pthread_barrierattr_setpshared.c: Likewise.
+ * pthread_barrier_destroy.c: Likewise.
+ * pthread_barrier_init.c: Likewise.
+ * pthread_barrier_wait.c: Likewise.
+ * pthread_cancel.c: Likewise.
+ * pthread_setcancelstate.c: Likewise.
+ * pthread_setcanceltype.c: Likewise.
+ * pthread_testcancel.c: Likewise.
+
+2002-02-04 Max Woodbury <mtew at cds.duke.edu>
+
+ Reduced name space pollution.
+ -----------------------------
+ When the appropriate symbols are defined, the headers
+ will restrict the definitions of new names. In particular,
+ it must be possible to NOT include the <windows.h>
+ header and related definitions with some combination
+ of symbol definitions. Secondly, it should be possible
+ that additional definitions should be limited to POSIX
+ compliant symbols by the definition of appropriate symbols.
+
+ * pthread.h: POSIX conditionals.
+ * sched.h: POSIX conditionals.
+ * semaphore.h: POSIX conditionals.
+
+ * semaphore.c: Included <limits.h>.
+ (sem_init): Changed magic 0x7FFFFFFFL to INT_MAX.
+ (sem_getvalue): Trial version.
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * semaphore.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * sem_close.c: Separated routine from semaphore.c.
+ * ptw32_decrease_semaphore.c: Likewise.
+ * sem_destroy.c: Likewise.
+ * sem_getvalue.c: Likewise.
+ * ptw32_increase_semaphore.c: Likewise.
+ * sem_init.c: Likewise.
+ * sem_open.c: Likewise.
+ * sem_post.c: Likewise.
+ * sem_post_multiple.c: Likewise.
+ * sem_timedwait.c: Likewise.
+ * sem_trywait.c: Likewise.
+ * sem_unlink.c: Likewise.
+ * sem_wait.c: Likewise.
+
+2002-02-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ The following extends the idea above to the rest of pthreads-win32 - rpj
+
+ * attr.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * pthread_attr_destroy.c: Separated routine from attr.c.
+ * pthread_attr_getdetachstate.c: Likewise.
+ * pthread_attr_getscope.c: Likewise.
+ * pthread_attr_getstackaddr.c: Likewise.
+ * pthread_attr_getstacksize.c: Likewise.
+ * pthread_attr_init.c: Likewise.
+ * pthread_attr_is_attr.c: Likewise.
+ * pthread_attr_setdetachstate.c: Likewise.
+ * pthread_attr_setscope.c: Likewise.
+ * pthread_attr_setstackaddr.c: Likewise.
+ * pthread_attr_setstacksize.c: Likewise.
+
+ * pthread.c: Agregation of agregate modules for super-inlineability.
+
+2002-02-02 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * cancel.c: Rearranged some code and introduced checks
+ to disable cancelation at the start of a thread's cancelation
+ run to prevent double cancelation. The main problem
+ arises if a thread is canceling and then receives a subsequent
+ async cancel request.
+ * private.c: Likewise.
+ * condvar.c: Place pragmas around cleanup_push/pop to turn
+ off inline optimisation (/Obn where n>0 - MSVC only). Various
+ optimisation switches in MSVC turn this on, which interferes with
+ the way that cleanup handlers are run in C++ EH and SEH
+ code. Application code compiled with inline optimisation must
+ also wrap cleanup_push/pop blocks with the pragmas, e.g.
+ #pragma inline_depth(0)
+ pthread_cleanup_push(...)
+ ...
+ pthread_cleanup_pop(...)
+ #pragma inline_depth(8)
+ * rwlock.c: Likewise.
+ * mutex.c: Remove attempts to inline some functions.
+ * signal.c: Modify misleading comment.
+
+2002-02-01 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.c (sem_trywait): Fix missing errno return
+ for systems that define NEED_SEM (e.g. early WinCE).
+ * mutex.c (pthread_mutex_timedlock): Return ENOTSUP
+ for systems that define NEED_SEM since they don't
+ have sem_trywait().
+
+2002-01-27 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_timedlock): New function suggested by
+ Alexander Terekhov. The logic required to implement this
+ properly came from Alexander, with some collaboration
+ with Thomas Pfaff.
+ (pthread_mutex_unlock): Wrap the waiters check and sema
+ post in a critical section to prevent a race with
+ pthread_mutex_timedlock.
+ (ptw32_timed_semwait): New function;
+ returns a special result if the absolute timeout parameter
+ represents a time already passed when called; used by
+ pthread_mutex_timedwait(). Have deliberately not reused
+ the name "ptw32_sem_timedwait" because they are not the same
+ routine.
+ * condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait()
+ instead of ptw32_sem_timedwait(), which now has a different
+ function. See previous.
+ * implement.h: Remove prototype for ptw32_sem_timedwait.
+ See next.
+ (pthread_mutex_t_): Add critical section element for access
+ to lock_idx during mutex post-timeout processing.
+ * semaphore.h (sem_timedwait): See next.
+ * semaphore.c (sem_timedwait): See next.
+ * private.c (ptw32_sem_timedwait): Move to semaphore.c
+ and rename as sem_timedwait().
+
+2002-01-18 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * sync.c (pthread_join): Was getting the exit code from the
+ calling thread rather than the joined thread if
+ defined(__MINGW32__) && !defined(__MSVCRT__).
+
+2002-01-15 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Unless the build explicitly defines __CLEANUP_SEH,
+ __CLEANUP_CXX, or __CLEANUP_C, then the build defaults to
+ __CLEANUP_C style cleanup. This style uses setjmp/longjmp
+ in the cancelation and thread exit implementations and therefore
+ won't do stack unwinding if linked to applications that have it
+ (e.g. C++ apps). This is currently consistent with most/all
+ commercial Unix POSIX threads implementations.
+
+ * spin.c (pthread_spin_init): Edit renamed function call.
+ * nonportable.c (pthread_num_processors_np): New.
+ (pthread_getprocessors_np): Renamed to ptw32_getprocessors
+ and moved to private.c.
+ * private.c (pthread_getprocessors): Moved here from
+ nonportable.c.
+ * pthread.def (pthread_getprocessors_np): Removed
+ from export list.
+
+ * rwlock.c (pthread_rwlockattr_init): New.
+ (pthread_rwlockattr_destroy): New.
+ (pthread_rwlockattr_getpshared): New.
+ (pthread_rwlockattr_setpshared): New.
+
+2002-01-14 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setscope): Fix struct pointer
+ indirection error introduced 2002-01-04.
+ (pthread_attr_getscope): Likewise.
+
+2002-01-12 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.dsp (SOURCE): Add missing source files.
+
+2002-01-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_trylock): use
+ ptw32_interlocked_compare_exchange function pointer
+ rather than ptw32_InterlockedCompareExchange() directly
+ to retain portability to non-iX86 processors,
+ e.g. WinCE etc. The pointer will point to the native
+ OS version of InterlockedCompareExchange() if the
+ OS supports it (see ChangeLog entry of 2001-10-17).
+
+2002-01-07 Thomas Pfaff <tpfaff at gmx.net>, Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * mutex.c (pthread_mutex_init): Remove critical
+ section calls.
+ (pthread_mutex_destroy): Likewise.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise; uses
+ ptw32_InterlockedCompareExchange() to avoid need for
+ critical section; library is no longer i386 compatible;
+ recursive mutexes now increment the lock count rather
+ than return EBUSY; errorcheck mutexes return EDEADLCK
+ rather than EBUSY. This behaviour is consistent with the
+ Solaris pthreads implementation.
+ * implement.h (pthread_mutex_t_): Remove critical
+ section element - no longer needed.
+
+
+2002-01-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setscope): Add more error
+ checking and actually store the scope value even
+ though it's not really necessary.
+ (pthread_attr_getscope): Return stored value.
+ * implement.h (pthread_attr_t_): Add new scope element.
+ * ANNOUNCE: Fix out of date comment next to
+ pthread_attr_setscope in conformance section.
+
+2001-12-21 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * mutex.c (pthread_mutex_lock): Decrementing lock_idx was
+ not thread-safe.
+ (pthread_mutex_trylock): Likewise.
+
+2001-10-26 prionx@juno.com
+
+ * semaphore.c (sem_init): Fix typo and missing bracket
+ in conditionally compiled code. Only older versions of
+ WinCE require this code, hence it doesn't normally get
+ tested; somehow when sem_t reverted to an opaque struct
+ the calloc NULL check was left in the conditionally included
+ section.
+ (sem_destroy): Likewise, the calloced sem_t wasn't being freed.
+
+2001-10-25 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * GNUmakefile (libwsock32): Add to linker flags for
+ WSAGetLastError() and WSASetLastError().
+ * Makefile (wsock32.lib): Likewise.
+ * create.c: Minor mostly inert changes.
+ * implement.h (PTW32_MAX): Move into here and renamed
+ from sched.h.
+ (PTW32_MIN): Likewise.
+ * GNUmakefile (TEST_ICE): Define if testing internal
+ implementation of InterlockedCompareExchange.
+ * Makefile (TEST_ICE): Likewise.
+ * private.c (TEST_ICE): Likewise.
+
+2001-10-24 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setstacksize): Quell warning
+ from LCC by conditionally compiling the stacksize
+ validity check. LCC correctly warns that the condition
+ (stacksize < PTHREAD_STACK_MIN) is suspicious
+ because STACK_MIN is 0 and stacksize is of type
+ size_t (or unsigned int).
+
+2001-10-17 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Move _LONG and _LPLONG defines into
+ implement.h; rename to PTW32_INTERLOCKED_LONG and
+ PTW32_INTERLOCKED_LPLONG respectively.
+ * spin.c: Likewise; ptw32_interlocked_compare_exchange used
+ in place of InterlockedCompareExchange directly.
+ * global.c (ptw32_interlocked_compare_exchange): Add
+ prototype for this new routine pointer to be used when
+ InterlockedCompareExchange isn't supported by Windows.
+ * nonportable.c (pthread_win32_process_attach_np): Check for
+ support of InterlockedCompareExchange in kernel32 and assign its
+ address to ptw32_interlocked_compare_exchange if it exists, or
+ our own ix86 specific implementation ptw32_InterlockedCompareExchange.
+ *private.c (ptw32_InterlockedCompareExchange): An
+ implementation of InterlockedCompareExchange() which is
+ specific to ix86; written directly in assembler for either
+ MSVC or GNU C; needed because Windows 95 doesn't support
+ InterlockedCompareExchange().
+
+ * sched.c (sched_get_priority_min): Extend to return
+ THREAD_PRIORITY_IDLE.
+ (sched_get_priority_max): Extend to return
+ THREAD_PRIORITY_CRITICAL.
+
+2001-10-15 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_lock): PTHREAD_SPINLOCK_INITIALIZER
+ was causing a program fault.
+ (pthread_spin_init): Could have alloced memory
+ without freeing under some error conditions.
+
+ * mutex.c (pthread_mutex_init): Move memory
+ allocation of mutex struct after checking for
+ PROCESS_SHARED.
+
+2001-10-12 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_unlock): Was not returning
+ EPERM if the spinlock was not locked, for multi CPU
+ machines.
+
+2001-10-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_trylock): Was not returning
+ EBUSY for multi CPU machines.
+
+2001-08-24 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * condvar.c (pthread_cond_destroy): Remove cv element
+ that is no longer used.
+ * implement.h: Likewise.
+
+2001-08-23 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * condvar.c (pthread_cond_destroy): fix bug with
+ respect to deadlock in the case of concurrent
+ _destroy/_unblock; a condition variable can be destroyed
+ immediately after all the threads that are blocked on
+ it are awakened.
+
+2001-08-23 Phil Frisbie, Jr. <phil at hawksoft.com>
+
+ * tsd.c (pthread_getspecific): Preserve the last
+ winsock error [from WSAGetLastError()].
+
+2001-07-18 Scott McCaskill <scott at magruder.org>
+
+ * mutex.c (pthread_mutexattr_init): Return ENOMEM
+ immediately and don't dereference the NULL pointer
+ if calloc fails.
+ (pthread_mutexattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+ * barrier.c (pthread_barrierattr_init): Likewise
+ (pthread_barrierattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+ * condvar.c (pthread_condattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+
+2001-07-15 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_wrlock): Is allowed to be
+ a cancelation point; re-enable deferred cancelability
+ around the CV call.
+
+2001-07-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Still more revamping. The exclusive access
+ mutex isn't really needed so it has been removed and replaced
+ by an InterlockedDecrement(). nSerial has been removed.
+ iStep is now dual-purpose. The process shared attribute
+ is now stored in the barrier struct.
+ * implement.h (pthread_barrier_t_): Lost some/gained one
+ elements.
+ * private.c (ptw32_threadStart): Removed some comments.
+
+2001-07-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Revamped to fix the race condition. Two alternating
+ semaphores are used instead of the PulseEvent. Also improved
+ overall throughput by returning PTHREAD_BARRIER_SERIAL_THREAD
+ to the first waking thread.
+ * implement.h (pthread_barrier_t_): Revamped.
+
+2001-07-09 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Fix several bugs in all routines. Now passes
+ tests/barrier5.c which is fairly rigorous. There is still
+ a non-optimal work-around for a race condition between
+ the barrier breeched event signal and event wait. Basically
+ the last (signalling) thread to hit the barrier yields
+ to allow any other threads, which may have lost the race,
+ to complete.
+
+2001-07-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Changed synchronisation mechanism to a
+ Win32 manual reset Event and use PulseEvent to signal
+ waiting threads. If the implementation continued to use
+ a semaphore it would require a second semaphore and
+ some management to use them alternately as barriers. A
+ single semaphore allows threads to cascade from one barrier
+ through the next, leaving some threads blocked at the first.
+ * implement.h (pthread_barrier_t_): As per above.
+ * general: Made a number of other routines inlinable.
+
+2001-07-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c: Revamped and working; included static initialiser.
+ Now beta level.
+ * barrier.c: Likewise.
+ * condvar.c: Macro constant change; inline auto init routine.
+ * mutex.c: Likewise.
+ * rwlock.c: Likewise.
+ * private.c: Add support for spinlock initialiser.
+ * global.c: Likewise.
+ * implement.h: Likewise.
+ * pthread.h (PTHREAD_SPINLOCK_INITIALIZER): Fix typo.
+
+2001-07-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Remove static initialisation - irrelevent
+ for this object.
+ * pthread.h (PTHREAD_BARRIER_INITIALIZER): Removed.
+ * rwlock.c (pthread_rwlock_wrlock): This routine is
+ not a cancelation point - disable deferred
+ cancelation around call to pthread_cond_wait().
+
+2001-07-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c: New module implementing spin locks.
+ * barrier.c: New module implementing barriers.
+ * pthread.h (_POSIX_SPIN_LOCKS): defined.
+ (_POSIX_BARRIERS): Defined.
+ (pthread_spin_*): Defined.
+ (pthread_barrier*): Defined.
+ (PTHREAD_BARRIER_SERIAL_THREAD): Defined.
+ * implement.h (pthread_spinlock_t_): Defined.
+ (pthread_barrier_t_): Defined.
+ (pthread_barrierattr_t_): Defined.
+
+ * mutex.c (pthread_mutex_lock): Return with the error
+ if an auto-initialiser initialisation fails.
+
+ * nonportable.c (pthread_getprocessors_np): New; gets the
+ number of available processors for the current process.
+
+2001-07-03 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread.h (_POSIX_READER_WRITER_LOCKS): Define it
+ if not already defined.
+
+2001-07-01 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * condvar.c: Fixed lost signal bug reported by Timur Aydin
+ (taydin@snet.net).
+ [RPJ (me) didn't translate the original algorithm
+ correctly.]
+ * semaphore.c: Added sem_post_multiple; this is a useful
+ routine, but it doesn't appear to be standard. For now it's
+ not an exported function.
+
+2001-06-25 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Add priority inheritance
+ attributes.
+ * mutex.c (pthread_mutex_lock): Remove some overhead for
+ PTHREAD_MUTEX_NORMAL mutex types. Specifically, avoid
+ calling pthread_self() and pthread_equal() to check/set
+ the mutex owner. Introduce a new pseudo owner for this
+ type. Test results suggest increases in speed of up to
+ 90% for non-blocking locks.
+ This is the default type of mutex used internally by other
+ synchronising objects, ie. condition variables and
+ read-write locks. The test rwlock7.c shows about a
+ 30-35% speed increase over snapshot 2001-06-06. The
+ price of this is that the application developer
+ must ensure correct behaviour, or explicitly set the
+ mutex to a safer type such as PTHREAD_MUTEX_ERRORCHECK.
+ For example, PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_DEFAULT)
+ type mutexes will not return an error if a thread which is not
+ the owner calls pthread_mutex_unlock. The call will succeed
+ in unlocking the mutex if it is currently locked, but a
+ subsequent unlock by the true owner will then fail with EPERM.
+ This is however consistent with some other implementations.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_destroy): Likewise.
+ * attr.c (pthread_attr_init): PTHREAD_EXPLICIT_SCHED is the
+ default inheritance attribute; THREAD_PRIORITY_NORMAL is
+ the default priority for new threads.
+ * sched.c (pthread_attr_setschedpolicy): Added routine.
+ (pthread_attr_getschedpolicy): Added routine.
+ (pthread_attr_setinheritsched): Added routine.
+ (pthread_attr_getinheritsched): Added routine.
+ * pthread.h (sched_rr_set_interval): Added as a macro;
+ returns -1 with errno set to ENOSYS.
+
+2001-06-23 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ *sched.c (pthread_attr_setschedparam): Add priority range
+ check.
+ (sched_setscheduler): New function; checks for a valid
+ pid and policy; checks for permission to set information
+ in the target process; expects pid to be a Win32 process ID,
+ not a process handle; the only scheduler policy allowed is
+ SCHED_OTHER.
+ (sched_getscheduler): Likewise, but checks for permission
+ to query.
+ * pthread.h (SCHED_*): Moved to sched.h as defined in the
+ POSIX standard.
+ * sched.h (SCHED_*): Moved from pthread.h.
+ (pid_t): Defined if necessary.
+ (sched_setscheduler): Defined.
+ (sched_getscheduler): Defined.
+ * pthread.def (sched_setscheduler): Exported.
+ (sched_getscheduler): Likewise.
+
+2001-06-23 Ralf Brese <Ralf.Brese at pdb4.siemens.de>
+
+ * create.c (pthread_create): Set thread priority from
+ thread attributes.
+
+2001-06-18 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * Made organisational-only changes to UWIN additions.
+ * dll.c (dllMain): Moved UWIN process attach code
+ to pthread_win32_process_attach_np(); moved
+ instance of pthread_count to global.c.
+ * global.c (pthread_count): Moved from dll.c.
+ * nonportable.c (pthread_win32_process_attach_np):
+ Moved _UWIN code to here from dll.c.
+ * implement.h (pthread_count): Define extern int.
+ * create.c (pthread_count): Remove extern int.
+ * private.c (pthread_count): Likewise.
+ * exit.c (pthread_count): Likewise.
+
+2001-06-18 David Korn <dgk at research.att.com>
+
+ * dll.c: Added changes necessary to work with UWIN.
+ * create.c: Likewise.
+ * pthread.h: Likewise.
+ * misc.c: Likewise.
+ * exit.c: Likewise.
+ * private.c: Likewise.
+ * implement.h: Likewise.
+ There is some room at the start of struct pthread_t_
+ to implement the signal semantics in UWIN's posix.dll
+ although this is not yet complete.
+ * Nmakefile: Compatible with UWIN's Nmake utility.
+ * Nmakefile.tests: Likewise - for running the tests.
+
+2001-06-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.h (sem_t): Fixed for compile and test.
+ * implement.h (sem_t_): Likewise.
+ * semaphore.c: Likewise.
+ * private.c (ptw32_sem_timedwait): Updated to use new
+ opaque sem_t.
+
+2001-06-06 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.h (sem_t): Is now an opaque pointer;
+ moved actual definition to implement.h.
+ * implement.h (sem_t_): Move here from semaphore.h;
+ was the definition of sem_t.
+ * semaphore.c: Wherever necessary, changed use of sem
+ from that of a pointer to a pointer-pointer; added
+ extra checks for a valid sem_t; NULL sem_t when
+ it is destroyed; added extra checks when creating
+ and destroying sem_t elements in the NEED_SEM
+ code branches; changed from using a pthread_mutex_t
+ ((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
+ in NEED_SEM branches for access serialisation.
+
+2001-06-06 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutexattr_init): Remove
+ ptw32_mutex_default_kind.
+
+2001-06-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * nonportable.c (pthread_mutex_setdefaultkind_np):
+ Remove - should not have been included in the first place.
+ (pthread_mutex_getdefaultkind_np): Likewise.
+ * global.c (ptw32_mutex_default_kind): Likewise.
+ * mutex.c (pthread_mutex_init): Remove use of
+ ptw32_mutex_default_kind.
+ * pthread.h (pthread_mutex_setdefaultkind_np): Likewise.
+ (pthread_mutex_getdefaultkind_np): Likewise.
+ * pthread.def (pthread_mutexattr_setkind_np): Added.
+ (pthread_mutexattr_getkind_np): Likewise.
+
+ * README: Many changes that should have gone in before
+ the last snapshot.
+ * README.NONPORTABLE: New - referred to by ANNOUNCE
+ but never created; documents the non-portable routines
+ included in the library - moved from README with new
+ routines added.
+ * ANNOUNCE (pthread_mutexattr_setkind_np): Added to
+ compliance list.
+ (pthread_mutexattr_getkind_np): Likewise.
+
+2001-06-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * condvar.c: Add original description of the algorithm as
+ developed by Terekhov and Thomas, plus reference to
+ README.CV.
+
+2001-06-03 Alexander Terekhov <TEREKHOV at de.ibm.com>, Louis Thomas <lthomas at arbitrade.com>
+
+ * condvar.c (pthread_cond_init): Completely revamped.
+ (pthread_cond_destroy): Likewise.
+ (ptw32_cond_wait_cleanup): Likewise.
+ (ptw32_cond_timedwait): Likewise.
+ (ptw32_cond_unblock): New general signaling routine.
+ (pthread_cond_signal): Now calls ptw32_cond_unblock.
+ (pthread_cond_broadcast): Likewise.
+ * implement.h (pthread_cond_t_): Revamped.
+ * README.CV: New; explanation of the above changes.
+
+2001-05-30 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread.h (rand_r): Fake using _seed argument to quell
+ compiler warning (compiler should optimise this away later).
+
+ * GNUmakefile (OPT): Leave symbolic information out of the library
+ and increase optimisation level - for smaller faster prebuilt
+ dlls.
+
+2001-05-29 Milan Gardian <Milan.Gardian at LEIBINGER.com>
+
+ * Makefile: fix typo.
+ * pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
+ remove the need for PT_STDCALL everywhere; remove warning supression.
+ * (errno): Fix the longstanding "inconsistent dll linkage" problem
+ with errno; now also works with /MD debugging libs -
+ warnings emerged when compiling pthreads library with /MD (or /MDd)
+ compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
+ using Multithreaded DLL CRT instead of Multithreaded statically linked
+ CRT).
+ * create.c (pthread_create): Likewise; fix typo.
+ * private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
+ throw exceptions.
+ * Remove unnecessary #includes from a number of modules -
+ [I had to #include malloc.h in implement.h for gcc - rpj].
+
+2001-05-29 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
+ PTHREAD_MUTEX_DEFAULT_NP.
+ * (PTHREAD_MUTEX_NORMAL): Similarly.
+ * (PTHREAD_MUTEX_ERRORCHECK): Similarly.
+ * (PTHREAD_MUTEX_RECURSIVE): Similarly.
+ * (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
+ for pthread_mutexattr_settype.
+ * (pthread_mutexattr_getkind_np): New; Linux compatibility stub
+ for pthread_mutexattr_gettype.
+ * mutex.c (pthread_mutexattr_settype): New; allow
+ the following types of mutex:
+ PTHREAD_MUTEX_DEFAULT_NP
+ PTHREAD_MUTEX_NORMAL_NP
+ PTHREAD_MUTEX_ERRORCHECK_NP
+ PTHREAD_MUTEX_RECURSIVE_NP
+ * Note that PTHREAD_MUTEX_DEFAULT is equivalent to
+ PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
+ be recursive by default, and a thread will deadlock if it
+ tries to relock a mutex it already owns. This is inline with
+ other pthreads implementations.
+ * (pthread_mutex_lock): Process the lock request
+ according to the mutex type.
+ * (pthread_mutex_init): Eliminate use of Win32 mutexes as the
+ basis of POSIX mutexes - instead, a combination of one critical section
+ and one semaphore are used in conjunction with Win32 Interlocked* routines.
+ * (pthread_mutex_destroy): Likewise.
+ * (pthread_mutex_lock): Likewise.
+ * (pthread_mutex_trylock): Likewise.
+ * (pthread_mutex_unlock): Likewise.
+ * Use longjmp/setjmp to implement cancelation when building the library
+ using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
+ that gcc -x c++ uses exceptions).
+ * Also fixed some of the same typos and eliminated PT_STDCALL as
+ Milan Gardian's patches above.
+
+2001-02-07 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * rwlock.c: Revamped.
+ * implement.h (pthread_rwlock_t_): Redefined.
+ This implementation does not have reader/writer starvation problem.
+ Rwlock attempts to behave more like a normal mutex with
+ races and scheduling policy determining who is more important;
+ It also supports recursive locking,
+ has less synchronization overhead (no broadcasts at all,
+ readers are not blocked on any condition variable) and seem to
+ be faster than the current implementation [W98 appears to be
+ approximately 15 percent faster at least - on top of speed increase
+ from Thomas Pfaff's changes to mutex.c - rpj].
+
+2000-12-29 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * Makefile: Back-out "for" loops which don't work.
+
+ * GNUmakefile: Remove the fake.a target; add the "realclean"
+ target; don't remove built libs under the "clean" target.
+
+ * config.h: Add a guard against multiple inclusion.
+
+ * semaphore.h: Add some defines from config.h to make
+ semaphore.h independent of config.h when building apps.
+
+ * pthread.h (_errno): Back-out previous fix until we know how to
+ fix it properly.
+
+ * implement.h (lockCount): Add missing element to pthread_mutex_t_.
+
+ * sync.c (pthread_join): Spelling fix in comment.
+
+ * private.c (ptw32_threadStart): Reset original termination
+ function (C++).
+ (ptw32_threadStart): Cleanup detached threads early in case
+ the library is statically linked.
+ (ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
+ destructor call so that unhandled exceptions will be passed through
+ to the system; call terminate() from [C++] try block for the same
+ reason.
+
+ * tsd.c (pthread_getspecific): Add comment.
+
+ * mutex.c (pthread_mutex_init): Initialise new elements in
+ pthread_mutex_t.
+ (pthread_mutex_unlock): Invert "pthread_equal()" test.
+
+2000-12-28 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
+
+ * config.h.in (HAVE_MODE_T): Added.
+ (_UWIN): Start adding defines for the UWIN package.
+
+ * private.c (ptw32_threadStart): Unhandled exceptions are
+ now passed through to the system to deal with. This is consistent
+ with normal Windows behaviour. C++ applications may use
+ set_terminate() to override the default behaviour which is
+ to call ptw32_terminate(). Ptw32_terminate() cleans up some
+ POSIX thread stuff before calling the system default function
+ which calls abort(). The users termination function should conform
+ to standard C++ semantics which is to not return. It should
+ exit the thread (call pthread_exit()) or exit the application.
+ * private.c (ptw32_terminate): Added as the default set_terminate()
+ function. It calls the system default function after cleaning up
+ some POSIX thread stuff.
+
+ * implement.h (ptw32_try_enter_critical_section): Move
+ declaration.
+ * global.c (ptw32_try_enter_critical_section): Moved
+ from dll.c.
+ * dll.c: Move process and thread attach/detach code into
+ functions in nonportable.c.
+ * nonportable.c (pthread_win32_process_attach_np): Process
+ attach code from dll.c is now available to static linked
+ applications.
+ * nonportable.c (pthread_win32_process_detach_np): Likewise.
+ * nonportable.c (pthread_win32_thread_attach_np): Likewise.
+ * nonportable.c (pthread_win32_thread_detach_np): Likewise.
+
+ * pthread.h: Add new non-portable prototypes for static
+ linked applications.
+
+ * GNUmakefile (OPT): Increase optimisation flag and remove
+ debug info flag.
+
+ * pthread.def: Add new non-portable exports for static
+ linked applications.
+
+2000-12-11 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * FAQ: Update Answer 6 re getting a fully working
+ Mingw32 built library.
+
+2000-10-10 Steven Reddie <smr at essemer.com.au>
+
+ * misc.c (pthread_self): Restore Win32 "last error"
+ cleared by TlsGetValue() call in
+ pthread_getspecific()
+
+2000-09-20 Arthur Kantor <akantor at bexusa.com>
+
+ * mutex.c (pthread_mutex_lock): Record the owner
+ of the mutex. This requires also keeping count of
+ recursive locks ourselves rather than leaving it
+ to Win32 since we need to know when to NULL the
+ thread owner when the mutex is unlocked.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_unlock): Check that the calling
+ thread owns the mutex, decrement the recursive
+ lock count, and NULL the owner if zero. Return
+ EPERM if the mutex is owned by another thread.
+ * implement.h (pthread_mutex_t_): Add ownerThread
+ and lockCount members.
+
+2000-09-13 Jef Gearhart <jgearhart at tpssys.com>
+
+ * mutex.c (pthread_mutex_init): Call
+ TryEnterCriticalSection through the pointer
+ rather than directly so that the dll can load
+ on Windows versions that can't resolve the
+ function, eg. Windows 95
+
+2000-09-09 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h (ctime_r): Fix arg.
+
+2000-09-08 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
+ doesn't seem to be needed though.
+
+ * cancel.c (pthread_cancel): Must get "self" through
+ calling pthread_self() which will ensure a POSIX thread
+ struct is built for non-POSIX threads; return an error
+ if this fails
+ - Ollie Leahy <ollie at mpt.ie>
+ (pthread_setcancelstate): Likewise.
+ (pthread_setcanceltype): Likewise.
+ * misc.c (ptw32_cancelable_wait): Likewise.
+
+ * private.c (ptw32_tkAssocCreate): Remove unused #if 0
+ wrapped code.
+
+ * pthread.h (ptw32_get_exception_services_code):
+ Needed to be forward declared unconditionally.
+
+2000-09-06 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cancel.c (pthread_cancel): If called from the main
+ thread "self" would be NULL; get "self" via pthread_self()
+ instead of directly from TLS so that an implicit
+ pthread object is created.
+
+ * misc.c (pthread_equal): Strengthen test for NULLs.
+
+2000-09-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * condvar.c (ptw32_cond_wait_cleanup): Ensure that all
+ waking threads check if they are the last, and notify
+ the broadcaster if so - even if an error occurs in the
+ waiter.
+
+ * semaphore.c (_decrease_semaphore): Should be
+ a call to ptw32_decrease_semaphore.
+ (_increase_semaphore): Should be a call to
+ ptw32_increase_semaphore.
+
+ * misc.c (ptw32_cancelable_wait): Renamed from
+ CancelableWait.
+ * rwlock.c (_rwlock_check*): Renamed to
+ ptw32_rwlock_check*.
+ * mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
+ * condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
+ (_cond_check*): Renamed to ptw32_cond_check*.
+ (cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
+ (ptw32_cond_timedwait): Add comments.
+
+2000-08-22 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * private.c (ptw32_throw): Fix exception test;
+ move exceptionInformation declaration.
+
+ * tsd.c (pthread_key_create): newkey wrongly declared.
+
+ * pthread.h: Fix comment block.
+
+2000-08-18 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_destroy): Check that the mutex isn't
+ held; invalidate the mutex as early as possible to avoid
+ contention; not perfect - FIXME!
+
+ * rwlock.c (pthread_rwlock_init): Remove redundant assignment
+ to "rw".
+ (pthread_rwlock_destroy): Invalidate the rwlock before
+ freeing up any of it's resources - to avoid contention.
+
+ * private.c (ptw32_tkAssocCreate): Change assoc->lock
+ to use a dynamically initialised mutex - only consumes
+ a W32 mutex or critical section when first used,
+ not before.
+
+ * mutex.c (pthread_mutex_init): Remove redundant assignment
+ to "mx".
+ (pthread_mutexattr_destroy): Set attribute to NULL
+ before freeing it's memory - to avoid contention.
+
+ * implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
+ Must be defined for all compilers - used as generic
+ exception selectors by ptw32_throw().
+
+ * Several: Fix typos from scripted edit session
+ yesterday.
+
+ * nonportable.c (pthread_mutexattr_setforcecs_np):
+ Moved this function from mutex.c.
+ (pthread_getw32threadhandle_np): New function to
+ return the win32 thread handle that the POSIX
+ thread is using.
+ * mutex.c (pthread_mutexattr_setforcecs_np):
+ Moved to new file "nonportable.c".
+
+ * pthread.h (PTW32_BUILD): Only redefine __except
+ and catch compiler keywords if we aren't building
+ the library (ie. PTW32_BUILD is not defined) -
+ this is safer than defining and then undefining
+ if not building the library.
+ * implement.h: Remove __except and catch undefines.
+ * Makefile (CFLAGS): Define PTW32_BUILD.
+ * GNUmakefile (CFLAGS): Define PTW32_BUILD.
+
+ * All appropriate: Change Pthread_exception* to
+ ptw32_exception* to be consistent with internal
+ identifier naming.
+
+ * private.c (ptw32_throw): New function to provide
+ a generic exception throw for all internal
+ exceptions and EH schemes.
+ (ptw32_threadStart): pthread_exit() value is now
+ returned via the thread structure exitStatus
+ element.
+ * exit.c (pthread_exit): pthread_exit() value is now
+ returned via the thread structure exitStatus
+ element.
+ * cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
+ (pthread_setcancelstate): Ditto.
+ (pthread_setcanceltype): Ditto.
+ (pthread_testcancel): Ditto.
+ (pthread_cancel): Ditto.
+ * misc.c (CancelableWait): Ditto.
+ * exit.c (pthread_exit): Ditto.
+ * All applicable: Change PTW32_ prefix to
+ PTW32_ prefix to remove leading underscores
+ from private library identifiers.
+
+2000-08-17 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * All applicable: Change _pthread_ prefix to
+ ptw32_ prefix to remove leading underscores
+ from private library identifiers (single
+ and double leading underscores are reserved in the
+ ANSI C standard for compiler implementations).
+
+ * tsd.c (pthread_create_key): Initialise temporary
+ key before returning it's address to avoid race
+ conditions.
+
+2000-08-13 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * errno.c: Add _MD precompile condition; thus far
+ had no effect when using /MD compile option but I
+ thnk it should be there.
+
+ * exit.c: Add __cplusplus to various #if lines;
+ was compiling SEH code even when VC++ had
+ C++ compile options.
+
+ * private.c: ditto.
+
+ * create.c (pthread_create): Add PT_STDCALL macro to
+ function pointer arg in _beginthread().
+
+ * pthread.h: PT_STDCALL really does need to be defined
+ in both this and impliment.h; don't set it to __cdecl
+ - this macro is only used to extend function pointer
+ casting for functions that will be passed as parameters.
+ (~PThreadCleanup): add cast and group expression.
+ (_errno): Add _MD compile conditional.
+ (PtW32NoCatchWarn): Change pragma message.
+
+ * implement.h: Move and change PT_STDCALL define.
+
+ * need_errno.h: Add _MD to compilation conditional.
+
+ * GNUmakefile: Substantial rewrite for new naming
+ convention; set for nil optimisation (turn it up
+ when we have a working library build; add target
+ "fake.a" to build a libpthreadw32.a from the VC++
+ built DLL pthreadVCE.dll.
+
+ * pthread.def (LIBRARY): Don't specify in the .def
+ file - it is specified on the linker command line
+ since we now use the same .def file for variously
+ named .dlls.
+
+ * Makefile: Substantial rewrite for new naming
+ convention; default nmake target only issues a
+ help message; run nmake with specific target
+ corresponding to the EH scheme being used.
+
+ * README: Update information; add naming convention
+ explanation.
+
+ * ANNOUNCE: Update information.
+
+2000-08-12 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Add compile-time message when using
+ MSC_VER compiler and C++ EH to warn application
+ programmers to use PtW32Catch instead of catch(...)
+ if they want cancelation and pthread_exit to work.
+
+ * implement.h: Remove #include <semaphore.h>; we
+ use our own local semaphore.h.
+
+2000-08-10 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cleanup.c (pthread_pop_cleanup): Remove _pthread
+ prefix from __except and catch keywords; implement.h
+ now simply undefines ptw32__except and
+ ptw32_catch if defined; VC++ was not textually
+ substituting ptw32_catch etc back to catch as
+ it was redefined; the reason for using the prefixed
+ version was to make it clear that it was not using
+ the pthread.h redefined catch keyword.
+
+ * private.c (ptw32_threadStart): Ditto.
+ (ptw32_callUserDestroyRoutines): Ditto.
+
+ * implement.h (ptw32__except): Remove #define.
+ (ptw32_catch): Remove #define.
+
+ * GNUmakefile (pthread.a): New target to build
+ libpthread32.a from pthread.dll using dlltool.
+
+ * buildlib.bat: Duplicate cl commands with args to
+ build C++ EH version of pthread.dll; use of .bat
+ files is redundant now that nmake compatible
+ Makefile is included; used as a kludge only now.
+
+ * Makefile: Localise some macros and fix up the clean:
+ target to extend it and work properly.
+
+ * CONTRIBUTORS: Add contributors.
+
+ * ANNOUNCE: Updated.
+
+ * README: Updated.
+
+2000-08-06 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Remove #warning - VC++ doesn't accept it.
+
+2000-08-05 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h (PtW32CatchAll): Add macro. When compiling
+ applications using VC++ with C++ EH rather than SEH
+ 'PtW32CatchAll' must be used in place of any 'catch( ... )'
+ if the application wants pthread cancelation or
+ pthread_exit() to work.
+
+2000-08-03 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Add a base class ptw32_exception for
+ library internal exceptions and change the "catch"
+ re-define macro to use it.
+
+2000-08-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * GNUmakefile (CFLAGS): Add -mthreads.
+ Add new targets to generate cpp and asm output.
+
+ * sync.c (pthread_join): Remove dead code.
+
+2000-07-25 Tristan Savatier <tristan at mpegtv.com>
+
+ * sched.c (sched_get_priority_max): Handle different WinCE and
+ Win32 priority values together.
+ (sched_get_priority_min): Ditto.
+
+2000-07-25 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Force new threads to wait until
+ pthread_create has the new thread's handle; we also retain
+ a local copy of the handle for internal use until
+ pthread_create returns.
+
+ * private.c (ptw32_threadStart): Initialise ei[].
+ (ptw32_threadStart): When beginthread is used to start the
+ thread, force waiting until the creator thread had the
+ thread handle.
+
+ * cancel.c (ptw32_cancel_thread): Include context switch
+ code for defined(_X86_) environments in addition to _M_IX86.
+
+ * rwlock.c (pthread_rwlock_destroy): Assignment changed
+ to avoid compiler warning.
+
+ * private.c (ptw32_get_exception_services_code): Cast
+ NULL return value to avoid compiler warning.
+
+ * cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
+ to avoid compiler warnings.
+
+ * misc.c (ptw32_new): Change "new" variable to "t" to avoid
+ confusion with the C++ keyword of the same name.
+
+ * condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
+ (cond_timedwait): Remove unused local variables. to avoid
+ compiler warnings.
+
+ * dll.c (dllMain): Remove 2000-07-21 change - problem
+ appears to be in pthread_create().
+
+2000-07-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): If a destructor was given
+ and the pthread_mutex_init failed, then would try to
+ reference a NULL pointer (*key); eliminate this section of
+ code by using a dynamically initialised mutex
+ (PTHREAD_MUTEX_INITIALIZER).
+
+ * tsd.c (pthread_setspecific): Return an error if
+ unable to set the value; simplify cryptic conditional.
+
+ * tsd.c (pthread_key_delete): Locking threadsLock relied
+ on mutex_lock returning an error if the key has no destructor.
+ ThreadsLock is only initialised if the key has a destructor.
+ Making this mutex a static could reduce the number of mutexes
+ used by an application since it is actually created only at
+ first use and it's often destroyed soon after.
+
+2000-07-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * FAQ: Added Q5 and Q6.
+
+2000-07-21 David Baggett <dmb at itasoftware.com>
+
+ * dll.c: Include resource leakage work-around. This is a
+ partial FIXME which doesn't stop all leakage. The real
+ problem needs to be found and fixed.
+
+2000-07-21 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Set threadH to 0 (zero)
+ everywhere. Some assignments were using NULL. Maybe
+ it should be NULL everywhere - need to check. (I know
+ they are nearly always the same thing - but not by
+ definition.)
+
+ * misc.c (pthread_self): Try to catch NULL thread handles
+ at the point where they might be generated, even though
+ they should always be valid at this point.
+
+ * tsd.c (pthread_setspecific): return an error value if
+ pthread_self() returns NULL.
+
+ * sync.c (pthread_join): return an error value if
+ pthread_self() returns NULL.
+
+ * signal.c (pthread_sigmask): return an error value if
+ pthread_self() returns NULL.
+
+2000-03-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_init): Set default stacksize to zero (0)
+ rather than PTHREAD_STACK_MIN even though these are now the same.
+
+ * pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
+
+2000-01-28 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
+ if critical sections can be used instead of Win32 mutexes, test
+ that the critical section works and return an error if not.
+
+2000-01-07 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
+ compiling as C++.
+ (pthread_push_cleanup): Include SEH code only if MSC is not
+ compiling as C++.
+
+ * pthread.h: Include SEH code only if MSC is not
+ compiling as C++.
+
+ * implement.h: Include SEH code only if MSC is not
+ compiling as C++.
+
+ * cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
+ (pthread_testcancel): Include SEH code only if MSC is not
+ compiling as C++.
+ (ptw32_cancel_self): Include SEH code only if MSC is not
+ compiling as C++.
+
+2000-01-06 Erik Hensema <erik.hensema at group2000.nl>
+
+ * Makefile: Remove inconsistencies in 'cl' args
+
+2000-01-04 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * private.c (ptw32_get_exception_services_code): New; returns
+ value of EXCEPTION_PTW32_SERVICES.
+ (ptw32_processInitialize): Remove initialisation of
+ ptw32_exception_services which is no longer needed.
+
+ * pthread.h (ptw32_exception_services): Remove extern.
+ (ptw32_get_exception_services_code): Add function prototype;
+ use this to return EXCEPTION_PTW32_SERVICES value instead of
+ using the ptw32_exception_services variable which I had
+ trouble exporting through pthread.def.
+
+ * global.c (ptw32_exception_services): Remove declaration.
+
+1999-11-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * implement.h: Forward declare ptw32_new();
+
+ * misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
+ (pthread_self): New thread struct is generated by new routine
+ ptw32_new().
+
+ * create.c (pthread_create): New thread struct is generated
+ by new routine ptw32_new().
+
+1999-11-21 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * global.c (ptw32_exception_services): Declare new variable.
+
+ * private.c (ptw32_threadStart): Destroy thread's
+ cancelLock mutex; make 'catch' and '__except' usageimmune to
+ redfinitions in pthread.h.
+ (ptw32_processInitialize): Init new constant ptw32_exception_services.
+
+ * create.c (pthread_create): Initialise thread's cancelLock
+ mutex.
+
+ * cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
+ usage immune to redfinition s in pthread.h.
+
+ * private.c: Ditto.
+
+ * pthread.h (catch): Redefine 'catch' so that C++ applications
+ won't catch our internal exceptions.
+ (__except): ditto for __except.
+
+ * implement.h (ptw32_catch): Define internal version
+ of 'catch' because 'catch' is redefined by pthread.h.
+ (__except): ditto for __except.
+ (struct pthread_t_): Add cancelLock mutex for async cancel
+ safety.
+
+1999-11-21 Jason Nye <jnye at nbnet.nb.ca>, Erik Hensema <erik.hensema at group2000.nl>
+
+ * cancel.c (ptw32_cancel_self): New; part of the async
+ cancellation implementation.
+ (ptw32_cancel_thread): Ditto; this function is X86
+ processor specific.
+ (pthread_setcancelstate): Add check for pending async
+ cancel request and cancel the calling thread if
+ required; add async-cancel safety lock.
+ (pthread_setcanceltype): Ditto.
+
+1999-11-13 Erik Hensema <erik.hensema at group2000.nl>
+
+ * configure.in (AC_OUTPUT): Put generated output into GNUmakefile
+ rather than Makefile. Makefile will become the MSC nmake compatible
+ version
+
+1999-11-13 John Bossom (John.Bossom@cognos.com>
+
+ * misc.c (pthread_self): Add a note about GetCurrentThread
+ returning a pseudo-handle
+
+1999-11-10 Todd Owen <towen at lucidcalm.dropbear.id.au>
+
+ * dll.c (dllMain): Free kernel32 ASAP.
+ If TryEnterCriticalSection is not being used, then free
+ the kernel32.dll handle now, rather than leaving it until
+ DLL_PROCESS_DETACH.
+
+ Note: this is not a pedantic exercise in freeing unused
+ resources! It is a work-around for a bug in Windows 95
+ (see microsoft knowledge base article, Q187684) which
+ does Bad Things when FreeLibrary is called within
+ the DLL_PROCESS_DETACH code, in certain situations.
+ Since w95 just happens to be a platform which does not
+ provide TryEnterCriticalSection, the bug will be
+ effortlessly avoided.
+
+1999-11-10 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Make it a deferred cancelation point.
+
+ * misc.c (pthread_self): Explicitly initialise implicitly
+ created thread state to default values.
+
+1999-11-05 Tristan Savatier <tristan at mpegtv.com>
+
+ * pthread.h (winsock.h): Include unconditionally.
+ (ETIMEDOUT): Change fallback value to that defined by winsock.h.
+
+ * general: Patched for portability to WinCE. The details are
+ described in the file WinCE-PORT. Follow the instructions
+ in README.WinCE to make the appropriate changes in config.h.
+
+1999-10-30 Erik Hensema <erik.hensema at group2000.nl>
+
+ * create.c (pthread_create): Explicitly initialise thread state to
+ default values.
+
+ * cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
+ for compatibility with Solaris pthreads;
+ (pthread_setcanceltype): ditto:
+
+1999-10-23 Erik Hensema <erik.hensema at group2000.nl>
+
+ * pthread.h (ctime_r): Fix incorrect argument "_tm"
+
+1999-10-21 Aurelio Medina <aureliom at crt.com>
+
+ * pthread.h (_POSIX_THREADS): Only define it if it isn't
+ already defined. Projects may need to define this on
+ the CC command line under Win32 as it doesn't have unistd.h
+
+1999-10-17 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
+ warning.
+
+ * condvar.c (pthread_cond_broadcast): Only release semaphores
+ if there are waiting threads.
+
+1999-10-15 Lorin Hochstein <lmh at xiphos.ca>, Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (cond_wait_cleanup): New static cleanup handler for
+ cond_timedwait;
+ (cond_timedwait): pthread_cleanup_push args changed;
+ canceling a thread while it's in pthread_cond_wait
+ will now decrement the waiters count and cleanup if it's the
+ last waiter.
+
+1999-10-15 Graham Dumpleton <Graham.Dumpleton at ra.pad.otc.telstra.com.au>
+
+ * condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's
+ wasBroadcast flag
+
+Thu Sep 16 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_destroy): Add serialisation.
+ (_rwlock_check_need_init): Check for detroyed rwlock.
+ * rwlock.c: Check return codes from _rwlock_check_need_init();
+ modify comments; serialise access to rwlock objects during
+ operations; rename rw_mutex to rw_lock.
+ * implement.h: Rename rw_mutex to rw_lock.
+ * mutex.c (pthread_mutex_destroy): Add serialisation.
+ (_mutex_check_need_init): Check for detroyed mutex.
+ * condvar.c (pthread_cond_destroy): Add serialisation.
+ (_cond_check_need_init): Check for detroyed condvar.
+ * mutex.c: Modify comments.
+ * condvar.c: Modify comments.
+
+1999-08-10 Aurelio Medina <aureliom at crt.com>
+
+ * implement.h (pthread_rwlock_t_): Add.
+ * pthread.h (pthread_rwlock_t): Add.
+ (PTHREAD_RWLOCK_INITIALIZER): Add.
+ Add rwlock function prototypes.
+ * rwlock.c: New module.
+ * pthread.def: Add new rwlock functions.
+ * private.c (ptw32_processInitialize): initialise
+ ptw32_rwlock_test_init_lock critical section.
+ * global.c (ptw32_rwlock_test_init_lock): Add.
+
+ * mutex.c (pthread_mutex_destroy): Don't free mutex memory
+ if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
+ initialised yet.
+
+1999-08-08 Milan Gardian <mg at tatramed.sk>
+
+ * mutex.c (pthread_mutex_destroy): Free mutex memory.
+
+1999-08-22 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * exit.c (pthread_exit): Fix reference to potentially
+ uninitialised pointer.
+
+1999-08-21 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): Apply fix of 1999-08-19
+ this time to C++ and non-trapped C versions. Ommitted to
+ do this the first time through.
+
+1999-08-19 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): Return exit status from
+ the application thread startup routine.
+ - Milan Gardian <mg at tatramed.sk>
+
+1999-08-18 John Bossom <john.Bossom at cognos.com>
+
+ * exit.c (pthread_exit): Put status into pthread_t->exitStatus
+ * private.c (ptw32_threadStart): Set pthread->exitStatus
+ on exit of try{} block.
+ * sync.c (pthread_join): use pthread_exitStatus value if the
+ thread exit doesn't return a value (for Mingw32 CRTDLL
+ which uses endthread instead of _endthreadex).
+
+Tue Aug 17 20:17:58 CDT 1999 Mumit Khan <khan at xraylith.wisc.edu>
+
+ * create.c (pthread_create): Add CRTDLL suppport.
+ * exit.c (pthread_exit): Likewise.
+ * private.c (ptw32_threadStart): Likewise.
+ (ptw32_threadDestroy): Likewise.
+ * sync.c (pthread_join): Likewise.
+ * tests/join1.c (main): Warn about partial support for CRTDLL.
+
+Tue Aug 17 20:00:08 1999 Mumit Khan <khan at xraylith.wisc.edu>
+
+ * Makefile.in (LD): Delete entry point.
+ * acconfig.h (STDCALL): Delete unused macro.
+ * configure.in: Remove test for STDCALL.
+ * config.h.in: Regenerate.
+ * errno.c (_errno): Fix self type.
+ * pthread.h (PT_STDCALL): Move from here to
+ * implement.h (PT_STDCALL): here.
+ (ptw32_threadStart): Fix prototype.
+ * private.c (ptw32_threadStart): Likewise.
+
+1999-08-14 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * exit.c (pthread_exit): Don't call pthread_self() but
+ get thread handle directly from TSD for efficiency.
+
+1999-08-12 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
+
+ * exit.c (pthread_exit): Check for implicitly created threads
+ to avoid raising an unhandled exception.
+
+1999-07-12 Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (pthread_cond_destroy): Add critical section.
+ (cond_timedwait): Add critical section; check for timeout
+ waiting on semaphore.
+ (pthread_cond_broadcast): Add critical section.
+
+1999-07-09 Lorin Hochstein <lmh at xiphos.ca>, John Bossom <John.Bossom at Cognos.COM>
+
+ The problem was that cleanup handlers were not executed when
+ pthread_exit() was called.
+
+ * implement.h (pthread_t_): Add exceptionInformation element for
+ C++ per-thread exception information.
+ (general): Define and rename exceptions.
+
+1999-07-09 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): PTW32_EPS_CANCEL (SEH) and
+ ptw32_exception_cancel (C++) used to identify the exception.
+
+ * cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
+ ptw32_exception_cancel (C++) used to identify the exception.
+
+ * exit.c (pthread_exit): throw/raise an exception to return to
+ ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
+ and ptw32_exception_exit (C++) used to identify the exception.
+
+ * private.c (ptw32_threadStart): Add pthread_exit exception trap;
+ clean up and exit the thread directly rather than via pthread_exit().
+
+Sun May 30 00:25:02 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.h (mode_t): Conditionally typedef it.
+
+Fri May 28 13:33:05 1999 Mark E. Armstrong <avail at pacbell.net>
+
+ * condvar.c (pthread_cond_broadcast): Fix possible memory fault
+
+Thu May 27 13:08:46 1999 Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (pthread_cond_broadcast): Fix logic bug
+
+Thu May 27 13:08:46 1999 Bossom, John <John.Bossom at Cognos.COM>
+
+ * condvar.c (pthread_cond_broadcast): optimise sem_post loop
+
+Fri May 14 12:13:18 1999 Mike Russo <miker at eai.com>
+
+ * attr.c (pthread_attr_setdetachstate): Fix logic bug
+
+Sat May 8 09:42:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def (sem_open): Add.
+ (sem_close): Add.
+ (sem_unlink): Add.
+ (sem_getvalue): Add.
+
+ * FAQ (Question 3): Add.
+
+Thu Apr 8 01:16:23 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.c (sem_open): New function; returns an error (ENOSYS).
+ (sem_close): ditto.
+ (sem_unlink): ditto.
+ (sem_getvalue): ditto.
+
+ * semaphore.h (_POSIX_SEMAPHORES): define.
+
+Wed Apr 7 14:09:52 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * errno.c (_REENTRANT || _MT): Invert condition.
+
+ * pthread.h (_errno): Conditionally include prototype.
+
+Wed Apr 7 09:37:00 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * *.c (comments): Remove individual attributions - these are
+ documented sufficiently elsewhere.
+
+ * implement.h (pthread.h): Remove extraneous include.
+
+Sun Apr 4 11:05:57 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sched.c (sched.h): Include.
+
+ * sched.h: New file for POSIX 1b scheduling.
+
+ * pthread.h: Move opaque structures to implement.h; move sched_*
+ prototypes out and into sched.h.
+
+ * implement.h: Add opaque structures from pthread.h.
+
+ * sched.c (sched_yield): New function.
+
+ * condvar.c (ptw32_sem_*): Rename to sem_*; except for
+ ptw32_sem_timedwait which is an private function.
+
+Sat Apr 3 23:28:00 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * Makefile.in (OBJS): Add errno.o.
+
+Fri Apr 2 11:08:50 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_sem_*): Remove prototypes now defined in
+ semaphore.h.
+
+ * pthread.h (sempahore.h): Include.
+
+ * semaphore.h: New file for POSIX 1b semaphores.
+
+ * semaphore.c (ptw32_sem_timedwait): Moved to private.c.
+
+ * pthread.h (ptw32_sem_t): Change to sem_t.
+
+ * private.c (ptw32_sem_timedwait): Moved from semaphore.c;
+ set errno on error.
+
+ * pthread.h (pthread_t_): Add per-thread errno element.
+
+Fri Apr 2 11:08:50 1999 John Bossom <jebossom at cognos.com>
+
+ * semaphore.c (ptw32_sem_*): Change to sem_*; these functions
+ will be exported from the library; set errno on error.
+
+ * errno.c (_errno): New file. New function.
+
+Fri Mar 26 14:11:45 1999 Tor Lillqvist <tml at iki.fi>
+
+ * semaphore.c (ptw32_sem_timedwait): Check for negative
+ milliseconds.
+
+Wed Mar 24 11:32:07 1999 John Bossom <jebossom at cognos.com>
+
+ * misc.c (CancelableWait): Initialise exceptionInformation[2].
+ (pthread_self): Get a real Win32 thread handle for implicit threads.
+
+ * cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
+
+ * implement.h (SE_INFORMATION): Fix values.
+
+ * private.c (ptw32_threadDestroy): Close the thread handle.
+
+Fri Mar 19 12:57:27 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cancel.c (comments): Update and cleanup.
+
+Fri Mar 19 09:12:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
+
+ * pthread.h (PTHREAD_CANCELED): defined.
+
+Tue Mar 16 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * all: Add GNU LGPL and Copyright and Warranty.
+
+Mon Mar 15 00:20:13 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): fix possible uninitialised use
+ of cv.
+
+Sun Mar 14 21:01:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_destroy): don't do full cleanup if
+ static initialised cv has never been used.
+ (cond_timedwait): check result of auto-initialisation.
+
+Thu Mar 11 09:01:48 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
+ define a value to serve as PTHREAD_MUTEX_INITIALIZER.
+ (pthread_mutex_t_): remove staticinit and valid elements.
+ (pthread_cond_t): revert to (pthread_cond_t_ *);
+ define a value to serve as PTHREAD_COND_INITIALIZER.
+ (pthread_cond_t_): remove staticinit and valid elements.
+
+ * mutex.c (pthread_mutex_t args): adjust indirection of references.
+ (all functions): check for PTHREAD_MUTEX_INITIALIZER value;
+ check for NULL (invalid).
+
+ * condvar.c (pthread_cond_t args): adjust indirection of references.
+ (all functions): check for PTHREAD_COND_INITIALIZER value;
+ check for NULL (invalid).
+
+Wed Mar 10 17:18:12 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Undo changes from Mar 8 and 7.
+
+Mon Mar 8 11:18:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
+ indexed element in the handles array. Enhance test for abandoned
+ objects.
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
+ initialised are set to zero by the compiler. This avoids the
+ problem of initialising the opaque critical section element in it.
+ (PTHREAD_COND_INITIALIZER): Ditto.
+
+ * semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
+
+Sun Mar 7 12:31:14 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): set semaphore initial value
+ to 0, not 1. cond_timedwait was returning signaled immediately.
+
+ * misc.c (CancelableWait): Place the cancel event handle first
+ in the handle table for WaitForMultipleObjects. This ensures that
+ the cancel event is recognised and acted apon if both objects
+ happen to be signaled together.
+
+ * private.c (ptw32_cond_test_init_lock): Initialise and destroy.
+
+ * implement.h (ptw32_cond_test_init_lock): Add extern.
+
+ * global.c (ptw32_cond_test_init_lock): Add declaration.
+
+ * condvar.c (pthread_cond_destroy): check for valid initialised CV;
+ flag destroyed CVs as invalid.
+ (pthread_cond_init): pthread_cond_t is no longer just a pointer.
+ This is because PTHREAD_COND_INITIALIZER needs state info to reside
+ in pthread_cond_t so that it can initialise on first use. Will work on
+ making pthread_cond_t (and other objects like it) opaque again, if
+ possible, later.
+ (cond_timedwait): add check for statically initialisation of
+ CV; initialise on first use.
+ (pthread_cond_signal): check for valid CV.
+ (pthread_cond_broadcast): check for valid CV.
+ (_cond_check_need_init): Add.
+
+ * pthread.h (PTHREAD_COND_INITIALIZER): Fix.
+ (pthread_cond_t): no longer a pointer to pthread_cond_t_.
+ (pthread_cond_t_): add 'staticinit' and 'valid' elements.
+
+Sat Mar 6 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Undate comments.
+
+Sun Feb 21 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
+ cs element initialiser.
+
+1999-02-21 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (pthread_exit): The return type of this function is
+ void, not int.
+
+ * exit.c (pthread_exit): Do not return 0.
+
+Sat Feb 20 16:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * dll.c (DLLMain): Expand TryEnterCriticalSection support test.
+
+ * mutex.c (pthread_mutex_trylock): The check for
+ ptw32_try_enter_critical_section == NULL should have been
+ removed long ago.
+
+Fri Feb 19 16:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Fix pthread_equal() test.
+
+ * mutex.c (pthread_mutex_trylock): Check mutex != NULL before
+ using it.
+
+Thu Feb 18 16:17:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (pthread_equal): Fix inverted result.
+
+ * Makefile.in: Use libpthread32.a as the name of the DLL export
+ library instead of pthread.lib.
+
+ * condvar.c (pthread_cond_init): cv could have been used unitialised;
+ initialise.
+
+ * create.c (pthread_create): parms could have been used unitialised;
+ initialise.
+
+ * pthread.h (struct pthread_once_t_): Remove redefinition.
+
+Sat Feb 13 03:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (struct pthread_once_t_): Replaced.
+
+ * misc.c (pthread_once): Replace with John Bossom's version;
+ has lighter weight serialisation; fixes problem of not holding
+ competing threads until after the init_routine completes.
+
+Thu Feb 11 13:34:14 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Change C++ exception throw.
+
+ * sync.c (pthread_join): Change FIXME comment - issue resolved.
+
+Wed Feb 10 12:49:11 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * configure: Various temporary changes.
+ - Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
+
+ * README: Update.
+
+ * pthread.def (pthread_attr_getstackaddr): uncomment
+ (pthread_attr_setstackaddr): uncomment
+
+Fri Feb 5 13:42:30 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * semaphore.c: Comment format changes.
+
+Thu Feb 4 10:07:28 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: Remove ptw32_exception instantiation.
+
+ * cancel.c (pthread_testcancel): Change C++ exception throw.
+
+ * implement.h: Remove extern declaration.
+
+Wed Feb 3 13:04:44 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
+
+ * pthread.def: Ditto.
+
+ * pthread.h: Ditto.
+
+ * pthread.def (pthread_cleanup_push): Remove from export list;
+ the function is defined as a macro under all compilers.
+ (pthread_cleanup_pop): Ditto.
+
+ * pthread.h: Remove #if defined().
+
+Wed Feb 3 10:13:48 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Check for NULL value_ptr arg;
+ check for detached threads.
+
+Tue Feb 2 18:07:43 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * implement.h: Add #include <pthread.h>.
+ Change sem_t to ptw32_sem_t.
+
+Tue Feb 2 18:07:43 1999 Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
+
+ * signal.c (pthread_sigmask): Add and modify casts.
+ Reverse LHS/RHS bitwise assignments.
+
+ * pthread.h: Remove #include <semaphore.h>.
+ (PTW32_ATTR_VALID): Add cast.
+ (struct pthread_t_): Add sigmask element.
+
+ * dll.c: Add "extern C" for DLLMain.
+ (DllMain): Add cast.
+
+ * create.c (pthread_create): Set sigmask in thread.
+
+ * condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
+
+ * attr.c: Changed #include.
+
+ * Makefile.in: Additional targets and changes to build the library
+ as a DLL.
+
+Fri Jan 29 11:56:28 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * Makefile.in (OBJS): Add semaphore.o to list.
+
+ * semaphore.c (ptw32_sem_timedwait): Move from private.c.
+ Rename sem_* to ptw32_sem_*.
+
+ * pthread.h (pthread_cond_t): Change type of sem_t.
+ _POSIX_SEMAPHORES no longer defined.
+
+ * semaphore.h: Contents moved to implement.h.
+ Removed from source tree.
+
+ * implement.h: Add semaphore function prototypes and rename all
+ functions to prepend 'ptw32_'. They are
+ now private to the pthreads-win32 implementation.
+
+ * private.c: Change #warning.
+ Move ptw32_sem_timedwait() to semaphore.c.
+
+ * cleanup.c: Change #warning.
+
+ * misc.c: Remove #include <errno.h>
+
+ * pthread.def: Cleanup CVS merge conflicts.
+
+ * global.c: Ditto.
+
+ * ChangeLog: Ditto.
+
+ * cleanup.c: Ditto.
+
+Sun Jan 24 01:34:52 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.c (sem_wait): Remove second arg to
+ pthreadCancelableWait() call.
+
+Sat Jan 23 17:36:40 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def: Add new functions to export list.
+
+ * pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New.
+ (PTHREAD_MUTEX_FORCE_CS_NP): New.
+
+ * README: Updated.
+
+Fri Jan 22 14:31:59 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed
+ with egcs. Add -g for debugging.
+
+ * create.c (pthread_create): Replace __stdcall with PT_STDCALL
+ macro. This is a hack and must be fixed.
+
+ * misc.c (CancelableWait): Remove redundant statement.
+
+ * mutex.c (pthread_mutexattr_init): Cast calloc return value.
+
+ * misc.c (CancelableWait): Add cast.
+ (pthread_self): Add cast.
+
+ * exit.c (pthread_exit): Add cast.
+
+ * condvar.c (pthread_condattr_init): Cast calloc return value.
+
+ * cleanup.c: Reorganise conditional compilation.
+
+ * attr.c (pthread_attr_init): Remove unused 'result'.
+ Cast malloc return value.
+
+ * private.c (ptw32_callUserDestroyRoutines): Redo conditional
+ compilation.
+
+ * misc.c (CancelableWait): C++ version uses 'throw'.
+
+ * cancel.c (pthread_testcancel): Ditto.
+
+ * implement.h (class ptw32_exception): Define for C++.
+
+ * pthread.h: Fix C, C++, and Win32 SEH condition compilation
+ mayhem around pthread_cleanup_* defines. C++ version now uses John
+ Bossom's cleanup handlers.
+ (pthread_attr_t): Make 'valid' unsigned.
+ Define '_timeb' as 'timeb' for Ming32.
+ Define PT_STDCALL as nothing for Mingw32. May be temporary.
+
+ * cancel.c (pthread_testcancel): Cast return value.
+
+Wed Jan 20 09:31:28 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutexattr_t): Changed to a pointer.
+
+ * mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
+ - from John Bossom's implementation.
+ (pthread_mutex_destroy): Conditionally close Win32 mutex
+ - from John Bossom's implementation.
+ (pthread_mutexattr_init): Replaced by John Bossom's version.
+ (pthread_mutexattr_destroy): Ditto.
+ (pthread_mutexattr_getpshared): New function from John Bossom's
+ implementation.
+ (pthread_mutexattr_setpshared): New function from John Bossom's
+ implementation.
+
+Tue Jan 19 18:27:42 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * pthread.h (pthreadCancelableTimedWait): New prototype.
+ (pthreadCancelableWait): Remove second argument.
+
+ * misc.c (CancelableWait): New static function is
+ pthreadCancelableWait() renamed.
+ (pthreadCancelableWait): Now just calls CancelableWait() with
+ INFINITE timeout.
+ (pthreadCancelableTimedWait): Just calls CancelableWait()
+ with passed in timeout.
+
+Tue Jan 19 18:27:42 1999 Scott Lightner <scott at curriculum.com>
+
+ * private.c (ptw32_sem_timedwait): 'abstime' arg really is
+ absolute time. Calculate relative time to wait from current
+ time before passing timeout to new routine
+ pthreadCancelableTimedWait().
+
+Tue Jan 19 10:27:39 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
+
+ * mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
+ attributes to 0.
+ (pthread_mutexattr_setforcecs_np): New function (not portable).
+
+ * pthread.h (pthread_mutex_t):
+ Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
+ The pthread_mutex_*() routines will try to optimise performance
+ by choosing either mutexes or critical sections as the basis
+ for pthread mutexes for each indevidual mutex.
+ (pthread_mutexattr_t_): Add 'forcecs' element.
+ Some applications may choose to force use of critical sections
+ if they know that:-
+ the mutex is PROCESS_PRIVATE and,
+ either the OS supports TryEnterCriticalSection() or
+ pthread_mutex_trylock() will never be called on the mutex.
+ This attribute will be setable via a non-portable routine.
+
+ Note: We don't yet support PROCESS_SHARED mutexes, so the
+ implementation as it stands will default to Win32 mutexes only if
+ the OS doesn't support TryEnterCriticalSection. On Win9x, and early
+ versions of NT 'forcecs' will need to be set in order to get
+ critical section based mutexes.
+
+Sun Jan 17 12:01:26 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
+ value to '1' and existing 'valid' value to '1'.
+
+ * global.c (ptw32_mutex_test_init_lock): Add.
+
+ * implement.h (ptw32_mutex_test_init_lock.): Add extern.
+
+ * private.c (ptw32_processInitialize): Init critical section for
+ global lock used by _mutex_check_need_init().
+ (ptw32_processTerminate): Ditto (:s/Init/Destroy/).
+
+ * dll.c (dllMain): Move call to FreeLibrary() so that it is only
+ called once when the process detaches.
+
+ * mutex.c (_mutex_check_need_init): New static function to test
+ and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
+ access to the internal state of the uninitialised static mutex.
+ Called from pthread_mutex_trylock() and pthread_mutex_lock() which
+ do a quick unguarded test to check if _mutex_check_need_init()
+ needs to be called. This is safe as the test is conservative
+ and is repeated inside the guarded section of
+ _mutex_check_need_init(). Thus in all calls except the first
+ calls to lock static mutexes, the additional overhead to lock any
+ mutex is a single memory fetch and test for zero.
+
+ * pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
+ initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
+ until the first attempt to lock it. Using the 'valid'
+ flag (which flags the mutex as destroyed or not) to record this
+ information would be messy. It is possible for a statically
+ initialised mutex such as this to be destroyed before ever being
+ used.
+
+ * mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
+ to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
+ (pthread_mutex_lock): Ditto.
+ (pthread_mutex_unlock): Add check to ensure we don't try to unlock
+ an unitialised static mutex.
+ (pthread_mutex_destroy): Add check to ensure we don't try to delete
+ a critical section that we never created. Allows us to destroy
+ a static mutex that has never been locked (and hence initialised).
+ (pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
+
+Sun Jan 17 12:01:26 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_sem_timedwait): Move from semaphore.c.
+
+ * semaphore.c : Remove redundant #includes.
+ (ptw32_sem_timedwait): Move to private.c.
+ (sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
+
+Fri Jan 15 23:38:05 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (cond_timedwait): Remove comment.
+
+Fri Jan 15 15:41:28 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
+ prototype.
+
+ * condvar.c (cond_timedwait): New generalised function called by
+ both pthread_cond_wait() and pthread_cond_timedwait(). This is
+ essentially pthread_cond_wait() renamed and modified to add the
+ 'abstime' arg and call the new ptw32_sem_timedwait() instead of
+ sem_wait().
+ (pthread_cond_wait): Now just calls the internal static
+ function cond_timedwait() with an INFINITE wait.
+ (pthread_cond_timedwait): Now implemented. Calls the internal
+ static function cond_timedwait().
+
+ * implement.h (ptw32_sem_timedwait): New internal function
+ prototype.
+
+ * misc.c (pthreadCancelableWait): Added new 'abstime' argument
+ to allow shorter than INFINITE wait.
+
+ * semaphore.c (ptw32_sem_timedwait): New function for internal
+ use. This is essentially sem_wait() modified to add the
+ 'abstime' arg and call the modified (see above)
+ pthreadCancelableWait().
+
+Thu Jan 14 14:27:13 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c: Correct _cplusplus to __cplusplus wherever used.
+
+ * Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
+ The derived Makefile will compile all units of the package as C++
+ so that those which include try/catch exception handling should work
+ properly. The package should compile ok if CC=gcc, however, exception
+ handling will not be included and thus thread cancellation, for
+ example, will not work.
+
+ * cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
+ file as C++ if using a cygwin32 environment. Perhaps the whole package
+ should be compiled using g++ under cygwin.
+
+ * private.c (ptw32_threadStart): Change #error directive
+ into #warning and bracket for __CYGWIN__ and derivative compilers.
+
+Wed Jan 13 09:34:52 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * build.bat: Delete old binaries before compiling/linking.
+
+Tue Jan 12 09:58:38 1999 Tor Lillqvist <tml at iki.fi>
+
+ * dll.c: The Microsoft compiler pragmas probably are more
+ appropriately protected by _MSC_VER than by _WIN32.
+
+ * pthread.h: Define ETIMEDOUT. This should be returned by
+ pthread_cond_timedwait which is not implemented yet as of
+ snapshot-1999-01-04-1305. It was implemented in the older version.
+ The Microsoft compiler pragmas probably are more appropriately
+ protected by _MSC_VER than by _WIN32.
+
+ * pthread.def: pthread_mutex_destroy was missing from the def file
+
+ * condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
+ if there were any waiting on the condition.
+ I think pthread_cond_broadcast should do the WaitForSingleObject
+ only if cv->waiters > 0? Otherwise it seems to hang, at least in the
+ testg thread program from glib.
+
+Tue Jan 12 09:58:38 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_timedwait): Fix function description
+ comments.
+
+ * semaphore.c (sem_post): Correct typo in comment.
+
+Mon Jan 11 20:33:19 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h: Re-arrange conditional compile of pthread_cleanup-*
+ macros.
+
+ * cleanup.c (ptw32_push_cleanup): Provide conditional
+ compile of cleanup->prev.
+
+1999-01-11 Tor Lillqvist <tml at iki.fi>
+
+ * condvar.c (pthread_cond_init): Invert logic when testing the
+ return value from calloc().
+
+Sat Jan 9 14:32:08 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Compile-time switch for CYGWIN derived environments
+ to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
+ Patch provided by Anders Norlander <anorland at hem2.passagen.se>.
+
+Tue Jan 5 16:33:04 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
+ block. Move trailing "}" out of #ifdef _WIN32 block left there by
+ (rpj's) mistake.
+
+ * private.c: Remove #include <errno.h> which is included by pthread.h.
+
+1998-12-11 Ben Elliston <bje at toilet.to.cygnus.com>
+
+ * README: Update info about subscribing to the mailing list.
+
+Mon Jan 4 11:23:40 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * all: No code changes, just cleanup.
+ - remove #if 0 /* Pre Bossom */ enclosed code.
+ - Remove some redundant #includes.
+ * pthread.h: Update implemented/unimplemented routines list.
+ * Tag the bossom merge branch getting ready to merge back to main
+ trunk.
+
+Tue Dec 29 13:11:16 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Move the following struct definitions to pthread.h:
+ pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
+ pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
+ pthread_condattr_t_, pthread_once_t_.
+
+ * pthread.h: Add "_" prefix to pthread_push_cleanup and
+ pthread_pop_cleanup internal routines, and associated struct and
+ typedefs.
+
+ * buildlib.bat: Add compile command for semaphore.c
+
+ * pthread.def: Comment out pthread_atfork routine name.
+ Now unimplemented.
+
+ * tsd.c (pthread_setspecific): Rename tkAssocCreate to
+ ptw32_tkAssocCreate.
+ (pthread_key_delete): Rename tkAssocDestroy to
+ ptw32_tkAssocDestroy.
+
+ * sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
+
+ * sched.c (is_attr): attr is now **attr (was *attr), so add extra
+ NULL pointer test.
+ (pthread_attr_setschedparam): Increase redirection for attr which is
+ now a **.
+ (pthread_attr_getschedparam): Ditto.
+ (pthread_setschedparam): Change thread validation and rename "thread"
+ Win32 thread Handle element name to match John Bossom's version.
+ (pthread_getschedparam): Ditto.
+
+ * private.c (ptw32_threadDestroy): Rename call to
+ callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
+
+ * misc.c: Add #include "implement.h".
+
+ * dll.c: Remove defined(KLUDGE) wrapped code.
+
+ * fork.c: Remove redefinition of ENOMEM.
+ Remove pthread_atfork() and fork() with #if 0/#endif.
+
+ * create.c (pthread_create): Rename threadStart and threadDestroy calls
+ to ptw32_threadStart and ptw32_threadDestroy.
+
+ * implement.h: Rename "detachedstate" to "detachstate".
+
+ * attr.c: Rename "detachedstate" to "detachstate".
+
+Mon Dec 28 09:54:39 1998 John Bossom
+
+ * semaphore.c: Initial version.
+ * semaphore.h: Initial version.
+
+Mon Dec 28 09:54:39 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
+
+Mon Dec 28 09:54:39 1998 John Bossom, Ben Elliston
+
+ * attr.c (pthread_attr_setstacksize): Merge with John's version.
+ (pthread_attr_getstacksize): Merge with John's version.
+ (pthread_attr_setstackaddr): Merge with John's version.
+ (pthread_attr_getstackaddr): Merge with John's version.
+ (pthread_attr_init): Merge with John's version.
+ (pthread_attr_destroy): Merge with John's version.
+ (pthread_attr_getdetachstate): Merge with John's version.
+ (pthread_attr_setdetachstate): Merge with John's version.
+ (is_attr): attr is now **attr (was *attr), so add extra NULL pointer
+ test.
+
+Mon Dec 28 09:54:39 1998 Ross Johnson
+
+ * implement.h (pthread_attr_t_): Add and rename elements in JEB's
+ version to correspond to original, so that it can be used with
+ original attr routines.
+
+ * pthread.h: Add #endif at end which was truncated in merging.
+
+Sun Dec 20 14:51:58 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
+ but provides a hook that can be used to implement cancellation points in
+ applications that use this library.
+
+ * pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
+ try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
+ In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
+ cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
+ should cause the cleanup to run irrespective of the execute arg.
+
+ * condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
+ (pthread_condattr_destroy): Replaced by John Bossom's version.
+ (pthread_condattr_getpshared): Replaced by John Bossom's version.
+ (pthread_condattr_setpshared): Replaced by John Bossom's version.
+ (pthread_cond_init): Replaced by John Bossom's version.
+ Fix comment (refered to mutex rather than condition variable).
+ (pthread_cond_destroy): Replaced by John Bossom's version.
+ (pthread_cond_wait): Replaced by John Bossom's version.
+ (pthread_cond_timedwait): Replaced by John Bossom's version.
+ (pthread_cond_signal): Replaced by John Bossom's version.
+ (pthread_cond_broadcast): Replaced by John Bossom's version.
+
+Thu Dec 17 19:10:46 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): Replaced by John Bossom's version.
+ (pthread_key_delete): Replaced by John Bossom's version.
+ (pthread_setspecific): Replaced by John Bossom's version.
+ (pthread_getspecific): Replaced by John Bossom's version.
+
+Mon Dec 7 09:44:40 1998 John Bossom
+
+ * cancel.c (pthread_setcancelstate): Replaced.
+ (pthread_setcanceltype): Replaced.
+ (pthread_testcancel): Replaced.
+ (pthread_cancel): Replaced.
+
+ * exit.c (pthread_exit): Replaced.
+
+ * misc.c (pthread_self): Replaced.
+ (pthread_equal): Replaced.
+
+ * sync.c (pthread_detach): Replaced.
+ (pthread_join): Replaced.
+
+ * create.c (pthread_create): Replaced.
+
+ * private.c (ptw32_processInitialize): New.
+ (ptw32_processTerminate): New.
+ (ptw32_threadStart): New.
+ (ptw32_threadDestroy): New.
+ (ptw32_cleanupStack): New.
+ (ptw32_tkAssocCreate): New.
+ (ptw32_tkAssocDestroy): New.
+ (ptw32_callUserDestroyRoutines): New.
+
+ * implement.h: Added non-API structures and declarations.
+
+ * dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
+ to resolve compile warning from MSVC.
+
+ * dll.c (DLLmain): Replaced.
+ * dll.c (PthreadsEntryPoint):
+ Re-applied Anders Norlander's patch:-
+ Initialize ptw32_try_enter_critical_section at startup
+ and release kernel32 handle when DLL is being unloaded.
+
+Sun Dec 6 21:54:35 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * buildlib.bat: Fix args to CL when building the .DLL
+
+ * cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
+ This is a tidy-up before TSD and Thread management is completely
+ replaced by John Bossom's code.
+
+ * tsd.c (pthread_key_create): Fix TSD key management.
+
+ * global.c (ptw32_key_virgin_next): Initialise.
+
+ * build.bat: New DOS script to compile and link a pthreads app
+ using Microsoft's CL compiler linker.
+ * buildlib.bat: New DOS script to compile all the object files
+ and create pthread.lib and pthread.dll using Microsoft's CL
+ compiler linker.
+
+1998-12-05 Anders Norlander <anorland at hem2.passagen.se>
+
+ * implement.h (ptw32_try_enter_critical_section): New extern
+ * dll.c (ptw32_try_enter_critical_section): New pointer to
+ TryEnterCriticalSection if it exists; otherwise NULL.
+ * dll.c (PthreadsEntryPoint):
+ Initialize ptw32_try_enter_critical_section at startup
+ and release kernel32 handle when DLL is being unloaded.
+ * mutex.c (pthread_mutex_trylock): Replaced check for NT with
+ a check if ptw32_try_enter_critical_section is valid
+ pointer to a function. Call ptw32_try_enter_critical_section
+ instead of TryEnterCriticalSection to avoid errors on Win95.
+
+Thu Dec 3 13:32:00 1998 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * README: Correct cygwin32 compatibility statement.
+
+Sun Nov 15 21:24:06 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
+ Fixup CVS merge conflicts.
+
+1998-10-30 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (cond_wait): Fix semantic error. Test for equality
+ instead of making an assignment.
+
+Fri Oct 30 15:15:50 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_handler_push): Fixed bug appending new
+ handler to list reported by Peter Slacik
+ <Peter.Slacik at leibinger.freinet.de>.
+ (new_thread): Rename poorly named local variable to
+ "new_handler".
+
+Sat Oct 24 18:34:59 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: Add TSD key management array and index declarations.
+
+ * implement.h: Ditto for externs.
+
+Fri Oct 23 00:08:09 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (PTW32_TSD_KEY_REUSE): Add enum.
+
+ * private.c (ptw32_delete_thread): Add call to
+ ptw32_destructor_run_all() to clean up the threads keys.
+
+ * cleanup.c (ptw32_destructor_run_all): Check for no more dirty
+ keys to run destructors on. Assume that the destructor call always
+ succeeds and set the key value to NULL.
+
+Thu Oct 22 21:44:44 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_setspecific): Add key management code.
+ (pthread_key_create): Ditto.
+ (pthread_key_delete): Ditto.
+
+ * implement.h (struct ptw32_tsd_key): Add status member.
+
+ * tsd.c: Add description of pthread_key_delete() from the
+ standard as a comment.
+
+Fri Oct 16 17:38:47 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_run_all): Fix and improve
+ stepping through the key table.
+
+Thu Oct 15 14:05:01 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * private.c (ptw32_new_thread): Remove init of destructorstack.
+ No longer an element of pthread_t.
+
+ * tsd.c (pthread_setspecific): Fix type declaration and cast.
+ (pthread_getspecific): Ditto.
+ (pthread_getspecific): Change error return value to NULL if key
+ is not in use.
+
+Thu Oct 15 11:53:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c (ptw32_tsd_key_table): Fix declaration.
+
+ * implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
+ (ptw32_tsd_mutex): Ditto.
+
+ * create.c (ptw32_start_call): Fix "keys" array declaration.
+ Add comment.
+
+ * tsd.c (pthread_setspecific): Fix type declaration and cast.
+ (pthread_getspecific): Ditto.
+
+ * cleanup.c (ptw32_destructor_run_all): Declare missing loop
+ counter.
+
+Wed Oct 14 21:09:24 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_new_thread): Increment ptw32_threads_count.
+ (ptw32_delete_thread): Decrement ptw32_threads_count.
+ Remove some comments.
+
+ * exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+ (ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
+
+ * create.c (pthread_create): Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+
+ * global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
+
+ * tsd.c (pthread_key_create): Add critical section.
+ (pthread_setspecific): Ditto.
+ (pthread_getspecific): Ditto.
+ (pthread_key_delete): Ditto.
+
+ * sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+
+Mon Oct 12 00:00:44 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_tsd_key_table): New.
+
+ * create.c (ptw32_start_call): Initialise per-thread TSD keys
+ to NULL.
+
+ * misc.c (pthread_once): Correct typo in comment.
+
+ * implement.h (ptw32_destructor_push): Remove.
+ (ptw32_destructor_pop): Remove.
+ (ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
+ (PTW32_TSD_KEY_DELETED): Add enum.
+ (PTW32_TSD_KEY_INUSE): Add enum.
+
+ * cleanup.c (ptw32_destructor_push): Remove.
+ (ptw32_destructor_pop): Remove.
+ (ptw32_destructor_run_all): Totally revamped TSD.
+
+ * dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
+
+ * tsd.c (pthread_setspecific): Totally revamped TSD.
+ (pthread_getspecific): Ditto.
+ (pthread_create): Ditto.
+ (pthread_delete): Ditto.
+
+Sun Oct 11 22:44:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c (ptw32_tsd_key_table): Add new global.
+
+ * implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
+ Add.
+ (struct _pthread): Remove destructorstack.
+
+ * cleanup.c (ptw32_destructor_run_all): Rename from
+ ptw32_destructor_pop_all. The key destructor stack was made
+ global rather than per-thread. No longer removes destructor nodes
+ from the stack. Comments updated.
+
+1998-10-06 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_signal): Likewise.
+
+1998-10-05 Ben Elliston <bje at cygnus.com>
+
+ * pthread.def: Update. Some functions aren't available yet, others
+ are macros in <pthread.h>.
+
+ * tests/join.c: Remove; useless.
+
+Mon Oct 5 14:25:08 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def: New file for building the DLL.
+
+1998-10-05 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_equal): Correct inverted logic bug.
+ (pthread_once): Use the POSIX mutex primitives, not Win32. Remove
+ irrelevant FIXME comment.
+
+ * global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
+ (pthread_mutex_t): Reimplement as a struct containing a valid
+ flag. If the flag is ever down upon entry to a mutex operation,
+ we call pthread_mutex_create() to initialise the object. This
+ fixes the problem of how to handle statically initialised objects
+ that can't call InitializeCriticalSection() due to their context.
+ (PTHREAD_ONCE_INIT): Define.
+
+ * mutex.c (pthread_mutex_init): Set valid flag.
+ (pthread_mutex_destroy): Clear valid flag.
+ (pthread_mutex_lock): Check and handle the valid flag.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+
+ * tests/mutex3.c: New file; test for the static initialisation
+ macro. Passes.
+
+ * tests/create1.c: New file; test pthread_create(). Passes.
+
+ * tests/equal.c: Poor test; remove.
+
+ * tests/equal1.c New file; test pthread_equal(). Passes.
+
+ * tests/once1.c: New file; test for pthread_once(). Passes.
+
+ * tests/self.c: Remove; rename to self1.c.
+
+ * tests/self1.c: This is the old self.c.
+
+ * tests/self2.c: New file. Test pthread_self() with a single
+ thread. Passes.
+
+ * tests/self3.c: New file. Test pthread_self() with a couple of
+ threads to ensure their thread IDs differ. Passes.
+
+1998-10-04 Ben Elliston <bje at cygnus.com>
+
+ * tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
+
+ * tests/mutex1.c: New basic test for mutex functions (it passes).
+ (main): Eliminate warning.
+
+ * configure.in: Test for __stdcall, not _stdcall. Typo.
+
+ * configure: Regenerate.
+
+ * attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
+ does know about ENOSYS after all.
+ (pthread_attr_setstackaddr): Likewise.
+
+1998-10-03 Ben Elliston <bje at cygnus.com>
+
+ * configure.in: Test for the `_stdcall' keyword. Define `STDCALL'
+ to `_stdcall' if we have it, null otherwise.
+
+ * configure: Regenerate.
+
+ * acconfig.h (STDCALL): New define.
+
+ * config.h.in: Regenerate.
+
+ * create.c (ptw32_start_call): Add STDCALL prefix.
+
+ * mutex.c (pthread_mutex_init): Correct function signature.
+
+ * attr.c (pthread_attr_init): Only zero out the `sigmask' member
+ if we have the sigset_t type.
+
+ * pthread.h: No need to include <unistd.h>. It doesn't even exist
+ on Win32! Again, an artifact of cross-compilation.
+ (pthread_sigmask): Only provide if we have the sigset_t type.
+
+ * process.h: Remove. This was a stand-in before we started doing
+ native compilation under Win32.
+
+ * pthread.h (pthread_mutex_init): Make `attr' argument const.
+
+1998-10-02 Ben Elliston <bje at cygnus.com>
+
+ * COPYING: Remove.
+
+ * COPYING.LIB: Add. This library is under the LGPL.
+
+1998-09-13 Ben Elliston <bje at cygnus.com>
+
+ * configure.in: Test for required system features.
+
+ * configure: Generate.
+
+ * acconfig.h: New file.
+
+ * config.h.in: Generate.
+
+ * Makefile.in: Renamed from Makefile.
+
+ * COPYING: Import from a recent GNU package.
+
+ * config.guess: Likewise.
+
+ * config.sub: Likewise.
+
+ * install-sh: Likewise.
+
+ * config.h: Remove.
+
+ * Makefile: Likewise.
+
+1998-09-12 Ben Elliston <bje at cygnus.com>
+
+ * windows.h: No longer needed; remove.
+
+ * windows.c: Likewise.
+
+Sat Sep 12 20:09:24 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * windows.h: Remove error number definitions. These are in <errno.h>
+
+ * tsd.c: Add comment explaining rationale for not building
+ POSIX TSD on top of Win32 TLS.
+
+1998-09-12 Ben Elliston <bje at cygnus.com>
+
+ * {most}.c: Include <errno.h> to get POSIX error values.
+
+ * signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
+ defined.
+
+ * config.h: #undef features, don't #define them. This will be
+ generated by autoconf very soon.
+
+1998-08-11 Ben Elliston <bje at cygnus.com>
+
+ * Makefile (LIB): Define.
+ (clean): Define target.
+ (all): Build a library not just the object files.
+
+ * pthread.h: Provide a definition for struct timespec if we don't
+ already have one.
+
+ * windows.c (TlsGetValue): Bug fix.
+
+Thu Aug 6 15:19:22 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
+ and LeaveCriticalSection() calls to pass address-of lock.
+
+ * fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
+ in each ptw32_handler_push() call.
+
+ * exit.c (ptw32_exit): Fix attr arg in
+ pthread_attr_getdetachstate() call.
+
+ * private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
+ (ptw32_delete_thread): Ditto.
+
+ * implement.h: (PTW32_MAX_THREADS): Add define. This keeps
+ changing in an attempt to make thread administration data types
+ opaque and cleanup DLL startup.
+
+ * dll.c (PthreadsEntryPoint):
+ (ptw32_virgins): Remove malloc() and free() calls.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * global.c (_POSIX_THREAD_THREADS_MAX): Initialise with
+ PTW32_MAX_THREADS.
+ (ptw32_virgins): Ditto.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * create.c (pthread_create): Typecast (HANDLE) NULL.
+ Typecast (unsigned (*)(void *)) start_routine.
+
+ * condvar.c (pthread_cond_init): Add address-of operator & to
+ arg 1 of pthread_mutex_init() call.
+ (pthread_cond_destroy): Add address-of operator & to
+ arg 1 of pthread_mutex_destroy() call.
+
+ * cleanup.c (ptw32_destructor_pop_all): Add (int) cast to
+ pthread_getspecific() arg.
+ (ptw32_destructor_pop): Add (void *) cast to "if" conditional.
+ (ptw32_destructor_push): Add (void *) cast to
+ ptw32_handler_push() "key" arg.
+ (malloc.h): Add include.
+
+ * implement.h (ptw32_destructor_pop): Add prototype.
+
+ * tsd.c (implement.h): Add include.
+
+ * sync.c (pthread_join): Remove target_thread_mutex and it's
+ initialisation. Rename getdetachedstate to getdetachstate.
+ Remove unused variable "exitcode".
+ (pthread_detach): Remove target_thread_mutex and it's
+ initialisation. Rename getdetachedstate to getdetachstate.
+ Rename setdetachedstate to setdetachstate.
+
+ * signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
+ Cast "set" to (long *) in assignment to passify compiler warning.
+ Add address-of operator & to thread->attr.sigmask in memcpy() call
+ and assignment.
+ (pthread_sigmask): Add address-of operator & to thread->attr.sigmask
+ in memcpy() call and assignment.
+
+ * windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
+ (THREAD_PRIORITY_LOWEST): Add.
+ (THREAD_PRIORITY_HIGHEST): Add.
+
+ * sched.c (is_attr): Add function.
+ (implement.h): Add include.
+ (pthread_setschedparam): Rename all instances of "sched_policy"
+ to "sched_priority".
+ (pthread_getschedparam): Ditto.
+
+Tue Aug 4 16:57:58 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
+
+ * global.c (ptw32_virgins): Change types from pointer to
+ array pointer.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * implement.h(ptw32_virgins): Change types from pointer to
+ array pointer.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * private.c (ptw32_delete_thread): Fix "entry" should be "thread".
+
+ * misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
+
+ * global.c: Add comment.
+
+ * misc.c (pthread_once): Fix member -> dereferences.
+ Change ptw32_once_flag to once_control->flag in "if" test.
+
+Tue Aug 4 00:09:30 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h(ptw32_virgins): Add extern.
+ (ptw32_virgin_next): Ditto.
+ (ptw32_reuse): Ditto.
+ (ptw32_reuse_top): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * global.c (ptw32_virgins): Changed from array to pointer.
+ Storage allocation for the array moved into dll.c.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * dll.c (PthreadsEntryPoint): Set up thread admin storage when
+ DLL is loaded.
+
+ * fork.c (pthread_atfork): Fix function pointer arg to all
+ ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
+
+ * exit.c: Add windows.h and process.h includes.
+ (ptw32_exit): Add local detachstate declaration.
+ (ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
+
+ * pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
+ (_POSIX_THREAD_ATTR_STACKADDR): Ditto.
+
+ * create.c (pthread_create): Fix #if should be #ifdef.
+ (ptw32_start_call): Remove usused variables.
+
+ * process.h: Create.
+
+ * windows.h: Move _beginthreadex and _endthreadex into
+ process.h
+
+Mon Aug 3 21:19:57 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): Add NULL attr to
+ pthread_mutex_init() call - default attributes will be used.
+ (cond_wait): Fix typo.
+ (cond_wait): Fix typo - cv was ev.
+ (pthread_cond_broadcast): Fix two identical typos.
+
+ * cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
+ PTHREAD_DESTRUCTOR_ITERATIONS.
+
+ * pthread.h: Move _POSIX_* values into posix.h
+
+ * pthread.h: Fix typo in pthread_mutex_init() prototype.
+
+ * attr.c (pthread_attr_init): Fix error in priority member init.
+
+ * windows.h (THREAD_PRIORITY_NORMAL): Add.
+
+ * pthread.h (sched_param): Add missing ';' to struct definition.
+
+ * attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
+ member initialisation - cancelstate, canceltype, cancel_pending.
+ (is_attr): Make arg "attr" a const.
+
+ * implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
+ (PTW32_HANDLER_POP_FIFO): Ditto.
+ (PTW32_VALID): Add missing newline escape (\).
+ (ptw32_handler_node): Make element "next" a pointer.
+
+1998-08-02 Ben Elliston <bje at cygnus.com>
+
+ * windows.h: Remove duplicate TlsSetValue() prototype. Add
+ TlsGetValue() prototype.
+ (FALSE): Define.
+ (TRUE): Likewise.
+ Add forgotten errno values. Guard against multiple #includes.
+
+ * windows.c: New file. Implement stubs for Win32 functions.
+
+ * Makefile (SRCS): Remove. Not explicitly needed.
+ (CFLAGS): Add -Wall for all warnings with GCC.
+
+Sun Aug 2 19:03:42 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * config.h: Create. This is a temporary stand-in for autoconf yet
+ to be done.
+ (HAVE_SIGNAL_H): Add.
+
+ * pthread.h: Minor rearrangement for temporary config.h.
+
+Fri Jul 31 14:00:29 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_pop): Implement. Removes
+ destructors associated with a key without executing them.
+ (ptw32_destructor_pop_all): Add FIXME comment.
+
+ * tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
+
+Fri Jul 31 00:05:45 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): Update to properly associate
+ the destructor routine with the key.
+ (pthread_key_delete): Add FIXME comment.
+
+ * exit.c (ptw32_vacuum): Add call to
+ ptw32_destructor_pop_all().
+
+ * implement.h (ptw32_handler_pop_all): Add prototype.
+ (ptw32_destructor_pop_all): Ditto.
+
+ * cleanup.c (ptw32_destructor_push): Implement. This is just a
+ call to ptw32_handler_push().
+ (ptw32_destructor_pop_all): Implement. This is significantly
+ different to ptw32_handler_pop_all().
+
+ * Makefile (SRCS): Create. Preliminary.
+
+ * windows.h: Create. Contains Win32 definitions for compile
+ testing. This is just a standin for the real one.
+
+ * pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
+ (windows.h): Add include. Required for CRITICAL_SECTION.
+ (pthread_cond_t): Move enum declaration outside of struct
+ definition.
+ (unistd.h): Add include - may be temporary.
+
+ * condvar.c (windows.h): Add include.
+
+ * implement.h (PTW32_THIS): Remove - no longer required.
+ (PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
+
+Thu Jul 30 23:12:45 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Remove ptw32_find_entry() prototype.
+
+ * private.c: Extend comments.
+ Remove ptw32_find_entry() - no longer needed.
+
+ * create.c (ptw32_start_call): Add call to TlsSetValue() to
+ store the thread ID.
+
+ * dll.c (PthreadsEntryPoint): Implement. This is called
+ whenever a process loads the DLL. Used to initialise thread
+ local storage.
+
+ * implement.h: Add ptw32_threadID_TlsIndex.
+ Add ()s around PTW32_VALID expression.
+
+ * misc.c (pthread_self): Re-implement using Win32 TLS to store
+ the threads own ID.
+
+Wed Jul 29 11:39:03 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c: Corrections in comments.
+ (ptw32_new_thread): Alter "if" flow to be more natural.
+
+ * cleanup.c (ptw32_handler_push): Same as below.
+
+ * create.c (pthread_create): Same as below.
+
+ * private.c (ptw32_new_thread): Rename "new" to "new_thread".
+ Since when has a C programmer been required to know C++?
+
+Tue Jul 28 14:04:29 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * implement.h: Add PTW32_VALID macro.
+
+ * sync.c (pthread_join): Modify to use the new thread
+ type and ptw32_delete_thread(). Rename "target" to "thread".
+ Remove extra local variable "target".
+ (pthread_detach): Ditto.
+
+ * signal.c (pthread_sigmask): Move init of "us" out of inner block.
+ Fix instance of "this" should have been "us". Rename "us" to "thread".
+
+ * sched.c (pthread_setschedparam): Modify to use the new thread
+ type.
+ (pthread_getschedparam): Ditto.
+
+ * private.c (ptw32_find_thread): Fix return type and arg.
+
+ * implement.h: Remove PTW32_YES and PTW32_NO.
+ (ptw32_new_thread): Add prototype.
+ (ptw32_find_thread): Ditto.
+ (ptw32_delete_thread): Ditto.
+ (ptw32_new_thread_entry): Remove prototype.
+ (ptw32_find_thread_entry): Ditto.
+ (ptw32_delete_thread_entry): Ditto.
+ ( PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
+ Add.
+
+
+ * create.c (pthread_create): Minor rename "us" to "new" (I need
+ these cues but it doesn't stop me coming out with some major bugs
+ at times).
+ Load start_routine and arg into the thread so the wrapper can
+ call it.
+
+ * exit.c (pthread_exit): Fix pthread_this should be pthread_self.
+
+ * cancel.c (pthread_setcancelstate): Change
+ ptw32_threads_thread_t * to pthread_t and init with
+ pthread_this().
+ (pthread_setcanceltype): Ditto.
+
+ * exit.c (ptw32_exit): Add new pthread_t arg.
+ Rename ptw32_delete_thread_entry to ptw32_delete_thread.
+ Rename "us" to "thread".
+ (pthread_exit): Call ptw32_exit with added thread arg.
+
+ * create.c (ptw32_start_call): Insert missing ")".
+ Add "us" arg to ptw32_exit() call.
+ (pthread_create): Modify to use new thread allocation scheme.
+
+ * private.c: Added detailed explanation of the new thread
+ allocation scheme.
+ (ptw32_new_thread): Totally rewritten to use
+ new thread allocation scheme.
+ (ptw32_delete_thread): Ditto.
+ (ptw32_find_thread): Obsolete.
+
+Mon Jul 27 17:46:37 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * create.c (pthread_create): Start of rewrite. Not completed yet.
+
+ * private.c (ptw32_new_thread_entry): Start of rewrite. Not
+ complete.
+
+ * implement.h (ptw32_threads_thread): Rename, remove thread
+ member, add win32handle and ptstatus members.
+ (ptw32_t): Add.
+
+ * pthread.h: pthread_t is no longer mapped directly to a Win32
+ HANDLE type. This is so we can let the Win32 thread terminate and
+ reuse the HANDLE while pthreads holds it's own thread ID until
+ the last waiting join exits.
+
+Mon Jul 27 00:20:37 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_delete_thread_entry): Destroy the thread
+ entry attribute object before deleting the thread entry itself.
+
+ * attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
+ (pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
+ (pthread_attr_getdetachstate): Ditto.
+
+ * exit.c (ptw32_exit): Fix incorrect check for detachedstate.
+
+ * implement.h (ptw32_call_t): Remove env member.
+
+Sun Jul 26 13:06:12 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_new_thread_entry): Fix prototype.
+ (ptw32_find_thread_entry): Ditto.
+ (ptw32_delete_thread_entry): Ditto.
+ (ptw32_exit): Add prototype.
+
+ * exit.c (ptw32_exit): New function. Called from pthread_exit()
+ and ptw32_start_call() to exit the thread. It allows an extra
+ argument which is the return code passed to _endthreadex().
+ (ptw32_exit): Move thread entry delete call from ptw32_vacuum()
+ into here. Add more explanation of thread entry deletion.
+ (ptw32_exit): Clarify comment.
+
+ * create.c (ptw32_start_call): Change pthread_exit() call to
+ ptw32_exit() call.
+
+ * exit.c (ptw32_vacuum): Add thread entry deletion code
+ moved from ptw32_start_call(). See next item.
+ (pthread_exit): Remove longjmp(). Add mutex lock around thread table
+ manipulation code. This routine now calls _enthreadex().
+
+ * create.c (ptw32_start_call): Remove setjmp() call and move
+ cleanup code out. Call pthread_exit(NULL) to terminate the thread.
+
+1998-07-26 Ben Elliston <bje at cygnus.com>
+
+ * tsd.c (pthread_getspecific): Update comments.
+
+ * mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
+ (pthread_mutexattr_getpshared): Likewise.
+
+ * pthread.h (pthread_mutexattr_setpshared): Remove prototype.
+ (pthread_mutexattr_getpshared): Likewise.
+
+Sun Jul 26 00:09:59 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c: Rename all instances of ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * implement.h: Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * global.c: Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * create.c (pthread_create): Add critical sections.
+ (ptw32_start_call): Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * cancel.c (pthread_setcancelstate): Fix indirection bug and rename
+ "this" to "us".
+
+ * signal.c (pthread_sigmask): Rename "this" to "us" and fix some
+ minor syntax errors. Declare "us" and initialise it.
+
+ * sync.c (pthread_detach): Rename "this" to "target".
+
+ * pthread.h: Converting PTHREAD_* defines to alias the (const int)
+ values in global.c.
+
+ * global.c: Started converting PTHREAD_* defines to (const int) as
+ a part of making the eventual pthreads DLL binary compatible
+ through version changes.
+
+ * condvar.c (cond_wait): Add cancelation point. This applies the
+ point to both pthread_cond_wait() and pthread_cond_timedwait().
+
+ * exit.c (pthread_exit): Rename "this" to "us".
+
+ * implement.h: Add comment.
+
+ * sync.c (pthread_join): I've satisfied myself that pthread_detach()
+ does set the detached attribute in the thread entry attributes
+ to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
+ that attribute instead of a separate flag.
+
+ * create.c (pthread_create): Rename "this" to "us".
+ (pthread_create): cancelstate and canceltype are not attributes
+ so the copy to thread entry attribute storage was removed.
+ Only the thread itself can change it's cancelstate or canceltype,
+ ie. the thread must exist already.
+
+ * private.c (ptw32_delete_thread_entry): Mutex locks removed.
+ Mutexes must be applied at the caller level.
+ (ptw32_new_thread_entry): Ditto.
+ (ptw32_new_thread_entry): Init cancelstate, canceltype, and
+ cancel_pending to default values.
+ (ptw32_new_thread_entry): Rename "this" to "new".
+ (ptw32_find_thread_entry): Rename "this" to "entry".
+ (ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
+
+ * create.c (ptw32_start_call): Mutexes changed to
+ ptw32_count_mutex. All access to the threads table entries is
+ under the one mutex. Otherwise chaos reigns.
+
+Sat Jul 25 23:16:51 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_threads_thread): Move cancelstate and
+ canceltype members out of pthread_attr_t into here.
+
+ * fork.c (fork): Add comment.
+
+1998-07-25 Ben Elliston <bje at cygnus.com>
+
+ * fork.c (fork): Autoconfiscate.
+
+Sat Jul 25 00:00:13 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (ptw32_start_call): Set thread priority. Ensure our
+ thread entry is removed from the thread table but only if
+ pthread_detach() was called and there are no waiting joins.
+ (pthread_create): Set detach flag in thread entry if the
+ thread is created PTHREAD_CREATE_DETACHED.
+
+ * pthread.h (pthread_attr_t): Rename member "detachedstate".
+
+ * attr.c (pthread_attr_init): Rename attr members.
+
+ * exit.c (pthread_exit): Fix indirection mistake.
+
+ * implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+ * exit.c (ptw32_vacuum): Fix incorrect args to
+ ptw32_handler_pop_all() calls.
+ Make thread entry removal conditional.
+
+ * sync.c (pthread_join): Add multiple join and async detach handling.
+
+ * implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+ * global.c (ptw32_threads_mutex_table): Add.
+
+ * implement.h (ptw32_once_flag): Remove.
+ (ptw32_once_lock): Ditto.
+ (ptw32_threads_mutex_table): Add.
+
+ * global.c (ptw32_once_flag): Remove.
+ (ptw32_once_lock): Ditto.
+
+ * sync.c (pthread_join): Fix tests involving new return value
+ from ptw32_find_thread_entry().
+ (pthread_detach): Ditto.
+
+ * private.c (ptw32_find_thread_entry): Failure return code
+ changed from -1 to NULL.
+
+Fri Jul 24 23:09:33 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (pthread_create): Change . to -> in sigmask memcpy() args.
+
+ * pthread.h: (pthread_cancel): Add function prototype.
+ (pthread_testcancel): Ditto.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (pthread_condattr_t): Rename dummy structure member.
+ (pthread_mutexattr_t): Likewise.
+
+Fri Jul 24 21:13:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cancel.c (pthread_cancel): Implement.
+ (pthread_testcancel): Implement.
+
+ * exit.c (pthread_exit): Add comment explaining the longjmp().
+
+ * implement.h (ptw32_threads_thread_t): New member cancelthread.
+ (PTW32_YES): Define.
+ (PTW32_NO): Define.
+ (RND_SIZEOF): Remove.
+
+ * create.c (pthread_create): Rename cancelability to cancelstate.
+
+ * pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
+ (PTHREAD_CANCELED): Define.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (SIG_BLOCK): Define if not already defined.
+ (SIG_UNBLOCK): Likewise.
+ (SIG_SETMASK): Likewise.
+ (pthread_attr_t): Add signal mask member.
+ (pthread_sigmask): Add function prototype.
+
+ * signal.c (pthread_sigmask): Implement.
+
+ * create.c: #include <string.h> to get a prototype for memcpy().
+ (pthread_create): New threads inherit their creator's signal
+ mask. Copy the signal mask to the new thread structure if we know
+ about signals.
+
+Fri Jul 24 16:33:17 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * fork.c (pthread_atfork): Add all the necessary push calls.
+ Local implementation semantics:
+ If we get an ENOMEM at any time then ALL handlers
+ (including those from previous pthread_atfork() calls) will be
+ popped off each of the three atfork stacks before we return.
+ (fork): Add all the necessary pop calls. Add the thread cancellation
+ and join calls to the child fork.
+ Add #includes.
+
+ * implement.h: (ptw32_handler_push): Fix return type and stack arg
+ type in prototype.
+ (ptw32_handler_pop): Fix stack arg type in prototype.
+ (ptw32_handler_pop_all): Fix stack arg type in prototype.
+
+ * cleanup.c (ptw32_handler_push): Change return type to int and
+ return ENOMEM if malloc() fails.
+
+ * sync.c (pthread_detach): Use equality test, not assignment.
+
+ * create.c (ptw32_start_call): Add call to Win32 CloseHandle()
+ if thread is detached.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * sync.c (pthread_detach): Close the Win32 thread handle to
+ emulate detached (or daemon) threads.
+
+Fri Jul 24 03:00:25 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Save valueptr arg in joinvalueptr for
+ pthread_exit() to use.
+
+ * private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
+ NULL.
+
+ * create.c (ptw32_start_call): Rewrite to facilitate joins.
+ pthread_exit() will do a longjmp() back to here. Does appropriate
+ cleanup and exit/return from the thread.
+ (pthread_create): _beginthreadex() now passes a pointer to our
+ thread table entry instead of just the call member of that entry.
+
+ * implement.h (ptw32_threads_thread): New member
+ void ** joinvalueptr.
+ (ptw32_call_t): New member jmpbuf env.
+
+ * exit.c (pthread_exit): Major rewrite to handle joins and handing
+ value pointer to joining thread. Uses longjmp() back to
+ ptw32_start_call().
+
+ * create.c (pthread_create): Ensure values of new attribute members
+ are copied to the thread attribute object.
+
+ * attr.c (pthread_attr_destroy): Fix merge conflicts.
+ (pthread_attr_getdetachstate): Fix merge conflicts.
+ (pthread_attr_setdetachstate): Fix merge conflicts.
+
+ * pthread.h: Fix merge conflicts.
+
+ * sync.c (pthread_join): Fix merge conflicts.
+
+Fri Jul 24 00:21:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Add check for valid and joinable
+ thread.
+ (pthread_detach): Implement. After checking for a valid and joinable
+ thread, it's still a no-op.
+
+ * private.c (ptw32_find_thread_entry): Bug prevented returning
+ an error value in some cases.
+
+ * attr.c (pthread_attr_setdetachedstate): Implement.
+ (pthread_attr_getdetachedstate): Implement.
+
+ * implement.h: Move more hidden definitions into here from
+ pthread.h.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (PTHREAD_CREATE_JOINABLE): Define.
+ (PTHREAD_CREATE_DETACHED): Likewise.
+ (pthread_attr_t): Add new structure member `detached'.
+ (pthread_attr_getdetachstate): Add function prototype.
+ (pthread_attr_setdetachstate): Likewise.
+
+ * sync.c (pthread_join): Return if the target thread is detached.
+
+ * attr.c (pthread_attr_init): Initialise cancelability and
+ canceltype structure members.
+ (pthread_attr_getdetachstate): Implement.
+ (pthread_attr_setdetachstate): Likewise.
+
+ * implement.h (PTW32_CANCEL_DEFAULTS): Remove. Bit fields
+ proved to be too cumbersome. Set the defaults in attr.c using the
+ public PTHREAD_CANCEL_* constants.
+
+ * cancel.c: New file.
+
+ * pthread.h (sched_param): Define this type.
+ (pthread_attr_getschedparam): Add function prototype.
+ (pthread_attr_setschedparam): Likewise.
+ (pthread_setcancelstate): Likewise.
+ (pthread_setcanceltype): Likewise.
+ (sched_get_priority_min): Likewise.
+ (sched_get_priority_max): Likewise.
+ (pthread_mutexattr_setprotocol): Remove; not supported.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (pthread_attr_t): Add canceltype member. Update comments.
+ (SCHED_OTHER): Define this scheduling policy constant.
+ (SCHED_FIFO): Likewise.
+ (SCHED_RR): Likewise.
+ (SCHED_MIN): Define the lowest possible value for this constant.
+ (SCHED_MAX): Likewise, the maximum possible value.
+ (PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
+ (PTHREAD_CANCEL_DEFERRED): Likewise.
+
+ * sched.c: New file.
+ (pthread_setschedparam): Implement.
+ (pthread_getschedparam): Implement.
+ (sched_get_priority_max): Validate policy argument.
+ (sched_get_priority_min): Likewise.
+
+ * mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+
+Fri Jul 24 00:21:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (pthread_create): Arg to ptw32_new_thread_entry()
+ changed. See next entry. Move mutex locks out. Changes made yesterday
+ and today allow us to start the new thread running rather than
+ temporarily suspended.
+
+ * private.c (ptw32_new_thread_entry): ptw32_thread_table
+ was changed back to a table of thread structures rather than pointers.
+ As such we're trading storage for increaded speed. This routine
+ was modified to work with the new table. Mutex lock put in around
+ global data accesses.
+ (ptw32_find_thread_entry): Ditto
+ (ptw32_delete_thread_entry): Ditto
+
+Thu Jul 23 23:25:30 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: New. Global data objects declared here. These moved from
+ pthread.h.
+
+ * pthread.h: Move implementation hidden definitions into
+ implement.h.
+
+ * implement.h: Move implementation hidden definitions from
+ pthread.h. Add constants to index into the different handler stacks.
+
+ * cleanup.c (ptw32_handler_push): Simplify args. Restructure.
+ (ptw32_handler_pop): Simplify args. Restructure.
+ (ptw32_handler_pop_all): Simplify args. Restructure.
+
+Wed Jul 22 00:16:22 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
+ conflicts.
+
+ * private.c (ptw32_find_thread_entry): Changes to return type
+ to support leaner ptw32_threads_table[] which now only stores
+ ptw32_thread_thread_t *.
+ (ptw32_new_thread_entry): Internal changes.
+ (ptw32_delete_thread_entry): Internal changes to avoid contention.
+ Calling routines changed accordingly.
+
+ * pthread.h: Modified cleanup macros to use new generic push and pop.
+ Added destructor and atfork stacks to ptw32_threads_thread_t.
+
+ * cleanup.c (ptw32_handler_push, ptw32_handler_pop,
+ ptw32_handler_pop_all): Renamed cleanup push and pop routines
+ and made generic to handle destructors and atfork handlers as
+ well.
+
+ * create.c (ptw32_start_call): New function is a wrapper for
+ all new threads. It allows us to do some cleanup when the thread
+ returns, ie. that is otherwise only done if the thread is cancelled.
+
+ * exit.c (ptw32_vacuum): New function contains code from
+ pthread_exit() that we need in the new ptw32_start_call()
+ as well.
+
+ * implement.h: Various additions and minor changes.
+
+ * pthread.h: Various additions and minor changes.
+ Change cleanup handler macros to use generic handler push and pop
+ functions.
+
+ * attr.c: Minor mods to all functions.
+ (is_attr): Implemented missing function.
+
+ * create.c (pthread_create): More clean up.
+
+ * private.c (ptw32_find_thread_entry): Implement.
+ (ptw32_delete_thread_entry): Implement.
+ (ptw32_new_thread_entry): Implement.
+ These functions manipulate the implementations internal thread
+ table and are part of general code cleanup and modularisation.
+ They replace ptw32_getthreadindex() which was removed.
+
+ * exit.c (pthread_exit): Changed to use the new code above.
+
+ * pthread.h: Add cancelability constants. Update comments.
+
+1998-07-22 Ben Elliston <bje at cygnus.com>
+
+ * attr.c (pthread_setstacksize): Update test of attr argument.
+ (pthread_getstacksize): Likewise.
+ (pthread_setstackaddr): Likewise.
+ (pthread_getstackaddr): Likewise.
+ (pthread_attr_init): No need to allocate any storage.
+ (pthread_attr_destroy): No need to free any storage.
+
+ * mutex.c (is_attr): Not likely to be needed; remove.
+ (remove_attr): Likewise.
+ (insert_attr): Likewise.
+
+ * implement.h (ptw32_mutexattr_t): Moved to a public definition
+ in pthread.h. There was little gain in hiding these details.
+ (ptw32_condattr_t): Likewise.
+ (ptw32_attr_t): Likewise.
+
+ * pthread.h (pthread_atfork): Add function prototype.
+ (pthread_attr_t): Moved here from implement.h.
+
+ * fork.c (pthread_atfork): Preliminary implementation.
+ (ptw32_fork): Likewise.
+
+Wed Jul 22 00:16:22 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cleanup.c (ptw32_cleanup_push): Implement.
+ (ptw32_cleanup_pop): Implement.
+ (ptw32_do_cancellation): Implement.
+ These are private to the implementation. The real cleanup functions
+ are macros. See below.
+
+ * pthread.h (pthread_cleanup_push): Implement as a macro.
+ (pthread_cleanup_pop): Implement as a macro.
+ Because these are macros which start and end a block, the POSIX scoping
+ requirement is observed. See the comment in the file.
+
+ * exit.c (pthread_exit): Refine the code.
+
+ * create.c (pthread_create): Code cleanup.
+
+ * implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
+ up to multiple of DWORD.
+ Add function prototypes.
+
+ * private.c (ptw32_getthreadindex): "*thread" should have been
+ "thread". Detect empty slot fail condition.
+
+1998-07-20 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_once): Implement. Don't use a per-application
+ flag and mutex--make `pthread_once_t' contain these elements in
+ their structure. The earlier version had incorrect semantics.
+
+ * pthread.h (ptw32_once_flag): Add new variable. Remove.
+ (ptw32_once_lock): Add new mutex lock to ensure integrity of
+ access to ptw32_once_flag. Remove.
+ (pthread_once): Add function prototype.
+ (pthread_once_t): Define this type.
+
+Mon Jul 20 02:31:05 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_getthreadindex): Implement.
+
+ * pthread.h: Add application static data dependent on
+ _PTHREADS_BUILD_DLL define. This is needed to avoid allocating
+ non-sharable static data within the pthread DLL.
+
+ * implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
+ and PTW32_HASH_INDEX.
+
+ * exit.c (pthread_exit): Begin work on cleanup and de-allocate
+ thread-private storage.
+
+ * create.c (pthread_create): Add thread to thread table.
+ Keep a thread-private copy of the attributes with default values
+ filled in when necessary. Same for the cleanup stack. Make
+ pthread_create C run-time library friendly by using _beginthreadex()
+ instead of CreateThread(). Fix error returns.
+
+Sun Jul 19 16:26:23 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Rename pthreads_thread_count to ptw32_threads_count.
+ Create ptw32_threads_thread_t struct to keep thread specific data.
+
+ * create.c: Rename pthreads_thread_count to ptw32_threads_count.
+ (pthread_create): Handle errors from CreateThread().
+
+1998-07-19 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_cond_wait): Generalise. Moved from here ..
+ (cond_wait): To here.
+ (pthread_cond_timedwait): Implement; use generalised cond_wait().
+
+ * pthread.h (pthread_key_t): Define this type.
+ (pthread_key_create): Add function prototype.
+ (pthread_setspecific): Likewise.
+ (pthread_getspecific): Likwise.
+ (pthread_key_delete): Likewise.
+
+ * tsd.c (pthread_key_create): Implement.
+ (pthread_setspecific): Likewise.
+ (pthread_getspecific): Likewise.
+ (pthread_key_delete): Likewise.
+
+ * mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
+ is called on a Win32 platform which is not Windows NT.
+
+1998-07-18 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_condattr_init): Do not attempt to malloc any
+ storage; none is needed now that condattr_t is an empty struct.
+ (pthread_condattr_destory): Likewise; do not free storage.
+ (pthread_condattr_setpshared): No longer supported; return ENOSYS.
+ (pthread_condattr_getpshared): Likewise.
+ (pthread_cond_init): Implement with help from Douglas Schmidt.
+ Remember to initialise the cv's internal mutex.
+ (pthread_cond_wait): Likewise.
+ (pthread_cond_signal): Likewise.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_timedwait): Preliminary implementation, but I need
+ to see some API documentation for `WaitForMultipleObject'.
+ (pthread_destory): Implement.
+
+ * pthread.h (pthread_cond_init): Add function protoype.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_signal): Likewise.
+ (pthread_cond_timedwait): Likewise.
+ (pthread_cond_wait): Likewise.
+ (pthread_cond_destroy): Likewise.
+ (pthread_cond_t): Define this type. Fix for u_int. Do not assume
+ that the mutex contained withing the pthread_cond_t structure will
+ be a critical section. Use our new POSIX type!
+
+ * implement.h (ptw32_condattr_t): Remove shared attribute.
+
+1998-07-17 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
+ (PTHREAD_PROCESS_SHARED): Likewise. No support for mutexes shared
+ across processes for now.
+ (pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
+ performance.
+
+ * implement.h (ptw32_mutexattr_t): Remove shared attribute.
+
+ * mutex.c (pthread_mutexattr_setpshared): This optional function
+ is no longer supported, since we want to implement POSIX mutex
+ variables using the much more efficient Win32 critical section
+ primitives. Critical section objects in Win32 cannot be shared
+ between processes.
+ (pthread_mutexattr_getpshared): Likewise.
+ (pthread_mutexattr_init): No need to malloc any storage; the
+ attributes structure is now empty.
+ (pthread_mutexattr_destroy): This is now a nop.
+ (pthread_mutex_init): Use InitializeCriticalSection().
+ (pthread_mutex_destroy): Use DeleteCriticalSection().
+ (pthread_mutex_lock): Use EnterCriticalSection().
+ (pthread_mutex_trylock): Use TryEnterCriticalSection(). This is
+ not supported by Windows 9x, but trylock is a hack anyway, IMHO.
+ (pthread_mutex_unlock): Use LeaveCriticalSection().
+
+1998-07-14 Ben Elliston <bje at cygnus.com>
+
+ * attr.c (pthread_attr_setstacksize): Implement.
+ (pthread_attr_getstacksize): Likewise.
+ (pthread_attr_setstackaddr): Likewise.
+ (pthread_attr_getstackaddr): Likewise.
+ (pthread_attr_init): Likewise.
+ (pthread_attr_destroy): Likewise.
+
+ * condvar.c (pthread_condattr_init): Add `_cond' to function name.
+
+ * mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_unlock): Likewise.
+
+ * pthread.h (pthread_condattr_setpshared): Fix typo.
+ (pthread_attr_init): Add function prototype.
+ (pthread_attr_destroy): Likewise.
+ (pthread_attr_setstacksize): Likewise.
+ (pthread_attr_getstacksize): Likewise.
+ (pthread_attr_setstackaddr): Likewise.
+ (pthread_attr_getstackaddr): Likewise.
+
+Mon Jul 13 01:09:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Wrap in #ifndef _IMPLEMENT_H
+
+ * create.c (pthread_create): Map stacksize attr to Win32.
+
+ * mutex.c: Include implement.h
+
+1998-07-13 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_condattr_init): Implement.
+ (pthread_condattr_destroy): Likewise.
+ (pthread_condattr_setpshared): Likewise.
+ (pthread_condattr_getpshared): Likewise.
+
+ * implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
+ (PTHREAD_STACK_MIN): Specify; needs confirming.
+ (ptw32_attr_t): Define this type.
+ (ptw32_condattr_t): Likewise.
+
+ * pthread.h (pthread_mutex_t): Define this type.
+ (pthread_condattr_t): Likewise.
+ (pthread_mutex_destroy): Add function prototype.
+ (pthread_lock): Likewise.
+ (pthread_trylock): Likewise.
+ (pthread_unlock): Likewise.
+ (pthread_condattr_init): Likewise.
+ (pthread_condattr_destroy): Likewise.
+ (pthread_condattr_setpshared): Likewise.
+ (pthread_condattr_getpshared): Likewise.
+
+ * mutex.c (pthread_mutex_init): Implement.
+ (pthread_mutex_destroy): Likewise.
+ (pthread_lock): Likewise.
+ (pthread_trylock): Likewise.
+ (pthread_unlock): Likewise.
+
+1998-07-12 Ben Elliston <bje at cygnus.com>
+
+ * implement.h (ptw32_mutexattr_t): Define this implementation
+ internal type. Application programmers only see a mutex attribute
+ object as a void pointer.
+
+ * pthread.h (pthread_mutexattr_t): Define this type.
+ (pthread_mutexattr_init): Add function prototype.
+ (pthread_mutexattr_destroy): Likewise.
+ (pthread_mutexattr_setpshared): Likewise.
+ (pthread_mutexattr_getpshared): Likewise.
+ (pthread_mutexattr_setprotocol): Likewise.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (PTHREAD_PROCESS_PRIVATE): Define.
+ (PTHREAD_PROCESS_SHARED): Define.
+
+ * mutex.c (pthread_mutexattr_init): Implement.
+ (pthread_mutexattr_destroy): Implement.
+ (pthread_mutexattr_setprotocol): Implement.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (pthread_mutexattr_setpshared): Likewise.
+ (pthread_mutexattr_getpshared): Likewise.
+ (insert_attr): New function; very preliminary implementation!
+ (is_attr): Likewise.
+ (remove_attr): Likewise.
+
+Sat Jul 11 14:48:54 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Preliminary implementation specific defines.
+
+ * create.c (pthread_create): Preliminary implementation.
+
+1998-07-11 Ben Elliston <bje at cygnus.com>
+
+ * sync.c (pthread_join): Implement.
+
+ * misc.c (pthread_equal): Likewise.
+
+ * pthread.h (pthread_join): Add function prototype.
+ (pthread_equal): Likewise.
+
+1998-07-10 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_self): Implement.
+
+ * exit.c (pthread_exit): Implement.
+
+ * pthread.h (pthread_exit): Add function prototype.
+ (pthread_self): Likewise.
+ (pthread_t): Define this type.
+
+1998-07-09 Ben Elliston <bje at cygnus.com>
+
+ * create.c (pthread_create): A dummy stub right now.
+
+ * pthread.h (pthread_create): Add function prototype.
diff --git a/libs/pthreads/docs/FAQ b/libs/pthreads/docs/FAQ
new file mode 100644
index 0000000000..cb1786c5ae
--- /dev/null
+++ b/libs/pthreads/docs/FAQ
@@ -0,0 +1,451 @@
+ =========================================
+ PTHREADS-WIN32 Frequently Asked Questions
+ =========================================
+
+INDEX
+-----
+
+Q 1 What is it?
+
+Q 2 Which of the several dll versions do I use?
+ or,
+ What are all these pthread*.dll and pthread*.lib files?
+
+Q 3 What is the library naming convention?
+
+Q 4 Cleanup code default style or: it used to work when I built
+ the library myself, but now it doesn't - why?
+
+Q 5 Why is the default library version now less exception-friendly?
+
+Q 6 Should I use Cygwin or Mingw32 as a development environment?
+
+Q 7 Now that pthreads-win32 builds under Mingw32, why do I get
+ memory access violations (segfaults)?
+
+Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0)
+
+Q 9 Cancelation doesn't work for me, why?
+
+Q 10 How do I generate pthreadGCE.dll and libpthreadw32.a for use
+ with Mingw32?
+
+Q 11 Why isn't pthread_t defined as a scalar (e.g. pointer or int)
+ like it is for other POSIX threads implementations?
+
+=============================================================================
+
+Q 1 What is it?
+---
+
+Pthreads-win32 is an Open Source Software implementation of the
+Threads component of the POSIX 1003.1c 1995 Standard for Microsoft's
+Win32 environment. Some functions from POSIX 1003.1b are also
+supported including semaphores. Other related functions include
+the set of read-write lock functions. The library also supports
+some of the functionality of the Open Group's Single Unix
+specification, version 2, namely mutex types.
+
+See the file "ANNOUNCE" for more information including standards
+conformance details and list of supported routines.
+
+
+------------------------------------------------------------------------------
+
+Q 2 Which of the several dll versions do I use?
+--- or,
+ What are all these pthread*.dll and pthread*.lib files?
+
+Simply, you only use one of them, but you need to choose carefully.
+
+The most important choice you need to make is whether to use a
+version that uses exceptions internally, or not (there are versions
+of the library that use exceptions as part of the thread
+cancelation and cleanup implementation, and one that uses
+setjmp/longjmp instead).
+
+There is some contension amongst POSIX threads experts as
+to how POSIX threads cancelation and exit should work
+with languages that include exceptions and handlers, e.g.
+C++ and even C (Microsoft's Structured Exceptions).
+
+The issue is: should cancelation of a thread in, say,
+a C++ application cause object destructors and C++ exception
+handlers to be invoked as the stack unwinds during thread
+exit, or not?
+
+There seems to be more opinion in favour of using the
+standard C version of the library (no EH) with C++ applications
+since this appears to be the assumption commercial pthreads
+implementations make. Therefore, if you use an EH version
+of pthreads-win32 then you may be under the illusion that
+your application will be portable, when in fact it is likely to
+behave very differently linked with other pthreads libraries.
+
+Now you may be asking: why have you kept the EH versions of
+the library?
+
+There are a couple of reasons:
+- there is division amongst the experts and so the code may
+ be needed in the future. (Yes, it's in the repository and we
+ can get it out anytime in the future, but ...)
+- pthreads-win32 is one of the few implementations, and possibly
+ the only freely available one, that has EH versions. It may be
+ useful to people who want to play with or study application
+ behaviour under these conditions.
+
+
+------------------------------------------------------------------------------
+
+Q 3 What is the library naming convention?
+---
+
+Because the library is being built using various exception
+handling schemes and compilers - and because the library
+may not work reliably if these are mixed in an application,
+each different version of the library has it's own name.
+
+Note 1: the incompatibility is really between EH implementations
+of the different compilers. It should be possible to use the
+standard C version from either compiler with C++ applications
+built with a different compiler. If you use an EH version of
+the library, then you must use the same compiler for the
+application. This is another complication and dependency that
+can be avoided by using only the standard C library version.
+
+Note 2: if you use a standard C pthread*.dll with a C++
+application, then any functions that you define that are
+intended to be called via pthread_cleanup_push() must be
+__cdecl.
+
+Note 3: the intention is to also name either the VC or GC
+version (it should be arbitrary) as pthread.dll, including
+pthread.lib and libpthread.a as appropriate.
+
+In general:
+ pthread[VG]{SE,CE,C}.dll
+ pthread[VG]{SE,CE,C}.lib
+
+where:
+ [VG] indicates the compiler
+ V - MS VC
+ G - GNU C
+
+ {SE,CE,C} indicates the exception handling scheme
+ SE - Structured EH
+ CE - C++ EH
+ C - no exceptions - uses setjmp/longjmp
+
+For example:
+ pthreadVSE.dll (MSVC/SEH)
+ pthreadGCE.dll (GNUC/C++ EH)
+ pthreadGC.dll (GNUC/not dependent on exceptions)
+
+The GNU library archive file names have changed to:
+
+ libpthreadGCE.a
+ libpthreadGC.a
+
+
+------------------------------------------------------------------------------
+
+Q 4 Cleanup code default style or: it used to work when I built
+--- the library myself, but now it doesn't - why?
+
+Up to and including snapshot 2001-07-12, if not defined, the cleanup
+style was determined automatically from the compiler used, and one
+of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw() in private.c).
+
+In short, the exceptions versions of the library throw an exception
+when a thread is canceled or exits (via pthread_exit()), which is
+caught by a handler in the thread startup routine, so that the
+the correct stack unwinding occurs regardless of where the thread
+is when it's canceled or exits via pthread_exit().
+
+After snapshot 2001-07-12, unless your build explicitly defines (e.g.
+via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build now ALWAYS defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most/all
+commercial Unix POSIX threads implementations.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+THE POINT OF ALL THIS IS: if you have not been defining one of these
+explicitly, then the defaults have been set according to the compiler
+and language you are using, as described at the top of this
+section.
+
+THIS NOW CHANGES, as has been explained above. For example:
+
+If you were building your application with MSVC++ i.e. using C++
+exceptions (rather than SEH) and not explicitly defining one of
+__CLEANUP_*, then __CLEANUP_C++ was defined for you in pthread.h.
+You should have been linking with pthreadVCE.dll, which does
+stack unwinding.
+
+If you now build your application as you had before, pthread.h will now
+set __CLEANUP_C as the default style, and you will need to link
+with pthreadVC.dll. Stack unwinding will now NOT occur when a
+thread is canceled, nor when the thread calls pthread_exit().
+
+Your application will now most likely behave differently to previous
+versions, and in non-obvious ways. Most likely is that local
+objects may not be destroyed or cleaned up after a thread
+is canceled.
+
+If you want the same behaviour as before, then you must now define
+__CLEANUP_C++ explicitly using a compiler option and link with
+pthreadVCE.dll as you did before.
+
+
+------------------------------------------------------------------------------
+
+Q 5 Why is the default library version now less exception-friendly?
+---
+
+Because most commercial Unix POSIX threads implementations don't allow you to
+choose to have stack unwinding. (Compaq's TRU64 Unix is possibly an exception.)
+
+Therefore, providing it in pthread-win32 as a default could be dangerous
+and non-portable. We still provide the choice but you must now consciously
+make it.
+
+WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
+There are a few reasons:
+- because there are well respected POSIX threads people who believe
+ that POSIX threads implementations should be exceptions-aware and
+ do the expected thing in that context. (There are equally respected
+ people who believe it should not be easily accessible, if it's there
+ at all.)
+- because pthreads-win32 is one of the few implementations that has
+ the choice, perhaps the only freely available one, and so offers
+ a laboratory to people who may want to explore the effects;
+- although the code will always be around somewhere for anyone who
+ wants it, once it's removed from the current version it will not be
+ nearly as visible to people who may have a use for it.
+
+
+------------------------------------------------------------------------------
+
+Q 6 Should I use Cygwin or Mingw32 as a development environment?
+---
+
+Important: see Q7 also.
+
+Use Mingw32 with the MSVCRT library to build applications that use
+the pthreads DLL.
+
+Cygwin's own internal support for POSIX threads is growing.
+Consult that project's documentation for more information.
+
+------------------------------------------------------------------------------
+
+Q 7 Now that pthreads-win32 builds under Mingw32, why do I get
+--- memory access violations (segfaults)?
+
+The latest Mingw32 package has thread-safe exception handling (see Q10).
+Also, see Q6 above.
+
+------------------------------------------------------------------------------
+
+Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0)
+---
+
+>
+> I'm a "rookie" when it comes to your pthread implementation. I'm currently
+> desperately trying to install the prebuilt .dll file into my MSVC compiler.
+> Could you please provide me with explicit instructions on how to do this (or
+> direct me to a resource(s) where I can acquire such information)?
+>
+> Thank you,
+>
+
+You should have a .dll, .lib, .def, and three .h files. It is recommended
+that you use pthreadVC.dll, rather than pthreadVCE.dll or pthreadVSE.dll
+(see Q2 above).
+
+The .dll can go in any directory listed in your PATH environment
+variable, so putting it into C:\WINDOWS should work.
+
+The .lib file can go in any directory listed in your LIB environment
+variable.
+
+The .h files can go in any directory listed in your INCLUDE
+environment variable.
+
+Or you might prefer to put the .lib and .h files into a new directory
+and add its path to LIB and INCLUDE. You can probably do this easiest
+by editing the file:-
+
+C:\Program Files\DevStudio\vc\bin\vcvars32.bat
+
+The .def file isn't used by anything in the pre-compiled version but
+is included for information.
+
+Cheers.
+Ross
+
+------------------------------------------------------------------------------
+
+Q 9 Cancelation doesn't work for me, why?
+---
+
+> I'm investigating a problem regarding thread cancelation. The thread I want
+> to cancel has PTHREAD_CANCEL_ASYNCHRONOUS, however, this piece of code
+> blocks on the join():
+>
+> if ((retv = Pthread_cancel( recvThread )) == 0)
+> {
+> retv = Pthread_join( recvThread, 0 );
+> }
+>
+> Pthread_* are just macro's; they call pthread_*.
+>
+> The thread recvThread seems to block on a select() call. It doesn't get
+> cancelled.
+>
+> Two questions:
+>
+> 1) is this normal behaviour?
+>
+> 2) if not, how does the cancel mechanism work? I'm not very familliar to
+> win32 programming, so I don't really understand how the *Event() family of
+> calls work.
+
+The answer to your first question is, normal POSIX behaviour would
+be to asynchronously cancel the thread. However, even that doesn't
+guarantee cancelation as the standard only says it should be
+cancelled as soon as possible.
+
+Snapshot 99-11-02 or earlier only partially supports asynchronous cancellation.
+Snapshots since then simulate async cancelation by poking the address of
+a cancelation routine into the PC of the threads context. This requires
+the thread to be resumed in some way for the cancelation to actually
+proceed. This is not true async cancelation, but it is as close as we've
+been able to get to it.
+
+If the thread you're trying to cancel is blocked (for instance, it could be
+waiting for data from the network), it will only get cancelled when it unblocks
+(when the data arrives). For true pre-emptive cancelation in these cases,
+pthreads-win32 from snapshot 2004-05-16 can automatically recognise and use the
+QueueUserAPCEx package by Panagiotis E. Hadjidoukas. This package is available
+from the pthreads-win32 ftp site and is included in the pthreads-win32
+self-unpacking zip from 2004-05-16 onwards.
+
+Using deferred cancelation would normally be the way to go, however,
+even though the POSIX threads standard lists a number of C library
+functions that are defined as deferred cancelation points, there is
+no hookup between those which are provided by Windows and the
+pthreads-win32 library.
+
+Incidently, it's worth noting for code portability that the older POSIX
+threads standards cancelation point lists didn't include "select" because
+(as I read in Butenhof) it wasn't part of POSIX. However, it does appear in
+the SUSV3.
+
+Effectively, the only mandatory cancelation points that pthreads-win32
+recognises are those the library implements itself, ie.
+
+ pthread_testcancel
+ pthread_cond_wait
+ pthread_cond_timedwait
+ pthread_join
+ sem_wait
+ sem_timedwait
+ pthread_delay_np
+
+The following routines from the non-mandatory list in SUSV3 are
+cancelation points in pthreads-win32:
+
+ pthread_rwlock_wrlock
+ pthread_rwlock_timedwrlock
+
+The following routines from the non-mandatory list in SUSV3 are not
+cancelation points in pthreads-win32:
+
+ pthread_rwlock_rdlock
+ pthread_rwlock_timedrdlock
+
+Pthreads-win32 also provides two functions that allow you to create
+cancelation points within your application, but only for cases where
+a thread is going to block on a Win32 handle. These are:
+
+ pthreadCancelableWait(HANDLE waitHandle) /* Infinite wait */
+
+ pthreadCancelableTimedWait(HANDLE waitHandle, DWORD timeout)
+
+------------------------------------------------------------------------------
+
+
+Q 10 How do I create thread-safe applications using
+---- pthreadGCE.dll, libpthreadw32.a and Mingw32?
+
+This should not be a problem with recent versions of MinGW32.
+
+For early versions, see Thomas Pfaff's email at:
+http://sources.redhat.com/ml/pthreads-win32/2002/msg00000.html
+------------------------------------------------------------------------------
+
+Q 11 Why isn't pthread_t defined as a scalar (e.g. pointer or int)
+ like it is for other POSIX threads implementations?
+----
+
+Originally pthread_t was defined as a pointer (to the opaque pthread_t_
+struct) and later it was changed to a struct containing the original
+pointer plus a sequence counter. This is allowed under both the original
+POSIX Threads Standard and the current Single Unix Specification.
+
+When pthread_t is a simple pointer to a struct some very difficult to
+debug problems arise from the process of freeing and later allocing
+thread structs because new pthread_t handles can acquire the identity of
+previously detached threads. The change to a struct was made, along with
+some changes to their internal managment, in order to guarantee (for
+practical applications) that the pthread_t handle will be unique over the
+life of the running process.
+
+Where application code attempts to compare one pthread_t against another
+directly, a compiler error will be emitted because structs can't be
+compared at that level. This should signal a potentially serious problem
+in the code design, which would go undetected if pthread_t was a scalar.
+
+The POSIX Threading API provides a function named pthread_equal() to
+compare pthread_t thread handles.
+
+Other pthreads implementations, such as Sun's, use an int as the handle
+but do guarantee uniqueness within the process scope. Win32 scalar typed
+thread handles also guarantee uniqueness in system scope. It wasn't clear
+how well the internal management of these handles would scale as the
+number of threads and the fragmentation of the sequence numbering
+increased for applications where thousands or millions of threads are
+created and detached over time. The current management of threads within
+pthreads-win32 using structs for pthread_t, and reusing without ever
+freeing them, reduces the management time overheads to a constant, which
+could be important given that pthreads-win32 threads are built on top of
+Win32 threads and will therefore include that management overhead on top
+of their own. The cost is that the memory resources used for thread
+handles will remain at the peak level until the process exits.
+
+While it may be inconvenient for developers to be forced away from making
+assumptions about the internals of pthread_t, the advantage for the
+future development of pthread-win32, as well as those applications that
+use it and other pthread implementations, is that the library is free to
+change pthread_t internals and management as better methods arise.
+
diff --git a/libs/pthreads/docs/GNUmakefile b/libs/pthreads/docs/GNUmakefile
new file mode 100644
index 0000000000..e489f002ec
--- /dev/null
+++ b/libs/pthreads/docs/GNUmakefile
@@ -0,0 +1,593 @@
+#
+# --------------------------------------------------------------------------
+#
+# Pthreads-win32 - POSIX Threads Library for Win32
+# Copyright(C) 1998 John E. Bossom
+# Copyright(C) 1999,2005 Pthreads-win32 contributors
+#
+# Contact Email: rpj@callisto.canberra.edu.au
+#
+# The current list of contributors is contained
+# in the file CONTRIBUTORS included with the source
+# code distribution. The list can also be seen at the
+# following World Wide Web location:
+# http://sources.redhat.com/pthreads-win32/contributors.html
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+
+DLL_VER = 2
+DLL_VERD= $(DLL_VER)d
+
+DEVROOT = C:\PTHREADS
+
+DLLDEST = $(DEVROOT)\DLL
+LIBDEST = $(DEVROOT)\DLL
+
+# If Running MsysDTK
+RM = rm -f
+MV = mv -f
+CP = cp -f
+
+# If not.
+#RM = erase
+#MV = rename
+#CP = copy
+
+# For cross compiling use e.g.
+# make CROSS=x86_64-w64-mingw32- clean GC-inlined
+CROSS =
+
+AR = $(CROSS)ar
+DLLTOOL = $(CROSS)dlltool
+CC = $(CROSS)gcc
+CXX = $(CROSS)g++
+RANLIB = $(CROSS)ranlib
+RC = $(CROSS)windres
+
+OPT = $(CLEANUP) -O3 # -finline-functions -findirect-inlining
+XOPT =
+
+RCFLAGS = --include-dir=.
+# Uncomment this if config.h defines RETAIN_WSALASTERROR
+#LFLAGS = -lws2_32
+
+# ----------------------------------------------------------------------
+# The library can be built with some alternative behaviour to
+# facilitate development of applications on Win32 that will be ported
+# to other POSIX systems. Nothing definable here will make the library
+# non-compliant, but applications that make assumptions that POSIX
+# does not garrantee may fail or misbehave under some settings.
+#
+# PTW32_THREAD_ID_REUSE_INCREMENT
+# Purpose:
+# POSIX says that applications should assume that thread IDs can be
+# recycled. However, Solaris and some other systems use a [very large]
+# sequence number as the thread ID, which provides virtual uniqueness.
+# Pthreads-win32 provides pseudo-unique IDs when the default increment
+# (1) is used, but pthread_t is not a scalar type like Solaris's.
+#
+# Usage:
+# Set to any value in the range: 0 <= value <= 2^wordsize
+#
+# Examples:
+# Set to 0 to emulate non recycle-unique behaviour like Linux or *BSD.
+# Set to 1 for recycle-unique thread IDs (this is the default).
+# Set to some other +ve value to emulate smaller word size types
+# (i.e. will wrap sooner).
+#
+#PTW32_FLAGS = "-DPTW32_THREAD_ID_REUSE_INCREMENT=0"
+#
+# ----------------------------------------------------------------------
+
+GC_CFLAGS = $(PTW32_FLAGS)
+GCE_CFLAGS = $(PTW32_FLAGS) -mthreads
+
+## Mingw
+MAKE ?= make
+CFLAGS = $(OPT) $(XOPT) -I. -DHAVE_PTW32_CONFIG_H -Wall
+
+DLL_INLINED_OBJS = \
+ pthread.o \
+ version.o
+
+# Agregate modules for inlinability
+DLL_OBJS = \
+ attr.o \
+ barrier.o \
+ cancel.o \
+ cleanup.o \
+ condvar.o \
+ create.o \
+ dll.o \
+ errno.o \
+ exit.o \
+ fork.o \
+ global.o \
+ misc.o \
+ mutex.o \
+ nonportable.o \
+ private.o \
+ rwlock.o \
+ sched.o \
+ semaphore.o \
+ signal.o \
+ spin.o \
+ sync.o \
+ tsd.o \
+ version.o
+
+# Separate modules for minimum size statically linked images
+SMALL_STATIC_OBJS = \
+ pthread_attr_init.o \
+ pthread_attr_destroy.o \
+ pthread_attr_getdetachstate.o \
+ pthread_attr_setdetachstate.o \
+ pthread_attr_getstackaddr.o \
+ pthread_attr_setstackaddr.o \
+ pthread_attr_getstacksize.o \
+ pthread_attr_setstacksize.o \
+ pthread_attr_getscope.o \
+ pthread_attr_setscope.o \
+ pthread_attr_setschedpolicy.o \
+ pthread_attr_getschedpolicy.o \
+ pthread_attr_setschedparam.o \
+ pthread_attr_getschedparam.o \
+ pthread_attr_setinheritsched.o \
+ pthread_attr_getinheritsched.o \
+ pthread_barrier_init.o \
+ pthread_barrier_destroy.o \
+ pthread_barrier_wait.o \
+ pthread_barrierattr_init.o \
+ pthread_barrierattr_destroy.o \
+ pthread_barrierattr_setpshared.o \
+ pthread_barrierattr_getpshared.o \
+ pthread_setcancelstate.o \
+ pthread_setcanceltype.o \
+ pthread_testcancel.o \
+ pthread_cancel.o \
+ cleanup.o \
+ pthread_condattr_destroy.o \
+ pthread_condattr_getpshared.o \
+ pthread_condattr_init.o \
+ pthread_condattr_setpshared.o \
+ pthread_cond_destroy.o \
+ pthread_cond_init.o \
+ pthread_cond_signal.o \
+ pthread_cond_wait.o \
+ create.o \
+ dll.o \
+ autostatic.o \
+ errno.o \
+ pthread_exit.o \
+ fork.o \
+ global.o \
+ pthread_mutex_init.o \
+ pthread_mutex_destroy.o \
+ pthread_mutexattr_init.o \
+ pthread_mutexattr_destroy.o \
+ pthread_mutexattr_getpshared.o \
+ pthread_mutexattr_setpshared.o \
+ pthread_mutexattr_settype.o \
+ pthread_mutexattr_gettype.o \
+ pthread_mutexattr_setrobust.o \
+ pthread_mutexattr_getrobust.o \
+ pthread_mutex_lock.o \
+ pthread_mutex_timedlock.o \
+ pthread_mutex_unlock.o \
+ pthread_mutex_trylock.o \
+ pthread_mutex_consistent.o \
+ pthread_mutexattr_setkind_np.o \
+ pthread_mutexattr_getkind_np.o \
+ pthread_getw32threadhandle_np.o \
+ pthread_getunique_np.o \
+ pthread_delay_np.o \
+ pthread_num_processors_np.o \
+ pthread_win32_attach_detach_np.o \
+ pthread_equal.o \
+ pthread_getconcurrency.o \
+ pthread_once.o \
+ pthread_self.o \
+ pthread_setconcurrency.o \
+ pthread_rwlock_init.o \
+ pthread_rwlock_destroy.o \
+ pthread_rwlockattr_init.o \
+ pthread_rwlockattr_destroy.o \
+ pthread_rwlockattr_getpshared.o \
+ pthread_rwlockattr_setpshared.o \
+ pthread_rwlock_rdlock.o \
+ pthread_rwlock_wrlock.o \
+ pthread_rwlock_unlock.o \
+ pthread_rwlock_tryrdlock.o \
+ pthread_rwlock_trywrlock.o \
+ pthread_setschedparam.o \
+ pthread_getschedparam.o \
+ pthread_timechange_handler_np.o \
+ ptw32_is_attr.o \
+ ptw32_cond_check_need_init.o \
+ ptw32_MCS_lock.o \
+ ptw32_mutex_check_need_init.o \
+ ptw32_processInitialize.o \
+ ptw32_processTerminate.o \
+ ptw32_threadStart.o \
+ ptw32_threadDestroy.o \
+ ptw32_tkAssocCreate.o \
+ ptw32_tkAssocDestroy.o \
+ ptw32_callUserDestroyRoutines.o \
+ ptw32_timespec.o \
+ ptw32_throw.o \
+ ptw32_getprocessors.o \
+ ptw32_calloc.o \
+ ptw32_new.o \
+ ptw32_reuse.o \
+ ptw32_semwait.o \
+ ptw32_relmillisecs.o \
+ ptw32_rwlock_check_need_init.o \
+ sched_get_priority_max.o \
+ sched_get_priority_min.o \
+ sched_setscheduler.o \
+ sched_getscheduler.o \
+ sched_yield.o \
+ sem_init.o \
+ sem_destroy.o \
+ sem_trywait.o \
+ sem_timedwait.o \
+ sem_wait.o \
+ sem_post.o \
+ sem_post_multiple.o \
+ sem_getvalue.o \
+ sem_open.o \
+ sem_close.o \
+ sem_unlink.o \
+ signal.o \
+ pthread_kill.o \
+ ptw32_spinlock_check_need_init.o \
+ pthread_spin_init.o \
+ pthread_spin_destroy.o \
+ pthread_spin_lock.o \
+ pthread_spin_unlock.o \
+ pthread_spin_trylock.o \
+ pthread_detach.o \
+ pthread_join.o \
+ pthread_key_create.o \
+ pthread_key_delete.o \
+ pthread_setspecific.o \
+ pthread_getspecific.o \
+ w32_CancelableWait.o \
+ version.o
+
+INCL = \
+ config.h \
+ implement.h \
+ semaphore.h \
+ pthread.h \
+ need_errno.h
+
+ATTR_SRCS = \
+ pthread_attr_init.c \
+ pthread_attr_destroy.c \
+ pthread_attr_getdetachstate.c \
+ pthread_attr_setdetachstate.c \
+ pthread_attr_getstackaddr.c \
+ pthread_attr_setstackaddr.c \
+ pthread_attr_getstacksize.c \
+ pthread_attr_setstacksize.c \
+ pthread_attr_getscope.c \
+ pthread_attr_setscope.c
+
+BARRIER_SRCS = \
+ pthread_barrier_init.c \
+ pthread_barrier_destroy.c \
+ pthread_barrier_wait.c \
+ pthread_barrierattr_init.c \
+ pthread_barrierattr_destroy.c \
+ pthread_barrierattr_setpshared.c \
+ pthread_barrierattr_getpshared.c
+
+CANCEL_SRCS = \
+ pthread_setcancelstate.c \
+ pthread_setcanceltype.c \
+ pthread_testcancel.c \
+ pthread_cancel.c
+
+CONDVAR_SRCS = \
+ ptw32_cond_check_need_init.c \
+ pthread_condattr_destroy.c \
+ pthread_condattr_getpshared.c \
+ pthread_condattr_init.c \
+ pthread_condattr_setpshared.c \
+ pthread_cond_destroy.c \
+ pthread_cond_init.c \
+ pthread_cond_signal.c \
+ pthread_cond_wait.c
+
+EXIT_SRCS = \
+ pthread_exit.c
+
+MISC_SRCS = \
+ pthread_equal.c \
+ pthread_getconcurrency.c \
+ pthread_kill.c \
+ pthread_once.c \
+ pthread_self.c \
+ pthread_setconcurrency.c \
+ ptw32_calloc.c \
+ ptw32_MCS_lock.c \
+ ptw32_new.c \
+ ptw32_reuse.c \
+ w32_CancelableWait.c
+
+MUTEX_SRCS = \
+ ptw32_mutex_check_need_init.c \
+ pthread_mutex_init.c \
+ pthread_mutex_destroy.c \
+ pthread_mutexattr_init.c \
+ pthread_mutexattr_destroy.c \
+ pthread_mutexattr_getpshared.c \
+ pthread_mutexattr_setpshared.c \
+ pthread_mutexattr_settype.c \
+ pthread_mutexattr_gettype.c \
+ pthread_mutexattr_setrobust.c \
+ pthread_mutexattr_getrobust.c \
+ pthread_mutex_lock.c \
+ pthread_mutex_timedlock.c \
+ pthread_mutex_unlock.c \
+ pthread_mutex_trylock.c \
+ pthread_mutex_consistent.c
+
+NONPORTABLE_SRCS = \
+ pthread_mutexattr_setkind_np.c \
+ pthread_mutexattr_getkind_np.c \
+ pthread_getw32threadhandle_np.c \
+ pthread_getunique_np.c \
+ pthread_delay_np.c \
+ pthread_num_processors_np.c \
+ pthread_win32_attach_detach_np.c \
+ pthread_timechange_handler_np.c
+
+PRIVATE_SRCS = \
+ ptw32_is_attr.c \
+ ptw32_processInitialize.c \
+ ptw32_processTerminate.c \
+ ptw32_threadStart.c \
+ ptw32_threadDestroy.c \
+ ptw32_tkAssocCreate.c \
+ ptw32_tkAssocDestroy.c \
+ ptw32_callUserDestroyRoutines.c \
+ ptw32_semwait.c \
+ ptw32_relmillisecs.c \
+ ptw32_timespec.c \
+ ptw32_throw.c \
+ ptw32_getprocessors.c
+
+RWLOCK_SRCS = \
+ ptw32_rwlock_check_need_init.c \
+ ptw32_rwlock_cancelwrwait.c \
+ pthread_rwlock_init.c \
+ pthread_rwlock_destroy.c \
+ pthread_rwlockattr_init.c \
+ pthread_rwlockattr_destroy.c \
+ pthread_rwlockattr_getpshared.c \
+ pthread_rwlockattr_setpshared.c \
+ pthread_rwlock_rdlock.c \
+ pthread_rwlock_timedrdlock.c \
+ pthread_rwlock_wrlock.c \
+ pthread_rwlock_timedwrlock.c \
+ pthread_rwlock_unlock.c \
+ pthread_rwlock_tryrdlock.c \
+ pthread_rwlock_trywrlock.c
+
+SCHED_SRCS = \
+ pthread_attr_setschedpolicy.c \
+ pthread_attr_getschedpolicy.c \
+ pthread_attr_setschedparam.c \
+ pthread_attr_getschedparam.c \
+ pthread_attr_setinheritsched.c \
+ pthread_attr_getinheritsched.c \
+ pthread_setschedparam.c \
+ pthread_getschedparam.c \
+ sched_get_priority_max.c \
+ sched_get_priority_min.c \
+ sched_setscheduler.c \
+ sched_getscheduler.c \
+ sched_yield.c
+
+SEMAPHORE_SRCS = \
+ sem_init.c \
+ sem_destroy.c \
+ sem_trywait.c \
+ sem_timedwait.c \
+ sem_wait.c \
+ sem_post.c \
+ sem_post_multiple.c \
+ sem_getvalue.c \
+ sem_open.c \
+ sem_close.c \
+ sem_unlink.c
+
+SPIN_SRCS = \
+ ptw32_spinlock_check_need_init.c \
+ pthread_spin_init.c \
+ pthread_spin_destroy.c \
+ pthread_spin_lock.c \
+ pthread_spin_unlock.c \
+ pthread_spin_trylock.c
+
+SYNC_SRCS = \
+ pthread_detach.c \
+ pthread_join.c
+
+TSD_SRCS = \
+ pthread_key_create.c \
+ pthread_key_delete.c \
+ pthread_setspecific.c \
+ pthread_getspecific.c
+
+
+GCE_DLL = pthreadGCE$(DLL_VER).dll
+GCED_DLL= pthreadGCE$(DLL_VERD).dll
+GCE_LIB = libpthreadGCE$(DLL_VER).a
+GCED_LIB= libpthreadGCE$(DLL_VERD).a
+GCE_INLINED_STAMP = pthreadGCE$(DLL_VER).stamp
+GCED_INLINED_STAMP = pthreadGCE$(DLL_VERD).stamp
+GCE_STATIC_STAMP = libpthreadGCE$(DLL_VER).stamp
+GCED_STATIC_STAMP = libpthreadGCE$(DLL_VERD).stamp
+
+GC_DLL = pthreadGC$(DLL_VER).dll
+GCD_DLL = pthreadGC$(DLL_VERD).dll
+GC_LIB = libpthreadGC$(DLL_VER).a
+GCD_LIB = libpthreadGC$(DLL_VERD).a
+GC_INLINED_STAMP = pthreadGC$(DLL_VER).stamp
+GCD_INLINED_STAMP = pthreadGC$(DLL_VERD).stamp
+GC_STATIC_STAMP = libpthreadGC$(DLL_VER).stamp
+GCD_STATIC_STAMP = libpthreadGC$(DLL_VERD).stamp
+
+PTHREAD_DEF = pthread.def
+
+help:
+ @ echo "Run one of the following command lines:"
+ @ echo "make clean GC (to build the GNU C dll with C cleanup code)"
+ @ echo "make clean GCE (to build the GNU C dll with C++ exception handling)"
+ @ echo "make clean GC-inlined (to build the GNU C inlined dll with C cleanup code)"
+ @ echo "make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling)"
+ @ echo "make clean GC-static (to build the GNU C inlined static lib with C cleanup code)"
+ @ echo "make clean GC-debug (to build the GNU C debug dll with C cleanup code)"
+ @ echo "make clean GCE-debug (to build the GNU C debug dll with C++ exception handling)"
+ @ echo "make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code)"
+ @ echo "make clean GCE-inlined-debug (to build the GNU C inlined debug dll with C++ exception handling)"
+ @ echo "make clean GC-static-debug (to build the GNU C inlined static debug lib with C cleanup code)"
+
+all:
+ @ $(MAKE) clean GCE
+ @ $(MAKE) clean GC
+
+GC:
+ $(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL)
+
+GC-debug:
+ $(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_DLL)
+
+GCE:
+ $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL)
+
+GCE-debug:
+ $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_DLL)
+
+GC-inlined:
+ $(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP)
+
+GC-inlined-debug:
+ $(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_INLINED_STAMP)
+
+GCE-inlined:
+ $(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP)
+
+GCE-inlined-debug:
+ $(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_INLINED_STAMP)
+
+GC-static:
+ $(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP)
+
+GC-static-debug:
+ $(MAKE) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_STATIC_STAMP)
+
+tests:
+ @ cd tests
+ @ $(MAKE) auto
+
+%.pre: %.c
+ $(CC) -E -o $@ $(CFLAGS) $^
+
+%.s: %.c
+ $(CC) -c $(CFLAGS) -DPTW32_BUILD_INLINED -Wa,-ahl $^ > $@
+
+%.o: %.rc
+ $(RC) $(RCFLAGS) $(CLEANUP) -o $@ -i $<
+
+.SUFFIXES: .dll .rc .c .o
+
+.c.o:; $(CC) -c -o $@ $(CFLAGS) $(XC_FLAGS) $<
+
+
+$(GC_DLL) $(GCD_DLL): $(DLL_OBJS)
+ $(CC) $(OPT) -shared -o $(GC_DLL) $(DLL_OBJS) $(LFLAGS)
+ $(DLLTOOL) -z pthread.def $(DLL_OBJS)
+ $(DLLTOOL) -k --dllname $@ --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
+
+$(GCE_DLL): $(DLL_OBJS)
+ $(CC) $(OPT) -mthreads -shared -o $(GCE_DLL) $(DLL_OBJS) $(LFLAGS)
+ $(DLLTOOL) -z pthread.def $(DLL_OBJS)
+ $(DLLTOOL) -k --dllname $@ --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
+
+$(GC_INLINED_STAMP) $(GCD_INLINED_STAMP): $(DLL_INLINED_OBJS)
+ $(CC) $(OPT) $(XOPT) -shared -o $(GC_DLL) $(DLL_INLINED_OBJS) $(LFLAGS)
+ $(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS)
+ $(DLLTOOL) -k --dllname $(GC_DLL) --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
+ echo touched > $(GC_INLINED_STAMP)
+
+$(GCE_INLINED_STAMP) $(GCED_INLINED_STAMP): $(DLL_INLINED_OBJS)
+ $(CC) $(OPT) $(XOPT) -mthreads -shared -o $(GCE_DLL) $(DLL_INLINED_OBJS) $(LFLAGS)
+ $(DLLTOOL) -z pthread.def $(DLL_INLINED_OBJS)
+ $(DLLTOOL) -k --dllname $(GCE_DLL) --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
+ echo touched > $(GCE_INLINED_STAMP)
+
+$(GC_STATIC_STAMP) $(GCD_STATIC_STAMP): $(DLL_INLINED_OBJS)
+ $(RM) $(GC_LIB)
+ $(AR) -rv $(GC_LIB) $(DLL_INLINED_OBJS)
+ $(RANLIB) $(GC_LIB)
+ echo touched > $(GC_STATIC_STAMP)
+
+clean:
+ -$(RM) *~
+ -$(RM) *.i
+ -$(RM) *.s
+ -$(RM) *.o
+ -$(RM) *.obj
+ -$(RM) *.exe
+ -$(RM) $(PTHREAD_DEF)
+
+realclean: clean
+ -$(RM) $(GC_LIB)
+ -$(RM) $(GCE_LIB)
+ -$(RM) $(GC_DLL)
+ -$(RM) $(GCE_DLL)
+ -$(RM) $(GC_INLINED_STAMP)
+ -$(RM) $(GCE_INLINED_STAMP)
+ -$(RM) $(GC_STATIC_STAMP)
+ -$(RM) $(GCD_LIB)
+ -$(RM) $(GCED_LIB)
+ -$(RM) $(GCD_DLL)
+ -$(RM) $(GCED_DLL)
+ -$(RM) $(GCD_INLINED_STAMP)
+ -$(RM) $(GCED_INLINED_STAMP)
+ -$(RM) $(GCD_STATIC_STAMP)
+
+attr.o: attr.c $(ATTR_SRCS) $(INCL)
+barrier.o: barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.o: cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.o: condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.o: exit.c $(EXIT_SRCS) $(INCL)
+misc.o: misc.c $(MISC_SRCS) $(INCL)
+mutex.o: mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.o: nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.o: private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.o: rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.o: sched.c $(SCHED_SRCS) $(INCL)
+semaphore.o: semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.o: spin.c $(SPIN_SRCS) $(INCL)
+sync.o: sync.c $(SYNC_SRCS) $(INCL)
+tsd.o: tsd.c $(TSD_SRCS) $(INCL)
+version.o: version.rc $(INCL)
diff --git a/libs/pthreads/docs/MAINTAINERS b/libs/pthreads/docs/MAINTAINERS
new file mode 100644
index 0000000000..d253c1f69e
--- /dev/null
+++ b/libs/pthreads/docs/MAINTAINERS
@@ -0,0 +1,4 @@
+CVS Repository maintainers
+
+Ross Johnson rpj@ise.canberra.edu.au
+Ben Elliston bje@cygnus.com
diff --git a/libs/pthreads/docs/Makefile b/libs/pthreads/docs/Makefile
new file mode 100644
index 0000000000..472969cf9b
--- /dev/null
+++ b/libs/pthreads/docs/Makefile
@@ -0,0 +1,514 @@
+# This makefile is compatible with MS nmake and can be used as a
+# replacement for buildlib.bat. I've changed the target from an ordinary dll
+# (/LD) to a debugging dll (/LDd).
+#
+# The variables $DLLDEST and $LIBDEST hold the destination directories for the
+# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
+
+
+# DLL_VER:
+# See pthread.h and README - This number is computed as 'current - age'
+DLL_VER = 2
+DLL_VERD= $(DLL_VER)d
+
+DEVROOT = C:\pthreads
+
+DLLDEST = $(DEVROOT)\dll
+LIBDEST = $(DEVROOT)\lib
+HDRDEST = $(DEVROOT)\include
+
+DLLS = pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \
+ pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll
+INLINED_STAMPS = pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \
+ pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp
+STATIC_STAMPS = pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \
+ pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static
+
+CC = cl
+CPPFLAGS = /I. /DHAVE_PTW32_CONFIG_H
+XCFLAGS = /W3 /MD /nologo
+CFLAGS = /O2 /Ob2 $(XCFLAGS)
+CFLAGSD = /Z7 $(XCFLAGS)
+
+# Uncomment this if config.h defines RETAIN_WSALASTERROR
+#XLIBS = wsock32.lib
+
+# Default cleanup style
+CLEANUP = __CLEANUP_C
+
+# C++ Exceptions
+VCEFLAGS = /EHsc /TP $(CPPFLAGS) $(CFLAGS)
+VCEFLAGSD = /EHsc /TP $(CPPFLAGS) $(CFLAGSD)
+#Structured Exceptions
+VSEFLAGS = $(CPPFLAGS) $(CFLAGS)
+VSEFLAGSD = $(CPPFLAGS) $(CFLAGSD)
+#C cleanup code
+VCFLAGS = $(CPPFLAGS) $(CFLAGS)
+VCFLAGSD = $(CPPFLAGS) $(CFLAGSD)
+
+DLL_INLINED_OBJS = \
+ pthread.obj \
+ version.res
+
+# Aggregate modules for inlinability
+DLL_OBJS = \
+ attr.obj \
+ barrier.obj \
+ cancel.obj \
+ cleanup.obj \
+ condvar.obj \
+ create.obj \
+ dll.obj \
+ autostatic.obj \
+ errno.obj \
+ exit.obj \
+ fork.obj \
+ global.obj \
+ misc.obj \
+ mutex.obj \
+ nonportable.obj \
+ private.obj \
+ rwlock.obj \
+ sched.obj \
+ semaphore.obj \
+ signal.obj \
+ spin.obj \
+ sync.obj \
+ tsd.obj \
+ version.res
+
+# Separate modules for minimising the size of statically linked images
+SMALL_STATIC_OBJS = \
+ pthread_attr_init.obj \
+ pthread_attr_destroy.obj \
+ pthread_attr_getdetachstate.obj \
+ pthread_attr_setdetachstate.obj \
+ pthread_attr_getstackaddr.obj \
+ pthread_attr_setstackaddr.obj \
+ pthread_attr_getstacksize.obj \
+ pthread_attr_setstacksize.obj \
+ pthread_attr_getscope.obj \
+ pthread_attr_setscope.obj \
+ pthread_attr_setschedpolicy.obj \
+ pthread_attr_getschedpolicy.obj \
+ pthread_attr_setschedparam.obj \
+ pthread_attr_getschedparam.obj \
+ pthread_attr_setinheritsched.obj \
+ pthread_attr_getinheritsched.obj \
+ pthread_barrier_init.obj \
+ pthread_barrier_destroy.obj \
+ pthread_barrier_wait.obj \
+ pthread_barrierattr_init.obj \
+ pthread_barrierattr_destroy.obj \
+ pthread_barrierattr_setpshared.obj \
+ pthread_barrierattr_getpshared.obj \
+ pthread_setcancelstate.obj \
+ pthread_setcanceltype.obj \
+ pthread_testcancel.obj \
+ pthread_cancel.obj \
+ cleanup.obj \
+ pthread_condattr_destroy.obj \
+ pthread_condattr_getpshared.obj \
+ pthread_condattr_init.obj \
+ pthread_condattr_setpshared.obj \
+ pthread_cond_destroy.obj \
+ pthread_cond_init.obj \
+ pthread_cond_signal.obj \
+ pthread_cond_wait.obj \
+ create.obj \
+ dll.obj \
+ autostatic.obj \
+ errno.obj \
+ pthread_exit.obj \
+ fork.obj \
+ global.obj \
+ pthread_mutex_init.obj \
+ pthread_mutex_destroy.obj \
+ pthread_mutexattr_init.obj \
+ pthread_mutexattr_destroy.obj \
+ pthread_mutexattr_getpshared.obj \
+ pthread_mutexattr_setpshared.obj \
+ pthread_mutexattr_settype.obj \
+ pthread_mutexattr_gettype.obj \
+ pthread_mutexattr_setrobust.obj \
+ pthread_mutexattr_getrobust.obj \
+ pthread_mutex_lock.obj \
+ pthread_mutex_timedlock.obj \
+ pthread_mutex_unlock.obj \
+ pthread_mutex_trylock.obj \
+ pthread_mutex_consistent.obj \
+ pthread_mutexattr_setkind_np.obj \
+ pthread_mutexattr_getkind_np.obj \
+ pthread_getw32threadhandle_np.obj \
+ pthread_getunique_np.obj \
+ pthread_delay_np.obj \
+ pthread_num_processors_np.obj \
+ pthread_win32_attach_detach_np.obj \
+ pthread_equal.obj \
+ pthread_getconcurrency.obj \
+ pthread_once.obj \
+ pthread_self.obj \
+ pthread_setconcurrency.obj \
+ pthread_rwlock_init.obj \
+ pthread_rwlock_destroy.obj \
+ pthread_rwlockattr_init.obj \
+ pthread_rwlockattr_destroy.obj \
+ pthread_rwlockattr_getpshared.obj \
+ pthread_rwlockattr_setpshared.obj \
+ pthread_rwlock_rdlock.obj \
+ pthread_rwlock_wrlock.obj \
+ pthread_rwlock_unlock.obj \
+ pthread_rwlock_tryrdlock.obj \
+ pthread_rwlock_trywrlock.obj \
+ pthread_setschedparam.obj \
+ pthread_getschedparam.obj \
+ pthread_timechange_handler_np.obj \
+ ptw32_is_attr.obj \
+ ptw32_processInitialize.obj \
+ ptw32_processTerminate.obj \
+ ptw32_threadStart.obj \
+ ptw32_threadDestroy.obj \
+ ptw32_tkAssocCreate.obj \
+ ptw32_tkAssocDestroy.obj \
+ ptw32_callUserDestroyRoutines.obj \
+ ptw32_timespec.obj \
+ ptw32_throw.obj \
+ ptw32_getprocessors.obj \
+ ptw32_calloc.obj \
+ ptw32_new.obj \
+ ptw32_reuse.obj \
+ ptw32_rwlock_check_need_init.obj \
+ ptw32_cond_check_need_init.obj \
+ ptw32_mutex_check_need_init.obj \
+ ptw32_semwait.obj \
+ ptw32_relmillisecs.obj \
+ ptw32_MCS_lock.obj \
+ sched_get_priority_max.obj \
+ sched_get_priority_min.obj \
+ sched_setscheduler.obj \
+ sched_getscheduler.obj \
+ sched_yield.obj \
+ sem_init.obj \
+ sem_destroy.obj \
+ sem_trywait.obj \
+ sem_timedwait.obj \
+ sem_wait.obj \
+ sem_post.obj \
+ sem_post_multiple.obj \
+ sem_getvalue.obj \
+ sem_open.obj \
+ sem_close.obj \
+ sem_unlink.obj \
+ signal.obj \
+ pthread_kill.obj \
+ ptw32_spinlock_check_need_init.obj \
+ pthread_spin_init.obj \
+ pthread_spin_destroy.obj \
+ pthread_spin_lock.obj \
+ pthread_spin_unlock.obj \
+ pthread_spin_trylock.obj \
+ pthread_detach.obj \
+ pthread_join.obj \
+ pthread_key_create.obj \
+ pthread_key_delete.obj \
+ pthread_setspecific.obj \
+ pthread_getspecific.obj \
+ w32_CancelableWait.obj \
+ version.res
+
+INCL = config.h implement.h semaphore.h pthread.h need_errno.h
+
+ATTR_SRCS = \
+ pthread_attr_init.c \
+ pthread_attr_destroy.c \
+ pthread_attr_getdetachstate.c \
+ pthread_attr_setdetachstate.c \
+ pthread_attr_getstackaddr.c \
+ pthread_attr_setstackaddr.c \
+ pthread_attr_getstacksize.c \
+ pthread_attr_setstacksize.c \
+ pthread_attr_getscope.c \
+ pthread_attr_setscope.c
+
+BARRIER_SRCS = \
+ pthread_barrier_init.c \
+ pthread_barrier_destroy.c \
+ pthread_barrier_wait.c \
+ pthread_barrierattr_init.c \
+ pthread_barrierattr_destroy.c \
+ pthread_barrierattr_setpshared.c \
+ pthread_barrierattr_getpshared.c
+
+CANCEL_SRCS = \
+ pthread_setcancelstate.c \
+ pthread_setcanceltype.c \
+ pthread_testcancel.c \
+ pthread_cancel.c
+
+CONDVAR_SRCS = \
+ ptw32_cond_check_need_init.c \
+ pthread_condattr_destroy.c \
+ pthread_condattr_getpshared.c \
+ pthread_condattr_init.c \
+ pthread_condattr_setpshared.c \
+ pthread_cond_destroy.c \
+ pthread_cond_init.c \
+ pthread_cond_signal.c \
+ pthread_cond_wait.c
+
+EXIT_SRCS = \
+ pthread_exit.c
+
+MISC_SRCS = \
+ pthread_equal.c \
+ pthread_getconcurrency.c \
+ pthread_kill.c \
+ pthread_once.c \
+ pthread_self.c \
+ pthread_setconcurrency.c \
+ ptw32_calloc.c \
+ ptw32_MCS_lock.c \
+ ptw32_new.c \
+ ptw32_reuse.c \
+ ptw32_relmillisecs.c \
+ w32_CancelableWait.c
+
+MUTEX_SRCS = \
+ ptw32_mutex_check_need_init.c \
+ pthread_mutex_init.c \
+ pthread_mutex_destroy.c \
+ pthread_mutexattr_init.c \
+ pthread_mutexattr_destroy.c \
+ pthread_mutexattr_getpshared.c \
+ pthread_mutexattr_setpshared.c \
+ pthread_mutexattr_settype.c \
+ pthread_mutexattr_gettype.c \
+ pthread_mutexattr_setrobust.c \
+ pthread_mutexattr_getrobust.c \
+ pthread_mutex_lock.c \
+ pthread_mutex_timedlock.c \
+ pthread_mutex_unlock.c \
+ pthread_mutex_trylock.c \
+ pthread_mutex_consistent.c
+
+NONPORTABLE_SRCS = \
+ pthread_mutexattr_setkind_np.c \
+ pthread_mutexattr_getkind_np.c \
+ pthread_getw32threadhandle_np.c \
+ pthread_getunique_np.c \
+ pthread_delay_np.c \
+ pthread_num_processors_np.c \
+ pthread_win32_attach_detach_np.c \
+ pthread_timechange_handler_np.c
+
+PRIVATE_SRCS = \
+ ptw32_is_attr.c \
+ ptw32_processInitialize.c \
+ ptw32_processTerminate.c \
+ ptw32_threadStart.c \
+ ptw32_threadDestroy.c \
+ ptw32_tkAssocCreate.c \
+ ptw32_tkAssocDestroy.c \
+ ptw32_callUserDestroyRoutines.c \
+ ptw32_semwait.c \
+ ptw32_timespec.c \
+ ptw32_throw.c \
+ ptw32_getprocessors.c
+
+RWLOCK_SRCS = \
+ ptw32_rwlock_check_need_init.c \
+ ptw32_rwlock_cancelwrwait.c \
+ pthread_rwlock_init.c \
+ pthread_rwlock_destroy.c \
+ pthread_rwlockattr_init.c \
+ pthread_rwlockattr_destroy.c \
+ pthread_rwlockattr_getpshared.c \
+ pthread_rwlockattr_setpshared.c \
+ pthread_rwlock_rdlock.c \
+ pthread_rwlock_timedrdlock.c \
+ pthread_rwlock_wrlock.c \
+ pthread_rwlock_timedwrlock.c \
+ pthread_rwlock_unlock.c \
+ pthread_rwlock_tryrdlock.c \
+ pthread_rwlock_trywrlock.c
+
+SCHED_SRCS = \
+ pthread_attr_setschedpolicy.c \
+ pthread_attr_getschedpolicy.c \
+ pthread_attr_setschedparam.c \
+ pthread_attr_getschedparam.c \
+ pthread_attr_setinheritsched.c \
+ pthread_attr_getinheritsched.c \
+ pthread_setschedparam.c \
+ pthread_getschedparam.c \
+ sched_get_priority_max.c \
+ sched_get_priority_min.c \
+ sched_setscheduler.c \
+ sched_getscheduler.c \
+ sched_yield.c
+
+SEMAPHORE_SRCS = \
+ sem_init.c \
+ sem_destroy.c \
+ sem_trywait.c \
+ sem_timedwait.c \
+ sem_wait.c \
+ sem_post.c \
+ sem_post_multiple.c \
+ sem_getvalue.c \
+ sem_open.c \
+ sem_close.c \
+ sem_unlink.c
+
+SPIN_SRCS = \
+ ptw32_spinlock_check_need_init.c \
+ pthread_spin_init.c \
+ pthread_spin_destroy.c \
+ pthread_spin_lock.c \
+ pthread_spin_unlock.c \
+ pthread_spin_trylock.c
+
+SYNC_SRCS = \
+ pthread_detach.c \
+ pthread_join.c
+
+TSD_SRCS = \
+ pthread_key_create.c \
+ pthread_key_delete.c \
+ pthread_setspecific.c \
+ pthread_getspecific.c
+
+
+help:
+ @ echo Run one of the following command lines:
+ @ echo nmake clean VCE (to build the MSVC dll with C++ exception handling)
+ @ echo nmake clean VSE (to build the MSVC dll with structured exception handling)
+ @ echo nmake clean VC (to build the MSVC dll with C cleanup code)
+ @ echo nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling)
+ @ echo nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling)
+ @ echo nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code)
+ @ echo nmake clean VC-static (to build the MSVC static lib with C cleanup code)
+ @ echo nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling)
+ @ echo nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling)
+ @ echo nmake clean VC-debug (to build the debug MSVC dll with C cleanup code)
+ @ echo nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling)
+ @ echo nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling)
+ @ echo nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code)
+ @ echo nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code)
+
+all:
+ @ $(MAKE) /E clean VCE-inlined
+ @ $(MAKE) /E clean VSE-inlined
+ @ $(MAKE) /E clean VC-inlined
+ @ $(MAKE) /E clean VCE-inlined-debug
+ @ $(MAKE) /E clean VSE-inlined-debug
+ @ $(MAKE) /E clean VC-inlined-debug
+
+VCE:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll
+
+VCE-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll
+
+VSE:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll
+
+VSE-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll
+
+VC:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll
+
+VC-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).dll
+
+#
+# The so-called inlined DLL is just a single translation unit with
+# inlining optimisation turned on.
+#
+VCE-inlined:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp
+
+VCE-inlined-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp
+
+VSE-inlined:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp
+
+VSE-inlined-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp
+
+VC-inlined:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp
+
+VC-inlined-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp
+
+VC-static:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static
+
+VC-static-debug:
+ @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).static
+
+realclean: clean
+ if exist pthread*.dll del pthread*.dll
+ if exist pthread*.lib del pthread*.lib
+ if exist *.manifest del *.manifest
+ if exist *.stamp del *.stamp
+
+clean:
+ if exist *.obj del *.obj
+ if exist *.def del *.def
+ if exist *.ilk del *.ilk
+ if exist *.pdb del *.pdb
+ if exist *.exp del *.exp
+ if exist *.map del *.map
+ if exist *.o del *.o
+ if exist *.i del *.i
+ if exist *.res del *.res
+
+
+install:
+ copy pthread*.dll $(DLLDEST)
+ copy pthread*.lib $(LIBDEST)
+ copy pthread.h $(HDRDEST)
+ copy sched.h $(HDRDEST)
+ copy semaphore.h $(HDRDEST)
+
+$(DLLS): $(DLL_OBJS)
+ $(CC) /LDd /Zi /nologo $(DLL_OBJS) /link /implib:$*.lib $(XLIBS) /out:$@
+
+$(INLINED_STAMPS): $(DLL_INLINED_OBJS)
+ $(CC) /LDd /Zi /nologo $(DLL_INLINED_OBJS) /link /implib:$*.lib $(XLIBS) /out:$*.dll
+
+$(STATIC_STAMPS): $(DLL_INLINED_OBJS)
+ if exist $*.lib del $*.lib
+ lib $(DLL_INLINED_OBJS) /out:$*.lib
+
+.c.obj:
+ $(CC) $(EHFLAGS) /D$(CLEANUP) -c $<
+
+# TARGET_CPU is an environment variable set by Visual Studio Command Prompt
+# as provided by the SDK
+.rc.res:
+ rc /dPTW32_ARCH$(TARGET_CPU) /dPTW32_RC_MSC /d$(CLEANUP) $<
+
+.c.i:
+ $(CC) /P /O2 /Ob1 $(VCFLAGS) $<
+
+attr.obj: attr.c $(ATTR_SRCS) $(INCL)
+barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.obj: exit.c $(EXIT_SRCS) $(INCL)
+misc.obj: misc.c $(MISC_SRCS) $(INCL)
+mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.obj: private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.obj: sched.c $(SCHED_SRCS) $(INCL)
+semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.obj: spin.c $(SPIN_SRCS) $(INCL)
+sync.obj: sync.c $(SYNC_SRCS) $(INCL)
+tsd.obj: tsd.c $(TSD_SRCS) $(INCL)
+version.res: version.rc $(INCL)
diff --git a/libs/pthreads/docs/NEWS b/libs/pthreads/docs/NEWS
new file mode 100644
index 0000000000..d1b789635f
--- /dev/null
+++ b/libs/pthreads/docs/NEWS
@@ -0,0 +1,1241 @@
+RELEASE 2.9.0
+-------------
+(2012-05-25)
+
+General
+-------
+New bug fixes in this release since 2.8.0 have NOT been applied to the
+1.x.x series.
+
+Some changes post 2011-02-26 in CVS may not be compatible with pre
+Windows 2000 systems.
+
+Use of other than the "C" version of the library is now discouraged.
+That is, the "C++" version fails some tests and does not provide any
+additional functionality.
+
+Testing and verification
+------------------------
+This version has been tested on SMP architecture (Intel x64 Hex Core)
+by completing the included test suite, stress and bench tests.
+
+New Features
+------------
+DLL properties now properly includes the target architecture, i.e.
+right-click on the file pthreadVC2.dll in explorer and choose the Detail
+tab will show the compiler and architecture in the description field, e.g.
+"MS C x64" or "MS C x86".
+- Ross Johnson
+
+(MSC and GNU builds) The statically linked library now automatically
+initialises and cleans up on program start/exit, i.e. statically linked
+applications need not call the routines pthread_win32_process_attach_np()
+and pthread_win32_process_detach_np() explicitly. The per-thread routine
+pthread_win32_thread_detach_np() is also called at program exit to cleanup
+POSIX resources acquired by the primary Windows native thread, if I (RJ)
+understand the process correctly. Other Windows native threads that call
+POSIX API routines may need to call the thread detach routine on thread
+exit if the application depends on reclaimed POSIX resources or running
+POSIX TSD (TLS) destructors.
+See README.NONPORTABLE for descriptions of these routines.
+- Ramiro Polla
+
+Robust mutexes are implemented within the PROCESS_PRIVATE scope. NOTE that
+pthread_mutex_* functions may return different error codes for robust
+mutexes than they otherwise do in normal usage, e.g. pthread_mutex_unlock
+is required to check ownership for all mutex types when the mutex is
+robust, whereas this does not occur for the "normal" non-robust mutex type.
+- Ross Johnson
+
+pthread_getunique_np is implemented for source level compatibility
+with some other implementations. This routine returns a 64 bit
+sequence number that is uniquely associated with a thread. It can be
+used by applications to order or hash POSIX thread handles.
+- Ross Johnson
+
+Bug fixes
+---------
+Many more changes for 64 bit systems.
+- Kai Tietz
+
+Various modifications and fixes to build and test for WinCE.
+- Marcel Ruff, Sinan Kaya
+
+Fix pthread_cond_destroy() - should not be a cancellation point. Other
+minor build problems fixed.
+- Romano Paolo Tenca
+
+Remove potential deadlock condition from pthread_cond_destroy().
+- Eric Berge
+
+Various modifications to build and test for Win64.
+- Kip Streithorst
+
+Various fixes to the QueueUserAPCEx async cancellation helper DLL
+(this is a separate download) and pthreads code cleanups.
+- Sebastian Gottschalk
+
+Removed potential NULL pointer reference.
+- Robert Kindred
+
+Removed the requirement that applications restrict the number of threads
+calling pthread_barrier_wait to just the barrier count. Also reduced the
+contention between barrier_wait and barrier_destroy. This change will have
+slowed barriers down slightly but halves the number of semaphores consumed
+per barrier to one.
+- Ross Johnson
+
+Fixed a handle leak in sched_[gs]etscheduler.
+- Mark Pizzolato
+
+Removed all of the POSIX re-entrant function compatibility macros from pthread.h.
+Some were simply not semanticly correct.
+- Igor Lubashev
+
+Threads no longer attempt to pass uncaught exceptions out of thread scope (C++
+and SEH builds only). Uncaught exceptions now cause the thread to exit with
+the return code PTHREAD_CANCELED.
+- Ross Johnson
+
+Lots of casting fixes particularly for x64, Interlocked fixes and reworking
+for x64.
+- Daniel Richard G., John Kamp
+
+Other changes
+-------------
+Dependence on the winsock library is now discretionary via
+#define RETAIN_WSALASTERROR in config.h. It is undefined by default unless
+WINCE is defined (because RJ is unsure of the dependency there).
+- Ramiro Polla
+
+Several static POSIX mutexes used for internal management were replaced by
+MCS queue-based locks to reduce resource consumption, in particular use of Win32
+objects.
+- Ross Johnson
+
+For security, the QuserEx.dll if used must now be installed in the Windows System
+folder.
+- Ross Johnson
+
+New tests
+---------
+robust[1-5].c - Robust mutexes
+sequence1.c - per-thread unique sequence numbers
+
+Modified tests and benchtests
+-----------------------------
+All mutex*.c tests wherever appropriate have been modified to also test
+robust mutexes under the same conditions.
+Added robust mutex benchtests to benchtest*.c wherever appropriate.
+
+
+RELEASE 2.8.0
+-------------
+(2006-12-22)
+
+General
+-------
+New bug fixes in this release since 2.7.0 have not been applied to the
+version 1.x.x series. It is probably time to drop version 1.
+
+Testing and verification
+------------------------
+This release has not yet been tested on SMP architechtures. All tests pass
+on a uni-processor system.
+
+Bug fixes
+---------
+Sem_destroy could return EBUSY even though no threads were waiting on the
+semaphore. Other races around invalidating semaphore structs (internally)
+have been removed as well.
+
+New tests
+---------
+semaphore5.c - tests the bug fix referred to above.
+
+
+RELEASE 2.7.0
+-------------
+(2005-06-04)
+
+General
+-------
+All new features in this release have been back-ported in release 1.11.0,
+including the incorporation of MCS locks in pthread_once, however, versions
+1 and 2 remain incompatible even though they are now identical in
+performance and functionality.
+
+Testing and verification
+------------------------
+This release has been tested (passed the test suite) on both uni-processor
+and multi-processor systems.
+- Tim Theisen
+
+Bug fixes
+---------
+Pthread_once has been re-implemented to remove priority boosting and other
+complexity to improve robustness. Races for Win32 handles that are not
+recycle-unique have been removed. The general form of pthread_once is now
+the same as that suggested earlier by Alexander Terekhov, but instead of the
+'named mutex', a queue-based lock has been implemented which has the required
+properties of dynamic self initialisation and destruction. This lock is also
+efficient. The ABI is unaffected in as much as the size of pthread_once_t has
+not changed and PTHREAD_ONCE_INIT has not changed, however, applications that
+peek inside pthread_once_t, which is supposed to be opaque, will break.
+- Vladimir Kliatchko
+
+New features
+------------
+* Support for Mingw cross development tools added to GNUmakefile.
+Mingw cross tools allow building the libraries on Linux.
+- Mikael Magnusson
+
+
+RELEASE 2.6.0
+-------------
+(2005-05-19)
+
+General
+-------
+All of the bug fixes and new features in this release have been
+back-ported in release 1.10.0.
+
+Testing and verification
+------------------------
+This release has been tested (passed the test suite) on both uni-processor
+and multi-processor systems. Thanks to Tim Theisen at TomoTherapy for
+exhaustively running the MP tests and for providing crutial observations
+and data when faults are detected.
+
+Bugs fixed
+----------
+
+* pthread_detach() now reclaims remaining thread resources if called after
+the target thread has terminated. Previously, this routine did nothing in
+this case.
+
+New tests
+---------
+
+* detach1.c - tests that pthread_detach properly invalidates the target
+thread, which indicates that the thread resources have been reclaimed.
+
+
+RELEASE 2.5.0
+-------------
+(2005-05-09)
+
+General
+-------
+
+The package now includes a reference documentation set consisting of
+HTML formatted Unix-style manual pages that have been edited for
+consistency with Pthreads-w32. The set can also be read online at:
+http://sources.redhat.com/pthreads-win32/manual/index.html
+
+Thanks again to Tim Theisen for running the test suite pre-release
+on an MP system.
+
+All of the bug fixes and new features in this release have been
+back-ported in release 1.9.0.
+
+Bugs fixed
+----------
+
+* Thread Specific Data (TSD) key management has been ammended to
+eliminate a source of (what was effectively) resource leakage (a HANDLE
+plus memory for each key destruct routine/thread association). This was
+not a true leak because these resources were eventually reclaimed when
+pthread_key_delete was run AND each thread referencing the key had exited.
+The problem was that these two conditions are often not met until very
+late, and often not until the process is about to exit.
+
+The ammended implementation avoids the need for the problematic HANDLE
+and reclaims the memory as soon as either the key is deleted OR the
+thread exits, whichever is first.
+
+Thanks to Richard Hughes at Aculab for identifying and locating the leak.
+
+* TSD key destructors are now processed up to PTHREAD_DESTRUCTOR_ITERATIONS
+times instead of just once. PTHREAD_DESTRUCTOR_ITERATIONS has been
+defined in pthread.h for some time but not used.
+
+* Fix a semaphore accounting race between sem_post/sem_post_multiple
+and sem_wait cancellation. This is the same issue as with
+sem_timedwait that was fixed in the last release.
+
+* sem_init, sem_post, and sem_post_multiple now check that the
+semaphore count never exceeds _POSIX_SEM_VALUE_MAX.
+
+* Although sigwait() is nothing more than a no-op, it should at least
+be a cancellation point to be consistent with the standard.
+
+New tests
+---------
+
+* stress1.c - attempts to expose problems in condition variable
+and semaphore timed wait logic. This test was inspired by Stephan
+Mueller's sample test code used to identify the sem_timedwait bug
+from the last release. It's not a part of the regular test suite
+because it can take awhile to run. To run it:
+nmake clean VC-stress
+
+* tsd2.c - tests that key destructors are re-run if the tsd key value is
+not NULL after the destructor routine has run. Also tests that
+pthread_setspecific() and pthread_getspecific() are callable from
+destructors.
+
+
+RELEASE 2.4.0
+-------------
+(2005-04-26)
+
+General
+-------
+
+There is now no plan to release a version 3.0.0 to fix problems in
+pthread_once(). Other possible implementations of pthread_once
+will still be investigated for a possible future release in an attempt
+to reduce the current implementation's complexity.
+
+All of the bug fixes and new features in this release have been
+back-ported for release 1.8.0.
+
+Bugs fixed
+----------
+
+* Fixed pthread_once race (failures on an MP system). Thanks to
+Tim Theisen for running exhaustive pre-release testing on his MP system
+using a range of compilers:
+ VC++ 6
+ VC++ 7.1
+ Intel C++ version 8.0
+All tests passed.
+Some minor speed improvements were also done.
+
+* Fix integer overrun error in pthread_mutex_timedlock() - missed when
+sem_timedwait() was fixed in release 2.2.0. This routine no longer returns
+ENOTSUP when NEED_SEM is defined - it is supported (NEED_SEM is only
+required for WinCE versions prior to 3.0).
+
+* Fix timeout bug in sem_timedwait().
+- Thanks to Stephan Mueller for reporting, providing diagnostic output
+and test code.
+
+* Fix several problems in the NEED_SEM conditionally included code.
+NEED_SEM included code is provided for systems that don't implement W32
+semaphores, such as WinCE prior to version 3.0. An alternate implementation
+of POSIX semaphores is built using W32 events for these systems when
+NEED_SEM is defined. This code has been completely rewritten in this
+release to reuse most of the default POSIX semaphore code, and particularly,
+to implement all of the sem_* routines supported by pthreads-win32. Tim
+Theisen also run the test suite over the NEED_SEM code on his MP system. All
+tests passed.
+
+* The library now builds without errors for the Borland Builder 5.5 compiler.
+
+New features
+------------
+
+* pthread_mutex_timedlock() and all sem_* routines provided by
+pthreads-win32 are now implemented for WinCE versions prior to 3.0. Those
+versions did not implement W32 semaphores. Define NEED_SEM in config.h when
+building the library for these systems.
+
+Known issues in this release
+----------------------------
+
+* pthread_once is too complicated - but it works as far as testing can
+determine..
+
+* The Borland version of the dll fails some of the tests with a memory read
+exception. The cause is not yet known but a compiler bug has not been ruled
+out.
+
+
+RELEASE 2.3.0
+-------------
+(2005-04-12)
+
+General
+-------
+
+Release 1.7.0 is a backport of features and bug fixes new in
+this release. See earlier notes under Release 2.0.0/General.
+
+Bugs fixed
+----------
+
+* Fixed pthread_once potential for post once_routine cancellation
+hanging due to starvation. See comments in pthread_once.c.
+Momentary priority boosting is used to ensure that, after a
+once_routine is cancelled, the thread that will run the
+once_routine is not starved by higher priority waiting threads at
+critical times. Priority boosting occurs only AFTER a once_routine
+cancellation, and is applied only to that once_control. The
+once_routine is run at the thread's normal base priority.
+
+New tests
+---------
+
+* once4.c: Aggressively tests pthread_once() under realtime
+conditions using threads with varying priorities. Windows'
+random priority boosting does not occur for threads with realtime
+priority levels.
+
+
+RELEASE 2.2.0
+-------------
+(2005-04-04)
+
+General
+-------
+
+* Added makefile targets to build static link versions of the library.
+Both MinGW and MSVC. Please note that this does not imply any change
+to the LGPL licensing, which still imposes psecific conditions on
+distributing software that has been statically linked with this library.
+
+* There is a known bug in pthread_once(). Cancellation of the init_routine
+exposes a potential starvation (i.e. deadlock) problem if a waiting thread
+has a higher priority than the initting thread. This problem will be fixed
+in version 3.0.0 of the library.
+
+Bugs fixed
+----------
+
+* Fix integer overrun error in sem_timedwait().
+Kevin Lussier
+
+* Fix preprocessor directives for static linking.
+Dimitar Panayotov
+
+
+RELEASE 2.1.0
+-------------
+(2005-03-16)
+
+Bugs fixed
+----------
+
+* Reverse change to pthread_setcancelstate() in 2.0.0.
+
+
+RELEASE 2.0.0
+-------------
+(2005-03-16)
+
+General
+-------
+
+This release represents an ABI change and the DLL version naming has
+incremented from 1 to 2, e.g. pthreadVC2.dll.
+
+Version 1.4.0 back-ports the new functionality included in this
+release. Please distribute DLLs built from that version with updates
+to applications built on pthreads-win32 version 1.x.x.
+
+The package naming has changed, replacing the snapshot date with
+the version number + descriptive information. E.g. this
+release is "pthreads-w32-2-0-0-release".
+
+Bugs fixed
+----------
+
+* pthread_setcancelstate() no longer checks for a pending
+async cancel event if the library is using alertable async
+cancel. See the README file (Prerequisites section) for info
+on adding alertable async cancelation.
+
+New features
+------------
+
+* pthread_once() now supports init_routine cancellability.
+
+New tests
+---------
+
+* Agressively test pthread_once() init_routine cancellability.
+
+
+SNAPSHOT 2005-03-08
+-------------------
+Version 1.3.0
+
+Bug reports (fixed)
+-------------------
+
+* Implicitly created threads leave Win32 handles behind after exiting.
+- Dmitrii Semii
+
+* pthread_once() starvation problem.
+- Gottlob Frege
+
+New tests
+---------
+
+* More intense testing of pthread_once().
+
+
+SNAPSHOT 2005-01-25
+-------------------
+Version 1.2.0
+
+Bug fixes
+---------
+
+* Attempted acquisition of a recursive mutex could cause waiting threads
+to not be woken when the mutex was released.
+- Ralf Kubis <RKubis at mc.com>
+
+* Various package omissions have been fixed.
+
+
+SNAPSHOT 2005-01-03
+-------------------
+Version 1.1.0
+
+Bug fixes
+---------
+
+* Unlocking recursive or errorcheck mutexes would sometimes
+unexpectedly return an EPERM error (bug introduced in
+snapshot-2004-11-03).
+- Konstantin Voronkov <beowinkle at yahoo.com>
+
+
+SNAPSHOT 2004-11-22
+-------------------
+Version 1.0.0
+
+This snapshot primarily fixes the condvar bug introduced in
+snapshot-2004-11-03. DLL versioning has also been included to allow
+applications to runtime check the Microsoft compatible DLL version
+information, and to extend the DLL naming system for ABI and major
+(non-backward compatible) API changes. See the README file for details.
+
+Bug fixes
+---------
+
+* Condition variables no longer deadlock (bug introduced in
+snapshot-2004-11-03).
+- Alexander Kotliarov and Nicolas at saintmac
+
+* DLL naming extended to avoid 'DLL hell' in the future, and to
+accommodate the ABI change introduced in snapshot-2004-11-03. Snapshot
+2004-11-03 will be removed from FTP sites.
+
+New features
+------------
+
+* A Microsoft-style version resource has been added to the DLL for
+applications that wish to check DLL compatibility at runtime.
+
+* Pthreads-win32 DLL naming has been extended to allow incompatible DLL
+versions to co-exist in the same filesystem. See the README file for details,
+but briefly: while the version information inside the DLL will change with
+each release from now on, the DLL version names will only change if the new
+DLL is not backward compatible with older applications.
+
+The versioning scheme has been borrowed from GNU Libtool, and the DLL
+naming scheme is from Cygwin. Provided the Libtool-style numbering rules are
+honoured, the Cygwin DLL naming scheme automatcally ensures that DLL name
+changes are minimal and that applications will not load an incompatible
+pthreads-win32 DLL.
+
+Those who use the pre-built DLLs will find that the DLL/LIB names have a new
+suffix (1) in this snapshot. E.g. pthreadVC1.dll etc.
+
+* The POSIX thread ID reuse uniqueness feature introduced in the last snapshot
+has been kept as default, but the behaviour can now be controlled when the DLL
+is built to effectively switch it off. This makes the library much more
+sensitive to applications that assume that POSIX thread IDs are unique, i.e.
+are not strictly compliant with POSIX. See the PTW32_THREAD_ID_REUSE_INCREMENT
+macro comments in config.h for details.
+
+Other changes
+-------------
+Certain POSIX macros have changed.
+
+These changes are intended to conform to the Single Unix Specification version 3,
+which states that, if set to 0 (zero) or not defined, then applications may use
+sysconf() to determine their values at runtime. Pthreads-win32 does not
+implement sysconf().
+
+The following macros are no longer undefined, but defined and set to -1
+(not implemented):
+
+ _POSIX_THREAD_ATTR_STACKADDR
+ _POSIX_THREAD_PRIO_INHERIT
+ _POSIX_THREAD_PRIO_PROTECT
+ _POSIX_THREAD_PROCESS_SHARED
+
+The following macros are defined and set to 200112L (implemented):
+
+ _POSIX_THREADS
+ _POSIX_THREAD_SAFE_FUNCTIONS
+ _POSIX_THREAD_ATTR_STACKSIZE
+ _POSIX_THREAD_PRIORITY_SCHEDULING
+ _POSIX_SEMAPHORES
+ _POSIX_READER_WRITER_LOCKS
+ _POSIX_SPIN_LOCKS
+ _POSIX_BARRIERS
+
+The following macros are defined and set to appropriate values:
+
+ _POSIX_THREAD_THREADS_MAX
+ _POSIX_SEM_VALUE_MAX
+ _POSIX_SEM_NSEMS_MAX
+ PTHREAD_DESTRUCTOR_ITERATIONS
+ PTHREAD_KEYS_MAX
+ PTHREAD_STACK_MIN
+ PTHREAD_THREADS_MAX
+
+
+SNAPSHOT 2004-11-03
+-------------------
+
+DLLs produced from this snapshot cannot be used with older applications without
+recompiling the application, due to a change to pthread_t to provide unique POSIX
+thread IDs.
+
+Although this snapshot passes the extended test suite, many of the changes are
+fairly major, and some applications may show different behaviour than previously,
+so adopt with care. Hopefully, any changed behaviour will be due to the library
+being better at it's job, not worse.
+
+Bug fixes
+---------
+
+* pthread_create() no longer accepts NULL as the thread reference arg.
+A segfault (memory access fault) will result, and no thread will be
+created.
+
+* pthread_barrier_wait() no longer acts as a cancelation point.
+
+* Fix potential race condition in pthread_once()
+- Tristan Savatier <tristan at mpegtv.com>
+
+* Changes to pthread_cond_destroy() exposed some coding weaknesses in several
+test suite mini-apps because pthread_cond_destroy() now returns EBUSY if the CV
+is still in use.
+
+New features
+------------
+
+* Added for compatibility:
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER,
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER,
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+
+* Initial support for Digital Mars compiler
+- Anuj Goyal <anuj.goyal at gmail.com>
+
+* Faster Mutexes. These have been been rewritten following a model provided by
+Alexander Terekhov that reduces kernel space checks, and eliminates some additional
+critical sections used to manage a race between timedlock expiration and unlock.
+Please be aware that the new mutexes do not enforce strict absolute FIFO scheduling
+of mutexes, however any out-of-order lock acquisition should be very rare.
+
+* Faster semaphores. Following a similar model to mutexes above, these have been
+rewritten to use preliminary users space checks.
+
+* sem_getvalue() now returns the number of waiters.
+
+* The POSIX thread ID now has much stronger uniqueness characteristics. The library
+garrantees not to reuse the same thread ID for at least 2^(wordsize) thread
+destruction/creation cycles.
+
+New tests
+---------
+
+* semaphore4.c: Tests cancelation of the new sem_wait().
+
+* semaphore4t.c: Likewise for sem_timedwait().
+
+* rwlock8.c: Tests and times the slow execution paths of r/w locks, and the CVs,
+mutexes, and semaphores that they're built on.
+
+
+SNAPSHOT 2004-05-16
+-------------------
+
+Attempt to add Watcom to the list of compilers that can build the library.
+This failed in the end due to it's non-thread-aware errno. The library
+builds but the test suite fails. See README.Watcom for more details.
+
+Bug fixes
+---------
+* Bug and memory leak in sem_init()
+- Alex Blanco <Alex.Blanco at motorola.com>
+
+* ptw32_getprocessors() now returns CPU count of 1 for WinCE.
+- James Ewing <james.ewing at sveasoft.com>
+
+* pthread_cond_wait() could be canceled at a point where it should not
+be cancelable. Fixed.
+- Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+* sem_timedwait() had an incorrect timeout calculation.
+- Philippe Di Cristo <philipped at voicebox.com>
+
+* Fix a memory leak left behind after threads are destroyed.
+- P. van Bruggen <pietvb at newbridges.nl>
+
+New features
+------------
+* Ported to AMD64.
+- Makoto Kato <raven at oldskool.jp>
+
+* True pre-emptive asynchronous cancelation of threads. This is optional
+and requires that Panagiotis E. Hadjidoukas's QueueUserAPCEx package be
+installed. This package is included in the pthreads-win32 self-unpacking
+Zip archive starting from this snapshot. See the README.txt file inside
+the package for installation details.
+
+Note: If you don't use async cancelation in your application, or don't need
+to cancel threads that are blocked on system resources such as network I/O,
+then the default non-preemptive async cancelation is probably good enough.
+However, pthreads-win32 auto-detects the availability of these components
+at run-time, so you don't need to rebuild the library from source if you
+change your mind later.
+
+All of the advice available in books and elsewhere on the undesirability
+of using async cancelation in any application still stands, but this
+feature is a welcome addition with respect to the library's conformance to
+the POSIX standard.
+
+SNAPSHOT 2003-09-18
+-------------------
+
+Cleanup of thread priority management. In particular, setting of thread
+priority now attempts to map invalid Win32 values within the range returned
+by sched_get_priority_min/max() to useful values. See README.NONPORTABLE
+under "Thread priority".
+
+Bug fixes
+---------
+* pthread_getschedparam() now returns the priority given by the most recent
+call to pthread_setschedparam() or established by pthread_create(), as
+required by the standard. Previously, pthread_getschedparam() incorrectly
+returned the running thread priority at the time of the call, which may have
+been adjusted or temporarily promoted/demoted.
+
+* sched_get_priority_min() and sched_get_priority_max() now return -1 on error
+and set errno. Previously, they incorrectly returned the error value directly.
+
+
+SNAPSHOT 2003-09-04
+-------------------
+
+Bug fixes
+---------
+* ptw32_cancelableWait() now allows cancelation of waiting implicit POSIX
+threads.
+
+New test
+--------
+* cancel8.c tests cancelation of Win32 threads waiting at a POSIX cancelation
+point.
+
+
+SNAPSHOT 2003-09-03
+-------------------
+
+Bug fixes
+---------
+* pthread_self() would free the newly created implicit POSIX thread handle if
+DuplicateHandle failed instead of recycle it (very unlikely).
+
+* pthread_exit() was neither freeing nor recycling the POSIX thread struct
+for implicit POSIX threads.
+
+New feature - Cancelation of/by Win32 (non-POSIX) threads
+---------------------------------------------------------
+Since John Bossom's original implementation, the library has allowed non-POSIX
+initialised threads (Win32 threads) to call pthreads-win32 routines and
+therefore interact with POSIX threads. This is done by creating an on-the-fly
+POSIX thread ID for the Win32 thread that, once created, allows fully
+reciprical interaction. This did not extend to thread cancelation (async or
+deferred). Now it does.
+
+Any thread can be canceled by any other thread (Win32 or POSIX) if the former
+thread's POSIX pthread_t value is known. It's TSD destructors and POSIX
+cleanup handlers will be run before the thread exits with an exit code of
+PTHREAD_CANCELED (retrieved with GetExitCodeThread()).
+
+This allows a Win32 thread to, for example, call POSIX CV routines in the same way
+that POSIX threads would/should, with pthread_cond_wait() cancelability and
+cleanup handlers (pthread_cond_wait() is a POSIX cancelation point).
+
+By adding cancelation, Win32 threads should now be able to call all POSIX
+threads routines that make sense including semaphores, mutexes, condition
+variables, read/write locks, barriers, spinlocks, tsd, cleanup push/pop,
+cancelation, pthread_exit, scheduling, etc.
+
+Note that these on-the-fly 'implicit' POSIX thread IDs are initialised as detached
+(not joinable) with deferred cancelation type. The POSIX thread ID will be created
+automatically by any POSIX routines that need a POSIX handle (unless the routine
+needs a pthread_t as a parameter of course). A Win32 thread can discover it's own
+POSIX thread ID by calling pthread_self(), which will create the handle if
+necessary and return the pthread_t value.
+
+New tests
+---------
+Test the above new feature.
+
+
+SNAPSHOT 2003-08-19
+-------------------
+
+This snapshot fixes some accidental corruption to new test case sources.
+There are no changes to the library source code.
+
+
+SNAPSHOT 2003-08-15
+-------------------
+
+Bug fixes
+---------
+
+* pthread.dsp now uses correct compile flags (/MD).
+- Viv <vcotirlea@hotmail.com>
+
+* pthread_win32_process_detach_np() fixed memory leak.
+- Steven Reddie <Steven.Reddie@ca.com>
+
+* pthread_mutex_destroy() fixed incorrect return code.
+- Nicolas Barry <boozai@yahoo.com>
+
+* pthread_spin_destroy() fixed memory leak.
+- Piet van Bruggen <pietvb@newbridges.nl>
+
+* Various changes to tighten arg checking, and to work with later versions of
+MinGW32 and MsysDTK.
+
+* pthread_getschedparam() etc, fixed dangerous thread validity checking.
+- Nicolas Barry <boozai@yahoo.com>
+
+* POSIX thread handles are now reused and their memory is not freed on thread exit.
+This allows for stronger thread validity checking.
+
+New standard routine
+--------------------
+
+* pthread_kill() added to provide thread validity checking to applications.
+It does not accept any non zero values for the signal arg.
+
+New test cases
+--------------
+
+* New test cases to confirm validity checking, pthread_kill(), and thread reuse.
+
+
+SNAPSHOT 2003-05-10
+-------------------
+
+Bug fixes
+---------
+
+* pthread_mutex_trylock() now returns correct error values.
+pthread_mutex_destroy() will no longer destroy a recursively locked mutex.
+pthread_mutex_lock() is no longer inadvertantly behaving as a cancelation point.
+- Thomas Pfaff <tpfaff@gmx.net>
+
+* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex
+ownership, causing deadlocks in some applications.
+- Robert Strycek <strycek@posam.sk> and Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+
+SNAPSHOT 2002-11-04
+-------------------
+
+Bug fixes
+---------
+
+* sem_getvalue() now returns the correct value under Win NT and WinCE.
+- Rob Fanner <rfanner@stonethree.com>
+
+* sem_timedwait() now uses tighter checks for unreasonable
+abstime values - that would result in unexpected timeout values.
+
+* ptw32_cond_wait_cleanup() no longer mysteriously consumes
+CV signals but may produce more spurious wakeups. It is believed
+that the sem_timedwait() call is consuming a CV signal that it
+shouldn't.
+- Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+* Fixed a memory leak in ptw32_threadDestroy() for implicit threads.
+
+* Fixed potential for deadlock in pthread_cond_destroy().
+A deadlock could occur for statically declared CVs (PTHREAD_COND_INITIALIZER),
+when one thread is attempting to destroy the condition variable while another
+is attempting to dynamically initialize it.
+- Michael Johnson <michaelj@maine.rr.com>
+
+
+SNAPSHOT 2002-03-02
+-------------------
+
+Cleanup code default style. (IMPORTANT)
+----------------------------------------------------------------------
+Previously, if not defined, the cleanup style was determined automatically
+from the compiler/language, and one of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw() in private.c).
+
+In short, the exceptions versions of the library throw an exception
+when a thread is canceled or exits (via pthread_exit()), which is
+caught by a handler in the thread startup routine, so that the
+the correct stack unwinding occurs regardless of where the thread
+is when it's canceled or exits via pthread_exit().
+
+In this and future snapshots, unless the build explicitly defines (e.g.
+via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build NOW always defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most
+current commercial Unix POSIX threads implementations. Compaq's TRU64
+may be an exception (no pun intended) and possible future trend.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+E.g. regardless of whether your app is C or C++, if you link with
+pthreadVC.lib or libpthreadGC.a, then you must define __CLEANUP_C.
+
+
+THE POINT OF ALL THIS IS: if you have not been defining one of these
+explicitly, then the defaults as described at the top of this
+section were being used.
+
+THIS NOW CHANGES, as has been explained above, but to try to make this
+clearer here's an example:
+
+If you were building your application with MSVC++ i.e. using C++
+exceptions and not explicitly defining one of __CLEANUP_*, then
+__CLEANUP_C++ was automatically defined for you in pthread.h.
+You should have been linking with pthreadVCE.dll, which does
+stack unwinding.
+
+If you now build your application as you had before, pthread.h will now
+automatically set __CLEANUP_C as the default style, and you will need to
+link with pthreadVC.dll. Stack unwinding will now NOT occur when a thread
+is canceled, or the thread calls pthread_exit().
+
+Your application will now most likely behave differently to previous
+versions, and in non-obvious ways. Most likely is that locally
+instantiated objects may not be destroyed or cleaned up after a thread
+is canceled.
+
+If you want the same behaviour as before, then you must now define
+__CLEANUP_C++ explicitly using a compiler option and link with
+pthreadVCE.dll as you did before.
+
+
+WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
+Because no commercial Unix POSIX threads implementation allows you to
+choose to have stack unwinding. Therefore, providing it in pthread-win32
+as a default is dangerous. We still provide the choice but unless
+you consciously choose to do otherwise, your pthreads applications will
+now run or crash in similar ways irrespective of the threads platform
+you use. Or at least this is the hope.
+
+
+WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
+There are a few reasons:
+- because there are well respected POSIX threads people who believe
+ that POSIX threads implementations should be exceptions aware and
+ do the expected thing in that context. (There are equally respected
+ people who believe it should not be easily accessible, if it's there
+ at all, for unconditional conformity to other implementations.)
+- because pthreads-win32 is one of the few implementations that has
+ the choice, perhaps the only freely available one, and so offers
+ a laboratory to people who may want to explore the effects;
+- although the code will always be around somewhere for anyone who
+ wants it, once it's removed from the current version it will not be
+ nearly as visible to people who may have a use for it.
+
+
+Source module splitting
+-----------------------
+In order to enable smaller image sizes to be generated
+for applications that link statically with the library,
+most routines have been separated out into individual
+source code files.
+
+This is being done in such a way as to be backward compatible.
+The old source files are reused to congregate the individual
+routine files into larger translation units (via a bunch of
+# includes) so that the compiler can still optimise wherever
+possible, e.g. through inlining, which can only be done
+within the same translation unit.
+
+It is also possible to build the entire library by compiling
+the single file named "pthread.c", which just #includes all
+the secondary congregation source files. The compiler
+may be able to use this to do more inlining of routines.
+
+Although the GNU compiler is able to produce libraries with
+the necessary separation (the -ffunction-segments switch),
+AFAIK, the MSVC and other compilers don't have this feature.
+
+Finally, since I use makefiles and command-line compilation,
+I don't know what havoc this reorganisation may wreak amongst
+IDE project file users. You should be able to continue
+using your existing project files without modification.
+
+
+New non-portable functions
+--------------------------
+pthread_num_processors_np():
+ Returns the number of processors in the system that are
+ available to the process, as determined from the processor
+ affinity mask.
+
+pthread_timechange_handler_np():
+ To improve tolerance against operator or time service initiated
+ system clock changes.
+
+ This routine can be called by an application when it
+ receives a WM_TIMECHANGE message from the system. At present
+ it broadcasts all condition variables so that waiting threads
+ can wake up and re-evaluate their conditions and restart
+ their timed waits if required.
+ - Suggested by Alexander Terekhov
+
+
+Platform dependence
+-------------------
+As Win95 doesn't provide one, the library now contains
+it's own InterlockedCompareExchange() routine, which is used
+whenever Windows doesn't provide it. InterlockedCompareExchange()
+is used to implement spinlocks and barriers, and also in mutexes.
+This routine relies on the CMPXCHG machine instruction which
+is not available on i386 CPUs. This library (from snapshot
+20010712 onwards) is therefore no longer supported on i386
+processor platforms.
+
+
+New standard routines
+---------------------
+For source code portability only - rwlocks cannot be process shared yet.
+
+ pthread_rwlockattr_init()
+ pthread_rwlockattr_destroy()
+ pthread_rwlockattr_setpshared()
+ pthread_rwlockattr_getpshared()
+
+As defined in the new POSIX standard, and the Single Unix Spec version 3:
+
+ sem_timedwait()
+ pthread_mutex_timedlock() - Alexander Terekhov and Thomas Pfaff
+ pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock()
+ pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock()
+
+
+pthread.h no longer includes windows.h
+--------------------------------------
+[Not yet for G++]
+
+This was done to prevent conflicts.
+
+HANDLE, DWORD, and NULL are temporarily defined within pthread.h if
+they are not already.
+
+
+pthread.h, sched.h and semaphore.h now use dllexport/dllimport
+--------------------------------------------------------------
+Not only to avoid the need for the pthread.def file, but to
+improve performance. Apparently, declaring functions with dllimport
+generates a direct call to the function and avoids the overhead
+of a stub function call.
+
+Bug fixes
+---------
+* Fixed potential NULL pointer dereferences in pthread_mutexattr_init,
+pthread_mutexattr_getpshared, pthread_barrierattr_init,
+pthread_barrierattr_getpshared, and pthread_condattr_getpshared.
+- Scott McCaskill <scott@magruder.org>
+
+* Removed potential race condition in pthread_mutex_trylock and
+pthread_mutex_lock;
+- Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+* The behaviour of pthread_mutex_trylock in relation to
+recursive mutexes was inconsistent with commercial implementations.
+Trylock would return EBUSY if the lock was owned already by the
+calling thread regardless of mutex type. Trylock now increments the
+recursion count and returns 0 for RECURSIVE mutexes, and will
+return EDEADLK rather than EBUSY for ERRORCHECK mutexes. This is
+consistent with Solaris.
+- Thomas Pfaff <tpfaff@gmx.net>
+
+* Found a fix for the library and workaround for applications for
+the known bug #2, i.e. where __CLEANUP_CXX or __CLEANUP_SEH is defined.
+See the "Known Bugs in this snapshot" section below.
+
+This could be made transparent to applications by replacing the macros that
+define the current C++ and SEH versions of pthread_cleanup_push/pop
+with the C version, but AFAIK cleanup handlers would not then run in the
+correct sequence with destructors and exception cleanup handlers when
+an exception occurs.
+
+* Cancelation once started in a thread cannot now be inadvertantly
+double canceled. That is, once a thread begins it's cancelation run,
+cancelation is disabled and a subsequent cancel request will
+return an error (ESRCH).
+
+* errno: An incorrect compiler directive caused a local version
+of errno to be used instead of the Win32 errno. Both instances are
+thread-safe but applications checking errno after a pthreads-win32
+call would be wrong. Fixing this also fixed a bad compiler
+option in the testsuite (/MT should have been /MD) which is
+needed to link with the correct library MSVCRT.LIB.
+
+
+SNAPSHOT 2001-07-12
+-------------------
+
+To be added
+
+
+SNAPSHOT 2001-07-03
+-------------------
+
+To be added
+
+
+SNAPSHOT 2000-08-13
+-------------------
+
+New:
+- Renamed DLL and LIB files:
+ pthreadVSE.dll (MS VC++/Structured EH)
+ pthreadVSE.lib
+ pthreadVCE.dll (MS VC++/C++ EH)
+ pthreadVCE.lib
+ pthreadGCE.dll (GNU G++/C++ EH)
+ libpthreadw32.a
+
+ Both your application and the pthread dll should use the
+ same exception handling scheme.
+
+Bugs fixed:
+- MSVC++ C++ exception handling.
+
+Some new tests have been added.
+
+
+SNAPSHOT 2000-08-10
+-------------------
+
+New:
+- asynchronous cancelation on X86 (Jason Nye)
+- Makefile compatible with MS nmake to replace
+ buildlib.bat
+- GNUmakefile for Mingw32
+- tests/Makefile for MS nmake replaces runall.bat
+- tests/GNUmakefile for Mingw32
+
+Bugs fixed:
+- kernel32 load/free problem
+- attempt to hide internel exceptions from application
+ exception handlers (__try/__except and try/catch blocks)
+- Win32 thread handle leakage bug
+ (David Baggett/Paul Redondo/Eyal Lebedinsky)
+
+Some new tests have been added.
+
+
+SNAPSHOT 1999-11-02
+-------------------
+
+Bugs fixed:
+- ctime_r macro had an incorrect argument (Erik Hensema),
+- threads were not being created
+ PTHREAD_CANCEL_DEFERRED. This should have
+ had little effect as deferred is the only
+ supported type. (Ross Johnson).
+
+Some compatibility improvements added, eg.
+- pthread_setcancelstate accepts NULL pointer
+ for the previous value argument. Ditto for
+ pthread_setcanceltype. This is compatible
+ with Solaris but should not affect
+ standard applications (Erik Hensema)
+
+Some new tests have been added.
+
+
+SNAPSHOT 1999-10-17
+-------------------
+
+Bug fix - Cancelation of threads waiting on condition variables
+now works properly (Lorin Hochstein and Peter Slacik)
+
+
+SNAPSHOT 1999-08-12
+-------------------
+
+Fixed exception stack cleanup if calling pthread_exit()
+- (Lorin Hochstein and John Bossom).
+
+Fixed bugs in condition variables - (Peter Slacik):
+ - additional contention checks
+ - properly adjust number of waiting threads after timed
+ condvar timeout.
+
+
+SNAPSHOT 1999-05-30
+-------------------
+
+Some minor bugs have been fixed. See the ChangeLog file for details.
+
+Some more POSIX 1b functions are now included but ony return an
+error (ENOSYS) if called. They are:
+
+ sem_open
+ sem_close
+ sem_unlink
+ sem_getvalue
+
+
+SNAPSHOT 1999-04-07
+-------------------
+
+Some POSIX 1b functions which were internally supported are now
+available as exported functions:
+
+ sem_init
+ sem_destroy
+ sem_wait
+ sem_trywait
+ sem_post
+ sched_yield
+ sched_get_priority_min
+ sched_get_priority_max
+
+Some minor bugs have been fixed. See the ChangeLog file for details.
+
+
+SNAPSHOT 1999-03-16
+-------------------
+
+Initial release.
+
diff --git a/libs/pthreads/docs/Nmakefile b/libs/pthreads/docs/Nmakefile
new file mode 100644
index 0000000000..d9e5bf1bc7
--- /dev/null
+++ b/libs/pthreads/docs/Nmakefile
@@ -0,0 +1,24 @@
+/*
+ * nmake file for uwin pthread library
+ */
+
+VERSION = -
+CCFLAGS = -V -g $(CC.DLL)
+HAVE_PTW32_CONFIG_H == 1
+_MT == 1
+_timeb == timeb
+_ftime == ftime
+_errno == _ast_errno
+
+$(INCLUDEDIR) :INSTALLDIR: pthread.h sched.h
+
+pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \
+ create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \
+ rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c
+
+:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \
+ Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \
+ TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \
+ config.guess config.h.in config.sub configure configure.in signal.c \
+ README.CV README.NONPORTABLE pthread.dsp pthread.dsw
+
diff --git a/libs/pthreads/docs/PROGRESS b/libs/pthreads/docs/PROGRESS
new file mode 100644
index 0000000000..9abf0bca47
--- /dev/null
+++ b/libs/pthreads/docs/PROGRESS
@@ -0,0 +1,4 @@
+Please see the ANNOUNCE file "Level of Standards Conformance"
+or the web page:
+
+http://sources.redhat.com/pthreads-win32/conformance.html
diff --git a/libs/pthreads/docs/README b/libs/pthreads/docs/README
new file mode 100644
index 0000000000..545360bfa7
--- /dev/null
+++ b/libs/pthreads/docs/README
@@ -0,0 +1,601 @@
+PTHREADS-WIN32
+==============
+
+Pthreads-win32 is free software, distributed under the GNU Lesser
+General Public License (LGPL). See the file 'COPYING.LIB' for terms
+and conditions. Also see the file 'COPYING' for information
+specific to pthreads-win32, copyrights and the LGPL.
+
+
+What is it?
+-----------
+
+Pthreads-win32 is an Open Source Software implementation of the
+Threads component of the POSIX 1003.1c 1995 Standard (or later)
+for Microsoft's Win32 environment. Some functions from POSIX
+1003.1b are also supported including semaphores. Other related
+functions include the set of read-write lock functions. The
+library also supports some of the functionality of the Open
+Group's Single Unix specification, version 2, namely mutex types,
+plus some common and pthreads-win32 specific non-portable
+routines (see README.NONPORTABLE).
+
+See the file "ANNOUNCE" for more information including standards
+conformance details and the list of supported and unsupported
+routines.
+
+
+Prerequisites
+-------------
+MSVC or GNU C (MinGW32 MSys development kit)
+ To build from source.
+
+QueueUserAPCEx by Panagiotis E. Hadjidoukas
+ To support any thread cancelation in C++ library builds or
+ to support cancelation of blocked threads in any build.
+ This library is not required otherwise.
+
+ For true async cancelation of threads (including blocked threads).
+ This is a DLL and Windows driver that provides pre-emptive APC
+ by forcing threads into an alertable state when the APC is queued.
+ Both the DLL and driver are provided with the pthreads-win32.exe
+ self-unpacking ZIP, and on the pthreads-win32 FTP site (in source
+ and pre-built forms). Currently this is a separate LGPL package to
+ pthreads-win32. See the README in the QueueUserAPCEx folder for
+ installation instructions.
+
+ Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL
+ QuserEx.DLL is available and whether the driver AlertDrv.sys is
+ loaded. If it is not available, pthreads-win32 will simulate async
+ cancelation, which means that it can async cancel only threads that
+ are runnable. The simulated async cancellation cannot cancel blocked
+ threads.
+
+ [FOR SECURITY] To be found Quserex.dll MUST be installed in the
+ Windows System Folder. This is not an unreasonable constraint given a
+ driver must also be installed and loaded at system startup.
+
+
+Library naming
+--------------
+
+Because the library is being built using various exception
+handling schemes and compilers - and because the library
+may not work reliably if these are mixed in an application,
+each different version of the library has it's own name.
+
+Note 1: the incompatibility is really between EH implementations
+of the different compilers. It should be possible to use the
+standard C version from either compiler with C++ applications
+built with a different compiler. If you use an EH version of
+the library, then you must use the same compiler for the
+application. This is another complication and dependency that
+can be avoided by using only the standard C library version.
+
+Note 2: if you use a standard C pthread*.dll with a C++
+application, then any functions that you define that are
+intended to be called via pthread_cleanup_push() must be
+__cdecl.
+
+Note 3: the intention was to also name either the VC or GC
+version (it should be arbitrary) as pthread.dll, including
+pthread.lib and libpthread.a as appropriate. This is no longer
+likely to happen.
+
+Note 4: the compatibility number was added so that applications
+can differentiate between binary incompatible versions of the
+libs and dlls.
+
+In general:
+ pthread[VG]{SE,CE,C}[c].dll
+ pthread[VG]{SE,CE,C}[c].lib
+
+where:
+ [VG] indicates the compiler
+ V - MS VC, or
+ G - GNU C
+
+ {SE,CE,C} indicates the exception handling scheme
+ SE - Structured EH, or
+ CE - C++ EH, or
+ C - no exceptions - uses setjmp/longjmp
+
+ c - DLL compatibility number indicating ABI and API
+ compatibility with applications built against
+ a snapshot with the same compatibility number.
+ See 'Version numbering' below.
+
+The name may also be suffixed by a 'd' to indicate a debugging version
+of the library. E.g. pthreadVC2d.lib. Debugging versions contain
+additional information for debugging (symbols etc) and are often not
+optimised in any way (compiled with optimisation turned off).
+
+Examples:
+ pthreadVSE.dll (MSVC/SEH)
+ pthreadGCE.dll (GNUC/C++ EH)
+ pthreadGC.dll (GNUC/not dependent on exceptions)
+ pthreadVC1.dll (MSVC/not dependent on exceptions - not binary
+ compatible with pthreadVC.dll)
+ pthreadVC2.dll (MSVC/not dependent on exceptions - not binary
+ compatible with pthreadVC1.dll or pthreadVC.dll)
+
+The GNU library archive file names have correspondingly changed to:
+
+ libpthreadGCEc.a
+ libpthreadGCc.a
+
+
+Versioning numbering
+--------------------
+
+Version numbering is separate from the snapshot dating system, and
+is the canonical version identification system embedded within the
+DLL using the Microsoft version resource system. The versioning
+system chosen follows the GNU Libtool system. See
+http://www.gnu.org/software/libtool/manual.html section 6.2.
+
+See the resource file 'version.rc'.
+
+Microsoft version numbers use 4 integers:
+
+ 0.0.0.0
+
+Pthreads-win32 uses the first 3 following the Libtool convention.
+The fourth is commonly used for the build number, but will be reserved
+for future use.
+
+ current.revision.age.0
+
+The numbers are changed as follows:
+
+1. If the library source code has changed at all since the last update,
+ then increment revision (`c:r:a' becomes `c:r+1:a').
+2. If any interfaces have been added, removed, or changed since the last
+ update, increment current, and set revision to 0.
+3. If any interfaces have been added since the last public release, then
+ increment age.
+4. If any interfaces have been removed or changed since the last public
+ release, then set age to 0.
+
+
+DLL compatibility numbering is an attempt to ensure that applications
+always load a compatible pthreads-win32 DLL by using a DLL naming system
+that is consistent with the version numbering system. It also allows
+older and newer DLLs to coexist in the same filesystem so that older
+applications can continue to be used. For pre .NET Windows systems,
+this inevitably requires incompatible versions of the same DLLs to have
+different names.
+
+Pthreads-win32 has adopted the Cygwin convention of appending a single
+integer number to the DLL name. The number used is based on the library
+version number and is computed as 'current' - 'age'.
+
+(See http://home.att.net/~perlspinr/libversioning.html for a nicely
+detailed explanation.)
+
+Using this method, DLL name/s will only change when the DLL's
+backwards compatibility changes. Note that the addition of new
+'interfaces' will not of itself change the DLL's compatibility for older
+applications.
+
+
+Which of the several dll versions to use?
+-----------------------------------------
+or,
+---
+What are all these pthread*.dll and pthread*.lib files?
+-------------------------------------------------------
+
+Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you
+use MSVC - where 'v' is the DLL versioning (compatibility) number.
+
+Otherwise, you need to choose carefully and know WHY.
+
+The most important choice you need to make is whether to use a
+version that uses exceptions internally, or not. There are versions
+of the library that use exceptions as part of the thread
+cancelation and exit implementation. The default version uses
+setjmp/longjmp.
+
+There is some contension amongst POSIX threads experts as
+to how POSIX threads cancelation and exit should work
+with languages that use exceptions, e.g. C++ and even C
+(Microsoft's Structured Exceptions).
+
+The issue is: should cancelation of a thread in, say,
+a C++ application cause object destructors and C++ exception
+handlers to be invoked as the stack unwinds during thread
+exit, or not?
+
+There seems to be more opinion in favour of using the
+standard C version of the library (no EH) with C++ applications
+for the reason that this appears to be the assumption commercial
+pthreads implementations make. Therefore, if you use an EH version
+of pthreads-win32 then you may be under the illusion that
+your application will be portable, when in fact it is likely to
+behave differently when linked with other pthreads libraries.
+
+Now you may be asking: then why have you kept the EH versions of
+the library?
+
+There are a couple of reasons:
+- there is division amongst the experts and so the code may
+ be needed in the future. Yes, it's in the repository and we
+ can get it out anytime in the future, but it would be difficult
+ to find.
+- pthreads-win32 is one of the few implementations, and possibly
+ the only freely available one, that has EH versions. It may be
+ useful to people who want to play with or study application
+ behaviour under these conditions.
+
+Notes:
+
+[If you use either pthreadVCE or pthreadGCE]
+
+1. [See also the discussion in the FAQ file - Q2, Q4, and Q5]
+
+If your application contains catch(...) blocks in your POSIX
+threads then you will need to replace the "catch(...)" with the macro
+"PtW32Catch", eg.
+
+ #ifdef PtW32Catch
+ PtW32Catch {
+ ...
+ }
+ #else
+ catch(...) {
+ ...
+ }
+ #endif
+
+Otherwise neither pthreads cancelation nor pthread_exit() will work
+reliably when using versions of the library that use C++ exceptions
+for cancelation and thread exit.
+
+This is due to what is believed to be a C++ compliance error in VC++
+whereby you may not have multiple handlers for the same exception in
+the same try/catch block. GNU G++ doesn't have this restriction.
+
+
+Other name changes
+------------------
+
+All snapshots prior to and including snapshot 2000-08-13
+used "_pthread_" as the prefix to library internal
+functions, and "_PTHREAD_" to many library internal
+macros. These have now been changed to "ptw32_" and "PTW32_"
+respectively so as to not conflict with the ANSI standard's
+reservation of identifiers beginning with "_" and "__" for
+use by compiler implementations only.
+
+If you have written any applications and you are linking
+statically with the pthreads-win32 library then you may have
+included a call to _pthread_processInitialize. You will
+now have to change that to ptw32_processInitialize.
+
+
+Cleanup code default style
+--------------------------
+
+Previously, if not defined, the cleanup style was determined automatically
+from the compiler used, and one of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw()).
+
+In short, the exceptions versions of the library throw an exception
+when a thread is canceled, or exits via pthread_exit(). This exception is
+caught by a handler in the thread startup routine, so that the
+the correct stack unwinding occurs regardless of where the thread
+is when it's canceled or exits via pthread_exit().
+
+In this snapshot, unless the build explicitly defines (e.g. via a
+compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build NOW always defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most/all
+commercial Unix POSIX threads implementations.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+It is recommended that you let pthread.h use it's default __CLEANUP_C
+for both library and application builds. That is, don't define any of
+the above, and then link with pthreadVC.lib (MSVC or MSVC++) and
+libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but
+another reason is that the prebuilt pthreadVCE.dll is currently broken.
+Versions built with MSVC++ later than version 6 may not be broken, but I
+can't verify this yet.
+
+WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
+Because no commercial Unix POSIX threads implementation allows you to
+choose to have stack unwinding. Therefore, providing it in pthread-win32
+as a default is dangerous. We still provide the choice but unless
+you consciously choose to do otherwise, your pthreads applications will
+now run or crash in similar ways irrespective of the pthreads platform
+you use. Or at least this is the hope.
+
+
+Building under VC++ using C++ EH, Structured EH, or just C
+----------------------------------------------------------
+
+From the source directory run nmake without any arguments to list
+help information. E.g.
+
+$ nmake
+
+Microsoft (R) Program Maintenance Utility Version 6.00.8168.0
+Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
+
+Run one of the following command lines:
+nmake clean VCE (to build the MSVC dll with C++ exception handling)
+nmake clean VSE (to build the MSVC dll with structured exception handling)
+nmake clean VC (to build the MSVC dll with C cleanup code)
+nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling)
+nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling)
+nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code)
+nmake clean VC-static (to build the MSVC static lib with C cleanup code)
+nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling)
+nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling)
+nmake clean VC-debug (to build the debug MSVC dll with C cleanup code)
+nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling)
+nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling)
+nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code)
+nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code)
+
+
+The pre-built dlls are normally built using the *-inlined targets.
+
+You can run the testsuite by changing to the "tests" directory and
+running nmake. E.g.:
+
+$ cd tests
+$ nmake
+
+Microsoft (R) Program Maintenance Utility Version 6.00.8168.0
+Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
+
+Run one of the following command lines:
+nmake clean VC (to test using VC dll with VC (no EH) applications)
+nmake clean VCX (to test using VC dll with VC++ (EH) applications)
+nmake clean VCE (to test using the VCE dll with VC++ EH applications)
+nmake clean VSE (to test using VSE dll with VC (SEH) applications)
+nmake clean VC-bench (to benchtest using VC dll with C bench app)
+nmake clean VCX-bench (to benchtest using VC dll with C++ bench app)
+nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app)
+nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app)
+nmake clean VC-static (to test using VC static lib with VC (no EH) applications)
+
+
+Building under Mingw32
+----------------------
+
+The dll can be built easily with recent versions of Mingw32.
+(The distributed versions are built using Mingw32 and MsysDTK
+from www.mingw32.org.)
+
+From the source directory, run make for help information. E.g.:
+
+$ make
+Run one of the following command lines:
+make clean GC (to build the GNU C dll with C cleanup code)
+make clean GCE (to build the GNU C dll with C++ exception handling)
+make clean GC-inlined (to build the GNU C inlined dll with C cleanup code)
+make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling)
+make clean GC-static (to build the GNU C inlined static lib with C cleanup code)
+make clean GC-debug (to build the GNU C debug dll with C cleanup code)
+make clean GCE-debug (to build the GNU C debug dll with C++ exception handling)
+make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code)
+make clean GCE-inlined-debug (to build the GNU C inlined debug dll with C++ exception handling)
+make clean GC-static-debug (to build the GNU C inlined static debug lib with C cleanup code)
+
+
+The pre-built dlls are normally built using the *-inlined targets.
+
+You can run the testsuite by changing to the "tests" directory and
+running make for help information. E.g.:
+
+$ cd tests
+$ make
+Run one of the following command lines:
+make clean GC (to test using GC dll with C (no EH) applications)
+make clean GCX (to test using GC dll with C++ (EH) applications)
+make clean GCE (to test using GCE dll with C++ (EH) applications)
+make clean GC-bench (to benchtest using GNU C dll with C cleanup code)
+make clean GCE-bench (to benchtest using GNU C dll with C++ exception handling)
+make clean GC-static (to test using GC static lib with C (no EH) applications)
+
+
+Building under Linux using the Mingw32 cross development tools
+--------------------------------------------------------------
+
+You can build the library without leaving Linux by using the Mingw32 cross
+development toolchain. See http://www.libsdl.org/extras/win32/cross/ for
+tools and info. The GNUmakefile contains some support for this, for example:
+
+make CROSS=i386-mingw32msvc- clean GC-inlined
+
+will build pthreadGCn.dll and libpthreadGCn.a (n=version#), provided your
+cross-tools/bin directory is in your PATH (or use the cross-make.sh script
+at the URL above).
+
+
+Building the library as a statically linkable library
+-----------------------------------------------------
+
+General: PTW32_STATIC_LIB must be defined for both the library build and the
+application build. The makefiles supplied and used by the following 'make'
+command lines will define this for you.
+
+MSVC (creates pthreadVCn.lib as a static link lib):
+
+nmake clean VC-static
+
+
+MinGW32 (creates libpthreadGCn.a as a static link lib):
+
+make clean GC-static
+
+
+Define PTW32_STATIC_LIB when building your application. Also, your
+application must call a two non-portable routines to initialise the
+some state on startup and cleanup before exit. One other routine needs
+to be called to cleanup after any Win32 threads have called POSIX API
+routines. See README.NONPORTABLE or the html reference manual pages for
+details on these routines:
+
+BOOL pthread_win32_process_attach_np (void);
+BOOL pthread_win32_process_detach_np (void);
+BOOL pthread_win32_thread_attach_np (void); // Currently a no-op
+BOOL pthread_win32_thread_detach_np (void);
+
+
+The tests makefiles have the same targets but only check that the
+static library is statically linkable. They don't run the full
+testsuite. To run the full testsuite, build the dlls and run the
+dll test targets.
+
+
+Building the library under Cygwin
+---------------------------------
+
+Cygwin is implementing it's own POSIX threads routines and these
+will be the ones to use if you develop using Cygwin.
+
+
+Ready to run binaries
+---------------------
+
+For convenience, the following ready-to-run files can be downloaded
+from the FTP site (see under "Availability" below):
+
+ pthread.h
+ semaphore.h
+ sched.h
+ pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp
+ pthreadVC.lib
+ pthreadVCE.dll - built with MSVC++ compiler using C++ EH
+ pthreadVCE.lib
+ pthreadVSE.dll - built with MSVC compiler using SEH
+ pthreadVSE.lib
+ pthreadGC.dll - built with Mingw32 GCC
+ libpthreadGC.a - derived from pthreadGC.dll
+ pthreadGCE.dll - built with Mingw32 G++
+ libpthreadGCE.a - derived from pthreadGCE.dll
+
+As of August 2003 pthreads-win32 pthreadG* versions are built and tested
+using the MinGW + MsysDTK environment current as of that date or later.
+The following file MAY be needed for older MinGW environments.
+
+ gcc.dll - needed to build and run applications that use
+ pthreadGCE.dll.
+
+
+Building applications with GNU compilers
+----------------------------------------
+
+If you're using pthreadGC.dll:
+
+With the three header files, pthreadGC.dll and libpthreadGC.a in the
+same directory as your application myapp.c, you could compile, link
+and run myapp.c under Mingw32 as follows:
+
+ gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC
+ myapp
+
+Or put pthreadGC.dll in an appropriate directory in your PATH,
+put libpthreadGC.a in your system lib directory, and
+put the three header files in your system include directory,
+then use:
+
+ gcc -o myapp.exe myapp.c -lpthreadGC
+ myapp
+
+
+If you're using pthreadGCE.dll:
+
+With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a
+in the same directory as your application myapp.c, you could compile,
+link and run myapp.c under Mingw32 as follows:
+
+ gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE
+ myapp
+
+Or put pthreadGCE.dll and gcc.dll in an appropriate directory in
+your PATH, put libpthreadGCE.a in your system lib directory, and
+put the three header files in your system include directory,
+then use:
+
+ gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE
+ myapp
+
+
+Availability
+------------
+
+The complete source code in either unbundled, self-extracting
+Zip file, or tar/gzipped format can be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32
+
+The pre-built DLL, export libraries and matching pthread.h can
+be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
+
+Home page:
+
+ http://sources.redhat.com/pthreads-win32/
+
+
+Mailing list
+------------
+
+There is a mailing list for discussing pthreads on Win32.
+To join, send email to:
+
+ pthreads-win32-subscribe@sources.redhat.com
+
+Unsubscribe by sending mail to:
+
+ pthreads-win32-unsubscribe@sources.redhat.com
+
+
+Acknowledgements
+----------------
+
+See the ANNOUNCE file for acknowledgements.
+See the 'CONTRIBUTORS' file for the list of contributors.
+
+As much as possible, the ChangeLog file attributes
+contributions and patches that have been incorporated
+in the library to the individuals responsible.
+
+Finally, thanks to all those who work on and contribute to the
+POSIX and Single Unix Specification standards. The maturity of an
+industry can be measured by it's open standards.
+
+----
+Ross Johnson
+<rpj@callisto.canberra.edu.au>
+
+
+
+
+
+
+
+
diff --git a/libs/pthreads/docs/TODO b/libs/pthreads/docs/TODO
new file mode 100644
index 0000000000..fa9efc46e7
--- /dev/null
+++ b/libs/pthreads/docs/TODO
@@ -0,0 +1,7 @@
+ Things that aren't done yet
+ ---------------------------
+
+1. Implement PTHREAD_PROCESS_SHARED for semaphores, mutexes,
+ condition variables, read/write locks, barriers.
+
+
diff --git a/libs/pthreads/docs/WinCE-PORT b/libs/pthreads/docs/WinCE-PORT
new file mode 100644
index 0000000000..7bcfdea6cc
--- /dev/null
+++ b/libs/pthreads/docs/WinCE-PORT
@@ -0,0 +1,222 @@
+NOTE: The comments in this file relate to the original WinCE port
+done by Tristan Savatier. The semaphore routines have been
+completely rewritten since (2005-04-25), having been progressively
+broken more and more by changes to the library. All of the semaphore
+routines implemented for W9x/WNT/2000 and up should now also work for
+WinCE. Also, pthread_mutex_timedlock should now work.
+
+Additional WinCE updates have been applied since this as well. Check the
+ChangeLog file and search for WINCE for example. (2007-01-07)
+
+[RPJ]
+
+----
+
+Some interesting news:
+
+I have been able to port pthread-win32 to Windows-CE,
+which uses a subset of the WIN32 API.
+
+Since we intend to keep using pthread-win32 for our
+Commercial WinCE developments, I would be very interested
+if WinCE support could be added to the main source tree
+of pthread-win32. Also, I would like to be credited
+for this port :-)
+
+Now, here is the story...
+
+The port was performed and tested on a Casio "Cassiopeia"
+PalmSize PC, which runs a MIP processor. The OS in the
+Casio is WinCE version 2.11, but I used VC++ 6.0 with
+the WinCE SDK for version 2.01.
+
+I used pthread-win32 to port a heavily multithreaded
+commercial application (real-time MPEG video player)
+from Linux to WinCE. I consider the changes that
+I have done to be quite well tested.
+
+Overall the modifications that we had to do are minor.
+
+The WinCE port were based on pthread-win32-snap-1999-05-30,
+but I am certain that they can be integrated very easiely
+to more recent versions of the source.
+
+I have attached the modified source code:
+pthread-win32-snap-1999-05-30-WinCE.
+
+All the changes do not affect the code compiled on non-WinCE
+environment, provided that the macros used for WinCE compilation
+are not used, of course!
+
+Overall description of the WinCE port:
+-------------------------------------
+
+Most of the changes had to be made in areas where
+pthread-win32 was relying on some standard-C librairies
+(e.g. _ftime, calloc, errno), which are not available
+on WinCE. We have changed the code to use native Win32
+API instead (or in some cases we made wrappers).
+
+The Win32 Semaphores are not available,
+so we had to re-implement Semaphores using mutexes
+and events.
+
+Limitations / known problems of the WinCE port:
+----------------------------------------------
+
+Not all the semaphore routines have been ported
+(semaphores are defined by Posix but are not part
+pf pthread). I have just done enough to make
+pthread routines (that rely internally on semaphores)
+work, like signal conditions.
+
+I noticed that the Win32 threads work slightly
+differently on WinCE. This may have some impact
+on some tricky parts of pthread-win32, but I have
+not really investigated. For example, on WinCE,
+the process is killed if the main thread falls off
+the bottom (or calls pthread_exit), regardless
+of the existence of any other detached thread.
+Microsoft manual indicates that this behavior is
+deffirent from that of Windows Threads for other
+Win32 platforms.
+
+
+Detailed descriptions of the changes and rationals:
+
+------------------------------------
+- use a new macro NEED_ERRNO.
+
+If defined, the code in errno.c that defines a reentrant errno
+is compiled, regardless of _MT and _REENTRANT.
+
+Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or
+any other standard C library, i.e. even if _MT or _REENTRANT
+is defined, errno is not provided by any library. NEED_ERRNO
+must be set to compile for WinCE.
+
+------------------------------------
+- In implement.h, change #include <semaphore.h> to #include "semaphore.h".
+
+Rational: semaphore.h is provided in pthread-win32 and should not
+be searched in the systems standard include. would not compile.
+This change does not seem to create problems on "classic" win32
+(e.g. win95).
+
+------------------------------------
+- use a new macro NEED_CALLOC.
+
+If defined, some code in misc.c will provide a replacement
+for calloc, which is not available on Win32.
+
+
+------------------------------------
+- use a new macro NEED_CREATETHREAD.
+
+If defined, implement.h defines the macro _beginthreadex
+and _endthreadex.
+
+Rational: On WinCE, the wrappers _beginthreadex and _endthreadex
+do not exist. The native Win32 routines must be used.
+
+------------------------------------
+- in misc.c:
+
+#ifdef NEED_DUPLICATEHANDLE
+ /* DuplicateHandle does not exist on WinCE */
+ self->threadH = GetCurrentThread();
+#else
+ if( !DuplicateHandle(
+ GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &self->threadH,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS ) )
+ {
+ free( self );
+ return (NULL);
+ }
+#endif
+
+Rational: On WinCE, DuplicateHandle does not exist. I could not understand
+why DuplicateHandle must be used. It seems to me that getting the current
+thread handle with GetCurrentThread() is sufficient, and it seems to work
+perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ?
+
+------------------------------------
+- In private.c, added some code at the beginning of ptw32_processInitialize
+to detect the case of multiple calls to ptw32_processInitialize.
+
+Rational: In order to debug pthread-win32, it is easier to compile
+it as a regular library (it is not possible to debug DLL's on winCE).
+In that case, the application must call ptw32_rocessInitialize()
+explicitely, to initialize pthread-win32. It is safer in this circumstance
+to handle the case where ptw32_processInitialize() is called on
+an already initialized library:
+
+int
+ptw32_processInitialize (void)
+{
+ if (ptw32_processInitialized) {
+ /*
+ * ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. such programs must call ptw32_processInitialize() explicitely,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return TRUE;
+ }
+ ptw32_processInitialized = TRUE;
+ [...]
+}
+
+------------------------------------
+- in private.c, if macro NEED_FTIME is defined, add routines to
+convert timespec_to_filetime and filetime_to_timespec, and modified
+code that was using _ftime() to use Win32 API instead.
+
+Rational: _ftime is not available on WinCE. It is necessary to use
+the native Win32 time API instead.
+
+Note: the routine timespec_to_filetime is provided as a convenience and a mean
+to test that filetime_to_timespec works, but it is not used by the library.
+
+------------------------------------
+- in semaphore.c, if macro NEED_SEM is defined, add code for the routines
+_increase_semaphore and _decrease_semaphore, and modify significantly
+the implementation of the semaphores so that it does not use CreateSemaphore.
+
+Rational: CreateSemaphore is not available on WinCE. I had to re-implement
+semaphores using mutexes and Events.
+
+Note: Only the semaphore routines that are used by pthread are implemented
+(i.e. signal conditions rely on a subset of the semaphores routines, and
+this subset works). Some other semaphore routines (e.g. sem_trywait) are
+not yet supported on my WinCE port (and since I don't need them, I am not
+planning to do anything about them).
+
+------------------------------------
+- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES
+
+/* TLS_OUT_OF_INDEXES not defined on WinCE */
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
+Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file
+on WinCE.
+
+------------------------------------
+- added file need_errno.h
+
+Rational: On WinCE, there is no errno.h file. need_errno.h is just a
+copy of windows version of errno.h, with minor modifications due to the fact
+that some of the error codes are defined by the WinCE socket library.
+In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is
+included (instead of <errno.h>).
+
+
+-- eof
diff --git a/libs/pthreads/pthreads.vcxproj b/libs/pthreads/pthreads.vcxproj
new file mode 100644
index 0000000000..d1ddccbe03
--- /dev/null
+++ b/libs/pthreads/pthreads.vcxproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E0EBB8A5-B577-414C-A5F9-9B4E2A0A66E9}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>pthreads</ProjectName>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <GenerateManifest>false</GenerateManifest>
+ <EmbedManifest>false</EmbedManifest>
+ <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141_xp</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir Condition="'$(Platform)'=='Win32'">$(SolutionDir)$(Configuration)\Libs\</OutDir>
+ <IntDir Condition="'$(Platform)'=='Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Platform)'=='x64'">$(SolutionDir)$(Configuration)64\Libs\</OutDir>
+ <IntDir Condition="'$(Platform)'=='x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <WholeProgramOptimization Condition="'$(Configuration)'=='Release'">true</WholeProgramOptimization>
+ <LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental>
+ <TargetName>pthreads</TargetName>
+ <TargetExt>.mir</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>$(ProjectDir)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">WIN32;HAVE_PTW32_CONFIG_H;PTW32_RC_MSC;PTW32_ARCHx86;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Platform)'=='x64'">WIN32;HAVE_PTW32_CONFIG_H;PTW32_RC_MSC;PTW32_ARCHx64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions Condition="'$(Platform)'=='Win32'">WIN32;HAVE_PTW32_CONFIG_H;PTW32_RC_MSC;PTW32_ARCHx86;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Platform)'=='x64'">WIN32;HAVE_PTW32_CONFIG_H;PTW32_RC_MSC;PTW32_ARCHx64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="src\config.h" />
+ <ClInclude Include="src\context.h" />
+ <ClInclude Include="src\implement.h" />
+ <ClInclude Include="src\need_errno.h" />
+ <ClInclude Include="src\sched.h" />
+ <ClInclude Include="src\semaphore.h" />
+ <ClInclude Include="src\pthread.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\pthread.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/libs/pthreads/pthreads.vcxproj.filters b/libs/pthreads/pthreads.vcxproj.filters
new file mode 100644
index 0000000000..49f1229401
--- /dev/null
+++ b/libs/pthreads/pthreads.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
+ <ItemGroup>
+ <ClCompile Include="src\stdafx.cxx">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\*.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/libs/pthreads/src/attr.c b/libs/pthreads/src/attr.c
new file mode 100644
index 0000000000..a9d55f4a4b
--- /dev/null
+++ b/libs/pthreads/src/attr.c
@@ -0,0 +1,53 @@
+/*
+ * attr.c
+ *
+ * Description:
+ * This translation unit agregates operations on thread attribute objects.
+ * It is used for inline optimisation.
+ *
+ * The included modules are used separately when static executable sizes
+ * must be minimised.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#include "pthread_attr_init.c"
+#include "pthread_attr_destroy.c"
+#include "pthread_attr_getdetachstate.c"
+#include "pthread_attr_setdetachstate.c"
+#include "pthread_attr_getstackaddr.c"
+#include "pthread_attr_setstackaddr.c"
+#include "pthread_attr_getstacksize.c"
+#include "pthread_attr_setstacksize.c"
+#include "pthread_attr_getscope.c"
+#include "pthread_attr_setscope.c"
diff --git a/libs/pthreads/src/autostatic.c b/libs/pthreads/src/autostatic.c
new file mode 100644
index 0000000000..092aff2aee
--- /dev/null
+++ b/libs/pthreads/src/autostatic.c
@@ -0,0 +1,69 @@
+/*
+ * autostatic.c
+ *
+ * Description:
+ * This translation unit implements static auto-init and auto-exit logic.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if defined(PTW32_STATIC_LIB)
+
+#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER)
+
+#include "pthread.h"
+#include "implement.h"
+
+static void on_process_init(void)
+{
+ pthread_win32_process_attach_np ();
+}
+
+static void on_process_exit(void)
+{
+ pthread_win32_thread_detach_np ();
+ pthread_win32_process_detach_np ();
+}
+
+#if defined(__MINGW64__) || defined(__MINGW32__)
+# define attribute_section(a) __attribute__((section(a)))
+#elif defined(_MSC_VER)
+# define attribute_section(a) __pragma(section(a,long,read)); __declspec(allocate(a))
+#endif
+
+attribute_section(".ctors") void *gcc_ctor = on_process_init;
+attribute_section(".dtors") void *gcc_dtor = on_process_exit;
+
+attribute_section(".CRT$XCU") void *msc_ctor = on_process_init;
+attribute_section(".CRT$XPU") void *msc_dtor = on_process_exit;
+
+#endif /* defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) */
+
+#endif /* PTW32_STATIC_LIB */
diff --git a/libs/pthreads/src/barrier.c b/libs/pthreads/src/barrier.c
new file mode 100644
index 0000000000..41b950cd12
--- /dev/null
+++ b/libs/pthreads/src/barrier.c
@@ -0,0 +1,47 @@
+/*
+ * barrier.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "pthread_barrier_init.c"
+#include "pthread_barrier_destroy.c"
+#include "pthread_barrier_wait.c"
+#include "pthread_barrierattr_init.c"
+#include "pthread_barrierattr_destroy.c"
+#include "pthread_barrierattr_getpshared.c"
+#include "pthread_barrierattr_setpshared.c"
diff --git a/libs/pthreads/src/cancel.c b/libs/pthreads/src/cancel.c
new file mode 100644
index 0000000000..1bd14ebe65
--- /dev/null
+++ b/libs/pthreads/src/cancel.c
@@ -0,0 +1,44 @@
+/*
+ * cancel.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "pthread_setcancelstate.c"
+#include "pthread_setcanceltype.c"
+#include "pthread_testcancel.c"
+#include "pthread_cancel.c"
diff --git a/libs/pthreads/src/cleanup.c b/libs/pthreads/src/cleanup.c
new file mode 100644
index 0000000000..381d1e87c8
--- /dev/null
+++ b/libs/pthreads/src/cleanup.c
@@ -0,0 +1,148 @@
+/*
+ * cleanup.c
+ *
+ * Description:
+ * This translation unit implements routines associated
+ * with cleaning up threads.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * The functions ptw32_pop_cleanup and ptw32_push_cleanup
+ * are implemented here for applications written in C with no
+ * SEH or C++ destructor support.
+ */
+
+ptw32_cleanup_t *
+ptw32_pop_cleanup (int execute)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function pops the most recently pushed cleanup
+ * handler. If execute is nonzero, then the cleanup handler
+ * is executed if non-null.
+ *
+ * PARAMETERS
+ * execute
+ * if nonzero, execute the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ * This function pops the most recently pushed cleanup
+ * handler. If execute is nonzero, then the cleanup handler
+ * is executed if non-null.
+ * NOTE: specify 'execute' as nonzero to avoid duplication
+ * of common cleanup code.
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_cleanup_t *cleanup;
+
+ cleanup = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
+
+ if (cleanup != NULL)
+ {
+ if (execute && (cleanup->routine != NULL))
+ {
+
+ (*cleanup->routine) (cleanup->arg);
+
+ }
+
+ pthread_setspecific (ptw32_cleanupKey, (void *) cleanup->prev);
+
+ }
+
+ return (cleanup);
+
+} /* ptw32_pop_cleanup */
+
+
+void
+ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
+ ptw32_cleanup_callback_t routine, void *arg)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function pushes a new cleanup handler onto the thread's stack
+ * of cleanup handlers. Each cleanup handler pushed onto the stack is
+ * popped and invoked with the argument 'arg' when
+ * a) the thread exits by calling 'pthread_exit',
+ * b) when the thread acts on a cancellation request,
+ * c) or when the thread calls pthread_cleanup_pop with a nonzero
+ * 'execute' argument
+ *
+ * PARAMETERS
+ * cleanup
+ * a pointer to an instance of pthread_cleanup_t,
+ *
+ * routine
+ * pointer to a cleanup handler,
+ *
+ * arg
+ * parameter to be passed to the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ * This function pushes a new cleanup handler onto the thread's stack
+ * of cleanup handlers. Each cleanup handler pushed onto the stack is
+ * popped and invoked with the argument 'arg' when
+ * a) the thread exits by calling 'pthread_exit',
+ * b) when the thread acts on a cancellation request,
+ * c) or when the thrad calls pthread_cleanup_pop with a nonzero
+ * 'execute' argument
+ * NOTE: pthread_push_cleanup, ptw32_pop_cleanup must be paired
+ * in the same lexical scope.
+ *
+ * RESULTS
+ * pthread_cleanup_t *
+ * pointer to the previous cleanup
+ *
+ * ------------------------------------------------------
+ */
+{
+ cleanup->routine = routine;
+ cleanup->arg = arg;
+
+ cleanup->prev = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
+
+ pthread_setspecific (ptw32_cleanupKey, (void *) cleanup);
+
+} /* ptw32_push_cleanup */
diff --git a/libs/pthreads/src/condvar.c b/libs/pthreads/src/condvar.c
new file mode 100644
index 0000000000..704f4d7931
--- /dev/null
+++ b/libs/pthreads/src/condvar.c
@@ -0,0 +1,50 @@
+/*
+ * condvar.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#include "ptw32_cond_check_need_init.c"
+#include "pthread_condattr_init.c"
+#include "pthread_condattr_destroy.c"
+#include "pthread_condattr_getpshared.c"
+#include "pthread_condattr_setpshared.c"
+#include "pthread_cond_init.c"
+#include "pthread_cond_destroy.c"
+#include "pthread_cond_wait.c"
+#include "pthread_cond_signal.c"
diff --git a/libs/pthreads/src/config.h b/libs/pthreads/src/config.h
new file mode 100644
index 0000000000..e63ce2da46
--- /dev/null
+++ b/libs/pthreads/src/config.h
@@ -0,0 +1,153 @@
+/* config.h */
+
+#ifndef PTW32_CONFIG_H
+#define PTW32_CONFIG_H
+
+/*********************************************************************
+ * Defaults: see target specific redefinitions below.
+ *********************************************************************/
+
+/* We're building the pthreads-win32 library */
+#define PTW32_BUILD
+
+/* Do we know about the C type sigset_t? */
+#undef HAVE_SIGSET_T
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the Borland TASM32 or compatible assembler. */
+#undef HAVE_TASM32
+
+/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */
+#undef NEED_DUPLICATEHANDLE
+
+/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */
+#undef NEED_CREATETHREAD
+
+/* Define if you don't have Win32 errno. (eg. WinCE) */
+#undef NEED_ERRNO
+
+/* Define if you don't have Win32 calloc. (eg. WinCE) */
+#undef NEED_CALLOC
+
+/* Define if you don't have Win32 ftime. (eg. WinCE) */
+#undef NEED_FTIME
+
+/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier) */
+#undef NEED_SEM
+
+/* Define if you need to convert string parameters to unicode. (eg. WinCE) */
+#undef NEED_UNICODE_CONSTS
+
+/* Define if your C (not C++) compiler supports "inline" functions. */
+#undef HAVE_C_INLINE
+
+/* Do we know about type mode_t? */
+#undef HAVE_MODE_T
+
+/*
+ * Define if GCC has atomic builtins, i.e. __sync_* intrinsics
+ * __sync_lock_* is implemented in mingw32 gcc 4.5.2 at least
+ * so this define does not turn those on or off. If you get an
+ * error from __sync_lock* then consider upgrading your gcc.
+ */
+#undef HAVE_GCC_ATOMIC_BUILTINS
+
+/* Define if you have the timespec struct */
+#define HAVE_STRUCT_TIMESPEC 1
+
+/* Define if you don't have the GetProcessAffinityMask() */
+#undef NEED_PROCESS_AFFINITY_MASK
+
+/* Define if your version of Windows TLSGetValue() clears WSALastError
+ * and calling SetLastError() isn't enough restore it. You'll also need to
+ * link against wsock32.lib (or libwsock32.a for MinGW).
+ */
+#undef RETAIN_WSALASTERROR
+
+/*
+# ----------------------------------------------------------------------
+# The library can be built with some alternative behaviour to better
+# facilitate development of applications on Win32 that will be ported
+# to other POSIX systems.
+#
+# Nothing described here will make the library non-compliant and strictly
+# compliant applications will not be affected in any way, but
+# applications that make assumptions that POSIX does not guarantee are
+# not strictly compliant and may fail or misbehave with some settings.
+#
+# PTW32_THREAD_ID_REUSE_INCREMENT
+# Purpose:
+# POSIX says that applications should assume that thread IDs can be
+# recycled. However, Solaris (and some other systems) use a [very large]
+# sequence number as the thread ID, which provides virtual uniqueness.
+# This provides a very high but finite level of safety for applications
+# that are not meticulous in tracking thread lifecycles e.g. applications
+# that call functions which target detached threads without some form of
+# thread exit synchronisation.
+#
+# Usage:
+# Set to any value in the range: 0 <= value < 2^wordsize.
+# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD.
+# Set to 1 for unique thread IDs like Solaris (this is the default).
+# Set to some factor of 2^wordsize to emulate smaller word size types
+# (i.e. will wrap sooner). This might be useful to emulate some embedded
+# systems.
+#
+# define PTW32_THREAD_ID_REUSE_INCREMENT 0
+#
+# ----------------------------------------------------------------------
+ */
+#undef PTW32_THREAD_ID_REUSE_INCREMENT
+
+
+/*********************************************************************
+ * Target specific groups
+ *
+ * If you find that these are incorrect or incomplete please report it
+ * to the pthreads-win32 maintainer. Thanks.
+ *********************************************************************/
+#if defined(WINCE)
+#define NEED_DUPLICATEHANDLE
+#define NEED_CREATETHREAD
+#define NEED_ERRNO
+#define NEED_CALLOC
+#define NEED_FTIME
+/* #define NEED_SEM */
+#define NEED_UNICODE_CONSTS
+#define NEED_PROCESS_AFFINITY_MASK
+/* This may not be needed */
+#define RETAIN_WSALASTERROR
+#endif
+
+#if defined(_UWIN)
+#define HAVE_MODE_T
+#define HAVE_STRUCT_TIMESPEC
+#endif
+
+#if defined(__GNUC__)
+#define HAVE_C_INLINE
+#endif
+
+#if defined(__MINGW64__)
+#define HAVE_MODE_T
+#define HAVE_STRUCT_TIMESPEC
+#elif defined(__MINGW32__)
+#define HAVE_MODE_T
+#endif
+
+#if defined(__BORLANDC__)
+#endif
+
+#if defined(__WATCOMC__)
+#endif
+
+#if defined(__DMC__)
+#define HAVE_SIGNAL_H
+#define HAVE_C_INLINE
+#endif
+
+
+
+#endif
diff --git a/libs/pthreads/src/context.h b/libs/pthreads/src/context.h
new file mode 100644
index 0000000000..3d4511f5b3
--- /dev/null
+++ b/libs/pthreads/src/context.h
@@ -0,0 +1,74 @@
+/*
+ * context.h
+ *
+ * Description:
+ * POSIX thread macros related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef PTW32_CONTEXT_H
+#define PTW32_CONTEXT_H
+
+#undef PTW32_PROGCTR
+
+#if defined(_M_IX86) || (defined(_X86_) && !defined(__amd64__))
+#define PTW32_PROGCTR(Context) ((Context).Eip)
+#endif
+
+#if defined (_M_IA64) || defined(_IA64)
+#define PTW32_PROGCTR(Context) ((Context).StIIP)
+#endif
+
+#if defined(_MIPS_) || defined(MIPS)
+#define PTW32_PROGCTR(Context) ((Context).Fir)
+#endif
+
+#if defined(_ALPHA_)
+#define PTW32_PROGCTR(Context) ((Context).Fir)
+#endif
+
+#if defined(_PPC_)
+#define PTW32_PROGCTR(Context) ((Context).Iar)
+#endif
+
+#if defined(_AMD64_) || defined(__amd64__)
+#define PTW32_PROGCTR(Context) ((Context).Rip)
+#endif
+
+#if defined(_ARM_) || defined(ARM)
+#define PTW32_PROGCTR(Context) ((Context).Pc)
+#endif
+
+#if !defined(PTW32_PROGCTR)
+#error Module contains CPU-specific code; modify and recompile.
+#endif
+
+#endif
diff --git a/libs/pthreads/src/create.c b/libs/pthreads/src/create.c
new file mode 100644
index 0000000000..8b036cc2e9
--- /dev/null
+++ b/libs/pthreads/src/create.c
@@ -0,0 +1,308 @@
+/*
+ * create.c
+ *
+ * Description:
+ * This translation unit implements routines associated with spawning a new
+ * thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#if ! defined(_UWIN) && ! defined(WINCE)
+#include <process.h>
+#endif
+
+int
+pthread_create (pthread_t * tid,
+ const pthread_attr_t * attr,
+ void *(PTW32_CDECL *start) (void *), void *arg)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function creates a thread running the start function,
+ * passing it the parameter value, 'arg'. The 'attr'
+ * argument specifies optional creation attributes.
+ * The identity of the new thread is returned
+ * via 'tid', which should not be NULL.
+ *
+ * PARAMETERS
+ * tid
+ * pointer to an instance of pthread_t
+ *
+ * attr
+ * optional pointer to an instance of pthread_attr_t
+ *
+ * start
+ * pointer to the starting routine for the new thread
+ *
+ * arg
+ * optional parameter passed to 'start'
+ *
+ *
+ * DESCRIPTION
+ * This function creates a thread running the start function,
+ * passing it the parameter value, 'arg'. The 'attr'
+ * argument specifies optional creation attributes.
+ * The identity of the new thread is returned
+ * via 'tid', which should not be the NULL pointer.
+ *
+ * RESULTS
+ * 0 successfully created thread,
+ * EINVAL attr invalid,
+ * EAGAIN insufficient resources.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_t thread;
+ ptw32_thread_t * tp;
+ register pthread_attr_t a;
+ HANDLE threadH = 0;
+ int result = EAGAIN;
+ int run = PTW32_TRUE;
+ ThreadParms *parms = NULL;
+ unsigned int stackSize;
+ int priority;
+ pthread_t self;
+
+ /*
+ * Before doing anything, check that tid can be stored through
+ * without invoking a memory protection error (segfault).
+ * Make sure that the assignment below can't be optimised out by the compiler.
+ * This is assured by conditionally assigning *tid again at the end.
+ */
+ tid->x = 0;
+
+ if (attr != NULL)
+ {
+ a = *attr;
+ }
+ else
+ {
+ a = NULL;
+ }
+
+ if ((thread = ptw32_new ()).p == NULL)
+ {
+ goto FAIL0;
+ }
+
+ tp = (ptw32_thread_t *) thread.p;
+
+ priority = tp->sched_priority;
+
+ if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
+ {
+ goto FAIL0;
+ }
+
+ parms->tid = thread;
+ parms->start = start;
+ parms->arg = arg;
+
+#if defined(HAVE_SIGSET_T)
+
+ /*
+ * Threads inherit their initial sigmask from their creator thread.
+ */
+ self = pthread_self();
+ tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask;
+
+#endif /* HAVE_SIGSET_T */
+
+
+ if (a != NULL)
+ {
+ stackSize = (unsigned int)a->stacksize;
+ tp->detachState = a->detachstate;
+ priority = a->param.sched_priority;
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+ /* WinCE */
+#else
+ /* Everything else */
+
+ /*
+ * Thread priority must be set to a valid system level
+ * without altering the value set by pthread_attr_setschedparam().
+ */
+
+ /*
+ * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
+ * don't inherit their creator's priority. They are started with
+ * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
+ * an 'attr' arg to pthread_create() is equivalent to defaulting to
+ * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
+ */
+ if (PTHREAD_INHERIT_SCHED == a->inheritsched)
+ {
+ /*
+ * If the thread that called pthread_create() is a Win32 thread
+ * then the inherited priority could be the result of a temporary
+ * system adjustment. This is not the case for POSIX threads.
+ */
+#if ! defined(HAVE_SIGSET_T)
+ self = pthread_self ();
+#endif
+ priority = ((ptw32_thread_t *) self.p)->sched_priority;
+ }
+
+#endif
+
+ }
+ else
+ {
+ /*
+ * Default stackSize
+ */
+ stackSize = PTHREAD_STACK_MIN;
+ }
+
+ tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
+
+ tp->keys = NULL;
+
+ /*
+ * Threads must be started in suspended mode and resumed if necessary
+ * after _beginthreadex returns us the handle. Otherwise we set up a
+ * race condition between the creating and the created threads.
+ * Note that we also retain a local copy of the handle for use
+ * by us in case thread.p->threadH gets NULLed later but before we've
+ * finished with it here.
+ */
+
+#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+
+ tp->threadH =
+ threadH =
+ (HANDLE) _beginthreadex ((void *) NULL, /* No security info */
+ stackSize, /* default stack size */
+ ptw32_threadStart,
+ parms,
+ (unsigned)
+ CREATE_SUSPENDED,
+ (unsigned *) &(tp->thread));
+
+ if (threadH != 0)
+ {
+ if (a != NULL)
+ {
+ (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
+ }
+
+ if (run)
+ {
+ ResumeThread (threadH);
+ }
+ }
+
+#else
+
+ {
+ ptw32_mcs_local_node_t stateLock;
+
+ /*
+ * This lock will force pthread_threadStart() to wait until we have
+ * the thread handle and have set the priority.
+ */
+ ptw32_mcs_lock_acquire(&tp->stateLock, &stateLock);
+
+ tp->threadH =
+ threadH =
+ (HANDLE) _beginthread (ptw32_threadStart, stackSize, /* default stack size */
+ parms);
+
+ /*
+ * Make the return code match _beginthreadex's.
+ */
+ if (threadH == (HANDLE) - 1L)
+ {
+ tp->threadH = threadH = 0;
+ }
+ else
+ {
+ if (!run)
+ {
+ /*
+ * beginthread does not allow for create flags, so we do it now.
+ * Note that beginthread itself creates the thread in SUSPENDED
+ * mode, and then calls ResumeThread to start it.
+ */
+ SuspendThread (threadH);
+ }
+
+ if (a != NULL)
+ {
+ (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority);
+ }
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+ }
+#endif
+
+ result = (threadH != 0) ? 0 : EAGAIN;
+
+ /*
+ * Fall Through Intentionally
+ */
+
+ /*
+ * ------------
+ * Failure Code
+ * ------------
+ */
+
+FAIL0:
+ if (result != 0)
+ {
+
+ ptw32_threadDestroy (thread);
+ tp = NULL;
+
+ if (parms != NULL)
+ {
+ free (parms);
+ }
+ }
+ else
+ {
+ *tid = thread;
+ }
+
+#if defined(_UWIN)
+ if (result == 0)
+ pthread_count++;
+#endif
+ return (result);
+
+} /* pthread_create */
diff --git a/libs/pthreads/src/dll.c b/libs/pthreads/src/dll.c
new file mode 100644
index 0000000000..05e01bee76
--- /dev/null
+++ b/libs/pthreads/src/dll.c
@@ -0,0 +1,92 @@
+/*
+ * dll.c
+ *
+ * Description:
+ * This translation unit implements DLL initialisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined(PTW32_STATIC_LIB)
+
+#include "pthread.h"
+#include "implement.h"
+
+#if defined(_MSC_VER)
+/*
+ * lpvReserved yields an unreferenced formal parameter;
+ * ignore it
+ */
+#pragma warning( disable : 4100 )
+#endif
+
+#if defined(__cplusplus)
+/*
+ * Dear c++: Please don't mangle this name. -thanks
+ */
+extern "C"
+#endif /* __cplusplus */
+ BOOL WINAPI
+DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
+{
+ BOOL result = PTW32_TRUE;
+
+ switch (fdwReason)
+ {
+
+ case DLL_PROCESS_ATTACH:
+ result = pthread_win32_process_attach_np ();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ /*
+ * A thread is being created
+ */
+ result = pthread_win32_thread_attach_np ();
+ break;
+
+ case DLL_THREAD_DETACH:
+ /*
+ * A thread is exiting cleanly
+ */
+ result = pthread_win32_thread_detach_np ();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ (void) pthread_win32_thread_detach_np ();
+ result = pthread_win32_process_detach_np ();
+ break;
+ }
+
+ return (result);
+
+} /* DllMain */
+
+#endif /* PTW32_STATIC_LIB */
diff --git a/libs/pthreads/src/errno.c b/libs/pthreads/src/errno.c
new file mode 100644
index 0000000000..78aa920a5b
--- /dev/null
+++ b/libs/pthreads/src/errno.c
@@ -0,0 +1,94 @@
+/*
+ * errno.c
+ *
+ * Description:
+ * This translation unit implements routines associated with spawning a new
+ * thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if defined(NEED_ERRNO)
+
+#include "pthread.h"
+#include "implement.h"
+
+static int reallyBad = ENOMEM;
+
+/*
+ * Re-entrant errno.
+ *
+ * Each thread has it's own errno variable in pthread_t.
+ *
+ * The benefit of using the pthread_t structure
+ * instead of another TSD key is TSD keys are limited
+ * on Win32 to 64 per process. Secondly, to implement
+ * it properly without using pthread_t you'd need
+ * to dynamically allocate an int on starting the thread
+ * and store it manually into TLS and then ensure that you free
+ * it on thread termination. We get all that for free
+ * by simply storing the errno on the pthread_t structure.
+ *
+ * MSVC and Mingw32 already have their own thread-safe errno.
+ *
+ * #if defined( _REENTRANT ) || defined( _MT )
+ * #define errno *_errno()
+ *
+ * int *_errno( void );
+ * #else
+ * extern int errno;
+ * #endif
+ *
+ */
+
+int *
+_errno (void)
+{
+ pthread_t self;
+ int *result;
+
+ if ((self = pthread_self ()).p == NULL)
+ {
+ /*
+ * Yikes! unable to allocate a thread!
+ * Throw an exception? return an error?
+ */
+ result = &reallyBad;
+ }
+ else
+ {
+ result = (int *)(&self.p->exitStatus);
+ }
+
+ return (result);
+
+} /* _errno */
+
+#endif /* (NEED_ERRNO) */
diff --git a/libs/pthreads/src/exit.c b/libs/pthreads/src/exit.c
new file mode 100644
index 0000000000..94369d007c
--- /dev/null
+++ b/libs/pthreads/src/exit.c
@@ -0,0 +1,44 @@
+/*
+ * exit.c
+ *
+ * Description:
+ * This translation unit implements routines associated with exiting from
+ * a thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#if ! defined(_UWIN) && ! defined(WINCE)
+# include <process.h>
+#endif
+
+#include "pthread_exit.c"
diff --git a/libs/pthreads/src/fork.c b/libs/pthreads/src/fork.c
new file mode 100644
index 0000000000..8a29550caf
--- /dev/null
+++ b/libs/pthreads/src/fork.c
@@ -0,0 +1,39 @@
+/*
+ * fork.c
+ *
+ * Description:
+ * Implementation of fork() for POSIX threads.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "pthread.h"
+#include "implement.h"
diff --git a/libs/pthreads/src/global.c b/libs/pthreads/src/global.c
new file mode 100644
index 0000000000..f1e9b3f669
--- /dev/null
+++ b/libs/pthreads/src/global.c
@@ -0,0 +1,107 @@
+/*
+ * global.c
+ *
+ * Description:
+ * This translation unit instantiates data associated with the implementation
+ * as a whole.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int ptw32_processInitialized = PTW32_FALSE;
+ptw32_thread_t * ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
+ptw32_thread_t * ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
+pthread_key_t ptw32_selfThreadKey = NULL;
+pthread_key_t ptw32_cleanupKey = NULL;
+pthread_cond_t ptw32_cond_list_head = NULL;
+pthread_cond_t ptw32_cond_list_tail = NULL;
+
+int ptw32_concurrency = 0;
+
+/* What features have been auto-detected */
+int ptw32_features = 0;
+
+/*
+ * Global [process wide] thread sequence Number
+ */
+unsigned __int64 ptw32_threadSeqNumber = 0;
+
+/*
+ * Function pointer to QueueUserAPCEx if it exists, otherwise
+ * it will be set at runtime to a substitute routine which cannot unblock
+ * blocked threads.
+ */
+DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL;
+
+/*
+ * Global lock for managing pthread_t struct reuse.
+ */
+ptw32_mcs_lock_t ptw32_thread_reuse_lock = 0;
+
+/*
+ * Global lock for testing internal state of statically declared mutexes.
+ */
+ptw32_mcs_lock_t ptw32_mutex_test_init_lock = 0;
+
+/*
+ * Global lock for testing internal state of PTHREAD_COND_INITIALIZER
+ * created condition variables.
+ */
+ptw32_mcs_lock_t ptw32_cond_test_init_lock = 0;
+
+/*
+ * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER
+ * created read/write locks.
+ */
+ptw32_mcs_lock_t ptw32_rwlock_test_init_lock = 0;
+
+/*
+ * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER
+ * created spin locks.
+ */
+ptw32_mcs_lock_t ptw32_spinlock_test_init_lock = 0;
+
+/*
+ * Global lock for condition variable linked list. The list exists
+ * to wake up CVs when a WM_TIMECHANGE message arrives. See
+ * w32_TimeChangeHandler.c.
+ */
+ptw32_mcs_lock_t ptw32_cond_list_lock = 0;
+
+#if defined(_UWIN)
+/*
+ * Keep a count of the number of threads.
+ */
+int pthread_count = 0;
+#endif
diff --git a/libs/pthreads/src/implement.h b/libs/pthreads/src/implement.h
new file mode 100644
index 0000000000..693be26a24
--- /dev/null
+++ b/libs/pthreads/src/implement.h
@@ -0,0 +1,943 @@
+/*
+ * implement.h
+ *
+ * Definitions that don't need to be public.
+ *
+ * Keeps all the internals out of pthread.h
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: Ross.Johnson@homemail.com.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined(_IMPLEMENT_H)
+#define _IMPLEMENT_H
+
+#if !defined(_WIN32_WINNT)
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include <windows.h>
+
+/*
+ * In case windows.h doesn't define it (e.g. WinCE perhaps)
+ */
+#if defined(WINCE)
+typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
+#endif
+
+/*
+ * note: ETIMEDOUT is correctly defined in winsock.h
+ */
+#include <winsock.h>
+
+/*
+ * In case ETIMEDOUT hasn't been defined above somehow.
+ */
+#if !defined(ETIMEDOUT)
+# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#endif
+
+#if !defined(malloc)
+#include <malloc.h>
+#endif
+
+#if defined(__CLEANUP_C)
+# include <setjmp.h>
+#endif
+
+#if !defined(INT_MAX)
+#include <limits.h>
+#endif
+
+/* use local include files during development */
+#include "semaphore.h"
+#include "sched.h"
+
+#if defined(HAVE_C_INLINE) || defined(__cplusplus)
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300
+/*
+ * MSVC 6 does not use the "volatile" qualifier
+ */
+#define PTW32_INTERLOCKED_VOLATILE
+#else
+#define PTW32_INTERLOCKED_VOLATILE volatile
+#endif
+#define PTW32_INTERLOCKED_LONG long
+#define PTW32_INTERLOCKED_SIZE size_t
+#define PTW32_INTERLOCKED_PVOID PVOID
+#define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long*
+#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t*
+#define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID*
+
+#if defined(__MINGW64__) || defined(__MINGW32__)
+# include <stdint.h>
+#elif defined(__BORLANDC__)
+# define int64_t ULONGLONG
+#else
+# define int64_t _int64
+# if defined(_MSC_VER) && _MSC_VER < 1300
+ typedef long intptr_t;
+# endif
+#endif
+
+typedef enum
+{
+ /*
+ * This enumeration represents the state of the thread;
+ * The thread is still "alive" if the numeric value of the
+ * state is greater or equal "PThreadStateRunning".
+ */
+ PThreadStateInitial = 0, /* Thread not running */
+ PThreadStateRunning, /* Thread alive & kicking */
+ PThreadStateSuspended, /* Thread alive but suspended */
+ PThreadStateCancelPending, /* Thread alive but */
+ /* has cancelation pending. */
+ PThreadStateCanceling, /* Thread alive but is */
+ /* in the process of terminating */
+ /* due to a cancellation request */
+ PThreadStateExiting, /* Thread alive but exiting */
+ /* due to an exception */
+ PThreadStateLast, /* All handlers have been run and now */
+ /* final cleanup can be done. */
+ PThreadStateReuse /* In reuse pool. */
+}
+PThreadState;
+
+typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t;
+typedef struct ptw32_mcs_node_t_* ptw32_mcs_lock_t;
+typedef struct ptw32_robust_node_t_ ptw32_robust_node_t;
+typedef struct ptw32_thread_t_ ptw32_thread_t;
+
+
+struct ptw32_thread_t_
+{
+ unsigned __int64 seqNumber; /* Process-unique thread sequence number */
+ HANDLE threadH; /* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
+ pthread_t ptHandle; /* This thread's permanent pthread_t handle */
+ ptw32_thread_t * prevReuse; /* Links threads on reuse stack */
+ volatile PThreadState state;
+ ptw32_mcs_lock_t threadLock; /* Used for serialised access to public thread state */
+ ptw32_mcs_lock_t stateLock; /* Used for async-cancel safety */
+ HANDLE cancelEvent;
+ void *exitStatus;
+ void *parms;
+ void *keys;
+ void *nextAssoc;
+#if defined(__CLEANUP_C)
+ jmp_buf start_mark; /* Jump buffer follows void* so should be aligned */
+#endif /* __CLEANUP_C */
+#if defined(HAVE_SIGSET_T)
+ sigset_t sigmask;
+#endif /* HAVE_SIGSET_T */
+ ptw32_mcs_lock_t
+ robustMxListLock; /* robustMxList lock */
+ ptw32_robust_node_t*
+ robustMxList; /* List of currenty held robust mutexes */
+ int ptErrno;
+ int detachState;
+ int sched_priority; /* As set, not as currently is */
+ int cancelState;
+ int cancelType;
+ int implicit:1;
+ DWORD thread; /* Win32 thread ID */
+#if defined(_UWIN)
+ DWORD dummy[5];
+#endif
+ size_t align; /* Force alignment if this struct is packed */
+};
+
+
+/*
+ * Special value to mark attribute objects as valid.
+ */
+#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
+
+struct pthread_attr_t_
+{
+ unsigned long valid;
+ void *stackaddr;
+ size_t stacksize;
+ int detachstate;
+ struct sched_param param;
+ int inheritsched;
+ int contentionscope;
+#if defined(HAVE_SIGSET_T)
+ sigset_t sigmask;
+#endif /* HAVE_SIGSET_T */
+};
+
+
+/*
+ * ====================
+ * ====================
+ * Semaphores, Mutexes and Condition Variables
+ * ====================
+ * ====================
+ */
+
+struct sem_t_
+{
+ int value;
+ pthread_mutex_t lock;
+ HANDLE sem;
+#if defined(NEED_SEM)
+ int leftToUnblock;
+#endif
+};
+
+#define PTW32_OBJECT_AUTO_INIT ((void *)(size_t) -1)
+#define PTW32_OBJECT_INVALID NULL
+
+struct pthread_mutex_t_
+{
+ LONG lock_idx; /* Provides exclusive access to mutex state
+ via the Interlocked* mechanism.
+ 0: unlocked/free.
+ 1: locked - no other waiters.
+ -1: locked - with possible other waiters.
+ */
+ int recursive_count; /* Number of unlocks a thread needs to perform
+ before the lock is released (recursive
+ mutexes only). */
+ int kind; /* Mutex type. */
+ pthread_t ownerThread;
+ HANDLE event; /* Mutex release notification to waiting
+ threads. */
+ ptw32_robust_node_t*
+ robustNode; /* Extra state for robust mutexes */
+};
+
+enum ptw32_robust_state_t_
+{
+ PTW32_ROBUST_CONSISTENT,
+ PTW32_ROBUST_INCONSISTENT,
+ PTW32_ROBUST_NOTRECOVERABLE
+};
+
+typedef enum ptw32_robust_state_t_ ptw32_robust_state_t;
+
+/*
+ * Node used to manage per-thread lists of currently-held robust mutexes.
+ */
+struct ptw32_robust_node_t_
+{
+ pthread_mutex_t mx;
+ ptw32_robust_state_t stateInconsistent;
+ ptw32_robust_node_t* prev;
+ ptw32_robust_node_t* next;
+};
+
+struct pthread_mutexattr_t_
+{
+ int pshared;
+ int kind;
+ int robustness;
+};
+
+/*
+ * Possible values, other than PTW32_OBJECT_INVALID,
+ * for the "interlock" element in a spinlock.
+ *
+ * In this implementation, when a spinlock is initialised,
+ * the number of cpus available to the process is checked.
+ * If there is only one cpu then "interlock" is set equal to
+ * PTW32_SPIN_USE_MUTEX and u.mutex is an initialised mutex.
+ * If the number of cpus is greater than 1 then "interlock"
+ * is set equal to PTW32_SPIN_UNLOCKED and the number is
+ * stored in u.cpus. This arrangement allows the spinlock
+ * routines to attempt an InterlockedCompareExchange on "interlock"
+ * immediately and, if that fails, to try the inferior mutex.
+ *
+ * "u.cpus" isn't used for anything yet, but could be used at
+ * some point to optimise spinlock behaviour.
+ */
+#define PTW32_SPIN_INVALID (0)
+#define PTW32_SPIN_UNLOCKED (1)
+#define PTW32_SPIN_LOCKED (2)
+#define PTW32_SPIN_USE_MUTEX (3)
+
+struct pthread_spinlock_t_
+{
+ long interlock; /* Locking element for multi-cpus. */
+ union
+ {
+ int cpus; /* No. of cpus if multi cpus, or */
+ pthread_mutex_t mutex; /* mutex if single cpu. */
+ } u;
+};
+
+/*
+ * MCS lock queue node - see ptw32_MCS_lock.c
+ */
+struct ptw32_mcs_node_t_
+{
+ struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */
+ struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */
+ HANDLE readyFlag; /* set after lock is released by
+ predecessor */
+ HANDLE nextFlag; /* set after 'next' ptr is set by
+ successor */
+};
+
+
+struct pthread_barrier_t_
+{
+ unsigned int nCurrentBarrierHeight;
+ unsigned int nInitialBarrierHeight;
+ int pshared;
+ sem_t semBarrierBreeched;
+ ptw32_mcs_lock_t lock;
+ ptw32_mcs_local_node_t proxynode;
+};
+
+struct pthread_barrierattr_t_
+{
+ int pshared;
+};
+
+struct pthread_key_t_
+{
+ DWORD key;
+ void (PTW32_CDECL *destructor) (void *);
+ ptw32_mcs_lock_t keyLock;
+ void *threads;
+};
+
+
+typedef struct ThreadParms ThreadParms;
+
+struct ThreadParms
+{
+ pthread_t tid;
+ void *(PTW32_CDECL *start) (void *);
+ void *arg;
+};
+
+
+struct pthread_cond_t_
+{
+ long nWaitersBlocked; /* Number of threads blocked */
+ long nWaitersGone; /* Number of threads timed out */
+ long nWaitersToUnblock; /* Number of threads to unblock */
+ sem_t semBlockQueue; /* Queue up threads waiting for the */
+ /* condition to become signalled */
+ sem_t semBlockLock; /* Semaphore that guards access to */
+ /* | waiters blocked count/block queue */
+ /* +-> Mandatory Sync.LEVEL-1 */
+ pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */
+ /* | waiters (to)unblock(ed) counts */
+ /* +-> Optional* Sync.LEVEL-2 */
+ pthread_cond_t next; /* Doubly linked list */
+ pthread_cond_t prev;
+};
+
+
+struct pthread_condattr_t_
+{
+ int pshared;
+};
+
+#define PTW32_RWLOCK_MAGIC 0xfacade2
+
+struct pthread_rwlock_t_
+{
+ pthread_mutex_t mtxExclusiveAccess;
+ pthread_mutex_t mtxSharedAccessCompleted;
+ pthread_cond_t cndSharedAccessCompleted;
+ int nSharedAccessCount;
+ int nExclusiveAccessCount;
+ int nCompletedSharedAccessCount;
+ int nMagic;
+};
+
+struct pthread_rwlockattr_t_
+{
+ int pshared;
+};
+
+typedef struct ThreadKeyAssoc ThreadKeyAssoc;
+
+struct ThreadKeyAssoc
+{
+ /*
+ * Purpose:
+ * This structure creates an association between a thread and a key.
+ * It is used to implement the implicit invocation of a user defined
+ * destroy routine for thread specific data registered by a user upon
+ * exiting a thread.
+ *
+ * Graphically, the arrangement is as follows, where:
+ *
+ * K - Key with destructor
+ * (head of chain is key->threads)
+ * T - Thread that has called pthread_setspecific(Kn)
+ * (head of chain is thread->keys)
+ * A - Association. Each association is a node at the
+ * intersection of two doubly-linked lists.
+ *
+ * T1 T2 T3
+ * | | |
+ * | | |
+ * K1 -----+-----A-----A----->
+ * | | |
+ * | | |
+ * K2 -----A-----A-----+----->
+ * | | |
+ * | | |
+ * K3 -----A-----+-----A----->
+ * | | |
+ * | | |
+ * V V V
+ *
+ * Access to the association is guarded by two locks: the key's
+ * general lock (guarding the row) and the thread's general
+ * lock (guarding the column). This avoids the need for a
+ * dedicated lock for each association, which not only consumes
+ * more handles but requires that the lock resources persist
+ * until both the key is deleted and the thread has called the
+ * destructor. The two-lock arrangement allows those resources
+ * to be freed as soon as either thread or key is concluded.
+ *
+ * To avoid deadlock, whenever both locks are required both the
+ * key and thread locks are acquired consistently in the order
+ * "key lock then thread lock". An exception to this exists
+ * when a thread calls the destructors, however, this is done
+ * carefully (but inelegantly) to avoid deadlock.
+ *
+ * An association is created when a thread first calls
+ * pthread_setspecific() on a key that has a specified
+ * destructor.
+ *
+ * An association is destroyed either immediately after the
+ * thread calls the key destructor function on thread exit, or
+ * when the key is deleted.
+ *
+ * Attributes:
+ * thread
+ * reference to the thread that owns the
+ * association. This is actually the pointer to the
+ * thread struct itself. Since the association is
+ * destroyed before the thread exits, this can never
+ * point to a different logical thread to the one that
+ * created the assoc, i.e. after thread struct reuse.
+ *
+ * key
+ * reference to the key that owns the association.
+ *
+ * nextKey
+ * The pthread_t->keys attribute is the head of a
+ * chain of associations that runs through the nextKey
+ * link. This chain provides the 1 to many relationship
+ * between a pthread_t and all pthread_key_t on which
+ * it called pthread_setspecific.
+ *
+ * prevKey
+ * Similarly.
+ *
+ * nextThread
+ * The pthread_key_t->threads attribute is the head of
+ * a chain of associations that runs through the
+ * nextThreads link. This chain provides the 1 to many
+ * relationship between a pthread_key_t and all the
+ * PThreads that have called pthread_setspecific for
+ * this pthread_key_t.
+ *
+ * prevThread
+ * Similarly.
+ *
+ * Notes:
+ * 1) As soon as either the key or the thread is no longer
+ * referencing the association, it can be destroyed. The
+ * association will be removed from both chains.
+ *
+ * 2) Under WIN32, an association is only created by
+ * pthread_setspecific if the user provided a
+ * destroyRoutine when they created the key.
+ *
+ *
+ */
+ ptw32_thread_t * thread;
+ pthread_key_t key;
+ ThreadKeyAssoc *nextKey;
+ ThreadKeyAssoc *nextThread;
+ ThreadKeyAssoc *prevKey;
+ ThreadKeyAssoc *prevThread;
+};
+
+
+#if defined(__CLEANUP_SEH)
+/*
+ * --------------------------------------------------------------
+ * MAKE_SOFTWARE_EXCEPTION
+ * This macro constructs a software exception code following
+ * the same format as the standard Win32 error codes as defined
+ * in WINERROR.H
+ * Values are 32 bit values laid out as follows:
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +---+-+-+-----------------------+-------------------------------+
+ * |Sev|C|R| Facility | Code |
+ * +---+-+-+-----------------------+-------------------------------+
+ *
+ * Severity Values:
+ */
+#define SE_SUCCESS 0x00
+#define SE_INFORMATION 0x01
+#define SE_WARNING 0x02
+#define SE_ERROR 0x03
+
+#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
+( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \
+ ( 1 << 29 ) | /* MS=0, User=1 */ \
+ ( 0 << 28 ) | /* Reserved */ \
+ ( (_facility) << 16 ) | /* Facility Code */ \
+ ( (_exception) << 0 ) /* Exception Code */ \
+ ) )
+
+/*
+ * We choose one specific Facility/Error code combination to
+ * identify our software exceptions vs. WIN32 exceptions.
+ * We store our actual component and error code within
+ * the optional information array.
+ */
+#define EXCEPTION_PTW32_SERVICES \
+ MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
+ PTW32_SERVICES_FACILITY, \
+ PTW32_SERVICES_ERROR )
+
+#define PTW32_SERVICES_FACILITY 0xBAD
+#define PTW32_SERVICES_ERROR 0xDEED
+
+#endif /* __CLEANUP_SEH */
+
+/*
+ * Services available through EXCEPTION_PTW32_SERVICES
+ * and also used [as parameters to ptw32_throw()] as
+ * generic exception selectors.
+ */
+
+#define PTW32_EPS_EXIT (1)
+#define PTW32_EPS_CANCEL (2)
+
+
+/* Useful macros */
+#define PTW32_MAX(a,b) ((a)<(b)?(b):(a))
+#define PTW32_MIN(a,b) ((a)>(b)?(b):(a))
+
+
+/* Declared in pthread_cancel.c */
+extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
+
+/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
+#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *)(size_t) 1)
+
+extern int ptw32_processInitialized;
+extern ptw32_thread_t * ptw32_threadReuseTop;
+extern ptw32_thread_t * ptw32_threadReuseBottom;
+extern pthread_key_t ptw32_selfThreadKey;
+extern pthread_key_t ptw32_cleanupKey;
+extern pthread_cond_t ptw32_cond_list_head;
+extern pthread_cond_t ptw32_cond_list_tail;
+
+extern int ptw32_mutex_default_kind;
+
+extern unsigned __int64 ptw32_threadSeqNumber;
+
+extern int ptw32_concurrency;
+
+extern int ptw32_features;
+
+extern ptw32_mcs_lock_t ptw32_thread_reuse_lock;
+extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_cond_list_lock;
+extern ptw32_mcs_lock_t ptw32_cond_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock;
+extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock;
+
+#if defined(_UWIN)
+extern int pthread_count;
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * =====================
+ * =====================
+ * Forward Declarations
+ * =====================
+ * =====================
+ */
+
+ int ptw32_is_attr (const pthread_attr_t * attr);
+
+ int ptw32_cond_check_need_init (pthread_cond_t * cond);
+ int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
+ int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
+
+ int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex);
+ void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self);
+ void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp);
+
+ DWORD
+ ptw32_RegisterCancelation (PAPCFUNC callback,
+ HANDLE threadH, DWORD callback_arg);
+
+ int ptw32_processInitialize (void);
+
+ void ptw32_processTerminate (void);
+
+ void ptw32_threadDestroy (pthread_t tid);
+
+ void ptw32_pop_cleanup_all (int execute);
+
+ pthread_t ptw32_new (void);
+
+ pthread_t ptw32_threadReusePop (void);
+
+ void ptw32_threadReusePush (pthread_t thread);
+
+ int ptw32_getprocessors (int *count);
+
+ int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
+
+ void ptw32_rwlock_cancelwrwait (void *arg);
+
+#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__))
+ unsigned __stdcall
+#else
+ void
+#endif
+ ptw32_threadStart (void *vthreadParms);
+
+ void ptw32_callUserDestroyRoutines (pthread_t thread);
+
+ int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key);
+
+ void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
+
+ int ptw32_semwait (sem_t * sem);
+
+ DWORD ptw32_relmillisecs (const struct timespec * abstime);
+
+ void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
+
+ int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
+
+ void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node);
+
+ void ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node);
+
+#if defined(NEED_FTIME)
+ void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
+ void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
+#endif
+
+/* Declared in misc.c */
+#if defined(NEED_CALLOC)
+#define calloc(n, s) ptw32_calloc(n, s)
+ void *ptw32_calloc (size_t n, size_t s);
+#endif
+
+/* Declared in private.c */
+#if defined(_MSC_VER)
+/*
+ * Ignore the warning:
+ * "C++ exception specification ignored except to indicate that
+ * the function is not __declspec(nothrow)."
+ */
+#pragma warning(disable:4290)
+#endif
+ void ptw32_throw (DWORD exception)
+#if defined(__CLEANUP_CXX)
+ throw(ptw32_exception_cancel,ptw32_exception_exit)
+#endif
+;
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+
+#if defined(_UWIN_)
+# if defined(_MT)
+# if defined(__cplusplus)
+extern "C"
+{
+# endif
+ _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
+ unsigned, void *);
+ _CRTIMP void __cdecl _endthread (void);
+ _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
+ unsigned (__stdcall *) (void *),
+ void *, unsigned, unsigned *);
+ _CRTIMP void __cdecl _endthreadex (unsigned);
+# if defined(__cplusplus)
+}
+# endif
+# endif
+#else
+# include <process.h>
+# endif
+
+
+/*
+ * Use intrinsic versions wherever possible. VC will do this
+ * automatically where possible and GCC define these if available:
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+ *
+ * The full set of Interlocked intrinsics in GCC are (check versions):
+ * type __sync_fetch_and_add (type *ptr, type value, ...)
+ * type __sync_fetch_and_sub (type *ptr, type value, ...)
+ * type __sync_fetch_and_or (type *ptr, type value, ...)
+ * type __sync_fetch_and_and (type *ptr, type value, ...)
+ * type __sync_fetch_and_xor (type *ptr, type value, ...)
+ * type __sync_fetch_and_nand (type *ptr, type value, ...)
+ * type __sync_add_and_fetch (type *ptr, type value, ...)
+ * type __sync_sub_and_fetch (type *ptr, type value, ...)
+ * type __sync_or_and_fetch (type *ptr, type value, ...)
+ * type __sync_and_and_fetch (type *ptr, type value, ...)
+ * type __sync_xor_and_fetch (type *ptr, type value, ...)
+ * type __sync_nand_and_fetch (type *ptr, type value, ...)
+ * bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
+ * type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
+ * __sync_synchronize (...) // Full memory barrier
+ * type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier
+ * void __sync_lock_release (type *ptr, ...) // Release barrier
+ *
+ * These are all overloaded and take 1,2,4,8 byte scalar or pointer types.
+ *
+ * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own.
+ */
+#if defined(__GNUC__)
+# if defined(_WIN64)
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "cmpxchgq %2,(%1)" \
+ :"=a" (_result) \
+ :"r" (location), "r" (value), "a" (comparand) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_EXCHANGE_64(location, value) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "xchgq %0,(%1)" \
+ :"=r" (_result) \
+ :"r" (location), "0" (value) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(location, value) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddq %0,(%1)" \
+ :"=r" (_result) \
+ :"r" (location), "0" (value) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_INCREMENT_64(location) \
+ ({ \
+ PTW32_INTERLOCKED_LONG _temp = 1; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddq %0,(%1)" \
+ :"+r" (_temp) \
+ :"r" (location) \
+ :"memory", "cc"); \
+ ++_temp; \
+ })
+# define PTW32_INTERLOCKED_DECREMENT_64(location) \
+ ({ \
+ PTW32_INTERLOCKED_LONG _temp = -1; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddq %2,(%1)" \
+ :"+r" (_temp) \
+ :"r" (location) \
+ :"memory", "cc"); \
+ --_temp; \
+ })
+#endif
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "cmpxchgl %2,(%1)" \
+ :"=a" (_result) \
+ :"r" (location), "r" (value), "a" (comparand) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_EXCHANGE_LONG(location, value) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "xchgl %0,(%1)" \
+ :"=r" (_result) \
+ :"r" (location), "0" (value) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(location, value) \
+ ({ \
+ __typeof (value) _result; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddl %0,(%1)" \
+ :"=r" (_result) \
+ :"r" (location), "0" (value) \
+ :"memory", "cc"); \
+ _result; \
+ })
+# define PTW32_INTERLOCKED_INCREMENT_LONG(location) \
+ ({ \
+ PTW32_INTERLOCKED_LONG _temp = 1; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddl %0,(%1)" \
+ :"+r" (_temp) \
+ :"r" (location) \
+ :"memory", "cc"); \
+ ++_temp; \
+ })
+# define PTW32_INTERLOCKED_DECREMENT_LONG(location) \
+ ({ \
+ PTW32_INTERLOCKED_LONG _temp = -1; \
+ __asm__ __volatile__ \
+ ( \
+ "lock\n\t" \
+ "xaddl %0,(%1)" \
+ :"+r" (_temp) \
+ :"r" (location) \
+ :"memory", "cc"); \
+ --_temp; \
+ })
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(location, value, comparand) \
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
+ (PTW32_INTERLOCKED_SIZE)value, \
+ (PTW32_INTERLOCKED_SIZE)comparand)
+# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
+ PTW32_INTERLOCKED_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \
+ (PTW32_INTERLOCKED_SIZE)value)
+#else
+# if defined(_WIN64)
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 InterlockedCompareExchange64
+# define PTW32_INTERLOCKED_EXCHANGE_64 InterlockedExchange64
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_64 InterlockedExchangeAdd64
+# define PTW32_INTERLOCKED_INCREMENT_64 InterlockedIncrement64
+# define PTW32_INTERLOCKED_DECREMENT_64 InterlockedDecrement64
+# endif
+# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \
+ ((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand)))
+# else
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange
+# endif
+# define PTW32_INTERLOCKED_EXCHANGE_LONG InterlockedExchange
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG InterlockedExchangeAdd
+# define PTW32_INTERLOCKED_INCREMENT_LONG InterlockedIncrement
+# define PTW32_INTERLOCKED_DECREMENT_LONG InterlockedDecrement
+# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange
+# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \
+ ((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value)))
+# else
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer
+# define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer
+# endif
+#endif
+#if defined(_WIN64)
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_64
+# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_64
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_64
+# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_64
+# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_64
+#else
+# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG
+# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_LONG
+# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_LONG
+# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_LONG
+# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_LONG
+#endif
+
+#if defined(NEED_CREATETHREAD)
+
+/*
+ * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
+ * in order to avoid warnings because of return type
+ */
+
+#define _beginthreadex(security, \
+ stack_size, \
+ start_proc, \
+ arg, \
+ flags, \
+ pid) \
+ CreateThread(security, \
+ stack_size, \
+ (LPTHREAD_START_ROUTINE) start_proc, \
+ arg, \
+ flags, \
+ pid)
+
+#define _endthreadex ExitThread
+
+#endif /* NEED_CREATETHREAD */
+
+
+#endif /* _IMPLEMENT_H */
diff --git a/libs/pthreads/src/misc.c b/libs/pthreads/src/misc.c
new file mode 100644
index 0000000000..06d1d21374
--- /dev/null
+++ b/libs/pthreads/src/misc.c
@@ -0,0 +1,50 @@
+/*
+ * misc.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "pthread_kill.c"
+#include "pthread_once.c"
+#include "pthread_self.c"
+#include "pthread_equal.c"
+#include "pthread_setconcurrency.c"
+#include "pthread_getconcurrency.c"
+#include "ptw32_new.c"
+#include "ptw32_calloc.c"
+#include "ptw32_reuse.c"
+#include "w32_CancelableWait.c"
diff --git a/libs/pthreads/src/mutex.c b/libs/pthreads/src/mutex.c
new file mode 100644
index 0000000000..c2b3607ca2
--- /dev/null
+++ b/libs/pthreads/src/mutex.c
@@ -0,0 +1,62 @@
+/*
+ * mutex.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if ! defined(_UWIN) && ! defined(WINCE)
+# include <process.h>
+#endif
+#if !defined(NEED_FTIME)
+#include <sys/timeb.h>
+#endif
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "ptw32_mutex_check_need_init.c"
+#include "pthread_mutex_init.c"
+#include "pthread_mutex_destroy.c"
+#include "pthread_mutexattr_init.c"
+#include "pthread_mutexattr_destroy.c"
+#include "pthread_mutexattr_getpshared.c"
+#include "pthread_mutexattr_setpshared.c"
+#include "pthread_mutexattr_settype.c"
+#include "pthread_mutexattr_gettype.c"
+#include "pthread_mutexattr_setrobust.c"
+#include "pthread_mutexattr_getrobust.c"
+#include "pthread_mutex_lock.c"
+#include "pthread_mutex_timedlock.c"
+#include "pthread_mutex_unlock.c"
+#include "pthread_mutex_trylock.c"
+#include "pthread_mutex_consistent.c"
diff --git a/libs/pthreads/src/need_errno.h b/libs/pthreads/src/need_errno.h
new file mode 100644
index 0000000000..abf1c95574
--- /dev/null
+++ b/libs/pthreads/src/need_errno.h
@@ -0,0 +1,145 @@
+/***
+* errno.h - system wide error numbers (set by system calls)
+*
+* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
+*
+* Purpose:
+* This file defines the system-wide error numbers (set by
+* system calls). Conforms to the XENIX standard. Extended
+* for compatibility with Uniforum standard.
+* [System V]
+*
+* [Public]
+*
+****/
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#if !defined(_INC_ERRNO)
+#define _INC_ERRNO
+
+#if !defined(_WIN32)
+#error ERROR: Only Win32 targets supported!
+#endif
+
+#include <winsock.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/* Define _CRTIMP */
+
+#ifndef _CRTIMP
+#if defined(_DLL)
+#define _CRTIMP __declspec(dllimport)
+#else /* ndef _DLL */
+#define _CRTIMP
+#endif /* _DLL */
+#endif /* _CRTIMP */
+
+
+/* Define __cdecl for non-Microsoft compilers */
+
+#if ( !defined(_MSC_VER) && !defined(__cdecl) )
+#define __cdecl
+#endif
+
+/* Define _CRTAPI1 (for compatibility with the NT SDK) */
+
+#if !defined(_CRTAPI1)
+#if _MSC_VER >= 800 && _M_IX86 >= 300
+#define _CRTAPI1 __cdecl
+#else
+#define _CRTAPI1
+#endif
+#endif
+
+#if !defined(PTW32_STATIC_LIB)
+# if defined(PTW32_BUILD)
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/* declare reference to errno */
+
+#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC)
+PTW32_DLLPORT int * __cdecl _errno(void);
+#define errno (*_errno())
+#else /* ndef _MT && ndef _MD && ndef _DLL */
+_CRTIMP extern int errno;
+#endif /* _MT || _MD || _DLL */
+
+/* Error Codes */
+
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 36
+
+/* defined differently in winsock.h on WinCE */
+#if !defined(ENAMETOOLONG)
+#define ENAMETOOLONG 38
+#endif
+
+#define ENOLCK 39
+#define ENOSYS 40
+
+/* defined differently in winsock.h on WinCE */
+#if !defined(ENOTEMPTY)
+#define ENOTEMPTY 41
+#endif
+
+#define EILSEQ 42
+
+/* POSIX 2008 - robust mutexes */
+#define EOWNERDEAD 43
+#define ENOTRECOVERABLE 44
+
+/*
+ * Support EDEADLOCK for compatibiity with older MS-C versions.
+ */
+#define EDEADLOCK EDEADLK
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _INC_ERRNO */
diff --git a/libs/pthreads/src/nonportable.c b/libs/pthreads/src/nonportable.c
new file mode 100644
index 0000000000..742cb969b4
--- /dev/null
+++ b/libs/pthreads/src/nonportable.c
@@ -0,0 +1,47 @@
+/*
+ * nonportable.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#include "pthread_mutexattr_setkind_np.c"
+#include "pthread_mutexattr_getkind_np.c"
+#include "pthread_getw32threadhandle_np.c"
+#include "pthread_getunique_np.c"
+#include "pthread_delay_np.c"
+#include "pthread_num_processors_np.c"
+#include "pthread_win32_attach_detach_np.c"
+#include "pthread_timechange_handler_np.c"
diff --git a/libs/pthreads/src/private.c b/libs/pthreads/src/private.c
new file mode 100644
index 0000000000..1b1ccb7c52
--- /dev/null
+++ b/libs/pthreads/src/private.c
@@ -0,0 +1,54 @@
+/*
+ * private.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#include "ptw32_MCS_lock.c"
+#include "ptw32_is_attr.c"
+#include "ptw32_processInitialize.c"
+#include "ptw32_processTerminate.c"
+#include "ptw32_threadStart.c"
+#include "ptw32_threadDestroy.c"
+#include "ptw32_tkAssocCreate.c"
+#include "ptw32_tkAssocDestroy.c"
+#include "ptw32_callUserDestroyRoutines.c"
+#include "ptw32_semwait.c"
+#include "ptw32_timespec.c"
+#include "ptw32_relmillisecs.c"
+#include "ptw32_throw.c"
+#include "ptw32_getprocessors.c"
diff --git a/libs/pthreads/src/pthread.c b/libs/pthreads/src/pthread.c
new file mode 100644
index 0000000000..60b53412be
--- /dev/null
+++ b/libs/pthreads/src/pthread.c
@@ -0,0 +1,66 @@
+/*
+ * pthread.c
+ *
+ * Description:
+ * This translation unit agregates pthreads-win32 translation units.
+ * It is used for inline optimisation of the library,
+ * maximising for speed at the expense of size.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* The following are ordered for inlining */
+
+#include "private.c"
+#include "attr.c"
+#include "barrier.c"
+#include "cancel.c"
+#include "cleanup.c"
+#include "condvar.c"
+#include "create.c"
+#include "dll.c"
+#include "autostatic.c"
+#include "errno.c"
+#include "exit.c"
+#include "fork.c"
+#include "global.c"
+#include "misc.c"
+#include "mutex.c"
+#include "nonportable.c"
+#include "rwlock.c"
+#include "sched.c"
+#include "semaphore.c"
+#include "signal.c"
+#include "spin.c"
+#include "sync.c"
+#include "tsd.c"
diff --git a/libs/pthreads/src/pthread.h b/libs/pthreads/src/pthread.h
new file mode 100644
index 0000000000..32ff72bb54
--- /dev/null
+++ b/libs/pthreads/src/pthread.h
@@ -0,0 +1,1368 @@
+/* This is an implementation of the threads API of POSIX 1003.1-2001.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined( PTHREAD_H )
+#define PTHREAD_H
+
+/*
+ * See the README file for an explanation of the pthreads-win32 version
+ * numbering scheme and how the DLL is named etc.
+ */
+#define PTW32_VERSION 2,9,1,0
+#define PTW32_VERSION_STRING "2, 9, 1, 0\0"
+
+/* There are three implementations of cancel cleanup.
+ * Note that pthread.h is included in both application
+ * compilation units and also internally for the library.
+ * The code here and within the library aims to work
+ * for all reasonable combinations of environments.
+ *
+ * The three implementations are:
+ *
+ * WIN32 SEH
+ * C
+ * C++
+ *
+ * Please note that exiting a push/pop block via
+ * "return", "exit", "break", or "continue" will
+ * lead to different behaviour amongst applications
+ * depending upon whether the library was built
+ * using SEH, C++, or C. For example, a library built
+ * with SEH will call the cleanup routine, while both
+ * C++ and C built versions will not.
+ */
+
+/*
+ * Define defaults for cleanup code.
+ * Note: Unless the build explicitly defines one of the following, then
+ * we default to standard C style cleanup. This style uses setjmp/longjmp
+ * in the cancelation and thread exit implementations and therefore won't
+ * do stack unwinding if linked to applications that have it (e.g.
+ * C++ apps). This is currently consistent with most/all commercial Unix
+ * POSIX threads implementations.
+ */
+#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
+# define __CLEANUP_C
+#endif
+
+#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
+#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
+#endif
+
+/*
+ * Stop here if we are being included by the resource compiler.
+ */
+#if !defined(RC_INVOKED)
+
+#undef PTW32_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_LEVEL_MAX 3
+
+#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL)
+#define PTW32_LEVEL PTW32_LEVEL_MAX
+/* Include everything */
+#endif
+
+#if defined(_UWIN)
+# define HAVE_STRUCT_TIMESPEC 1
+# define HAVE_SIGNAL_H 1
+# undef HAVE_PTW32_CONFIG_H
+# pragma comment(lib, "pthread")
+#endif
+
+/*
+ * -------------------------------------------------------------
+ *
+ *
+ * Module: pthread.h
+ *
+ * Purpose:
+ * Provides an implementation of PThreads based upon the
+ * standard:
+ *
+ * POSIX 1003.1-2001
+ * and
+ * The Single Unix Specification version 3
+ *
+ * (these two are equivalent)
+ *
+ * in order to enhance code portability between Windows,
+ * various commercial Unix implementations, and Linux.
+ *
+ * See the ANNOUNCE file for a full list of conforming
+ * routines and defined constants, and a list of missing
+ * routines and constants not defined in this implementation.
+ *
+ * Authors:
+ * There have been many contributors to this library.
+ * The initial implementation was contributed by
+ * John Bossom, and several others have provided major
+ * sections or revisions of parts of the implementation.
+ * Often significant effort has been contributed to
+ * find and fix important bugs and other problems to
+ * improve the reliability of the library, which sometimes
+ * is not reflected in the amount of code which changed as
+ * result.
+ * As much as possible, the contributors are acknowledged
+ * in the ChangeLog file in the source code distribution
+ * where their changes are noted in detail.
+ *
+ * Contributors are listed in the CONTRIBUTORS file.
+ *
+ * As usual, all bouquets go to the contributors, and all
+ * brickbats go to the project maintainer.
+ *
+ * Maintainer:
+ * The code base for this project is coordinated and
+ * eventually pre-tested, packaged, and made available by
+ *
+ * Ross Johnson <rpj@callisto.canberra.edu.au>
+ *
+ * QA Testers:
+ * Ultimately, the library is tested in the real world by
+ * a host of competent and demanding scientists and
+ * engineers who report bugs and/or provide solutions
+ * which are then fixed or incorporated into subsequent
+ * versions of the library. Each time a bug is fixed, a
+ * test case is written to prove the fix and ensure
+ * that later changes to the code don't reintroduce the
+ * same error. The number of test cases is slowly growing
+ * and therefore so is the code reliability.
+ *
+ * Compliance:
+ * See the file ANNOUNCE for the list of implemented
+ * and not-implemented routines and defined options.
+ * Of course, these are all defined is this file as well.
+ *
+ * Web site:
+ * The source code and other information about this library
+ * are available from
+ *
+ * http://sources.redhat.com/pthreads-win32/
+ *
+ * -------------------------------------------------------------
+ */
+
+/* Try to avoid including windows.h */
+#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus)
+#define PTW32_INCLUDE_WINDOWS_H
+#endif
+
+#if defined(PTW32_INCLUDE_WINDOWS_H)
+#include <windows.h>
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
+/*
+ * VC++6.0 or early compiler's header has no DWORD_PTR type.
+ */
+typedef unsigned long DWORD_PTR;
+typedef unsigned long ULONG_PTR;
+#endif
+/*
+ * -----------------
+ * autoconf switches
+ * -----------------
+ */
+
+#if defined(HAVE_PTW32_CONFIG_H)
+#include "config.h"
+#endif /* HAVE_PTW32_CONFIG_H */
+
+#if !defined(NEED_FTIME)
+#include <time.h>
+#else /* NEED_FTIME */
+/* use native WIN32 time API */
+#endif /* NEED_FTIME */
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif /* HAVE_SIGNAL_H */
+
+#include <limits.h>
+
+/*
+ * Boolean values to make us independent of system includes.
+ */
+enum {
+ PTW32_FALSE = 0,
+ PTW32_TRUE = (! PTW32_FALSE)
+};
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#if !defined(PTW32_CONFIG_H)
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_MSC_VER) || defined(__MINGW64__)
+# define HAVE_STRUCT_TIMESPEC
+# define HAVE_MODE_T
+# elif defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#if defined(NEED_ERRNO)
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Several systems don't define some error numbers.
+ */
+#if !defined(ENOTSUP)
+# define ENOTSUP 48 /* This is the value in Solaris. */
+#endif
+
+#if !defined(ETIMEDOUT)
+# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */
+#endif
+
+#if !defined(ENOSYS)
+# define ENOSYS 140 /* Semi-arbitrary value */
+#endif
+
+#if !defined(EDEADLK)
+# if defined(EDEADLOCK)
+# define EDEADLK EDEADLOCK
+# else
+# define EDEADLK 36 /* This is the value in MSVC. */
+# endif
+#endif
+
+/* POSIX 2008 - related to robust mutexes */
+#if !defined(EOWNERDEAD)
+# define EOWNERDEAD 43
+#endif
+#if !defined(ENOTRECOVERABLE)
+# define ENOTRECOVERABLE 44
+#endif
+
+#include <sched.h>
+
+/*
+ * To avoid including windows.h we define only those things that we
+ * actually need from it.
+ */
+#if !defined(PTW32_INCLUDE_WINDOWS_H)
+#if !defined(HANDLE)
+# define PTW32__HANDLE_DEF
+# define HANDLE void *
+#endif
+#if !defined(DWORD)
+# define PTW32__DWORD_DEF
+# define DWORD unsigned long
+#endif
+#endif
+
+#if !defined(HAVE_STRUCT_TIMESPEC)
+#define HAVE_STRUCT_TIMESPEC
+#if !defined(_TIMESPEC_DEFINED)
+#define _TIMESPEC_DEFINED
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#endif /* _TIMESPEC_DEFINED */
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+#if !defined(SIG_BLOCK)
+#define SIG_BLOCK 0
+#endif /* SIG_BLOCK */
+
+#if !defined(SIG_UNBLOCK)
+#define SIG_UNBLOCK 1
+#endif /* SIG_UNBLOCK */
+
+#if !defined(SIG_SETMASK)
+#define SIG_SETMASK 2
+#endif /* SIG_SETMASK */
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * -------------------------------------------------------------
+ *
+ * POSIX 1003.1-2001 Options
+ * =========================
+ *
+ * Options are normally set in <unistd.h>, which is not provided
+ * with pthreads-win32.
+ *
+ * For conformance with the Single Unix Specification (version 3), all of the
+ * options below are defined, and have a value of either -1 (not supported)
+ * or 200112L (supported).
+ *
+ * These options can neither be left undefined nor have a value of 0, because
+ * either indicates that sysconf(), which is not implemented, may be used at
+ * runtime to check the status of the option.
+ *
+ * _POSIX_THREADS (== 200112L)
+ * If == 200112L, you can use threads
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
+ * If == 200112L, you can control the size of a thread's
+ * stack
+ * pthread_attr_getstacksize
+ * pthread_attr_setstacksize
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR (== -1)
+ * If == 200112L, you can allocate and control a thread's
+ * stack. If not supported, the following functions
+ * will return ENOSYS, indicating they are not
+ * supported:
+ * pthread_attr_getstackaddr
+ * pthread_attr_setstackaddr
+ *
+ * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
+ * If == 200112L, you can use realtime scheduling.
+ * This option indicates that the behaviour of some
+ * implemented functions conforms to the additional TPS
+ * requirements in the standard. E.g. rwlocks favour
+ * writers over readers when threads have equal priority.
+ *
+ * _POSIX_THREAD_PRIO_INHERIT (== -1)
+ * If == 200112L, you can create priority inheritance
+ * mutexes.
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PRIO_PROTECT (== -1)
+ * If == 200112L, you can create priority ceiling mutexes
+ * Indicates the availability of:
+ * pthread_mutex_getprioceiling
+ * pthread_mutex_setprioceiling
+ * pthread_mutexattr_getprioceiling
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprioceiling
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PROCESS_SHARED (== -1)
+ * If set, you can create mutexes and condition
+ * variables that can be shared with another
+ * process.If set, indicates the availability
+ * of:
+ * pthread_mutexattr_getpshared
+ * pthread_mutexattr_setpshared
+ * pthread_condattr_getpshared
+ * pthread_condattr_setpshared
+ *
+ * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
+ * If == 200112L you can use the special *_r library
+ * functions that provide thread-safe behaviour
+ *
+ * _POSIX_READER_WRITER_LOCKS (== 200112L)
+ * If == 200112L, you can use read/write locks
+ *
+ * _POSIX_SPIN_LOCKS (== 200112L)
+ * If == 200112L, you can use spin locks
+ *
+ * _POSIX_BARRIERS (== 200112L)
+ * If == 200112L, you can use barriers
+ *
+ * + These functions provide both 'inherit' and/or
+ * 'protect' protocol, based upon these macro
+ * settings.
+ *
+ * -------------------------------------------------------------
+ */
+
+/*
+ * POSIX Options
+ */
+#undef _POSIX_THREADS
+#define _POSIX_THREADS 200809L
+
+#undef _POSIX_READER_WRITER_LOCKS
+#define _POSIX_READER_WRITER_LOCKS 200809L
+
+#undef _POSIX_SPIN_LOCKS
+#define _POSIX_SPIN_LOCKS 200809L
+
+#undef _POSIX_BARRIERS
+#define _POSIX_BARRIERS 200809L
+
+#undef _POSIX_THREAD_SAFE_FUNCTIONS
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
+
+#undef _POSIX_THREAD_ATTR_STACKSIZE
+#define _POSIX_THREAD_ATTR_STACKSIZE 200809L
+
+/*
+ * The following options are not supported
+ */
+#undef _POSIX_THREAD_ATTR_STACKADDR
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+
+#undef _POSIX_THREAD_PRIO_INHERIT
+#define _POSIX_THREAD_PRIO_INHERIT -1
+
+#undef _POSIX_THREAD_PRIO_PROTECT
+#define _POSIX_THREAD_PRIO_PROTECT -1
+
+/* TPS is not fully supported. */
+#undef _POSIX_THREAD_PRIORITY_SCHEDULING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+
+#undef _POSIX_THREAD_PROCESS_SHARED
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+
+/*
+ * POSIX 1003.1-2001 Limits
+ * ===========================
+ *
+ * These limits are normally set in <limits.h>, which is not provided with
+ * pthreads-win32.
+ *
+ * PTHREAD_DESTRUCTOR_ITERATIONS
+ * Maximum number of attempts to destroy
+ * a thread's thread-specific data on
+ * termination (must be at least 4)
+ *
+ * PTHREAD_KEYS_MAX
+ * Maximum number of thread-specific data keys
+ * available per process (must be at least 128)
+ *
+ * PTHREAD_STACK_MIN
+ * Minimum supported stack size for a thread
+ *
+ * PTHREAD_THREADS_MAX
+ * Maximum number of threads supported per
+ * process (must be at least 64).
+ *
+ * SEM_NSEMS_MAX
+ * The maximum number of semaphores a process can have.
+ * (must be at least 256)
+ *
+ * SEM_VALUE_MAX
+ * The maximum value a semaphore can have.
+ * (must be at least 32767)
+ *
+ */
+#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+
+#undef PTHREAD_DESTRUCTOR_ITERATIONS
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+#undef _POSIX_THREAD_KEYS_MAX
+#define _POSIX_THREAD_KEYS_MAX 128
+
+#undef PTHREAD_KEYS_MAX
+#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
+
+#undef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 0
+
+#undef _POSIX_THREAD_THREADS_MAX
+#define _POSIX_THREAD_THREADS_MAX 64
+
+ /* Arbitrary value */
+#undef PTHREAD_THREADS_MAX
+#define PTHREAD_THREADS_MAX 2019
+
+#undef _POSIX_SEM_NSEMS_MAX
+#define _POSIX_SEM_NSEMS_MAX 256
+
+ /* Arbitrary value */
+#undef SEM_NSEMS_MAX
+#define SEM_NSEMS_MAX 1024
+
+#undef _POSIX_SEM_VALUE_MAX
+#define _POSIX_SEM_VALUE_MAX 32767
+
+#undef SEM_VALUE_MAX
+#define SEM_VALUE_MAX INT_MAX
+
+
+#if defined(__GNUC__) && !defined(__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the library, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the library,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#if !defined(PTW32_STATIC_LIB)
+# if defined(PTW32_BUILD)
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * The Open Watcom C/C++ compiler uses a non-standard calling convention
+ * that passes function args in registers unless __cdecl is explicitly specified
+ * in exposed function prototypes.
+ *
+ * We force all calls to cdecl even though this could slow Watcom code down
+ * slightly. If you know that the Watcom compiler will be used to build both
+ * the DLL and application, then you can probably define this as a null string.
+ * Remember that pthread.h (this file) is used for both the DLL and application builds.
+ */
+#define PTW32_CDECL __cdecl
+
+#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
+# include <sys/types.h>
+#else
+/*
+ * Generic handle type - intended to extend uniqueness beyond
+ * that available with a simple pointer. It should scale for either
+ * IA-32 or IA-64.
+ */
+typedef struct {
+ void * p; /* Pointer to actual object */
+ unsigned int x; /* Extra information - reuse count etc */
+} ptw32_handle_t;
+
+typedef ptw32_handle_t pthread_t;
+typedef struct pthread_attr_t_ * pthread_attr_t;
+typedef struct pthread_once_t_ pthread_once_t;
+typedef struct pthread_key_t_ * pthread_key_t;
+typedef struct pthread_mutex_t_ * pthread_mutex_t;
+typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
+typedef struct pthread_cond_t_ * pthread_cond_t;
+typedef struct pthread_condattr_t_ * pthread_condattr_t;
+#endif
+typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
+typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
+typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
+typedef struct pthread_barrier_t_ * pthread_barrier_t;
+typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
+
+/*
+ * ====================
+ * ====================
+ * POSIX Threads
+ * ====================
+ * ====================
+ */
+
+enum {
+/*
+ * pthread_attr_{get,set}detachstate
+ */
+ PTHREAD_CREATE_JOINABLE = 0, /* Default */
+ PTHREAD_CREATE_DETACHED = 1,
+
+/*
+ * pthread_attr_{get,set}inheritsched
+ */
+ PTHREAD_INHERIT_SCHED = 0,
+ PTHREAD_EXPLICIT_SCHED = 1, /* Default */
+
+/*
+ * pthread_{get,set}scope
+ */
+ PTHREAD_SCOPE_PROCESS = 0,
+ PTHREAD_SCOPE_SYSTEM = 1, /* Default */
+
+/*
+ * pthread_setcancelstate paramters
+ */
+ PTHREAD_CANCEL_ENABLE = 0, /* Default */
+ PTHREAD_CANCEL_DISABLE = 1,
+
+/*
+ * pthread_setcanceltype parameters
+ */
+ PTHREAD_CANCEL_ASYNCHRONOUS = 0,
+ PTHREAD_CANCEL_DEFERRED = 1, /* Default */
+
+/*
+ * pthread_mutexattr_{get,set}pshared
+ * pthread_condattr_{get,set}pshared
+ */
+ PTHREAD_PROCESS_PRIVATE = 0,
+ PTHREAD_PROCESS_SHARED = 1,
+
+/*
+ * pthread_mutexattr_{get,set}robust
+ */
+ PTHREAD_MUTEX_STALLED = 0, /* Default */
+ PTHREAD_MUTEX_ROBUST = 1,
+
+/*
+ * pthread_barrier_wait
+ */
+ PTHREAD_BARRIER_SERIAL_THREAD = -1
+};
+
+/*
+ * ====================
+ * ====================
+ * Cancelation
+ * ====================
+ * ====================
+ */
+#define PTHREAD_CANCELED ((void *)(size_t) -1)
+
+
+/*
+ * ====================
+ * ====================
+ * Once Key
+ * ====================
+ * ====================
+ */
+#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}
+
+struct pthread_once_t_
+{
+ int done; /* indicates if user function has been executed */
+ void * lock;
+ int reserved1;
+ int reserved2;
+};
+
+
+/*
+ * ====================
+ * ====================
+ * Object initialisers
+ * ====================
+ * ====================
+ */
+#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1)
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2)
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3)
+
+/*
+ * Compatibility with LinuxThreads
+ */
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+
+#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1)
+
+#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1)
+
+#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1)
+
+
+/*
+ * Mutex types.
+ */
+enum
+{
+ /* Compatibility with LinuxThreads */
+ PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
+ /* For compatibility with POSIX */
+ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+};
+
+
+typedef struct ptw32_cleanup_t ptw32_cleanup_t;
+
+#if defined(_MSC_VER)
+/* Disable MSVC 'anachronism used' warning */
+#pragma warning( disable : 4229 )
+#endif
+
+typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);
+
+#if defined(_MSC_VER)
+#pragma warning( default : 4229 )
+#endif
+
+struct ptw32_cleanup_t
+{
+ ptw32_cleanup_callback_t routine;
+ void *arg;
+ struct ptw32_cleanup_t *prev;
+};
+
+#if defined(__CLEANUP_SEH)
+ /*
+ * WIN32 SEH version of cancel cleanup.
+ */
+
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ ptw32_cleanup_t _cleanup; \
+ \
+ _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
+ _cleanup.arg = (_arg); \
+ __try \
+ { \
+
+#define pthread_cleanup_pop( _execute ) \
+ } \
+ __finally \
+ { \
+ if( _execute || AbnormalTermination()) \
+ { \
+ (*(_cleanup.routine))( _cleanup.arg ); \
+ } \
+ } \
+ }
+
+#else /* __CLEANUP_SEH */
+
+#if defined(__CLEANUP_C)
+
+ /*
+ * C implementation of PThreads cancel cleanup
+ */
+
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ ptw32_cleanup_t _cleanup; \
+ \
+ ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
+
+#define pthread_cleanup_pop( _execute ) \
+ (void) ptw32_pop_cleanup( _execute ); \
+ }
+
+#else /* __CLEANUP_C */
+
+#if defined(__CLEANUP_CXX)
+
+ /*
+ * C++ version of cancel cleanup.
+ * - John E. Bossom.
+ */
+
+ class PThreadCleanup {
+ /*
+ * PThreadCleanup
+ *
+ * Purpose
+ * This class is a C++ helper class that is
+ * used to implement pthread_cleanup_push/
+ * pthread_cleanup_pop.
+ * The destructor of this class automatically
+ * pops the pushed cleanup routine regardless
+ * of how the code exits the scope
+ * (i.e. such as by an exception)
+ */
+ ptw32_cleanup_callback_t cleanUpRout;
+ void * obj;
+ int executeIt;
+
+ public:
+ PThreadCleanup() :
+ cleanUpRout( 0 ),
+ obj( 0 ),
+ executeIt( 0 )
+ /*
+ * No cleanup performed
+ */
+ {
+ }
+
+ PThreadCleanup(
+ ptw32_cleanup_callback_t routine,
+ void * arg ) :
+ cleanUpRout( routine ),
+ obj( arg ),
+ executeIt( 1 )
+ /*
+ * Registers a cleanup routine for 'arg'
+ */
+ {
+ }
+
+ ~PThreadCleanup()
+ {
+ if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
+ {
+ (void) (*cleanUpRout)( obj );
+ }
+ }
+
+ void execute( int exec )
+ {
+ executeIt = exec;
+ }
+ };
+
+ /*
+ * C++ implementation of PThreads cancel cleanup;
+ * This implementation takes advantage of a helper
+ * class who's destructor automatically calls the
+ * cleanup routine if we exit our scope weirdly
+ */
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
+ (void *) (_arg) );
+
+#define pthread_cleanup_pop( _execute ) \
+ cleanup.execute( _execute ); \
+ }
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* __CLEANUP_C */
+
+#endif /* __CLEANUP_SEH */
+
+/*
+ * ===============
+ * ===============
+ * Methods
+ * ===============
+ * ===============
+ */
+
+/*
+ * PThread Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,
+ int *detachstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,
+ void **stackaddr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,
+ size_t * stacksize);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,
+ int detachstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,
+ void *stackaddr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,
+ size_t stacksize);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,
+ struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,
+ const struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,
+ int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *,
+ int *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
+ int inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr,
+ int * inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
+ int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
+ int *);
+
+/*
+ * PThread Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
+ const pthread_attr_t * attr,
+ void *(PTW32_CDECL *start) (void *),
+ void *arg);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
+ pthread_t t2);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
+ void **value_ptr);
+
+PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
+ int *oldstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
+ int *oldtype);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
+ void (PTW32_CDECL *init_routine) (void));
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
+
+PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
+ ptw32_cleanup_callback_t routine,
+ void *arg);
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread Specific Data Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
+ void (PTW32_CDECL *destructor) (void *));
+
+PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
+ const void *value);
+
+PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
+
+
+/*
+ * Mutex Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
+ int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust(
+ pthread_mutexattr_t *attr,
+ int robust);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust(
+ const pthread_mutexattr_t * attr,
+ int * robust);
+
+/*
+ * Barrier Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
+ int pshared);
+
+/*
+ * Mutex Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex);
+
+/*
+ * Spinlock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
+
+/*
+ * Barrier Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
+ const pthread_barrierattr_t * attr,
+ unsigned int count);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
+
+/*
+ * Condition Variable Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
+ int pshared);
+
+/*
+ * Condition Variable Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
+ const pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
+
+/*
+ * Scheduling
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
+ int policy,
+ const struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
+ int *policy,
+ struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
+
+/*
+ * Read-Write Lock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
+ const pthread_rwlockattr_t *attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
+ int pshared);
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
+
+/*
+ * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
+ * already have signal.h that don't define these.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
+
+/*
+ * Non-portable functions
+ */
+
+/*
+ * Compatibility with Linux.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
+ int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
+ int *kind);
+
+/*
+ * Possibly supported by other POSIX threads implementations
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
+PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
+PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread);
+
+/*
+ * Useful if an application wants to statically link
+ * the lib rather than load the DLL at run-time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
+
+/*
+ * Features that are auto-detected at load/run time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
+enum ptw32_features {
+ PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
+ PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */
+};
+
+/*
+ * Register a system time change with the library.
+ * Causes the library to perform various functions
+ * in response to the change. Should be called whenever
+ * the application's top level window receives a
+ * WM_TIMECHANGE message. It can be passed directly to
+ * pthread_create() as a new thread if desired.
+ */
+PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
+
+#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/*
+ * Returns the Win32 HANDLE for the POSIX thread.
+ */
+PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
+/*
+ * Returns the win32 thread ID for POSIX thread.
+ */
+PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread);
+
+
+/*
+ * Protected Methods
+ *
+ * This function blocks until the given WIN32 handle
+ * is signaled or pthread_cancel had been called.
+ * This function allows the caller to hook into the
+ * PThreads cancel mechanism. It is implemented using
+ *
+ * WaitForMultipleObjects
+ *
+ * on 'waitHandle' and a manually reset WIN32 Event
+ * used to implement pthread_cancel. The 'timeout'
+ * argument to TimedWait is simply passed to
+ * WaitForMultipleObjects.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
+ DWORD timeout);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread-Safe C Runtime Library Mappings.
+ */
+#if !defined(_UWIN)
+# if defined(NEED_ERRNO)
+ PTW32_DLLPORT int * PTW32_CDECL _errno( void );
+# else
+# if !defined(errno)
+# if (defined(_MT) || defined(_DLL))
+ __declspec(dllimport) extern int * __cdecl _errno(void);
+# define errno (*_errno())
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * Some compiler environments don't define some things.
+ */
+#if defined(__BORLANDC__)
+# define _ftime ftime
+# define _timeb timeb
+#endif
+
+#if defined(__cplusplus)
+
+/*
+ * Internal exceptions
+ */
+class ptw32_exception {};
+class ptw32_exception_cancel : public ptw32_exception {};
+class ptw32_exception_exit : public ptw32_exception {};
+
+#endif
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/* FIXME: This is only required if the library was built using SEH */
+/*
+ * Get internal SEH tag
+ */
+PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#if !defined(PTW32_BUILD)
+
+#if defined(__CLEANUP_SEH)
+
+/*
+ * Redefine the SEH __except keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#define __except( E ) \
+ __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
+ ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
+
+#endif /* __CLEANUP_SEH */
+
+#if defined(__CLEANUP_CXX)
+
+/*
+ * Redefine the C++ catch keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#if defined(_MSC_VER)
+ /*
+ * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
+ * if you want Pthread-Win32 cancelation and pthread_exit to work.
+ */
+
+#if !defined(PtW32NoCatchWarn)
+
+#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
+#pragma message("------------------------------------------------------------------")
+#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
+#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
+#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
+#pragma message(" cancelation and pthread_exit to work. For example:")
+#pragma message("")
+#pragma message(" #if defined(PtW32CatchAll)")
+#pragma message(" PtW32CatchAll")
+#pragma message(" #else")
+#pragma message(" catch(...)")
+#pragma message(" #endif")
+#pragma message(" {")
+#pragma message(" /* Catchall block processing */")
+#pragma message(" }")
+#pragma message("------------------------------------------------------------------")
+
+#endif
+
+#define PtW32CatchAll \
+ catch( ptw32_exception & ) { throw; } \
+ catch( ... )
+
+#else /* _MSC_VER */
+
+#define catch( E ) \
+ catch( ptw32_exception & ) { throw; } \
+ catch( E )
+
+#endif /* _MSC_VER */
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* ! PTW32_BUILD */
+
+#if defined(__cplusplus)
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#if defined(PTW32__HANDLE_DEF)
+# undef HANDLE
+#endif
+#if defined(PTW32__DWORD_DEF)
+# undef DWORD
+#endif
+
+#undef PTW32_LEVEL
+#undef PTW32_LEVEL_MAX
+
+#endif /* ! RC_INVOKED */
+
+#endif /* PTHREAD_H */
diff --git a/libs/pthreads/src/pthread_attr_destroy.c b/libs/pthreads/src/pthread_attr_destroy.c
new file mode 100644
index 0000000000..8b3e04c536
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_destroy.c
@@ -0,0 +1,79 @@
+/*
+ * pthread_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_destroy (pthread_attr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a thread attributes object.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a thread attributes object.
+ *
+ * NOTES:
+ * 1) Does not affect threads created with 'attr'.
+ *
+ * RESULTS
+ * 0 successfully destroyed attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Set the attribute object to a specific invalid value.
+ */
+ (*attr)->valid = 0;
+ free (*attr);
+ *attr = NULL;
+
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_getdetachstate.c b/libs/pthreads/src/pthread_attr_getdetachstate.c
new file mode 100644
index 0000000000..188533b13c
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getdetachstate.c
@@ -0,0 +1,86 @@
+/*
+ * pthread_attr_getdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines whether threads created with
+ * 'attr' will run detached.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * detachstate
+ * pointer to an integer into which is returned one
+ * of:
+ *
+ * PTHREAD_CREATE_JOINABLE
+ * Thread ID is valid, must be joined
+ *
+ * PTHREAD_CREATE_DETACHED
+ * Thread ID is invalid, cannot be joined,
+ * canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ * This function determines whether threads created with
+ * 'attr' will run detached.
+ *
+ * NOTES:
+ * 1) You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ * 0 successfully retrieved detach state,
+ * EINVAL 'attr' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0 || detachstate == NULL)
+ {
+ return EINVAL;
+ }
+
+ *detachstate = (*attr)->detachstate;
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_getinheritsched.c b/libs/pthreads/src/pthread_attr_getinheritsched.c
new file mode 100644
index 0000000000..9c6885ed92
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * pthread_attr_getinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getinheritsched (const pthread_attr_t * attr, int *inheritsched)
+{
+ if (ptw32_is_attr (attr) != 0 || inheritsched == NULL)
+ {
+ return EINVAL;
+ }
+
+ *inheritsched = (*attr)->inheritsched;
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_getschedparam.c b/libs/pthreads/src/pthread_attr_getschedparam.c
new file mode 100644
index 0000000000..ab89b2241a
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getschedparam.c
@@ -0,0 +1,52 @@
+/*
+ * pthread_attr_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getschedparam (const pthread_attr_t * attr,
+ struct sched_param *param)
+{
+ if (ptw32_is_attr (attr) != 0 || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ memcpy (param, &(*attr)->param, sizeof (*param));
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_getschedpolicy.c b/libs/pthreads/src/pthread_attr_getschedpolicy.c
new file mode 100644
index 0000000000..94a257d609
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getschedpolicy.c
@@ -0,0 +1,61 @@
+/*
+ * pthread_attr_getschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getschedpolicy (const pthread_attr_t * attr, int *policy)
+{
+ if (ptw32_is_attr (attr) != 0 || policy == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Validate the policy arg.
+ * Check that a policy constant wasn't passed rather than &policy.
+ */
+ if (policy <= (int *) SCHED_MAX)
+ {
+ return EINVAL;
+ }
+
+ *policy = SCHED_OTHER;
+
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_getscope.c b/libs/pthreads/src/pthread_attr_getscope.c
new file mode 100644
index 0000000000..2efdb2fe6d
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getscope.c
@@ -0,0 +1,54 @@
+/*
+ * pthread_attr_getscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope)
+{
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+ *contentionscope = (*attr)->contentionscope;
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libs/pthreads/src/pthread_attr_getstackaddr.c b/libs/pthreads/src/pthread_attr_getstackaddr.c
new file mode 100644
index 0000000000..1a2da01c78
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getstackaddr.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_attr_getstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines the address of the stack
+ * on which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stackaddr
+ * pointer into which is returned the stack address.
+ *
+ *
+ * DESCRIPTION
+ * This function determines the address of the stack
+ * on which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR
+ *
+ * 2) Create only one thread for each stack
+ * address..
+ *
+ * RESULTS
+ * 0 successfully retreived stack address,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ *stackaddr = (*attr)->stackaddr;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}
diff --git a/libs/pthreads/src/pthread_attr_getstacksize.c b/libs/pthreads/src/pthread_attr_getstacksize.c
new file mode 100644
index 0000000000..dff9230f28
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_getstacksize.c
@@ -0,0 +1,100 @@
+/*
+ * pthread_attr_getstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stacksize
+ * pointer to size_t into which is returned the
+ * stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ * This function determines the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ * 2) Use on newly created attributes object to
+ * find the default stack size.
+ *
+ * RESULTS
+ * 0 successfully retrieved stack size,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /* Everything is okay. */
+ *stacksize = (*attr)->stacksize;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}
diff --git a/libs/pthreads/src/pthread_attr_init.c b/libs/pthreads/src/pthread_attr_init.c
new file mode 100644
index 0000000000..ae9d3eb5f4
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_init.c
@@ -0,0 +1,117 @@
+/*
+ * pthread_attr_init.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_init (pthread_attr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a thread attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a thread attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define thread attributes
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_attr_t attr_result;
+
+ if (attr == NULL)
+ {
+ /* This is disallowed. */
+ return EINVAL;
+ }
+
+ attr_result = (pthread_attr_t) malloc (sizeof (*attr_result));
+
+ if (attr_result == NULL)
+ {
+ return ENOMEM;
+ }
+
+#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
+ /*
+ * Default to zero size. Unless changed explicitly this
+ * will allow Win32 to set the size to that of the
+ * main thread.
+ */
+ attr_result->stacksize = 0;
+#endif
+
+#if defined(_POSIX_THREAD_ATTR_STACKADDR)
+ /* FIXME: Set this to something sensible when we support it. */
+ attr_result->stackaddr = NULL;
+#endif
+
+ attr_result->detachstate = PTHREAD_CREATE_JOINABLE;
+
+#if defined(HAVE_SIGSET_T)
+ memset (&(attr_result->sigmask), 0, sizeof (sigset_t));
+#endif /* HAVE_SIGSET_T */
+
+ /*
+ * Win32 sets new threads to THREAD_PRIORITY_NORMAL and
+ * not to that of the parent thread. We choose to default to
+ * this arrangement.
+ */
+ attr_result->param.sched_priority = THREAD_PRIORITY_NORMAL;
+ attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED;
+ attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM;
+
+ attr_result->valid = PTW32_ATTR_VALID;
+
+ *attr = attr_result;
+
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_setdetachstate.c b/libs/pthreads/src/pthread_attr_setdetachstate.c
new file mode 100644
index 0000000000..784642a807
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setdetachstate.c
@@ -0,0 +1,91 @@
+/*
+ * pthread_attr_setdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function specifies whether threads created with
+ * 'attr' will run detached.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * detachstate
+ * an integer containing one of:
+ *
+ * PTHREAD_CREATE_JOINABLE
+ * Thread ID is valid, must be joined
+ *
+ * PTHREAD_CREATE_DETACHED
+ * Thread ID is invalid, cannot be joined,
+ * canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ * This function specifies whether threads created with
+ * 'attr' will run detached.
+ *
+ * NOTES:
+ * 1) You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ * 0 successfully set detach state,
+ * EINVAL 'attr' or 'detachstate' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (detachstate != PTHREAD_CREATE_JOINABLE &&
+ detachstate != PTHREAD_CREATE_DETACHED)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->detachstate = detachstate;
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_setinheritsched.c b/libs/pthreads/src/pthread_attr_setinheritsched.c
new file mode 100644
index 0000000000..e0a407a3b7
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setinheritsched.c
@@ -0,0 +1,57 @@
+/*
+ * pthread_attr_setinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched)
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (PTHREAD_INHERIT_SCHED != inheritsched
+ && PTHREAD_EXPLICIT_SCHED != inheritsched)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->inheritsched = inheritsched;
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_setschedparam.c b/libs/pthreads/src/pthread_attr_setschedparam.c
new file mode 100644
index 0000000000..f246bfae7a
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setschedparam.c
@@ -0,0 +1,63 @@
+/*
+ * pthread_attr_setschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setschedparam (pthread_attr_t * attr,
+ const struct sched_param *param)
+{
+ int priority;
+
+ if (ptw32_is_attr (attr) != 0 || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ priority = param->sched_priority;
+
+ /* Validate priority level. */
+ if (priority < sched_get_priority_min (SCHED_OTHER) ||
+ priority > sched_get_priority_max (SCHED_OTHER))
+ {
+ return EINVAL;
+ }
+
+ memcpy (&(*attr)->param, param, sizeof (*param));
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_setschedpolicy.c b/libs/pthreads/src/pthread_attr_setschedpolicy.c
new file mode 100644
index 0000000000..45ff165973
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setschedpolicy.c
@@ -0,0 +1,55 @@
+/*
+ * pthread_attr_setschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy)
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (policy != SCHED_OTHER)
+ {
+ return ENOTSUP;
+ }
+
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_attr_setscope.c b/libs/pthreads/src/pthread_attr_setscope.c
new file mode 100644
index 0000000000..39a51df887
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setscope.c
@@ -0,0 +1,62 @@
+/*
+ * pthread_attr_setscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_setscope (pthread_attr_t * attr, int contentionscope)
+{
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+ switch (contentionscope)
+ {
+ case PTHREAD_SCOPE_SYSTEM:
+ (*attr)->contentionscope = contentionscope;
+ return 0;
+ case PTHREAD_SCOPE_PROCESS:
+ return ENOTSUP;
+ default:
+ return EINVAL;
+ }
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libs/pthreads/src/pthread_attr_setstackaddr.c b/libs/pthreads/src/pthread_attr_setstackaddr.c
new file mode 100644
index 0000000000..1316c06592
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setstackaddr.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_attr_setstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Threads created with 'attr' will run on the stack
+ * starting at 'stackaddr'.
+ * Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stackaddr
+ * the address of the stack to use
+ *
+ *
+ * DESCRIPTION
+ * Threads created with 'attr' will run on the stack
+ * starting at 'stackaddr'.
+ * Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR
+ *
+ * 2) Create only one thread for each stack
+ * address..
+ *
+ * 3) Ensure that stackaddr is aligned.
+ *
+ * RESULTS
+ * 0 successfully set stack address,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->stackaddr = stackaddr;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}
diff --git a/libs/pthreads/src/pthread_attr_setstacksize.c b/libs/pthreads/src/pthread_attr_setstacksize.c
new file mode 100644
index 0000000000..eb13589a00
--- /dev/null
+++ b/libs/pthreads/src/pthread_attr_setstacksize.c
@@ -0,0 +1,110 @@
+/*
+ * pthread_attr_setstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function specifies the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stacksize
+ * stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ * This function specifies the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ * 2) Find the default first (using
+ * pthread_attr_getstacksize), then increase
+ * by multiplying.
+ *
+ * 3) Only use if thread needs more than the
+ * default.
+ *
+ * RESULTS
+ * 0 successfully set stack size,
+ * EINVAL 'attr' is invalid or stacksize too
+ * small or too big.
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined(_POSIX_THREAD_ATTR_STACKSIZE)
+
+#if PTHREAD_STACK_MIN > 0
+
+ /* Verify that the stack size is within range. */
+ if (stacksize < PTHREAD_STACK_MIN)
+ {
+ return EINVAL;
+ }
+
+#endif
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /* Everything is okay. */
+ (*attr)->stacksize = stacksize;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}
diff --git a/libs/pthreads/src/pthread_barrier_destroy.c b/libs/pthreads/src/pthread_barrier_destroy.c
new file mode 100644
index 0000000000..55163cc858
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrier_destroy.c
@@ -0,0 +1,103 @@
+/*
+ * pthread_barrier_destroy.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_barrier_destroy (pthread_barrier_t * barrier)
+{
+ int result = 0;
+ pthread_barrier_t b;
+ ptw32_mcs_local_node_t node;
+
+ if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
+ {
+ return EINVAL;
+ }
+
+ if (0 != ptw32_mcs_lock_try_acquire(&(*barrier)->lock, &node))
+ {
+ return EBUSY;
+ }
+
+ b = *barrier;
+
+ if (b->nCurrentBarrierHeight < b->nInitialBarrierHeight)
+ {
+ result = EBUSY;
+ }
+ else
+ {
+ if (0 == (result = sem_destroy (&(b->semBarrierBreeched))))
+ {
+ *barrier = (pthread_barrier_t) PTW32_OBJECT_INVALID;
+ /*
+ * Release the lock before freeing b.
+ *
+ * FIXME: There may be successors which, when we release the lock,
+ * will be linked into b->lock, which will be corrupted at some
+ * point with undefined results for the application. To fix this
+ * will require changing pthread_barrier_t from a pointer to
+ * pthread_barrier_t_ to an instance. This is a change to the ABI
+ * and will require a major version number increment.
+ */
+ ptw32_mcs_lock_release(&node);
+ (void) free (b);
+ return 0;
+ }
+ else
+ {
+ /*
+ * This should not ever be reached.
+ * Restore the barrier to working condition before returning.
+ */
+ (void) sem_init (&(b->semBarrierBreeched), b->pshared, 0);
+ }
+
+ if (result != 0)
+ {
+ /*
+ * The barrier still exists and is valid
+ * in the event of any error above.
+ */
+ result = EBUSY;
+ }
+ }
+
+ ptw32_mcs_lock_release(&node);
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_barrier_init.c b/libs/pthreads/src/pthread_barrier_init.c
new file mode 100644
index 0000000000..618bfae264
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrier_init.c
@@ -0,0 +1,69 @@
+/*
+ * pthread_barrier_init.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrier_init (pthread_barrier_t * barrier,
+ const pthread_barrierattr_t * attr, unsigned int count)
+{
+ pthread_barrier_t b;
+
+ if (barrier == NULL || count == 0)
+ {
+ return EINVAL;
+ }
+
+ if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b))))
+ {
+ b->pshared = (attr != NULL && *attr != NULL
+ ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE);
+
+ b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count;
+ b->lock = 0;
+
+ if (0 == sem_init (&(b->semBarrierBreeched), b->pshared, 0))
+ {
+ *barrier = b;
+ return 0;
+ }
+ (void) free (b);
+ }
+
+ return ENOMEM;
+}
diff --git a/libs/pthreads/src/pthread_barrier_wait.c b/libs/pthreads/src/pthread_barrier_wait.c
new file mode 100644
index 0000000000..e0e97e6c78
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrier_wait.c
@@ -0,0 +1,104 @@
+/*
+ * pthread_barrier_wait.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrier_wait (pthread_barrier_t * barrier)
+{
+ int result;
+ pthread_barrier_t b;
+
+ ptw32_mcs_local_node_t node;
+
+ if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
+ {
+ return EINVAL;
+ }
+
+ ptw32_mcs_lock_acquire(&(*barrier)->lock, &node);
+
+ b = *barrier;
+ if (--b->nCurrentBarrierHeight == 0)
+ {
+ /*
+ * We are the last thread to arrive at the barrier before it releases us.
+ * Move our MCS local node to the global scope barrier handle so that the
+ * last thread out (not necessarily us) can release the lock.
+ */
+ ptw32_mcs_node_transfer(&b->proxynode, &node);
+
+ /*
+ * Any threads that have not quite entered sem_wait below when the
+ * multiple_post has completed will nevertheless continue through
+ * the semaphore (barrier).
+ */
+ result = (b->nInitialBarrierHeight > 1
+ ? sem_post_multiple (&(b->semBarrierBreeched),
+ b->nInitialBarrierHeight - 1) : 0);
+ }
+ else
+ {
+ ptw32_mcs_lock_release(&node);
+ /*
+ * Use the non-cancelable version of sem_wait().
+ *
+ * It is possible that all nInitialBarrierHeight-1 threads are
+ * at this point when the last thread enters the barrier, resets
+ * nCurrentBarrierHeight = nInitialBarrierHeight and leaves.
+ * If pthread_barrier_destroy is called at that moment then the
+ * barrier will be destroyed along with the semas.
+ */
+ result = ptw32_semwait (&(b->semBarrierBreeched));
+ }
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_INCREMENT_LONG((PTW32_INTERLOCKED_LONGPTR)&b->nCurrentBarrierHeight)
+ == (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight)
+ {
+ /*
+ * We are the last thread to cross this barrier
+ */
+ ptw32_mcs_lock_release(&b->proxynode);
+ if (0 == result)
+ {
+ result = PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_barrierattr_destroy.c b/libs/pthreads/src/pthread_barrierattr_destroy.c
new file mode 100644
index 0000000000..5ab662e3f4
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrierattr_destroy.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_barrier_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_destroy (pthread_barrierattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a barrier attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a barrier attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect barrieres created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_barrierattr_t ba = *attr;
+
+ *attr = NULL;
+ free (ba);
+ }
+
+ return (result);
+} /* pthread_barrierattr_destroy */
diff --git a/libs/pthreads/src/pthread_barrierattr_getpshared.c b/libs/pthreads/src/pthread_barrierattr_getpshared.c
new file mode 100644
index 0000000000..44c467e2bf
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrierattr_getpshared.c
@@ -0,0 +1,95 @@
+/*
+ * pthread_barrier_attr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr,
+ int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether barriers created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared barriers MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared barriers
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+} /* pthread_barrierattr_getpshared */
diff --git a/libs/pthreads/src/pthread_barrierattr_init.c b/libs/pthreads/src/pthread_barrierattr_init.c
new file mode 100644
index 0000000000..342f8b0c69
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrierattr_init.c
@@ -0,0 +1,85 @@
+/*
+ * pthread_barrier_attr_init.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_init (pthread_barrierattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a barrier attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a barrier attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define barrier types
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_barrierattr_t ba;
+ int result = 0;
+
+ ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba));
+
+ if (ba == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ ba->pshared = PTHREAD_PROCESS_PRIVATE;
+ }
+
+ *attr = ba;
+
+ return (result);
+} /* pthread_barrierattr_init */
diff --git a/libs/pthreads/src/pthread_barrierattr_setpshared.c b/libs/pthreads/src/pthread_barrierattr_setpshared.c
new file mode 100644
index 0000000000..08c6fde30b
--- /dev/null
+++ b/libs/pthreads/src/pthread_barrierattr_setpshared.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_barrier_attr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Barriers created with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared barriers MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared barriers
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_barrierattr_setpshared */
diff --git a/libs/pthreads/src/pthread_cancel.c b/libs/pthreads/src/pthread_cancel.c
new file mode 100644
index 0000000000..ae60b72936
--- /dev/null
+++ b/libs/pthreads/src/pthread_cancel.c
@@ -0,0 +1,189 @@
+/*
+ * pthread_cancel.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "context.h"
+
+static void
+ptw32_cancel_self (void)
+{
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+}
+
+static void CALLBACK
+ptw32_cancel_callback (ULONG_PTR unused)
+{
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+}
+
+/*
+ * ptw32_RegisterCancelation() -
+ * Must have args of same type as QueueUserAPCEx because this function
+ * is a substitute for QueueUserAPCEx if it's not available.
+ */
+DWORD
+ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2)
+{
+ CONTEXT context;
+
+ context.ContextFlags = CONTEXT_CONTROL;
+ GetThreadContext (threadH, &context);
+ PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self;
+ SetThreadContext (threadH, &context);
+ return 0;
+}
+
+int
+pthread_cancel (pthread_t thread)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function requests cancellation of 'thread'.
+ *
+ * PARAMETERS
+ * thread
+ * reference to an instance of pthread_t
+ *
+ *
+ * DESCRIPTION
+ * This function requests cancellation of 'thread'.
+ * NOTE: cancellation is asynchronous; use pthread_join to
+ * wait for termination of 'thread' if necessary.
+ *
+ * RESULTS
+ * 0 successfully requested cancellation,
+ * ESRCH no thread found corresponding to 'thread',
+ * ENOMEM implicit self thread create failed.
+ * ------------------------------------------------------
+ */
+{
+ int result;
+ int cancel_self;
+ pthread_t self;
+ ptw32_thread_t * tp;
+ ptw32_mcs_local_node_t stateLock;
+
+ result = pthread_kill (thread, 0);
+
+ if (0 != result)
+ {
+ return result;
+ }
+
+ if ((self = pthread_self ()).p == NULL)
+ {
+ return ENOMEM;
+ };
+
+ /*
+ * For self cancellation we need to ensure that a thread can't
+ * deadlock itself trying to cancel itself asynchronously
+ * (pthread_cancel is required to be an async-cancel
+ * safe function).
+ */
+ cancel_self = pthread_equal (thread, self);
+
+ tp = (ptw32_thread_t *) thread.p;
+
+ /*
+ * Lock for async-cancel safety.
+ */
+ ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock);
+
+ if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
+ && tp->cancelState == PTHREAD_CANCEL_ENABLE
+ && tp->state < PThreadStateCanceling)
+ {
+ if (cancel_self)
+ {
+ tp->state = PThreadStateCanceling;
+ tp->cancelState = PTHREAD_CANCEL_DISABLE;
+
+ ptw32_mcs_lock_release (&stateLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+ else
+ {
+ HANDLE threadH = tp->threadH;
+
+ SuspendThread (threadH);
+
+ if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT)
+ {
+ tp->state = PThreadStateCanceling;
+ tp->cancelState = PTHREAD_CANCEL_DISABLE;
+ /*
+ * If alertdrv and QueueUserAPCEx is available then the following
+ * will result in a call to QueueUserAPCEx with the args given, otherwise
+ * this will result in a call to ptw32_RegisterCancelation and only
+ * the threadH arg will be used.
+ */
+ ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0);
+ ptw32_mcs_lock_release (&stateLock);
+ ResumeThread (threadH);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Set for deferred cancellation.
+ */
+ if (tp->state < PThreadStateCancelPending)
+ {
+ tp->state = PThreadStateCancelPending;
+ if (!SetEvent (tp->cancelEvent))
+ {
+ result = ESRCH;
+ }
+ }
+ else if (tp->state >= PThreadStateCanceling)
+ {
+ result = ESRCH;
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_cond_destroy.c b/libs/pthreads/src/pthread_cond_destroy.c
new file mode 100644
index 0000000000..40d4a0896c
--- /dev/null
+++ b/libs/pthreads/src/pthread_cond_destroy.c
@@ -0,0 +1,253 @@
+/*
+ * pthread_cond_destroy.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_cond_destroy (pthread_cond_t * cond)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function destroys a condition variable
+ *
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ * This function destroys a condition variable.
+ *
+ * NOTES:
+ * 1) A condition variable can be destroyed
+ * immediately after all the threads that
+ * are blocked on it are awakened. e.g.
+ *
+ * struct list {
+ * pthread_mutex_t lm;
+ * ...
+ * }
+ *
+ * struct elt {
+ * key k;
+ * int busy;
+ * pthread_cond_t notbusy;
+ * ...
+ * }
+ *
+ *
+ * struct elt *
+ * list_find(struct list *lp, key k)
+ * {
+ * struct elt *ep;
+ *
+ * pthread_mutex_lock(&lp->lm);
+ * while ((ep = find_elt(l,k) != NULL) && ep->busy)
+ * pthread_cond_wait(&ep->notbusy, &lp->lm);
+ * if (ep != NULL)
+ * ep->busy = 1;
+ * pthread_mutex_unlock(&lp->lm);
+ * return(ep);
+ * }
+ *
+ * delete_elt(struct list *lp, struct elt *ep)
+ * {
+ * pthread_mutex_lock(&lp->lm);
+ * assert(ep->busy);
+ * ... remove ep from list ...
+ * ep->busy = 0;
+ * (A) pthread_cond_broadcast(&ep->notbusy);
+ * pthread_mutex_unlock(&lp->lm);
+ * (B) pthread_cond_destroy(&rp->notbusy);
+ * free(ep);
+ * }
+ *
+ * In this example, the condition variable
+ * and its list element may be freed (line B)
+ * immediately after all threads waiting for
+ * it are awakened (line A), since the mutex
+ * and the code ensure that no other thread
+ * can touch the element to be deleted.
+ *
+ * RESULTS
+ * 0 successfully released condition variable,
+ * EINVAL 'cond' is invalid,
+ * EBUSY 'cond' is in use,
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_cond_t cv;
+ int result = 0, result1 = 0, result2 = 0;
+
+ /*
+ * Assuming any race condition here is harmless.
+ */
+ if (cond == NULL || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*cond != PTHREAD_COND_INITIALIZER)
+ {
+ ptw32_mcs_local_node_t node;
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
+
+ cv = *cond;
+
+ /*
+ * Close the gate; this will synchronize this thread with
+ * all already signaled waiters to let them retract their
+ * waiter status - SEE NOTE 1 ABOVE!!!
+ */
+ if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */
+ {
+ result = errno;
+ }
+ else
+ {
+ /*
+ * !TRY! lock mtxUnblockLock; try will detect busy condition
+ * and will not cause a deadlock with respect to concurrent
+ * signal/broadcast.
+ */
+ if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0)
+ {
+ (void) sem_post (&(cv->semBlockLock));
+ }
+ }
+
+ if (result != 0)
+ {
+ ptw32_mcs_lock_release(&node);
+ return result;
+ }
+
+ /*
+ * Check whether cv is still busy (still has waiters)
+ */
+ if (cv->nWaitersBlocked > cv->nWaitersGone)
+ {
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ result = errno;
+ }
+ result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ result2 = EBUSY;
+ }
+ else
+ {
+ /*
+ * Now it is safe to destroy
+ */
+ *cond = NULL;
+
+ if (sem_destroy (&(cv->semBlockLock)) != 0)
+ {
+ result = errno;
+ }
+ if (sem_destroy (&(cv->semBlockQueue)) != 0)
+ {
+ result1 = errno;
+ }
+ if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
+ {
+ result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock));
+ }
+
+ /* Unlink the CV from the list */
+
+ if (ptw32_cond_list_head == cv)
+ {
+ ptw32_cond_list_head = cv->next;
+ }
+ else
+ {
+ cv->prev->next = cv->next;
+ }
+
+ if (ptw32_cond_list_tail == cv)
+ {
+ ptw32_cond_list_tail = cv->prev;
+ }
+ else
+ {
+ cv->next->prev = cv->prev;
+ }
+
+ (void) free (cv);
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+ else
+ {
+ ptw32_mcs_local_node_t node;
+ /*
+ * See notes in ptw32_cond_check_need_init() above also.
+ */
+ ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
+
+ /*
+ * Check again.
+ */
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised cond that has not yet been used (initialised).
+ * If we get to here, another thread waiting to initialise
+ * this cond will get an EINVAL. That's OK.
+ */
+ *cond = NULL;
+ }
+ else
+ {
+ /*
+ * The cv has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+
+ return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
+}
diff --git a/libs/pthreads/src/pthread_cond_init.c b/libs/pthreads/src/pthread_cond_init.c
new file mode 100644
index 0000000000..f28fd67b43
--- /dev/null
+++ b/libs/pthreads/src/pthread_cond_init.c
@@ -0,0 +1,167 @@
+/*
+ * pthread_cond_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function initializes a condition variable.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * attr
+ * specifies optional creation attributes.
+ *
+ *
+ * DESCRIPTION
+ * This function initializes a condition variable.
+ *
+ * RESULTS
+ * 0 successfully created condition variable,
+ * EINVAL 'attr' is invalid,
+ * EAGAIN insufficient resources (other than
+ * memory,
+ * ENOMEM insufficient memory,
+ * EBUSY 'cond' is already initialized,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+ pthread_cond_t cv = NULL;
+
+ if (cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
+ {
+ /*
+ * Creating condition variable that can be shared between
+ * processes.
+ */
+ result = ENOSYS;
+ goto DONE;
+ }
+
+ cv = (pthread_cond_t) calloc (1, sizeof (*cv));
+
+ if (cv == NULL)
+ {
+ result = ENOMEM;
+ goto DONE;
+ }
+
+ cv->nWaitersBlocked = 0;
+ cv->nWaitersToUnblock = 0;
+ cv->nWaitersGone = 0;
+
+ if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
+ {
+ result = errno;
+ goto FAIL0;
+ }
+
+ if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
+ {
+ result = errno;
+ goto FAIL1;
+ }
+
+ if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0)
+ {
+ goto FAIL2;
+ }
+
+ result = 0;
+
+ goto DONE;
+
+ /*
+ * -------------
+ * Failed...
+ * -------------
+ */
+FAIL2:
+ (void) sem_destroy (&(cv->semBlockQueue));
+
+FAIL1:
+ (void) sem_destroy (&(cv->semBlockLock));
+
+FAIL0:
+ (void) free (cv);
+ cv = NULL;
+
+DONE:
+ if (0 == result)
+ {
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
+
+ cv->next = NULL;
+ cv->prev = ptw32_cond_list_tail;
+
+ if (ptw32_cond_list_tail != NULL)
+ {
+ ptw32_cond_list_tail->next = cv;
+ }
+
+ ptw32_cond_list_tail = cv;
+
+ if (ptw32_cond_list_head == NULL)
+ {
+ ptw32_cond_list_head = cv;
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+
+ *cond = cv;
+
+ return result;
+
+} /* pthread_cond_init */
diff --git a/libs/pthreads/src/pthread_cond_signal.c b/libs/pthreads/src/pthread_cond_signal.c
new file mode 100644
index 0000000000..2b4f6d4d44
--- /dev/null
+++ b/libs/pthreads/src/pthread_cond_signal.c
@@ -0,0 +1,231 @@
+/*
+ * pthread_cond_signal.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * See the comments at the top of pthread_cond_wait.c.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static INLINE int
+ptw32_cond_unblock (pthread_cond_t * cond, int unblockAll)
+ /*
+ * Notes.
+ *
+ * Does not use the external mutex for synchronisation,
+ * therefore semBlockLock is needed.
+ * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the
+ * state where the external mutex is not necessarily locked by
+ * any thread, ie. between cond_wait unlocking and re-acquiring
+ * the lock after having been signaled or a timeout or
+ * cancellation.
+ *
+ * Uses the following CV elements:
+ * nWaitersBlocked
+ * nWaitersToUnblock
+ * nWaitersGone
+ * mtxUnblockLock
+ * semBlockLock
+ * semBlockQueue
+ */
+{
+ int result;
+ pthread_cond_t cv;
+ int nSignalsToIssue;
+
+ if (cond == NULL || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ cv = *cond;
+
+ /*
+ * No-op if the CV is static and hasn't been initialised yet.
+ * Assuming that any race condition is harmless.
+ */
+ if (cv == PTHREAD_COND_INITIALIZER)
+ {
+ return 0;
+ }
+
+ if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+ {
+ return result;
+ }
+
+ if (0 != cv->nWaitersToUnblock)
+ {
+ if (0 == cv->nWaitersBlocked)
+ {
+ return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ }
+ if (unblockAll)
+ {
+ cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked);
+ cv->nWaitersBlocked = 0;
+ }
+ else
+ {
+ nSignalsToIssue = 1;
+ cv->nWaitersToUnblock++;
+ cv->nWaitersBlocked--;
+ }
+ }
+ else if (cv->nWaitersBlocked > cv->nWaitersGone)
+ {
+ /* Use the non-cancellable version of sem_wait() */
+ if (ptw32_semwait (&(cv->semBlockLock)) != 0)
+ {
+ result = errno;
+ (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ return result;
+ }
+ if (0 != cv->nWaitersGone)
+ {
+ cv->nWaitersBlocked -= cv->nWaitersGone;
+ cv->nWaitersGone = 0;
+ }
+ if (unblockAll)
+ {
+ nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked;
+ cv->nWaitersBlocked = 0;
+ }
+ else
+ {
+ nSignalsToIssue = cv->nWaitersToUnblock = 1;
+ cv->nWaitersBlocked--;
+ }
+ }
+ else
+ {
+ return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ }
+
+ if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
+ {
+ if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0)
+ {
+ result = errno;
+ }
+ }
+
+ return result;
+
+} /* ptw32_cond_unblock */
+
+int
+pthread_cond_signal (pthread_cond_t * cond)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function signals a condition variable, waking
+ * one waiting thread.
+ * If SCHED_FIFO or SCHED_RR policy threads are waiting
+ * the highest priority waiter is awakened; otherwise,
+ * an unspecified waiter is awakened.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ * This function signals a condition variable, waking
+ * one waiting thread.
+ * If SCHED_FIFO or SCHED_RR policy threads are waiting
+ * the highest priority waiter is awakened; otherwise,
+ * an unspecified waiter is awakened.
+ *
+ * NOTES:
+ *
+ * 1) Use when any waiter can respond and only one need
+ * respond (all waiters being equal).
+ *
+ * RESULTS
+ * 0 successfully signaled condition,
+ * EINVAL 'cond' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The '0'(FALSE) unblockAll arg means unblock ONE waiter.
+ */
+ return (ptw32_cond_unblock (cond, 0));
+
+} /* pthread_cond_signal */
+
+int
+pthread_cond_broadcast (pthread_cond_t * cond)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function broadcasts the condition variable,
+ * waking all current waiters.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ * This function signals a condition variable, waking
+ * all waiting threads.
+ *
+ * NOTES:
+ *
+ * 1) Use when more than one waiter may respond to
+ * predicate change or if any waiting thread may
+ * not be able to respond
+ *
+ * RESULTS
+ * 0 successfully signalled condition to all
+ * waiting threads,
+ * EINVAL 'cond' is invalid
+ * ENOSPC a required resource has been exhausted,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The TRUE unblockAll arg means unblock ALL waiters.
+ */
+ return (ptw32_cond_unblock (cond, PTW32_TRUE));
+
+} /* pthread_cond_broadcast */
diff --git a/libs/pthreads/src/pthread_cond_wait.c b/libs/pthreads/src/pthread_cond_wait.c
new file mode 100644
index 0000000000..359219ae9b
--- /dev/null
+++ b/libs/pthreads/src/pthread_cond_wait.c
@@ -0,0 +1,567 @@
+/*
+ * pthread_cond_wait.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * The algorithm used in this implementation is that developed by
+ * Alexander Terekhov in colaboration with Louis Thomas. The bulk
+ * of the discussion is recorded in the file README.CV, which contains
+ * several generations of both colaborators original algorithms. The final
+ * algorithm used here is the one referred to as
+ *
+ * Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code as it appeared:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ * [auto: register int result ] // error checking omitted
+ * [auto: register int nSignalsWasLeft ]
+ * [auto: register int nWaitersWasGone ]
+ *
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked++;
+ * sem_post( semBlockLock );
+ *
+ * unlock( mtxExternal );
+ * bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ * lock( mtxUnblockLock );
+ * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ * if ( bTimeout ) { // timeout (or canceled)
+ * if ( 0 != nWaitersBlocked ) {
+ * nWaitersBlocked--;
+ * }
+ * else {
+ * nWaitersGone++; // count spurious wakeups.
+ * }
+ * }
+ * if ( 0 == --nWaitersToUnblock ) {
+ * if ( 0 != nWaitersBlocked ) {
+ * sem_post( semBlockLock ); // open the gate.
+ * nSignalsWasLeft = 0; // do not open the gate
+ * // below again.
+ * }
+ * else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ * nWaitersGone = 0;
+ * }
+ * }
+ * }
+ * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ * // spurious semaphore :-)
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked -= nWaitersGone; // something is going on here
+ * // - test of timeouts? :-)
+ * sem_post( semBlockLock );
+ * nWaitersGone = 0;
+ * }
+ * unlock( mtxUnblockLock );
+ *
+ * if ( 1 == nSignalsWasLeft ) {
+ * if ( 0 != nWaitersWasGone ) {
+ * // sem_adjust( semBlockQueue,-nWaitersWasGone );
+ * while ( nWaitersWasGone-- ) {
+ * sem_wait( semBlockQueue ); // better now than spurious later
+ * }
+ * } sem_post( semBlockLock ); // open the gate
+ * }
+ *
+ * lock( mtxExternal );
+ *
+ * return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ * [auto: register int result ]
+ * [auto: register int nSignalsToIssue]
+ *
+ * lock( mtxUnblockLock );
+ *
+ * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ * if ( 0 == nWaitersBlocked ) { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ * if (bAll) {
+ * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = 1;
+ * nWaitersToUnblock++;
+ * nWaitersBlocked--;
+ * }
+ * }
+ * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ * sem_wait( semBlockLock ); // close the gate
+ * if ( 0 != nWaitersGone ) {
+ * nWaitersBlocked -= nWaitersGone;
+ * nWaitersGone = 0;
+ * }
+ * if (bAll) {
+ * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = nWaitersToUnblock = 1;
+ * nWaitersBlocked--;
+ * }
+ * }
+ * else { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ *
+ * unlock( mtxUnblockLock );
+ * sem_post( semBlockQueue,nSignalsToIssue );
+ * return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ * Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code; basically 8a...
+ * ...BUT W/O "spurious wakes" prevention:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ * [auto: register int result ] // error checking omitted
+ * [auto: register int nSignalsWasLeft ]
+ *
+ * sem_wait( semBlockLock );
+ * ++nWaitersBlocked;
+ * sem_post( semBlockLock );
+ *
+ * unlock( mtxExternal );
+ * bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ * lock( mtxUnblockLock );
+ * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ * --nWaitersToUnblock;
+ * }
+ * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ * // spurious semaphore :-)
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked -= nWaitersGone; // something is going on here
+ * // - test of timeouts? :-)
+ * sem_post( semBlockLock );
+ * nWaitersGone = 0;
+ * }
+ * unlock( mtxUnblockLock );
+ *
+ * if ( 1 == nSignalsWasLeft ) {
+ * sem_post( semBlockLock ); // open the gate
+ * }
+ *
+ * lock( mtxExternal );
+ *
+ * return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ * [auto: register int result ]
+ * [auto: register int nSignalsToIssue]
+ *
+ * lock( mtxUnblockLock );
+ *
+ * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ * if ( 0 == nWaitersBlocked ) { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ * if (bAll) {
+ * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = 1;
+ * ++nWaitersToUnblock;
+ * --nWaitersBlocked;
+ * }
+ * }
+ * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ * sem_wait( semBlockLock ); // close the gate
+ * if ( 0 != nWaitersGone ) {
+ * nWaitersBlocked -= nWaitersGone;
+ * nWaitersGone = 0;
+ * }
+ * if (bAll) {
+ * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = nWaitersToUnblock = 1;
+ * --nWaitersBlocked;
+ * }
+ * }
+ * else { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ *
+ * unlock( mtxUnblockLock );
+ * sem_post( semBlockQueue,nSignalsToIssue );
+ * return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Arguments for cond_wait_cleanup, since we can only pass a
+ * single void * to it.
+ */
+typedef struct
+{
+ pthread_mutex_t *mutexPtr;
+ pthread_cond_t cv;
+ int *resultPtr;
+} ptw32_cond_wait_cleanup_args_t;
+
+static void PTW32_CDECL
+ptw32_cond_wait_cleanup (void *args)
+{
+ ptw32_cond_wait_cleanup_args_t *cleanup_args =
+ (ptw32_cond_wait_cleanup_args_t *) args;
+ pthread_cond_t cv = cleanup_args->cv;
+ int *resultPtr = cleanup_args->resultPtr;
+ int nSignalsWasLeft;
+ int result;
+
+ /*
+ * Whether we got here as a result of signal/broadcast or because of
+ * timeout on wait or thread cancellation we indicate that we are no
+ * longer waiting. The waiter is responsible for adjusting waiters
+ * (to)unblock(ed) counts (protected by unblock lock).
+ */
+ if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+ {
+ *resultPtr = result;
+ return;
+ }
+
+ if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock))
+ {
+ --(cv->nWaitersToUnblock);
+ }
+ else if (INT_MAX / 2 == ++(cv->nWaitersGone))
+ {
+ /* Use the non-cancellable version of sem_wait() */
+ if (ptw32_semwait (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ /*
+ * This is a fatal error for this CV,
+ * so we deliberately don't unlock
+ * cv->mtxUnblockLock before returning.
+ */
+ return;
+ }
+ cv->nWaitersBlocked -= cv->nWaitersGone;
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ /*
+ * This is a fatal error for this CV,
+ * so we deliberately don't unlock
+ * cv->mtxUnblockLock before returning.
+ */
+ return;
+ }
+ cv->nWaitersGone = 0;
+ }
+
+ if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0)
+ {
+ *resultPtr = result;
+ return;
+ }
+
+ if (1 == nSignalsWasLeft)
+ {
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ return;
+ }
+ }
+
+ /*
+ * XSH: Upon successful return, the mutex has been locked and is owned
+ * by the calling thread.
+ */
+ if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0)
+ {
+ *resultPtr = result;
+ }
+} /* ptw32_cond_wait_cleanup */
+
+static INLINE int
+ptw32_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex, const struct timespec *abstime)
+{
+ int result = 0;
+ pthread_cond_t cv;
+ ptw32_cond_wait_cleanup_args_t cleanup_args;
+
+ if (cond == NULL || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static condition variable. We check
+ * again inside the guarded section of ptw32_cond_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ {
+ result = ptw32_cond_check_need_init (cond);
+ }
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+
+ cv = *cond;
+
+ /* Thread can be cancelled in sem_wait() but this is OK */
+ if (sem_wait (&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+
+ ++(cv->nWaitersBlocked);
+
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+
+ /*
+ * Setup this waiter cleanup handler
+ */
+ cleanup_args.mutexPtr = mutex;
+ cleanup_args.cv = cv;
+ cleanup_args.resultPtr = &result;
+
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args);
+
+ /*
+ * Now we can release 'mutex' and...
+ */
+ if ((result = pthread_mutex_unlock (mutex)) == 0)
+ {
+
+ /*
+ * ...wait to be awakened by
+ * pthread_cond_signal, or
+ * pthread_cond_broadcast, or
+ * timeout, or
+ * thread cancellation
+ *
+ * Note:
+ *
+ * sem_timedwait is a cancellation point,
+ * hence providing the mechanism for making
+ * pthread_cond_wait a cancellation point.
+ * We use the cleanup mechanism to ensure we
+ * re-lock the mutex and adjust (to)unblock(ed) waiters
+ * counts if we are cancelled, timed out or signalled.
+ */
+ if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
+ {
+ result = errno;
+ }
+ }
+
+ /*
+ * Always cleanup
+ */
+ pthread_cleanup_pop (1);
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+
+ /*
+ * "result" can be modified by the cleanup handler.
+ */
+ return result;
+
+} /* ptw32_cond_timedwait */
+
+
+int
+pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a condition variable until
+ * awakened by a signal or broadcast.
+ *
+ * Caller MUST be holding the mutex lock; the
+ * lock is released and the caller is blocked waiting
+ * on 'cond'. When 'cond' is signaled, the mutex
+ * is re-acquired before returning to the caller.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * mutex
+ * pointer to an instance of pthread_mutex_t
+ *
+ *
+ * DESCRIPTION
+ * This function waits on a condition variable until
+ * awakened by a signal or broadcast.
+ *
+ * NOTES:
+ *
+ * 1) The function must be called with 'mutex' LOCKED
+ * by the calling thread, or undefined behaviour
+ * will result.
+ *
+ * 2) This routine atomically releases 'mutex' and causes
+ * the calling thread to block on the condition variable.
+ * The blocked thread may be awakened by
+ * pthread_cond_signal or
+ * pthread_cond_broadcast.
+ *
+ * Upon successful completion, the 'mutex' has been locked and
+ * is owned by the calling thread.
+ *
+ *
+ * RESULTS
+ * 0 caught condition; mutex released,
+ * EINVAL 'cond' or 'mutex' is invalid,
+ * EINVAL different mutexes for concurrent waits,
+ * EINVAL mutex is not held by the calling thread,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The NULL abstime arg means INFINITE waiting.
+ */
+ return (ptw32_cond_timedwait (cond, mutex, NULL));
+
+} /* pthread_cond_wait */
+
+
+int
+pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a condition variable either until
+ * awakened by a signal or broadcast; or until the time
+ * specified by abstime passes.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * mutex
+ * pointer to an instance of pthread_mutex_t
+ *
+ * abstime
+ * pointer to an instance of (const struct timespec)
+ *
+ *
+ * DESCRIPTION
+ * This function waits on a condition variable either until
+ * awakened by a signal or broadcast; or until the time
+ * specified by abstime passes.
+ *
+ * NOTES:
+ * 1) The function must be called with 'mutex' LOCKED
+ * by the calling thread, or undefined behaviour
+ * will result.
+ *
+ * 2) This routine atomically releases 'mutex' and causes
+ * the calling thread to block on the condition variable.
+ * The blocked thread may be awakened by
+ * pthread_cond_signal or
+ * pthread_cond_broadcast.
+ *
+ *
+ * RESULTS
+ * 0 caught condition; mutex released,
+ * EINVAL 'cond', 'mutex', or abstime is invalid,
+ * EINVAL different mutexes for concurrent waits,
+ * EINVAL mutex is not held by the calling thread,
+ * ETIMEDOUT abstime ellapsed before cond was signaled.
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (abstime == NULL)
+ {
+ return EINVAL;
+ }
+
+ return (ptw32_cond_timedwait (cond, mutex, abstime));
+
+} /* pthread_cond_timedwait */
diff --git a/libs/pthreads/src/pthread_condattr_destroy.c b/libs/pthreads/src/pthread_condattr_destroy.c
new file mode 100644
index 0000000000..58a14828fd
--- /dev/null
+++ b/libs/pthreads/src/pthread_condattr_destroy.c
@@ -0,0 +1,86 @@
+/*
+ * condvar_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_destroy (pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a condition variable attributes object.
+ * The object can no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a condition variable attributes object.
+ * The object can no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect condition variables created
+ * using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ (void) free (*attr);
+
+ *attr = NULL;
+ result = 0;
+ }
+
+ return result;
+
+} /* pthread_condattr_destroy */
diff --git a/libs/pthreads/src/pthread_condattr_getpshared.c b/libs/pthreads/src/pthread_condattr_getpshared.c
new file mode 100644
index 0000000000..a0ac6d8829
--- /dev/null
+++ b/libs/pthreads/src/pthread_condattr_getpshared.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_condattr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether condition variables created with 'attr'
+ * can be shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Condition Variables created with 'attr' can be shared
+ * between processes if pthread_cond_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared condition variables MUST be allocated in
+ * shared memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' or 'pshared' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return result;
+
+} /* pthread_condattr_getpshared */
diff --git a/libs/pthreads/src/pthread_condattr_init.c b/libs/pthreads/src/pthread_condattr_init.c
new file mode 100644
index 0000000000..5987878e0c
--- /dev/null
+++ b/libs/pthreads/src/pthread_condattr_init.c
@@ -0,0 +1,87 @@
+/*
+ * pthread_condattr_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_init (pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a condition variable attributes object
+ * with default attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a condition variable attributes object
+ * with default attributes.
+ *
+ * NOTES:
+ * 1) Use to define condition variable types
+ * 2) It is up to the application to ensure
+ * that it doesn't re-init an attribute
+ * without destroying it first. Otherwise
+ * a memory leak is created.
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_condattr_t attr_result;
+ int result = 0;
+
+ attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result));
+
+ if (attr_result == NULL)
+ {
+ result = ENOMEM;
+ }
+
+ *attr = attr_result;
+
+ return result;
+
+} /* pthread_condattr_init */
diff --git a/libs/pthreads/src/pthread_condattr_setpshared.c b/libs/pthreads/src/pthread_condattr_setpshared.c
new file mode 100644
index 0000000000..954fb38299
--- /dev/null
+++ b/libs/pthreads/src/pthread_condattr_setpshared.c
@@ -0,0 +1,117 @@
+/*
+ * pthread_condattr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Mutexes created with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL)
+ && ((pshared == PTHREAD_PROCESS_SHARED)
+ || (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+#else
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return result;
+
+} /* pthread_condattr_setpshared */
diff --git a/libs/pthreads/src/pthread_delay_np.c b/libs/pthreads/src/pthread_delay_np.c
new file mode 100644
index 0000000000..e6c96d8070
--- /dev/null
+++ b/libs/pthreads/src/pthread_delay_np.c
@@ -0,0 +1,172 @@
+/*
+ * pthreads_delay_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * pthread_delay_np
+ *
+ * DESCRIPTION
+ *
+ * This routine causes a thread to delay execution for a specific period of time.
+ * This period ends at the current time plus the specified interval. The routine
+ * will not return before the end of the period is reached, but may return an
+ * arbitrary amount of time after the period has gone by. This can be due to
+ * system load, thread priorities, and system timer granularity.
+ *
+ * Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
+ * allowed and can be used to force the thread to give up the processor or to
+ * deliver a pending cancelation request.
+ *
+ * The timespec structure contains the following two fields:
+ *
+ * tv_sec is an integer number of seconds.
+ * tv_nsec is an integer number of nanoseconds.
+ *
+ * Return Values
+ *
+ * If an error condition occurs, this routine returns an integer value indicating
+ * the type of error. Possible return values are as follows:
+ *
+ * 0
+ * Successful completion.
+ * [EINVAL]
+ * The value specified by interval is invalid.
+ *
+ * Example
+ *
+ * The following code segment would wait for 5 and 1/2 seconds
+ *
+ * struct timespec tsWait;
+ * int intRC;
+ *
+ * tsWait.tv_sec = 5;
+ * tsWait.tv_nsec = 500000000L;
+ * intRC = pthread_delay_np(&tsWait);
+ */
+int
+pthread_delay_np (struct timespec *interval)
+{
+ DWORD wait_time;
+ DWORD secs_in_millisecs;
+ DWORD millisecs;
+ DWORD status;
+ pthread_t self;
+ ptw32_thread_t * sp;
+
+ if (interval == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (interval->tv_sec == 0L && interval->tv_nsec == 0L)
+ {
+ pthread_testcancel ();
+ Sleep (0);
+ pthread_testcancel ();
+ return (0);
+ }
+
+ /* convert secs to millisecs */
+ secs_in_millisecs = (DWORD)interval->tv_sec * 1000L;
+
+ /* convert nanosecs to millisecs (rounding up) */
+ millisecs = (interval->tv_nsec + 999999L) / 1000000L;
+
+#if defined(__WATCOMC__)
+#pragma disable_message (124)
+#endif
+
+ /*
+ * Most compilers will issue a warning 'comparison always 0'
+ * because the variable type is unsigned, but we need to keep this
+ * for some reason I can't recall now.
+ */
+ if (0 > (wait_time = secs_in_millisecs + millisecs))
+ {
+ return EINVAL;
+ }
+
+#if defined(__WATCOMC__)
+#pragma enable_message (124)
+#endif
+
+ if (NULL == (self = pthread_self ()).p)
+ {
+ return ENOMEM;
+ }
+
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+ {
+ /*
+ * Async cancelation won't catch us until wait_time is up.
+ * Deferred cancelation will cancel us immediately.
+ */
+ if (WAIT_OBJECT_0 ==
+ (status = WaitForSingleObject (sp->cancelEvent, wait_time)))
+ {
+ ptw32_mcs_local_node_t stateLock;
+ /*
+ * Canceling!
+ */
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+ if (sp->state < PThreadStateCanceling)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ptw32_mcs_lock_release (&stateLock);
+
+ ptw32_throw (PTW32_EPS_CANCEL);
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+ return ESRCH;
+ }
+ else if (status != WAIT_TIMEOUT)
+ {
+ return EINVAL;
+ }
+ }
+ else
+ {
+ Sleep (wait_time);
+ }
+
+ return (0);
+}
diff --git a/libs/pthreads/src/pthread_detach.c b/libs/pthreads/src/pthread_detach.c
new file mode 100644
index 0000000000..9ff6587f3c
--- /dev/null
+++ b/libs/pthreads/src/pthread_detach.c
@@ -0,0 +1,136 @@
+/*
+ * pthread_detach.c
+ *
+ * Description:
+ * This translation unit implements functions related to thread
+ * synchronisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Not needed yet, but defining it should indicate clashes with build target
+ * environment that should be fixed.
+ */
+#if !defined(WINCE)
+# include <signal.h>
+#endif
+
+
+int
+pthread_detach (pthread_t thread)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function detaches the given thread.
+ *
+ * PARAMETERS
+ * thread
+ * an instance of a pthread_t
+ *
+ *
+ * DESCRIPTION
+ * This function detaches the given thread. You may use it to
+ * detach the main thread or to detach a joinable thread.
+ * NOTE: detached threads cannot be joined;
+ * storage is freed immediately on termination.
+ *
+ * RESULTS
+ * 0 successfully detached the thread,
+ * EINVAL thread is not a joinable thread,
+ * ENOSPC a required resource has been exhausted,
+ * ESRCH no thread could be found for 'thread',
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+ BOOL destroyIt = PTW32_FALSE;
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ if (NULL == tp
+ || thread.x != tp->ptHandle.x)
+ {
+ result = ESRCH;
+ }
+ else if (PTHREAD_CREATE_DETACHED == tp->detachState)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ ptw32_mcs_local_node_t stateLock;
+ /*
+ * Joinable ptw32_thread_t structs are not scavenged until
+ * a join or detach is done. The thread may have exited already,
+ * but all of the state and locks etc are still there.
+ */
+ result = 0;
+
+ ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock);
+ if (tp->state != PThreadStateLast)
+ {
+ tp->detachState = PTHREAD_CREATE_DETACHED;
+ }
+ else if (tp->detachState != PTHREAD_CREATE_DETACHED)
+ {
+ /*
+ * Thread is joinable and has exited or is exiting.
+ */
+ destroyIt = PTW32_TRUE;
+ }
+ ptw32_mcs_lock_release (&stateLock);
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ if (result == 0)
+ {
+ /* Thread is joinable */
+
+ if (destroyIt)
+ {
+ /* The thread has exited or is exiting but has not been joined or
+ * detached. Need to wait in case it's still exiting.
+ */
+ (void) WaitForSingleObject(tp->threadH, INFINITE);
+ ptw32_threadDestroy (thread);
+ }
+ }
+
+ return (result);
+
+} /* pthread_detach */
diff --git a/libs/pthreads/src/pthread_equal.c b/libs/pthreads/src/pthread_equal.c
new file mode 100644
index 0000000000..5ddd82acba
--- /dev/null
+++ b/libs/pthreads/src/pthread_equal.c
@@ -0,0 +1,76 @@
+/*
+ * pthread_equal.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_equal (pthread_t t1, pthread_t t2)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns nonzero if t1 and t2 are equal, else
+ * returns zero
+ *
+ * PARAMETERS
+ * t1,
+ * t2
+ * thread IDs
+ *
+ *
+ * DESCRIPTION
+ * This function returns nonzero if t1 and t2 are equal, else
+ * returns zero.
+ *
+ * RESULTS
+ * non-zero if t1 and t2 refer to the same thread,
+ * 0 t1 and t2 do not refer to the same thread
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ /*
+ * We also accept NULL == NULL - treating NULL as a thread
+ * for this special case, because there is no error that we can return.
+ */
+ result = ( t1.p == t2.p && t1.x == t2.x );
+
+ return (result);
+
+} /* pthread_equal */
diff --git a/libs/pthreads/src/pthread_exit.c b/libs/pthreads/src/pthread_exit.c
new file mode 100644
index 0000000000..37b3c09902
--- /dev/null
+++ b/libs/pthreads/src/pthread_exit.c
@@ -0,0 +1,106 @@
+/*
+ * pthread_exit.c
+ *
+ * Description:
+ * This translation unit implements routines associated with exiting from
+ * a thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#if !defined(_UWIN)
+/*# include <process.h> */
+#endif
+
+void
+pthread_exit (void *value_ptr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function terminates the calling thread, returning
+ * the value 'value_ptr' to any joining thread.
+ *
+ * PARAMETERS
+ * value_ptr
+ * a generic data value (i.e. not the address of a value)
+ *
+ *
+ * DESCRIPTION
+ * This function terminates the calling thread, returning
+ * the value 'value_ptr' to any joining thread.
+ * NOTE: thread should be joinable.
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_thread_t * sp;
+
+ /*
+ * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
+ * unnecessarily.
+ */
+ sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+#if defined(_UWIN)
+ if (--pthread_count <= 0)
+ exit ((int) value_ptr);
+#endif
+
+ if (NULL == sp)
+ {
+ /*
+ * A POSIX thread handle was never created. I.e. this is a
+ * Win32 thread that has never called a pthreads-win32 routine that
+ * required a POSIX handle.
+ *
+ * Implicit POSIX handles are cleaned up in ptw32_throw() now.
+ */
+
+#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ _endthreadex ((unsigned) (size_t) value_ptr);
+#else
+ _endthread ();
+#endif
+
+ /* Never reached */
+ }
+
+ sp->exitStatus = value_ptr;
+
+ ptw32_throw (PTW32_EPS_EXIT);
+
+ /* Never reached. */
+
+}
diff --git a/libs/pthreads/src/pthread_getconcurrency.c b/libs/pthreads/src/pthread_getconcurrency.c
new file mode 100644
index 0000000000..cf9e9c85c2
--- /dev/null
+++ b/libs/pthreads/src/pthread_getconcurrency.c
@@ -0,0 +1,45 @@
+/*
+ * pthread_getconcurrency.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_getconcurrency (void)
+{
+ return ptw32_concurrency;
+}
diff --git a/libs/pthreads/src/pthread_getschedparam.c b/libs/pthreads/src/pthread_getschedparam.c
new file mode 100644
index 0000000000..0afcfb74a9
--- /dev/null
+++ b/libs/pthreads/src/pthread_getschedparam.c
@@ -0,0 +1,75 @@
+/*
+ * sched_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_getschedparam (pthread_t thread, int *policy,
+ struct sched_param *param)
+{
+ int result;
+
+ /* Validate the thread id. */
+ result = pthread_kill (thread, 0);
+ if (0 != result)
+ {
+ return result;
+ }
+
+ /*
+ * Validate the policy and param args.
+ * Check that a policy constant wasn't passed rather than &policy.
+ */
+ if (policy <= (int *) SCHED_MAX || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ /* Fill out the policy. */
+ *policy = SCHED_OTHER;
+
+ /*
+ * This function must return the priority value set by
+ * the most recent pthread_setschedparam() or pthread_create()
+ * for the target thread. It must not return the actual thread
+ * priority as altered by any system priority adjustments etc.
+ */
+ param->sched_priority = ((ptw32_thread_t *)thread.p)->sched_priority;
+
+ return 0;
+}
diff --git a/libs/pthreads/src/pthread_getspecific.c b/libs/pthreads/src/pthread_getspecific.c
new file mode 100644
index 0000000000..5ee1641dc1
--- /dev/null
+++ b/libs/pthreads/src/pthread_getspecific.c
@@ -0,0 +1,87 @@
+/*
+ * pthread_getspecific.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void *
+pthread_getspecific (pthread_key_t key)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns the current value of key in the
+ * calling thread. If no value has been set for 'key' in
+ * the thread, NULL is returned.
+ *
+ * PARAMETERS
+ * key
+ * an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ * This function returns the current value of key in the
+ * calling thread. If no value has been set for 'key' in
+ * the thread, NULL is returned.
+ *
+ * RESULTS
+ * key value or NULL on failure
+ *
+ * ------------------------------------------------------
+ */
+{
+ void * ptr;
+
+ if (key == NULL)
+ {
+ ptr = NULL;
+ }
+ else
+ {
+ int lasterror = GetLastError ();
+#if defined(RETAIN_WSALASTERROR)
+ int lastWSAerror = WSAGetLastError ();
+#endif
+ ptr = TlsGetValue (key->key);
+
+ SetLastError (lasterror);
+#if defined(RETAIN_WSALASTERROR)
+ WSASetLastError (lastWSAerror);
+#endif
+ }
+
+ return ptr;
+}
diff --git a/libs/pthreads/src/pthread_getunique_np.c b/libs/pthreads/src/pthread_getunique_np.c
new file mode 100644
index 0000000000..4496c68bf5
--- /dev/null
+++ b/libs/pthreads/src/pthread_getunique_np.c
@@ -0,0 +1,47 @@
+/*
+ * pthread_getunique_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ *
+ */
+unsigned __int64
+pthread_getunique_np (pthread_t thread)
+{
+ return ((ptw32_thread_t*)thread.p)->seqNumber;
+}
diff --git a/libs/pthreads/src/pthread_getw32threadhandle_np.c b/libs/pthreads/src/pthread_getw32threadhandle_np.c
new file mode 100644
index 0000000000..309a8f281f
--- /dev/null
+++ b/libs/pthreads/src/pthread_getw32threadhandle_np.c
@@ -0,0 +1,65 @@
+/*
+ * pthread_getw32threadhandle_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * pthread_getw32threadhandle_np()
+ *
+ * Returns the win32 thread handle that the POSIX
+ * thread "thread" is running as.
+ *
+ * Applications can use the win32 handle to set
+ * win32 specific attributes of the thread.
+ */
+HANDLE
+pthread_getw32threadhandle_np (pthread_t thread)
+{
+ return ((ptw32_thread_t *)thread.p)->threadH;
+}
+
+/*
+ * pthread_getw32threadid_np()
+ *
+ * Returns the win32 thread id that the POSIX
+ * thread "thread" is running as.
+ */
+DWORD
+pthread_getw32threadid_np (pthread_t thread)
+{
+ return ((ptw32_thread_t *)thread.p)->thread;
+}
diff --git a/libs/pthreads/src/pthread_join.c b/libs/pthreads/src/pthread_join.c
new file mode 100644
index 0000000000..c2b7c1e757
--- /dev/null
+++ b/libs/pthreads/src/pthread_join.c
@@ -0,0 +1,157 @@
+/*
+ * pthread_join.c
+ *
+ * Description:
+ * This translation unit implements functions related to thread
+ * synchronisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Not needed yet, but defining it should indicate clashes with build target
+ * environment that should be fixed.
+ */
+#if !defined(WINCE)
+# include <signal.h>
+#endif
+
+
+int
+pthread_join (pthread_t thread, void **value_ptr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits for 'thread' to terminate and
+ * returns the thread's exit value if 'value_ptr' is not
+ * NULL. This also detaches the thread on successful
+ * completion.
+ *
+ * PARAMETERS
+ * thread
+ * an instance of pthread_t
+ *
+ * value_ptr
+ * pointer to an instance of pointer to void
+ *
+ *
+ * DESCRIPTION
+ * This function waits for 'thread' to terminate and
+ * returns the thread's exit value if 'value_ptr' is not
+ * NULL. This also detaches the thread on successful
+ * completion.
+ * NOTE: detached threads cannot be joined or canceled
+ *
+ * RESULTS
+ * 0 'thread' has completed
+ * EINVAL thread is not a joinable thread,
+ * ESRCH no thread could be found with ID 'thread',
+ * ENOENT thread couldn't find it's own valid handle,
+ * EDEADLK attempt to join thread with self
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+ pthread_t self;
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ if (NULL == tp
+ || thread.x != tp->ptHandle.x)
+ {
+ result = ESRCH;
+ }
+ else if (PTHREAD_CREATE_DETACHED == tp->detachState)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ result = 0;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ if (result == 0)
+ {
+ /*
+ * The target thread is joinable and can't be reused before we join it.
+ */
+ self = pthread_self();
+
+ if (NULL == self.p)
+ {
+ result = ENOENT;
+ }
+ else if (pthread_equal (self, thread))
+ {
+ result = EDEADLK;
+ }
+ else
+ {
+ /*
+ * Pthread_join is a cancelation point.
+ * If we are canceled then our target thread must not be
+ * detached (destroyed). This is guarranteed because
+ * pthreadCancelableWait will not return if we
+ * are canceled.
+ */
+ result = pthreadCancelableWait (tp->threadH);
+
+ if (0 == result)
+ {
+ if (value_ptr != NULL)
+ {
+ *value_ptr = tp->exitStatus;
+ }
+
+ /*
+ * The result of making multiple simultaneous calls to
+ * pthread_join() or pthread_detach() specifying the same
+ * target is undefined.
+ */
+ result = pthread_detach (thread);
+ }
+ else
+ {
+ result = ESRCH;
+ }
+ }
+ }
+
+ return (result);
+
+} /* pthread_join */
diff --git a/libs/pthreads/src/pthread_key_create.c b/libs/pthreads/src/pthread_key_create.c
new file mode 100644
index 0000000000..65c6f95081
--- /dev/null
+++ b/libs/pthreads/src/pthread_key_create.c
@@ -0,0 +1,108 @@
+/*
+ * pthread_key_create.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/* TLS_OUT_OF_INDEXES not defined on WinCE */
+#if !defined(TLS_OUT_OF_INDEXES)
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
+int
+pthread_key_create (pthread_key_t * key, void (PTW32_CDECL *destructor) (void *))
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function creates a thread-specific data key visible
+ * to all threads. All existing and new threads have a value
+ * NULL for key until set using pthread_setspecific. When any
+ * thread with a non-NULL value for key terminates, 'destructor'
+ * is called with key's current value for that thread.
+ *
+ * PARAMETERS
+ * key
+ * pointer to an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ * This function creates a thread-specific data key visible
+ * to all threads. All existing and new threads have a value
+ * NULL for key until set using pthread_setspecific. When any
+ * thread with a non-NULL value for key terminates, 'destructor'
+ * is called with key's current value for that thread.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * EAGAIN insufficient resources or PTHREAD_KEYS_MAX
+ * exceeded,
+ * ENOMEM insufficient memory to create the key,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_key_t newkey;
+
+ if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL)
+ {
+ result = ENOMEM;
+ }
+ else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES)
+ {
+ result = EAGAIN;
+
+ free (newkey);
+ newkey = NULL;
+ }
+ else if (destructor != NULL)
+ {
+ /*
+ * Have to manage associations between thread and key;
+ * Therefore, need a lock that allows competing threads
+ * to gain exclusive access to the key->threads list.
+ *
+ * The mutex will only be created when it is first locked.
+ */
+ newkey->keyLock = 0;
+ newkey->destructor = destructor;
+ }
+
+ *key = newkey;
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_key_delete.c b/libs/pthreads/src/pthread_key_delete.c
new file mode 100644
index 0000000000..09d70c63f5
--- /dev/null
+++ b/libs/pthreads/src/pthread_key_delete.c
@@ -0,0 +1,125 @@
+/*
+ * pthread_key_delete.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_key_delete (pthread_key_t key)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function deletes a thread-specific data key. This
+ * does not change the value of the thread specific data key
+ * for any thread and does not run the key's destructor
+ * in any thread so it should be used with caution.
+ *
+ * PARAMETERS
+ * key
+ * pointer to an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ * This function deletes a thread-specific data key. This
+ * does not change the value of the thread specific data key
+ * for any thread and does not run the key's destructor
+ * in any thread so it should be used with caution.
+ *
+ * RESULTS
+ * 0 successfully deleted the key,
+ * EINVAL key is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_mcs_local_node_t keyLock;
+ int result = 0;
+
+ if (key != NULL)
+ {
+ if (key->threads != NULL && key->destructor != NULL)
+ {
+ ThreadKeyAssoc *assoc;
+ ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
+ /*
+ * Run through all Thread<-->Key associations
+ * for this key.
+ *
+ * While we hold at least one of the locks guarding
+ * the assoc, we know that the assoc pointed to by
+ * key->threads is valid.
+ */
+ while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL)
+ {
+ ptw32_mcs_local_node_t threadLock;
+ ptw32_thread_t * thread = assoc->thread;
+
+ if (assoc == NULL)
+ {
+ /* Finished */
+ break;
+ }
+
+ ptw32_mcs_lock_acquire (&(thread->threadLock), &threadLock);
+ /*
+ * Since we are starting at the head of the key's threads
+ * chain, this will also point key->threads at the next assoc.
+ * While we hold key->keyLock, no other thread can insert
+ * a new assoc via pthread_setspecific.
+ */
+ ptw32_tkAssocDestroy (assoc);
+ ptw32_mcs_lock_release (&threadLock);
+ ptw32_mcs_lock_release (&keyLock);
+ }
+ }
+
+ TlsFree (key->key);
+ if (key->destructor != NULL)
+ {
+ /* A thread could be holding the keyLock */
+ ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
+ ptw32_mcs_lock_release (&keyLock);
+ }
+
+#if defined( _DEBUG )
+ memset ((char *) key, 0, sizeof (*key));
+#endif
+ free (key);
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_kill.c b/libs/pthreads/src/pthread_kill.c
new file mode 100644
index 0000000000..5473b43cd4
--- /dev/null
+++ b/libs/pthreads/src/pthread_kill.c
@@ -0,0 +1,105 @@
+/*
+ * pthread_kill.c
+ *
+ * Description:
+ * This translation unit implements the pthread_kill routine.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Not needed yet, but defining it should indicate clashes with build target
+ * environment that should be fixed.
+ */
+#if !defined(WINCE)
+# include <signal.h>
+#endif
+
+int
+pthread_kill (pthread_t thread, int sig)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function requests that a signal be delivered to the
+ * specified thread. If sig is zero, error checking is
+ * performed but no signal is actually sent such that this
+ * function can be used to check for a valid thread ID.
+ *
+ * PARAMETERS
+ * thread reference to an instances of pthread_t
+ * sig signal. Currently only a value of 0 is supported.
+ *
+ *
+ * DESCRIPTION
+ * This function requests that a signal be delivered to the
+ * specified thread. If sig is zero, error checking is
+ * performed but no signal is actually sent such that this
+ * function can be used to check for a valid thread ID.
+ *
+ * RESULTS
+ * ESRCH the thread is not a valid thread ID,
+ * EINVAL the value of the signal is invalid
+ * or unsupported.
+ * 0 the signal was successfully sent.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ ptw32_thread_t * tp;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ tp = (ptw32_thread_t *) thread.p;
+
+ if (NULL == tp
+ || thread.x != tp->ptHandle.x
+ || NULL == tp->threadH)
+ {
+ result = ESRCH;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ if (0 == result && 0 != sig)
+ {
+ /*
+ * Currently does not support any signals.
+ */
+ result = EINVAL;
+ }
+
+ return result;
+
+} /* pthread_kill */
diff --git a/libs/pthreads/src/pthread_mutex_consistent.c b/libs/pthreads/src/pthread_mutex_consistent.c
new file mode 100644
index 0000000000..b7805e7b19
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_consistent.c
@@ -0,0 +1,190 @@
+/*
+ * pthread_mutex_consistent.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * From the Sun Multi-threaded Programming Guide
+ *
+ * robustness defines the behavior when the owner of the mutex terminates without unlocking the
+ * mutex, usually because its process terminated abnormally. The value of robustness that is
+ * defined in pthread.h is PTHREAD_MUTEX_ROBUST or PTHREAD_MUTEX_STALLED. The
+ * default value is PTHREAD_MUTEX_STALLED .
+ * ■ PTHREAD_MUTEX_STALLED
+ * When the owner of the mutex terminates without unlocking the mutex, all subsequent calls
+ * to pthread_mutex_lock() are blocked from progress in an unspecified manner.
+ * ■ PTHREAD_MUTEX_ROBUST
+ * When the owner of the mutex terminates without unlocking the mutex, the mutex is
+ * unlocked. The next owner of this mutex acquires the mutex with an error return of
+ * EOWNERDEAD.
+ * Note – Your application must always check the return code from pthread_mutex_lock() for
+ * a mutex initialized with the PTHREAD_MUTEX_ROBUST attribute.
+ * ■ The new owner of this mutex should make the state protected by the mutex consistent.
+ * This state might have been left inconsistent when the previous owner terminated.
+ * ■ If the new owner is able to make the state consistent, call
+ * pthread_mutex_consistent() for the mutex before unlocking the mutex. This
+ * marks the mutex as consistent and subsequent calls to pthread_mutex_lock() and
+ * pthread_mutex_unlock() will behave in the normal manner.
+ * ■ If the new owner is not able to make the state consistent, do not call
+ * pthread_mutex_consistent() for the mutex, but unlock the mutex.
+ * All waiters are woken up and all subsequent calls to pthread_mutex_lock() fail to
+ * acquire the mutex. The return code is ENOTRECOVERABLE. The mutex can be made
+ * consistent by calling pthread_mutex_destroy() to uninitialize the mutex, and calling
+ * pthread_mutex_int() to reinitialize the mutex.However, the state that was protected
+ * by the mutex remains inconsistent and some form of application recovery is required.
+ * ■ If the thread that acquires the lock with EOWNERDEAD terminates without unlocking the
+ * mutex, the next owner acquires the lock with an EOWNERDEAD return code.
+ */
+#if !defined(_UWIN)
+/*# include <process.h> */
+#endif
+#include "pthread.h"
+#include "implement.h"
+
+INLINE
+int
+ptw32_robust_mutex_inherit(pthread_mutex_t * mutex)
+{
+ int result;
+ pthread_mutex_t mx = *mutex;
+ ptw32_robust_node_t* robust = mx->robustNode;
+
+ switch ((LONG)PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)&robust->stateInconsistent,
+ (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT,
+ (PTW32_INTERLOCKED_LONG)-1 /* The terminating thread sets this */))
+ {
+ case -1L:
+ result = EOWNERDEAD;
+ break;
+ case (LONG)PTW32_ROBUST_NOTRECOVERABLE:
+ result = ENOTRECOVERABLE;
+ break;
+ default:
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * The next two internal support functions depend on only being
+ * called by the thread that owns the robust mutex. This enables
+ * us to avoid additional locks.
+ * Any mutex currently in the thread's robust mutex list is held
+ * by the thread, again eliminating the need for locks.
+ * The forward/backward links allow the thread to unlock mutexes
+ * in any order, not necessarily the reverse locking order.
+ * This is all possible because it is an error if a thread that
+ * does not own the [robust] mutex attempts to unlock it.
+ */
+
+INLINE
+void
+ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self)
+{
+ ptw32_robust_node_t** list;
+ pthread_mutex_t mx = *mutex;
+ ptw32_thread_t* tp = (ptw32_thread_t*)self.p;
+ ptw32_robust_node_t* robust = mx->robustNode;
+
+ list = &tp->robustMxList;
+ mx->ownerThread = self;
+ if (NULL == *list)
+ {
+ robust->prev = NULL;
+ robust->next = NULL;
+ *list = robust;
+ }
+ else
+ {
+ robust->prev = NULL;
+ robust->next = *list;
+ (*list)->prev = robust;
+ *list = robust;
+ }
+}
+
+INLINE
+void
+ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp)
+{
+ ptw32_robust_node_t** list;
+ pthread_mutex_t mx = *mutex;
+ ptw32_robust_node_t* robust = mx->robustNode;
+
+ list = &(((ptw32_thread_t*)mx->ownerThread.p)->robustMxList);
+ mx->ownerThread.p = otp;
+ if (robust->next != NULL)
+ {
+ robust->next->prev = robust->prev;
+ }
+ if (robust->prev != NULL)
+ {
+ robust->prev->next = robust->next;
+ }
+ if (*list == robust)
+ {
+ *list = robust->next;
+ }
+}
+
+
+int
+pthread_mutex_consistent (pthread_mutex_t* mutex)
+{
+ pthread_mutex_t mx = *mutex;
+ int result = 0;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+ if (mx == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (mx->kind >= 0
+ || (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT != PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent,
+ (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_CONSISTENT,
+ (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT))
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+}
+
diff --git a/libs/pthreads/src/pthread_mutex_destroy.c b/libs/pthreads/src/pthread_mutex_destroy.c
new file mode 100644
index 0000000000..7b8c9cd65b
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_destroy.c
@@ -0,0 +1,148 @@
+/*
+ * pthread_mutex_destroy.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_destroy (pthread_mutex_t * mutex)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * Check to see if we have something to delete.
+ */
+ if (*mutex < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ mx = *mutex;
+
+ result = pthread_mutex_trylock (&mx);
+
+ /*
+ * If trylock succeeded and the mutex is not recursively locked it
+ * can be destroyed.
+ */
+ if (0 == result || ENOTRECOVERABLE == result)
+ {
+ if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count)
+ {
+ /*
+ * FIXME!!!
+ * The mutex isn't held by another thread but we could still
+ * be too late invalidating the mutex below since another thread
+ * may already have entered mutex_lock and the check for a valid
+ * *mutex != NULL.
+ */
+ *mutex = NULL;
+
+ result = (0 == result)?pthread_mutex_unlock(&mx):0;
+
+ if (0 == result)
+ {
+ if (mx->robustNode != NULL)
+ {
+ free(mx->robustNode);
+ }
+ if (!CloseHandle (mx->event))
+ {
+ *mutex = mx;
+ result = EINVAL;
+ }
+ else
+ {
+ free (mx);
+ }
+ }
+ else
+ {
+ /*
+ * Restore the mutex before we return the error.
+ */
+ *mutex = mx;
+ }
+ }
+ else /* mx->recursive_count > 1 */
+ {
+ /*
+ * The mutex must be recursive and already locked by us (this thread).
+ */
+ mx->recursive_count--; /* Undo effect of pthread_mutex_trylock() above */
+ result = EBUSY;
+ }
+ }
+ }
+ else
+ {
+ ptw32_mcs_local_node_t node;
+
+ /*
+ * See notes in ptw32_mutex_check_need_init() above also.
+ */
+
+ ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
+
+ /*
+ * Check again.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised mutex that has not yet been used (initialised).
+ * If we get to here, another thread
+ * waiting to initialise this mutex will get an EINVAL.
+ */
+ *mutex = NULL;
+ }
+ else
+ {
+ /*
+ * The mutex has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+ ptw32_mcs_lock_release(&node);
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_mutex_init.c b/libs/pthreads/src/pthread_mutex_init.c
new file mode 100644
index 0000000000..daf805e5bc
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_init.c
@@ -0,0 +1,130 @@
+/*
+ * pthread_mutex_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ if (mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (attr != NULL && *attr != NULL)
+ {
+ if ((*attr)->pshared == PTHREAD_PROCESS_SHARED)
+ {
+ /*
+ * Creating mutex that can be shared between
+ * processes.
+ */
+#if _POSIX_THREAD_PROCESS_SHARED >= 0
+
+ /*
+ * Not implemented yet.
+ */
+
+#error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet.
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+ }
+ }
+
+ mx = (pthread_mutex_t) calloc (1, sizeof (*mx));
+
+ if (mx == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ mx->lock_idx = 0;
+ mx->recursive_count = 0;
+ mx->robustNode = NULL;
+ if (attr == NULL || *attr == NULL)
+ {
+ mx->kind = PTHREAD_MUTEX_DEFAULT;
+ }
+ else
+ {
+ mx->kind = (*attr)->kind;
+ if ((*attr)->robustness == PTHREAD_MUTEX_ROBUST)
+ {
+ /*
+ * Use the negative range to represent robust types.
+ * Replaces a memory fetch with a register negate and incr
+ * in pthread_mutex_lock etc.
+ *
+ * Map 0,1,..,n to -1,-2,..,(-n)-1
+ */
+ mx->kind = -mx->kind - 1;
+
+ mx->robustNode = (ptw32_robust_node_t*) malloc(sizeof(ptw32_robust_node_t));
+ mx->robustNode->stateInconsistent = PTW32_ROBUST_CONSISTENT;
+ mx->robustNode->mx = mx;
+ mx->robustNode->next = NULL;
+ mx->robustNode->prev = NULL;
+ }
+ }
+
+ mx->ownerThread.p = NULL;
+
+ mx->event = CreateEvent (NULL, PTW32_FALSE, /* manual reset = No */
+ PTW32_FALSE, /* initial state = not signaled */
+ NULL); /* event name */
+
+ if (0 == mx->event)
+ {
+ result = ENOSPC;
+ free (mx);
+ mx = NULL;
+ }
+ }
+
+ *mutex = mx;
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_mutex_lock.c b/libs/pthreads/src/pthread_mutex_lock.c
new file mode 100644
index 0000000000..eee9abe8c7
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_lock.c
@@ -0,0 +1,269 @@
+/*
+ * pthread_mutex_lock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined(_UWIN)
+/*# include <process.h> */
+#endif
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_mutex_lock (pthread_mutex_t * mutex)
+{
+ int kind;
+ pthread_mutex_t mx;
+ int result = 0;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+ if (*mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static mutex. We check
+ * again inside the guarded section of ptw32_mutex_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ mx = *mutex;
+ kind = mx->kind;
+
+ if (kind >= 0)
+ {
+ /* Non-robust */
+ if (PTHREAD_MUTEX_NORMAL == kind)
+ {
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1) != 0)
+ {
+ while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
+ {
+ result = EINVAL;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0) == 0)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ if (kind == PTHREAD_MUTEX_RECURSIVE)
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EDEADLK;
+ }
+ }
+ else
+ {
+ while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
+ {
+ result = EINVAL;
+ break;
+ }
+ }
+
+ if (0 == result)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Robust types
+ * All types record the current owner thread.
+ * The mutex is added to a per thread list when ownership is acquired.
+ */
+ ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ result = ENOTRECOVERABLE;
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ kind = -kind - 1; /* Convert to non-robust range */
+
+ if (PTHREAD_MUTEX_NORMAL == kind)
+ {
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1) != 0)
+ {
+ while (0 == (result = ptw32_robust_mutex_inherit(mutex))
+ && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
+ {
+ result = EINVAL;
+ break;
+ }
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ /* Unblock the next thread */
+ SetEvent(mx->event);
+ result = ENOTRECOVERABLE;
+ break;
+ }
+ }
+ }
+ if (0 == result || EOWNERDEAD == result)
+ {
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ }
+ else
+ {
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0) == 0)
+ {
+ mx->recursive_count = 1;
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ if (PTHREAD_MUTEX_RECURSIVE == kind)
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EDEADLK;
+ }
+ }
+ else
+ {
+ while (0 == (result = ptw32_robust_mutex_inherit(mutex))
+ && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE))
+ {
+ result = EINVAL;
+ break;
+ }
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ /* Unblock the next thread */
+ SetEvent(mx->event);
+ result = ENOTRECOVERABLE;
+ break;
+ }
+ }
+
+ if (0 == result || EOWNERDEAD == result)
+ {
+ mx->recursive_count = 1;
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (result);
+}
+
diff --git a/libs/pthreads/src/pthread_mutex_timedlock.c b/libs/pthreads/src/pthread_mutex_timedlock.c
new file mode 100644
index 0000000000..1745316795
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_timedlock.c
@@ -0,0 +1,324 @@
+/*
+ * pthread_mutex_timedlock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+static INLINE int
+ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DESCRIPTION
+ * This function waits on an event until signaled or until
+ * abstime passes.
+ * If abstime has passed when this routine is called then
+ * it returns a result to indicate this.
+ *
+ * If 'abstime' is a NULL pointer then this function will
+ * block until it can successfully decrease the value or
+ * until interrupted by a signal.
+ *
+ * This routine is not a cancelation point.
+ *
+ * RESULTS
+ * 0 successfully signaled,
+ * ETIMEDOUT abstime passed
+ * EINVAL 'event' is not a valid event,
+ *
+ * ------------------------------------------------------
+ */
+{
+
+ DWORD milliseconds;
+ DWORD status;
+
+ if (event == NULL)
+ {
+ return EINVAL;
+ }
+ else
+ {
+ if (abstime == NULL)
+ {
+ milliseconds = INFINITE;
+ }
+ else
+ {
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+ milliseconds = ptw32_relmillisecs (abstime);
+ }
+
+ status = WaitForSingleObject (event, milliseconds);
+
+ if (status == WAIT_OBJECT_0)
+ {
+ return 0;
+ }
+ else if (status == WAIT_TIMEOUT)
+ {
+ return ETIMEDOUT;
+ }
+ else
+ {
+ return EINVAL;
+ }
+ }
+
+ return 0;
+
+} /* ptw32_timed_semwait */
+
+
+int
+pthread_mutex_timedlock (pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+{
+ pthread_mutex_t mx;
+ int kind;
+ int result = 0;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static mutex. We check
+ * again inside the guarded section of ptw32_mutex_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ mx = *mutex;
+ kind = mx->kind;
+
+ if (kind >= 0)
+ {
+ if (mx->kind == PTHREAD_MUTEX_NORMAL)
+ {
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1) != 0)
+ {
+ while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ }
+ }
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0) == 0)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ return EDEADLK;
+ }
+ }
+ else
+ {
+ while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ }
+
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Robust types
+ * All types record the current owner thread.
+ * The mutex is added to a per thread list when ownership is acquired.
+ */
+ ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ result = ENOTRECOVERABLE;
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ kind = -kind - 1; /* Convert to non-robust range */
+
+ if (PTHREAD_MUTEX_NORMAL == kind)
+ {
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1) != 0)
+ {
+ while (0 == (result = ptw32_robust_mutex_inherit(mutex))
+ && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ /* Unblock the next thread */
+ SetEvent(mx->event);
+ result = ENOTRECOVERABLE;
+ break;
+ }
+ }
+
+ if (0 == result || EOWNERDEAD == result)
+ {
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ }
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ mx->recursive_count = 1;
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ if (PTHREAD_MUTEX_RECURSIVE == kind)
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ return EDEADLK;
+ }
+ }
+ else
+ {
+ while (0 == (result = ptw32_robust_mutex_inherit(mutex))
+ && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ }
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ /* Unblock the next thread */
+ SetEvent(mx->event);
+ result = ENOTRECOVERABLE;
+ }
+ else if (0 == result || EOWNERDEAD == result)
+ {
+ mx->recursive_count = 1;
+ /*
+ * Add mutex to the per-thread robust mutex currently-held list.
+ * If the thread terminates, all mutexes in this list will be unlocked.
+ */
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_mutex_trylock.c b/libs/pthreads/src/pthread_mutex_trylock.c
new file mode 100644
index 0000000000..5728728b62
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_trylock.c
@@ -0,0 +1,158 @@
+/*
+ * pthread_mutex_trylock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_trylock (pthread_mutex_t * mutex)
+{
+ pthread_mutex_t mx;
+ int kind;
+ int result = 0;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static mutex. We check
+ * again inside the guarded section of ptw32_mutex_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ mx = *mutex;
+ if (mx == NULL) {
+ return EINVAL;
+ }
+
+ kind = mx->kind;
+
+ if (kind >= 0)
+ {
+ /* Non-robust */
+ if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ if (kind != PTHREAD_MUTEX_NORMAL)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = pthread_self ();
+ }
+ }
+ else
+ {
+ if (kind == PTHREAD_MUTEX_RECURSIVE &&
+ pthread_equal (mx->ownerThread, pthread_self ()))
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EBUSY;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Robust types
+ * All types record the current owner thread.
+ * The mutex is added to a per thread list when ownership is acquired.
+ */
+ pthread_t self;
+ ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ return ENOTRECOVERABLE;
+ }
+
+ self = pthread_self();
+ kind = -kind - 1; /* Convert to non-robust range */
+
+ if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ if (kind != PTHREAD_MUTEX_NORMAL)
+ {
+ mx->recursive_count = 1;
+ }
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ else
+ {
+ if (PTHREAD_MUTEX_RECURSIVE == kind &&
+ pthread_equal (mx->ownerThread, pthread_self ()))
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex)))
+ {
+ mx->recursive_count = 1;
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ else
+ {
+ if (0 == result)
+ {
+ result = EBUSY;
+ }
+ }
+ }
+ }
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_mutex_unlock.c b/libs/pthreads/src/pthread_mutex_unlock.c
new file mode 100644
index 0000000000..77175bb5da
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutex_unlock.c
@@ -0,0 +1,178 @@
+/*
+ * pthread_mutex_unlock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_unlock (pthread_mutex_t * mutex)
+{
+ int result = 0;
+ int kind;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ mx = *mutex;
+ if (mx == NULL) {
+ return EINVAL;
+ }
+
+ /*
+ * If the thread calling us holds the mutex then there is no
+ * race condition. If another thread holds the
+ * lock then we shouldn't be in here.
+ */
+ if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ kind = mx->kind;
+
+ if (kind >= 0)
+ {
+ if (kind == PTHREAD_MUTEX_NORMAL)
+ {
+ LONG idx;
+
+ idx = (LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG)0);
+ if (idx != 0)
+ {
+ if (idx < 0)
+ {
+ /*
+ * Someone may be waiting on that mutex.
+ */
+ if (SetEvent (mx->event) == 0)
+ {
+ result = EINVAL;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, pthread_self()))
+ {
+ if (kind != PTHREAD_MUTEX_RECURSIVE
+ || 0 == --mx->recursive_count)
+ {
+ mx->ownerThread.p = NULL;
+
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG)0) < 0L)
+ {
+ /* Someone may be waiting on that mutex */
+ if (SetEvent (mx->event) == 0)
+ {
+ result = EINVAL;
+ }
+ }
+ }
+ }
+ else
+ {
+ result = EPERM;
+ }
+ }
+ }
+ else
+ {
+ /* Robust types */
+ pthread_t self = pthread_self();
+ kind = -kind - 1; /* Convert to non-robust range */
+
+ /*
+ * The thread must own the lock regardless of type if the mutex
+ * is robust.
+ */
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->robustNode->stateInconsistent,
+ (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE,
+ (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT);
+ if (PTHREAD_MUTEX_NORMAL == kind)
+ {
+ ptw32_robust_mutex_remove(mutex, NULL);
+
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 0) < 0)
+ {
+ /*
+ * Someone may be waiting on that mutex.
+ */
+ if (SetEvent (mx->event) == 0)
+ {
+ result = EINVAL;
+ }
+ }
+ }
+ else
+ {
+ if (kind != PTHREAD_MUTEX_RECURSIVE
+ || 0 == --mx->recursive_count)
+ {
+ ptw32_robust_mutex_remove(mutex, NULL);
+
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 0) < 0)
+ {
+ /*
+ * Someone may be waiting on that mutex.
+ */
+ if (SetEvent (mx->event) == 0)
+ {
+ result = EINVAL;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ result = EPERM;
+ }
+ }
+ }
+ else if (mx != PTHREAD_MUTEX_INITIALIZER)
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_mutexattr_destroy.c b/libs/pthreads/src/pthread_mutexattr_destroy.c
new file mode 100644
index 0000000000..9d424bfa28
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_destroy.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_mutexattr_destroy.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_destroy (pthread_mutexattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a mutex attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a mutex attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect mutexes created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_mutexattr_t ma = *attr;
+
+ *attr = NULL;
+ free (ma);
+ }
+
+ return (result);
+} /* pthread_mutexattr_destroy */
diff --git a/libs/pthreads/src/pthread_mutexattr_getkind_np.c b/libs/pthreads/src/pthread_mutexattr_getkind_np.c
new file mode 100644
index 0000000000..2d82ec6bc7
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_getkind_np.c
@@ -0,0 +1,44 @@
+/*
+ * pthread_mutexattr_getkind_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_mutexattr_getkind_np (pthread_mutexattr_t * attr, int *kind)
+{
+ return pthread_mutexattr_gettype (attr, kind);
+}
diff --git a/libs/pthreads/src/pthread_mutexattr_getpshared.c b/libs/pthreads/src/pthread_mutexattr_getpshared.c
new file mode 100644
index 0000000000..42f9589c51
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_getpshared.c
@@ -0,0 +1,95 @@
+/*
+ * pthread_mutexattr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr, int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether mutexes created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_mutexattr_getpshared */
diff --git a/libs/pthreads/src/pthread_mutexattr_getrobust.c b/libs/pthreads/src/pthread_mutexattr_getrobust.c
new file mode 100644
index 0000000000..be004837bc
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_getrobust.c
@@ -0,0 +1,113 @@
+/*
+ * pthread_mutexattr_getrobust.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_getrobust (const pthread_mutexattr_t * attr, int * robust)
+ /*
+ * ------------------------------------------------------
+ *
+ * DOCPUBLIC
+ * The pthread_mutexattr_setrobust() and
+ * pthread_mutexattr_getrobust() functions respectively set and
+ * get the mutex robust attribute. This attribute is set in the
+ * robust parameter to these functions.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * robust
+ * must be one of:
+ *
+ * PTHREAD_MUTEX_STALLED
+ *
+ * PTHREAD_MUTEX_ROBUST
+ *
+ * DESCRIPTION
+ * The pthread_mutexattr_setrobust() and
+ * pthread_mutexattr_getrobust() functions respectively set and
+ * get the mutex robust attribute. This attribute is set in the
+ * robust parameter to these functions. The default value of the
+ * robust attribute is PTHREAD_MUTEX_STALLED.
+ *
+ * The robustness of mutex is contained in the robustness attribute
+ * of the mutex attributes. Valid mutex robustness values are:
+ *
+ * PTHREAD_MUTEX_STALLED
+ * No special actions are taken if the owner of the mutex is
+ * terminated while holding the mutex lock. This can lead to
+ * deadlocks if no other thread can unlock the mutex.
+ * This is the default value.
+ *
+ * PTHREAD_MUTEX_ROBUST
+ * If the process containing the owning thread of a robust mutex
+ * terminates while holding the mutex lock, the next thread that
+ * acquires the mutex shall be notified about the termination by
+ * the return value [EOWNERDEAD] from the locking function. If the
+ * owning thread of a robust mutex terminates while holding the mutex
+ * lock, the next thread that acquires the mutex may be notified
+ * about the termination by the return value [EOWNERDEAD]. The
+ * notified thread can then attempt to mark the state protected by
+ * the mutex as consistent again by a call to
+ * pthread_mutex_consistent(). After a subsequent successful call to
+ * pthread_mutex_unlock(), the mutex lock shall be released and can
+ * be used normally by other threads. If the mutex is unlocked without
+ * a call to pthread_mutex_consistent(), it shall be in a permanently
+ * unusable state and all attempts to lock the mutex shall fail with
+ * the error [ENOTRECOVERABLE]. The only permissible operation on such
+ * a mutex is pthread_mutex_destroy().
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or 'robust' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = EINVAL;
+
+ if ((attr != NULL && *attr != NULL && robust != NULL))
+ {
+ *robust = (*attr)->robustness;
+ result = 0;
+ }
+
+ return (result);
+} /* pthread_mutexattr_getrobust */
diff --git a/libs/pthreads/src/pthread_mutexattr_gettype.c b/libs/pthreads/src/pthread_mutexattr_gettype.c
new file mode 100644
index 0000000000..c63fcfa03a
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_gettype.c
@@ -0,0 +1,56 @@
+/*
+ * pthread_mutexattr_gettype.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind)
+{
+ int result = 0;
+
+ if (attr != NULL && *attr != NULL && kind != NULL)
+ {
+ *kind = (*attr)->kind;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_mutexattr_init.c b/libs/pthreads/src/pthread_mutexattr_init.c
new file mode 100644
index 0000000000..d2797ff248
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_init.c
@@ -0,0 +1,86 @@
+/*
+ * pthread_mutexattr_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_init (pthread_mutexattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a mutex attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a mutex attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define mutex types
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_mutexattr_t ma;
+
+ ma = (pthread_mutexattr_t) calloc (1, sizeof (*ma));
+
+ if (ma == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ ma->pshared = PTHREAD_PROCESS_PRIVATE;
+ ma->kind = PTHREAD_MUTEX_DEFAULT;
+ }
+
+ *attr = ma;
+
+ return (result);
+} /* pthread_mutexattr_init */
diff --git a/libs/pthreads/src/pthread_mutexattr_setkind_np.c b/libs/pthreads/src/pthread_mutexattr_setkind_np.c
new file mode 100644
index 0000000000..faa936658f
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_setkind_np.c
@@ -0,0 +1,44 @@
+/*
+ * pthread_mutexattr_setkind_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr, int kind)
+{
+ return pthread_mutexattr_settype (attr, kind);
+}
diff --git a/libs/pthreads/src/pthread_mutexattr_setpshared.c b/libs/pthreads/src/pthread_mutexattr_setpshared.c
new file mode 100644
index 0000000000..cfa6f71994
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_setpshared.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_mutexattr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Mutexes created with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_mutexattr_setpshared */
diff --git a/libs/pthreads/src/pthread_mutexattr_setrobust.c b/libs/pthreads/src/pthread_mutexattr_setrobust.c
new file mode 100644
index 0000000000..b1acef7572
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_setrobust.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_mutexattr_setrobust.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_setrobust (pthread_mutexattr_t * attr, int robust)
+ /*
+ * ------------------------------------------------------
+ *
+ * DOCPUBLIC
+ * The pthread_mutexattr_setrobust() and
+ * pthread_mutexattr_getrobust() functions respectively set and
+ * get the mutex robust attribute. This attribute is set in the
+ * robust parameter to these functions.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * robust
+ * must be one of:
+ *
+ * PTHREAD_MUTEX_STALLED
+ *
+ * PTHREAD_MUTEX_ROBUST
+ *
+ * DESCRIPTION
+ * The pthread_mutexattr_setrobust() and
+ * pthread_mutexattr_getrobust() functions respectively set and
+ * get the mutex robust attribute. This attribute is set in the
+ * robust parameter to these functions. The default value of the
+ * robust attribute is PTHREAD_MUTEX_STALLED.
+ *
+ * The robustness of mutex is contained in the robustness attribute
+ * of the mutex attributes. Valid mutex robustness values are:
+ *
+ * PTHREAD_MUTEX_STALLED
+ * No special actions are taken if the owner of the mutex is
+ * terminated while holding the mutex lock. This can lead to
+ * deadlocks if no other thread can unlock the mutex.
+ * This is the default value.
+ *
+ * PTHREAD_MUTEX_ROBUST
+ * If the process containing the owning thread of a robust mutex
+ * terminates while holding the mutex lock, the next thread that
+ * acquires the mutex shall be notified about the termination by
+ * the return value [EOWNERDEAD] from the locking function. If the
+ * owning thread of a robust mutex terminates while holding the mutex
+ * lock, the next thread that acquires the mutex may be notified
+ * about the termination by the return value [EOWNERDEAD]. The
+ * notified thread can then attempt to mark the state protected by
+ * the mutex as consistent again by a call to
+ * pthread_mutex_consistent(). After a subsequent successful call to
+ * pthread_mutex_unlock(), the mutex lock shall be released and can
+ * be used normally by other threads. If the mutex is unlocked without
+ * a call to pthread_mutex_consistent(), it shall be in a permanently
+ * unusable state and all attempts to lock the mutex shall fail with
+ * the error [ENOTRECOVERABLE]. The only permissible operation on such
+ * a mutex is pthread_mutex_destroy().
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or 'robust' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = EINVAL;
+
+ if ((attr != NULL && *attr != NULL))
+ {
+ switch (robust)
+ {
+ case PTHREAD_MUTEX_STALLED:
+ case PTHREAD_MUTEX_ROBUST:
+ (*attr)->robustness = robust;
+ result = 0;
+ break;
+ }
+ }
+
+ return (result);
+} /* pthread_mutexattr_setrobust */
diff --git a/libs/pthreads/src/pthread_mutexattr_settype.c b/libs/pthreads/src/pthread_mutexattr_settype.c
new file mode 100644
index 0000000000..8365daf65d
--- /dev/null
+++ b/libs/pthreads/src/pthread_mutexattr_settype.c
@@ -0,0 +1,143 @@
+/*
+ * pthread_mutexattr_settype.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind)
+ /*
+ * ------------------------------------------------------
+ *
+ * DOCPUBLIC
+ * The pthread_mutexattr_settype() and
+ * pthread_mutexattr_gettype() functions respectively set and
+ * get the mutex type attribute. This attribute is set in the
+ * type parameter to these functions.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * type
+ * must be one of:
+ *
+ * PTHREAD_MUTEX_DEFAULT
+ *
+ * PTHREAD_MUTEX_NORMAL
+ *
+ * PTHREAD_MUTEX_ERRORCHECK
+ *
+ * PTHREAD_MUTEX_RECURSIVE
+ *
+ * DESCRIPTION
+ * The pthread_mutexattr_settype() and
+ * pthread_mutexattr_gettype() functions respectively set and
+ * get the mutex type attribute. This attribute is set in the
+ * type parameter to these functions. The default value of the
+ * type attribute is PTHREAD_MUTEX_DEFAULT.
+ *
+ * The type of mutex is contained in the type attribute of the
+ * mutex attributes. Valid mutex types include:
+ *
+ * PTHREAD_MUTEX_NORMAL
+ * This type of mutex does not detect deadlock. A
+ * thread attempting to relock this mutex without
+ * first unlocking it will deadlock. Attempting to
+ * unlock a mutex locked by a different thread
+ * results in undefined behavior. Attempting to
+ * unlock an unlocked mutex results in undefined
+ * behavior.
+ *
+ * PTHREAD_MUTEX_ERRORCHECK
+ * This type of mutex provides error checking. A
+ * thread attempting to relock this mutex without
+ * first unlocking it will return with an error. A
+ * thread attempting to unlock a mutex which another
+ * thread has locked will return with an error. A
+ * thread attempting to unlock an unlocked mutex will
+ * return with an error.
+ *
+ * PTHREAD_MUTEX_DEFAULT
+ * Same as PTHREAD_MUTEX_NORMAL.
+ *
+ * PTHREAD_MUTEX_RECURSIVE
+ * A thread attempting to relock this mutex without
+ * first unlocking it will succeed in locking the
+ * mutex. The relocking deadlock which can occur with
+ * mutexes of type PTHREAD_MUTEX_NORMAL cannot occur
+ * with this type of mutex. Multiple locks of this
+ * mutex require the same number of unlocks to
+ * release the mutex before another thread can
+ * acquire the mutex. A thread attempting to unlock a
+ * mutex which another thread has locked will return
+ * with an error. A thread attempting to unlock an
+ * unlocked mutex will return with an error. This
+ * type of mutex is only supported for mutexes whose
+ * process shared attribute is
+ * PTHREAD_PROCESS_PRIVATE.
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or 'type' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if ((attr != NULL && *attr != NULL))
+ {
+ switch (kind)
+ {
+ case PTHREAD_MUTEX_FAST_NP:
+ case PTHREAD_MUTEX_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ERRORCHECK_NP:
+ (*attr)->kind = kind;
+ break;
+ default:
+ result = EINVAL;
+ break;
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+} /* pthread_mutexattr_settype */
diff --git a/libs/pthreads/src/pthread_num_processors_np.c b/libs/pthreads/src/pthread_num_processors_np.c
new file mode 100644
index 0000000000..3067d117d3
--- /dev/null
+++ b/libs/pthreads/src/pthread_num_processors_np.c
@@ -0,0 +1,56 @@
+/*
+ * pthread_num_processors_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * pthread_num_processors_np()
+ *
+ * Get the number of CPUs available to the process.
+ */
+int
+pthread_num_processors_np (void)
+{
+ int count;
+
+ if (ptw32_getprocessors (&count) != 0)
+ {
+ count = 1;
+ }
+
+ return (count);
+}
diff --git a/libs/pthreads/src/pthread_once.c b/libs/pthreads/src/pthread_once.c
new file mode 100644
index 0000000000..3bfeb9f0bf
--- /dev/null
+++ b/libs/pthreads/src/pthread_once.c
@@ -0,0 +1,79 @@
+/*
+ * pthread_once.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_once (pthread_once_t * once_control, void (PTW32_CDECL *init_routine) (void))
+{
+ if (once_control == NULL || init_routine == NULL)
+ {
+ return EINVAL;
+ }
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_FALSE ==
+ (PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_EXCHANGE_ADD_LONG((PTW32_INTERLOCKED_LONGPTR)&once_control->done,
+ (PTW32_INTERLOCKED_LONG)0)) /* MBR fence */
+ {
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&once_control->lock, &node);
+
+ if (!once_control->done)
+ {
+
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+
+ pthread_cleanup_push(ptw32_mcs_lock_release, &node);
+ (*init_routine)();
+ pthread_cleanup_pop(0);
+
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+
+ once_control->done = PTW32_TRUE;
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+
+ return 0;
+
+} /* pthread_once */
diff --git a/libs/pthreads/src/pthread_rwlock_destroy.c b/libs/pthreads/src/pthread_rwlock_destroy.c
new file mode 100644
index 0000000000..245a892410
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_destroy.c
@@ -0,0 +1,143 @@
+/*
+ * pthread_rwlock_destroy.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_destroy (pthread_rwlock_t * rwlock)
+{
+ pthread_rwlock_t rwl;
+ int result = 0, result1 = 0, result2 = 0;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*rwlock != PTHREAD_RWLOCK_INITIALIZER)
+ {
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ /*
+ * Check whether any threads own/wait for the lock (wait for ex.access);
+ * report "BUSY" if so.
+ */
+ if (rwl->nExclusiveAccessCount > 0
+ || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount)
+ {
+ result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ result2 = EBUSY;
+ }
+ else
+ {
+ rwl->nMagic = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ pthread_mutex_unlock (&rwl->mtxExclusiveAccess);
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ *rwlock = NULL; /* Invalidate rwlock before anything else */
+ result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted));
+ result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
+ result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
+ (void) free (rwl);
+ }
+ }
+ else
+ {
+ ptw32_mcs_local_node_t node;
+ /*
+ * See notes in ptw32_rwlock_check_need_init() above also.
+ */
+ ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
+
+ /*
+ * Check again.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised rwlock that has not yet been used (initialised).
+ * If we get to here, another thread
+ * waiting to initialise this rwlock will get an EINVAL.
+ */
+ *rwlock = NULL;
+ }
+ else
+ {
+ /*
+ * The rwlock has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+
+ return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
+}
diff --git a/libs/pthreads/src/pthread_rwlock_init.c b/libs/pthreads/src/pthread_rwlock_init.c
new file mode 100644
index 0000000000..597c1ff266
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_init.c
@@ -0,0 +1,109 @@
+/*
+ * pthread_rwlock_init.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_init (pthread_rwlock_t * rwlock,
+ const pthread_rwlockattr_t * attr)
+{
+ int result;
+ pthread_rwlock_t rwl = 0;
+
+ if (rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (attr != NULL && *attr != NULL)
+ {
+ result = EINVAL; /* Not supported */
+ goto DONE;
+ }
+
+ rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl));
+
+ if (rwl == NULL)
+ {
+ result = ENOMEM;
+ goto DONE;
+ }
+
+ rwl->nSharedAccessCount = 0;
+ rwl->nExclusiveAccessCount = 0;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL);
+ if (result != 0)
+ {
+ goto FAIL0;
+ }
+
+ result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL);
+ if (result != 0)
+ {
+ goto FAIL1;
+ }
+
+ result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL);
+ if (result != 0)
+ {
+ goto FAIL2;
+ }
+
+ rwl->nMagic = PTW32_RWLOCK_MAGIC;
+
+ result = 0;
+ goto DONE;
+
+FAIL2:
+ (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
+
+FAIL1:
+ (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
+
+FAIL0:
+ (void) free (rwl);
+ rwl = NULL;
+
+DONE:
+ *rwlock = rwl;
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_rwlock_rdlock.c b/libs/pthreads/src/pthread_rwlock_rdlock.c
new file mode 100644
index 0000000000..91e180835e
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_rdlock.c
@@ -0,0 +1,102 @@
+/*
+ * pthread_rwlock_rdlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_rdlock (pthread_rwlock_t * rwlock)
+{
+ int result;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
+}
diff --git a/libs/pthreads/src/pthread_rwlock_timedrdlock.c b/libs/pthreads/src/pthread_rwlock_timedrdlock.c
new file mode 100644
index 0000000000..7133778bf1
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_timedrdlock.c
@@ -0,0 +1,109 @@
+/*
+ * pthread_rwlock_timedrdlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock,
+ const struct timespec *abstime)
+{
+ int result;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result =
+ pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted),
+ abstime)) != 0)
+ {
+ if (result == ETIMEDOUT)
+ {
+ ++rwl->nCompletedSharedAccessCount;
+ }
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
+}
diff --git a/libs/pthreads/src/pthread_rwlock_timedwrlock.c b/libs/pthreads/src/pthread_rwlock_timedwrlock.c
new file mode 100644
index 0000000000..8c111bbb1b
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_timedwrlock.c
@@ -0,0 +1,139 @@
+/*
+ * pthread_rwlock_timedwrlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock,
+ const struct timespec *abstime)
+{
+ int result;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result =
+ pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0)
+ {
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted),
+ abstime)) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if (rwl->nCompletedSharedAccessCount > 0)
+ {
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+ }
+
+ if (rwl->nSharedAccessCount > 0)
+ {
+ rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount;
+
+ /*
+ * This routine may be a cancelation point
+ * according to POSIX 1003.1j section 18.1.2.
+ */
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl);
+
+ do
+ {
+ result =
+ pthread_cond_timedwait (&(rwl->cndSharedAccessCompleted),
+ &(rwl->mtxSharedAccessCompleted),
+ abstime);
+ }
+ while (result == 0 && rwl->nCompletedSharedAccessCount < 0);
+
+ pthread_cleanup_pop ((result != 0) ? 1 : 0);
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+
+ if (result == 0)
+ {
+ rwl->nSharedAccessCount = 0;
+ }
+ }
+ }
+
+ if (result == 0)
+ {
+ rwl->nExclusiveAccessCount++;
+ }
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_rwlock_tryrdlock.c b/libs/pthreads/src/pthread_rwlock_tryrdlock.c
new file mode 100644
index 0000000000..0fc5458579
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_tryrdlock.c
@@ -0,0 +1,102 @@
+/*
+ * pthread_rwlock_tryrdlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_tryrdlock (pthread_rwlock_t * rwlock)
+{
+ int result;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&rwl->mtxExclusiveAccess));
+}
diff --git a/libs/pthreads/src/pthread_rwlock_trywrlock.c b/libs/pthreads/src/pthread_rwlock_trywrlock.c
new file mode 100644
index 0000000000..9997c5d7fb
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_trywrlock.c
@@ -0,0 +1,122 @@
+/*
+ * pthread_rwlock_trywrlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock)
+{
+ int result, result1;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result = pthread_mutex_trylock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_trylock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return ((result1 != 0) ? result1 : result);
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if (rwl->nCompletedSharedAccessCount > 0)
+ {
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+ }
+
+ if (rwl->nSharedAccessCount > 0)
+ {
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) == 0)
+ {
+ result = EBUSY;
+ }
+ }
+ else
+ {
+ rwl->nExclusiveAccessCount = 1;
+ }
+ }
+ else
+ {
+ result = EBUSY;
+ }
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_rwlock_unlock.c b/libs/pthreads/src/pthread_rwlock_unlock.c
new file mode 100644
index 0000000000..d48d18705b
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_unlock.c
@@ -0,0 +1,93 @@
+/*
+ * pthread_rwlock_unlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t * rwlock)
+{
+ int result, result1;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return (EINVAL);
+ }
+
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ /*
+ * Assume any race condition here is harmless.
+ */
+ return 0;
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nCompletedSharedAccessCount == 0)
+ {
+ result = pthread_cond_signal (&(rwl->cndSharedAccessCompleted));
+ }
+
+ result1 = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ }
+ else
+ {
+ rwl->nExclusiveAccessCount--;
+
+ result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+
+ }
+
+ return ((result != 0) ? result : result1);
+}
diff --git a/libs/pthreads/src/pthread_rwlock_wrlock.c b/libs/pthreads/src/pthread_rwlock_wrlock.c
new file mode 100644
index 0000000000..e8b4fbb303
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlock_wrlock.c
@@ -0,0 +1,133 @@
+/*
+ * pthread_rwlock_wrlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_wrlock (pthread_rwlock_t * rwlock)
+{
+ int result;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static rwlock. We check
+ * again inside the guarded section of ptw32_rwlock_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = ptw32_rwlock_check_need_init (rwlock);
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if ((result = pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if (rwl->nCompletedSharedAccessCount > 0)
+ {
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+ }
+
+ if (rwl->nSharedAccessCount > 0)
+ {
+ rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount;
+
+ /*
+ * This routine may be a cancelation point
+ * according to POSIX 1003.1j section 18.1.2.
+ */
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl);
+
+ do
+ {
+ result = pthread_cond_wait (&(rwl->cndSharedAccessCompleted),
+ &(rwl->mtxSharedAccessCompleted));
+ }
+ while (result == 0 && rwl->nCompletedSharedAccessCount < 0);
+
+ pthread_cleanup_pop ((result != 0) ? 1 : 0);
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+
+ if (result == 0)
+ {
+ rwl->nSharedAccessCount = 0;
+ }
+ }
+ }
+
+ if (result == 0)
+ {
+ rwl->nExclusiveAccessCount++;
+ }
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_rwlockattr_destroy.c b/libs/pthreads/src/pthread_rwlockattr_destroy.c
new file mode 100644
index 0000000000..868e727d30
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlockattr_destroy.c
@@ -0,0 +1,84 @@
+/*
+ * pthread_rwlockattr_destroy.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a rwlock attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a rwlock attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect rwlockss created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_rwlockattr_t rwa = *attr;
+
+ *attr = NULL;
+ free (rwa);
+ }
+
+ return (result);
+} /* pthread_rwlockattr_destroy */
diff --git a/libs/pthreads/src/pthread_rwlockattr_getpshared.c b/libs/pthreads/src/pthread_rwlockattr_getpshared.c
new file mode 100644
index 0000000000..eeace207f2
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlockattr_getpshared.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_rwlockattr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether rwlocks created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Rwlocks creatd with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared rwlocks MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared rwlocks
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_rwlockattr_getpshared */
diff --git a/libs/pthreads/src/pthread_rwlockattr_init.c b/libs/pthreads/src/pthread_rwlockattr_init.c
new file mode 100644
index 0000000000..a2d2b945f4
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlockattr_init.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_rwlockattr_init.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a rwlock attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a rwlock attributes object with default
+ * attributes.
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_rwlockattr_t rwa;
+
+ rwa = (pthread_rwlockattr_t) calloc (1, sizeof (*rwa));
+
+ if (rwa == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ rwa->pshared = PTHREAD_PROCESS_PRIVATE;
+ }
+
+ *attr = rwa;
+
+ return (result);
+} /* pthread_rwlockattr_init */
diff --git a/libs/pthreads/src/pthread_rwlockattr_setpshared.c b/libs/pthreads/src/pthread_rwlockattr_setpshared.c
new file mode 100644
index 0000000000..a83dd70a4b
--- /dev/null
+++ b/libs/pthreads/src/pthread_rwlockattr_setpshared.c
@@ -0,0 +1,120 @@
+/*
+ * pthread_rwlockattr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Rwlocks created with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Rwlocks creatd with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared rwlocks MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared rwlocks
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_rwlockattr_setpshared */
diff --git a/libs/pthreads/src/pthread_self.c b/libs/pthreads/src/pthread_self.c
new file mode 100644
index 0000000000..9a1765f82e
--- /dev/null
+++ b/libs/pthreads/src/pthread_self.c
@@ -0,0 +1,141 @@
+/*
+ * pthread_self.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+pthread_t
+pthread_self (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns a reference to the current running
+ * thread.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ *
+ * DESCRIPTION
+ * This function returns a reference to the current running
+ * thread.
+ *
+ * RESULTS
+ * pthread_t reference to the current thread
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_t self;
+ pthread_t nil = {NULL, 0};
+ ptw32_thread_t * sp;
+
+#if defined(_UWIN)
+ if (!ptw32_selfThreadKey)
+ return nil;
+#endif
+
+ sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+ if (sp != NULL)
+ {
+ self = sp->ptHandle;
+ }
+ else
+ {
+ /*
+ * Need to create an implicit 'self' for the currently
+ * executing thread.
+ */
+ self = ptw32_new ();
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp != NULL)
+ {
+ /*
+ * This is a non-POSIX thread which has chosen to call
+ * a POSIX threads function for some reason. We assume that
+ * it isn't joinable, but we do assume that it's
+ * (deferred) cancelable.
+ */
+ sp->implicit = 1;
+ sp->detachState = PTHREAD_CREATE_DETACHED;
+ sp->thread = GetCurrentThreadId ();
+
+#if defined(NEED_DUPLICATEHANDLE)
+ /*
+ * DuplicateHandle does not exist on WinCE.
+ *
+ * NOTE:
+ * GetCurrentThread only returns a pseudo-handle
+ * which is only valid in the current thread context.
+ * Therefore, you should not pass the handle to
+ * other threads for whatever purpose.
+ */
+ sp->threadH = GetCurrentThread ();
+#else
+ if (!DuplicateHandle (GetCurrentProcess (),
+ GetCurrentThread (),
+ GetCurrentProcess (),
+ &sp->threadH,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ /*
+ * Should not do this, but we have no alternative if
+ * we can't get a Win32 thread handle.
+ * Thread structs are never freed.
+ */
+ ptw32_threadReusePush (self);
+ /*
+ * As this is a win32 thread calling us and we have failed,
+ * return a value that makes sense to win32.
+ */
+ return nil;
+ }
+#endif
+
+ /*
+ * No need to explicitly serialise access to sched_priority
+ * because the new handle is not yet public.
+ */
+ sp->sched_priority = GetThreadPriority (sp->threadH);
+ pthread_setspecific (ptw32_selfThreadKey, (void *) sp);
+ }
+ }
+
+ return (self);
+
+} /* pthread_self */
diff --git a/libs/pthreads/src/pthread_setcancelstate.c b/libs/pthreads/src/pthread_setcancelstate.c
new file mode 100644
index 0000000000..bbcd624af8
--- /dev/null
+++ b/libs/pthreads/src/pthread_setcancelstate.c
@@ -0,0 +1,125 @@
+/*
+ * pthread_setcancelstate.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_setcancelstate (int state, int *oldstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function atomically sets the calling thread's
+ * cancelability state to 'state' and returns the previous
+ * cancelability state at the location referenced by
+ * 'oldstate'
+ *
+ * PARAMETERS
+ * state,
+ * oldstate
+ * PTHREAD_CANCEL_ENABLE
+ * cancellation is enabled,
+ *
+ * PTHREAD_CANCEL_DISABLE
+ * cancellation is disabled
+ *
+ *
+ * DESCRIPTION
+ * This function atomically sets the calling thread's
+ * cancelability state to 'state' and returns the previous
+ * cancelability state at the location referenced by
+ * 'oldstate'.
+ *
+ * NOTES:
+ * 1) Use to disable cancellation around 'atomic' code that
+ * includes cancellation points
+ *
+ * COMPATIBILITY ADDITIONS
+ * If 'oldstate' is NULL then the previous state is not returned
+ * but the function still succeeds. (Solaris)
+ *
+ * RESULTS
+ * 0 successfully set cancelability type,
+ * EINVAL 'state' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_mcs_local_node_t stateLock;
+ int result = 0;
+ pthread_t self = pthread_self ();
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+
+ if (sp == NULL
+ || (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE))
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Lock for async-cancel safety.
+ */
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+
+ if (oldstate != NULL)
+ {
+ *oldstate = sp->cancelState;
+ }
+
+ sp->cancelState = state;
+
+ /*
+ * Check if there is a pending asynchronous cancel
+ */
+ if (state == PTHREAD_CANCEL_ENABLE
+ && sp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
+ && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ResetEvent (sp->cancelEvent);
+ ptw32_mcs_lock_release (&stateLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+
+ return (result);
+
+} /* pthread_setcancelstate */
diff --git a/libs/pthreads/src/pthread_setcanceltype.c b/libs/pthreads/src/pthread_setcanceltype.c
new file mode 100644
index 0000000000..72b0af5bbc
--- /dev/null
+++ b/libs/pthreads/src/pthread_setcanceltype.c
@@ -0,0 +1,126 @@
+/*
+ * pthread_setcanceltype.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_setcanceltype (int type, int *oldtype)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function atomically sets the calling thread's
+ * cancelability type to 'type' and returns the previous
+ * cancelability type at the location referenced by
+ * 'oldtype'
+ *
+ * PARAMETERS
+ * type,
+ * oldtype
+ * PTHREAD_CANCEL_DEFERRED
+ * only deferred cancelation is allowed,
+ *
+ * PTHREAD_CANCEL_ASYNCHRONOUS
+ * Asynchronous cancellation is allowed
+ *
+ *
+ * DESCRIPTION
+ * This function atomically sets the calling thread's
+ * cancelability type to 'type' and returns the previous
+ * cancelability type at the location referenced by
+ * 'oldtype'
+ *
+ * NOTES:
+ * 1) Use with caution; most code is not safe for use
+ * with asynchronous cancelability.
+ *
+ * COMPATIBILITY ADDITIONS
+ * If 'oldtype' is NULL then the previous type is not returned
+ * but the function still succeeds. (Solaris)
+ *
+ * RESULTS
+ * 0 successfully set cancelability type,
+ * EINVAL 'type' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_mcs_local_node_t stateLock;
+ int result = 0;
+ pthread_t self = pthread_self ();
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+
+ if (sp == NULL
+ || (type != PTHREAD_CANCEL_DEFERRED
+ && type != PTHREAD_CANCEL_ASYNCHRONOUS))
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Lock for async-cancel safety.
+ */
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+
+ if (oldtype != NULL)
+ {
+ *oldtype = sp->cancelType;
+ }
+
+ sp->cancelType = type;
+
+ /*
+ * Check if there is a pending asynchronous cancel
+ */
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE
+ && type == PTHREAD_CANCEL_ASYNCHRONOUS
+ && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ResetEvent (sp->cancelEvent);
+ ptw32_mcs_lock_release (&stateLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+
+ return (result);
+
+} /* pthread_setcanceltype */
diff --git a/libs/pthreads/src/pthread_setconcurrency.c b/libs/pthreads/src/pthread_setconcurrency.c
new file mode 100644
index 0000000000..f62346f8e5
--- /dev/null
+++ b/libs/pthreads/src/pthread_setconcurrency.c
@@ -0,0 +1,53 @@
+/*
+ * pthread_setconcurrency.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_setconcurrency (int level)
+{
+ if (level < 0)
+ {
+ return EINVAL;
+ }
+ else
+ {
+ ptw32_concurrency = level;
+ return 0;
+ }
+}
diff --git a/libs/pthreads/src/pthread_setschedparam.c b/libs/pthreads/src/pthread_setschedparam.c
new file mode 100644
index 0000000000..b762753cdd
--- /dev/null
+++ b/libs/pthreads/src/pthread_setschedparam.c
@@ -0,0 +1,123 @@
+/*
+ * sched_setschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_setschedparam (pthread_t thread, int policy,
+ const struct sched_param *param)
+{
+ int result;
+
+ /* Validate the thread id. */
+ result = pthread_kill (thread, 0);
+ if (0 != result)
+ {
+ return result;
+ }
+
+ /* Validate the scheduling policy. */
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ return EINVAL;
+ }
+
+ /* Ensure the policy is SCHED_OTHER. */
+ if (policy != SCHED_OTHER)
+ {
+ return ENOTSUP;
+ }
+
+ return (ptw32_setthreadpriority (thread, policy, param->sched_priority));
+}
+
+
+int
+ptw32_setthreadpriority (pthread_t thread, int policy, int priority)
+{
+ int prio;
+ ptw32_mcs_local_node_t threadLock;
+ int result = 0;
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+
+ prio = priority;
+
+ /* Validate priority level. */
+ if (prio < sched_get_priority_min (policy) ||
+ prio > sched_get_priority_max (policy))
+ {
+ return EINVAL;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+/* WinCE */
+#else
+/* Everything else */
+
+ if (THREAD_PRIORITY_IDLE < prio && THREAD_PRIORITY_LOWEST > prio)
+ {
+ prio = THREAD_PRIORITY_LOWEST;
+ }
+ else if (THREAD_PRIORITY_TIME_CRITICAL > prio
+ && THREAD_PRIORITY_HIGHEST < prio)
+ {
+ prio = THREAD_PRIORITY_HIGHEST;
+ }
+
+#endif
+
+ ptw32_mcs_lock_acquire (&tp->threadLock, &threadLock);
+
+ /* If this fails, the current priority is unchanged. */
+ if (0 == SetThreadPriority (tp->threadH, prio))
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ /*
+ * Must record the thread's sched_priority as given,
+ * not as finally adjusted.
+ */
+ tp->sched_priority = priority;
+ }
+
+ ptw32_mcs_lock_release (&threadLock);
+
+ return result;
+}
diff --git a/libs/pthreads/src/pthread_setspecific.c b/libs/pthreads/src/pthread_setspecific.c
new file mode 100644
index 0000000000..0f29e704ab
--- /dev/null
+++ b/libs/pthreads/src/pthread_setspecific.c
@@ -0,0 +1,167 @@
+/*
+ * pthread_setspecific.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_setspecific (pthread_key_t key, const void *value)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function sets the value of the thread specific
+ * key in the calling thread.
+ *
+ * PARAMETERS
+ * key
+ * an instance of pthread_key_t
+ * value
+ * the value to set key to
+ *
+ *
+ * DESCRIPTION
+ * This function sets the value of the thread specific
+ * key in the calling thread.
+ *
+ * RESULTS
+ * 0 successfully set value
+ * EAGAIN could not set value
+ * ENOENT SERIOUS!!
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_t self;
+ int result = 0;
+
+ if (key != ptw32_selfThreadKey)
+ {
+ /*
+ * Using pthread_self will implicitly create
+ * an instance of pthread_t for the current
+ * thread if one wasn't explicitly created
+ */
+ self = pthread_self ();
+ if (self.p == NULL)
+ {
+ return ENOENT;
+ }
+ }
+ else
+ {
+ /*
+ * Resolve catch-22 of registering thread with selfThread
+ * key
+ */
+ ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+ if (sp == NULL)
+ {
+ if (value == NULL)
+ {
+ return ENOENT;
+ }
+ self = *((pthread_t *) value);
+ }
+ else
+ {
+ self = sp->ptHandle;
+ }
+ }
+
+ result = 0;
+
+ if (key != NULL)
+ {
+ if (self.p != NULL && key->destructor != NULL && value != NULL)
+ {
+ ptw32_mcs_local_node_t keyLock;
+ ptw32_mcs_local_node_t threadLock;
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+ /*
+ * Only require associations if we have to
+ * call user destroy routine.
+ * Don't need to locate an existing association
+ * when setting data to NULL for WIN32 since the
+ * data is stored with the operating system; not
+ * on the association; setting assoc to NULL short
+ * circuits the search.
+ */
+ ThreadKeyAssoc *assoc;
+
+ ptw32_mcs_lock_acquire(&(key->keyLock), &keyLock);
+ ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
+
+ assoc = (ThreadKeyAssoc *) sp->keys;
+ /*
+ * Locate existing association
+ */
+ while (assoc != NULL)
+ {
+ if (assoc->key == key)
+ {
+ /*
+ * Association already exists
+ */
+ break;
+ }
+ assoc = assoc->nextKey;
+ }
+
+ /*
+ * create an association if not found
+ */
+ if (assoc == NULL)
+ {
+ result = ptw32_tkAssocCreate (sp, key);
+ }
+
+ ptw32_mcs_lock_release(&threadLock);
+ ptw32_mcs_lock_release(&keyLock);
+ }
+
+ if (result == 0)
+ {
+ if (!TlsSetValue (key->key, (LPVOID) value))
+ {
+ result = EAGAIN;
+ }
+ }
+ }
+
+ return (result);
+} /* pthread_setspecific */
diff --git a/libs/pthreads/src/pthread_spin_destroy.c b/libs/pthreads/src/pthread_spin_destroy.c
new file mode 100644
index 0000000000..786c4e34cd
--- /dev/null
+++ b/libs/pthreads/src/pthread_spin_destroy.c
@@ -0,0 +1,111 @@
+/*
+ * pthread_spin_destroy.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_destroy (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+ int result = 0;
+
+ if (lock == NULL || *lock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ if (s->interlock == PTW32_SPIN_USE_MUTEX)
+ {
+ result = pthread_mutex_destroy (&(s->u.mutex));
+ }
+ else if ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED !=
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_INVALID,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
+ {
+ result = EINVAL;
+ }
+
+ if (0 == result)
+ {
+ /*
+ * We are relying on the application to ensure that all other threads
+ * have finished with the spinlock before destroying it.
+ */
+ *lock = NULL;
+ (void) free (s);
+ }
+ }
+ else
+ {
+ /*
+ * See notes in ptw32_spinlock_check_need_init() above also.
+ */
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
+
+ /*
+ * Check again.
+ */
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised spinlock that has not yet been used (initialised).
+ * If we get to here, another thread
+ * waiting to initialise this mutex will get an EINVAL.
+ */
+ *lock = NULL;
+ }
+ else
+ {
+ /*
+ * The spinlock has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+
+ ptw32_mcs_lock_release(&node);
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_spin_init.c b/libs/pthreads/src/pthread_spin_init.c
new file mode 100644
index 0000000000..553af7eac8
--- /dev/null
+++ b/libs/pthreads/src/pthread_spin_init.c
@@ -0,0 +1,123 @@
+/*
+ * pthread_spin_init.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_init (pthread_spinlock_t * lock, int pshared)
+{
+ pthread_spinlock_t s;
+ int cpus = 0;
+ int result = 0;
+
+ if (lock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (0 != ptw32_getprocessors (&cpus))
+ {
+ cpus = 1;
+ }
+
+ if (cpus > 1)
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+ /*
+ * Creating spinlock that can be shared between
+ * processes.
+ */
+#if _POSIX_THREAD_PROCESS_SHARED >= 0
+
+ /*
+ * Not implemented yet.
+ */
+
+#error ERROR [__FILE__, line __LINE__]: Process shared spin locks are not supported yet.
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ }
+
+ s = (pthread_spinlock_t) calloc (1, sizeof (*s));
+
+ if (s == NULL)
+ {
+ return ENOMEM;
+ }
+
+ if (cpus > 1)
+ {
+ s->u.cpus = cpus;
+ s->interlock = PTW32_SPIN_UNLOCKED;
+ }
+ else
+ {
+ pthread_mutexattr_t ma;
+ result = pthread_mutexattr_init (&ma);
+
+ if (0 == result)
+ {
+ ma->pshared = pshared;
+ result = pthread_mutex_init (&(s->u.mutex), &ma);
+ if (0 == result)
+ {
+ s->interlock = PTW32_SPIN_USE_MUTEX;
+ }
+ }
+ (void) pthread_mutexattr_destroy (&ma);
+ }
+
+ if (0 == result)
+ {
+ *lock = s;
+ }
+ else
+ {
+ (void) free (s);
+ *lock = NULL;
+ }
+
+ return (result);
+}
diff --git a/libs/pthreads/src/pthread_spin_lock.c b/libs/pthreads/src/pthread_spin_lock.c
new file mode 100644
index 0000000000..b560e14891
--- /dev/null
+++ b/libs/pthreads/src/pthread_spin_lock.c
@@ -0,0 +1,80 @@
+/*
+ * pthread_spin_lock.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_lock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ int result;
+
+ if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ s = *lock;
+
+ while ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED ==
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
+ {
+ }
+
+ if (s->interlock == PTW32_SPIN_LOCKED)
+ {
+ return 0;
+ }
+ else if (s->interlock == PTW32_SPIN_USE_MUTEX)
+ {
+ return pthread_mutex_lock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/libs/pthreads/src/pthread_spin_trylock.c b/libs/pthreads/src/pthread_spin_trylock.c
new file mode 100644
index 0000000000..a6c65aff6a
--- /dev/null
+++ b/libs/pthreads/src/pthread_spin_trylock.c
@@ -0,0 +1,77 @@
+/*
+ * pthread_spin_trylock.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_trylock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ int result;
+
+ if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ s = *lock;
+
+ switch ((long)
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED))
+ {
+ case PTW32_SPIN_UNLOCKED:
+ return 0;
+ case PTW32_SPIN_LOCKED:
+ return EBUSY;
+ case PTW32_SPIN_USE_MUTEX:
+ return pthread_mutex_trylock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/libs/pthreads/src/pthread_spin_unlock.c b/libs/pthreads/src/pthread_spin_unlock.c
new file mode 100644
index 0000000000..3a6932aef3
--- /dev/null
+++ b/libs/pthreads/src/pthread_spin_unlock.c
@@ -0,0 +1,71 @@
+/*
+ * pthread_spin_unlock.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_unlock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ s = *lock;
+
+ if (s == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ return EPERM;
+ }
+
+ switch ((long)
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED,
+ (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED))
+ {
+ case PTW32_SPIN_LOCKED:
+ case PTW32_SPIN_UNLOCKED:
+ return 0;
+ case PTW32_SPIN_USE_MUTEX:
+ return pthread_mutex_unlock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/libs/pthreads/src/pthread_testcancel.c b/libs/pthreads/src/pthread_testcancel.c
new file mode 100644
index 0000000000..6658650000
--- /dev/null
+++ b/libs/pthreads/src/pthread_testcancel.c
@@ -0,0 +1,103 @@
+/*
+ * pthread_testcancel.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void
+pthread_testcancel (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function creates a deferred cancellation point
+ * in the calling thread. The call has no effect if the
+ * current cancelability state is
+ * PTHREAD_CANCEL_DISABLE
+ *
+ * PARAMETERS
+ * N/A
+ *
+ *
+ * DESCRIPTION
+ * This function creates a deferred cancellation point
+ * in the calling thread. The call has no effect if the
+ * current cancelability state is
+ * PTHREAD_CANCEL_DISABLE
+ *
+ * NOTES:
+ * 1) Cancellation is asynchronous. Use pthread_join
+ * to wait for termination of thread if necessary
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_mcs_local_node_t stateLock;
+ pthread_t self = pthread_self ();
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+
+ if (sp == NULL)
+ {
+ return;
+ }
+
+ /*
+ * Pthread_cancel() will have set sp->state to PThreadStateCancelPending
+ * and set an event, so no need to enter kernel space if
+ * sp->state != PThreadStateCancelPending - that only slows us down.
+ */
+ if (sp->state != PThreadStateCancelPending)
+ {
+ return;
+ }
+
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+
+ if (sp->cancelState != PTHREAD_CANCEL_DISABLE)
+ {
+ ResetEvent(sp->cancelEvent);
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ptw32_mcs_lock_release (&stateLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+ /* Never returns here */
+ }
+
+ ptw32_mcs_lock_release (&stateLock);
+} /* pthread_testcancel */
diff --git a/libs/pthreads/src/pthread_timechange_handler_np.c b/libs/pthreads/src/pthread_timechange_handler_np.c
new file mode 100644
index 0000000000..0f97e74f14
--- /dev/null
+++ b/libs/pthreads/src/pthread_timechange_handler_np.c
@@ -0,0 +1,108 @@
+/*
+ * pthread_timechange_handler_np.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Notes on handling system time adjustments (especially negative ones).
+ * ---------------------------------------------------------------------
+ *
+ * This solution was suggested by Alexander Terekhov, but any errors
+ * in the implementation are mine - [Ross Johnson]
+ *
+ * 1) The problem: threads doing a timedwait on a CV may expect to timeout
+ * at a specific absolute time according to a system timer. If the
+ * system clock is adjusted backwards then those threads sleep longer than
+ * expected. Also, pthreads-win32 converts absolute times to intervals in
+ * order to make use of the underlying Win32, and so waiting threads may
+ * awake before their proper abstimes.
+ *
+ * 2) We aren't able to distinquish between threads on timed or untimed waits,
+ * so we wake them all at the time of the adjustment so that they can
+ * re-evaluate their conditions and re-compute their timeouts.
+ *
+ * 3) We rely on correctly written applications for this to work. Specifically,
+ * they must be able to deal properly with spurious wakeups. That is,
+ * they must re-test their condition upon wakeup and wait again if
+ * the condition is not satisfied.
+ */
+
+void *
+pthread_timechange_handler_np (void *arg)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Broadcasts all CVs to force re-evaluation and
+ * new timeouts if required.
+ *
+ * PARAMETERS
+ * NONE
+ *
+ *
+ * DESCRIPTION
+ * Broadcasts all CVs to force re-evaluation and
+ * new timeouts if required.
+ *
+ * This routine may be passed directly to pthread_create()
+ * as a new thread in order to run asynchronously.
+ *
+ *
+ * RESULTS
+ * 0 successfully broadcast all CVs
+ * EAGAIN Not all CVs were broadcast
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_cond_t cv;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node);
+
+ cv = ptw32_cond_list_head;
+
+ while (cv != NULL && 0 == result)
+ {
+ result = pthread_cond_broadcast (&cv);
+ cv = cv->next;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return (void *) (size_t) (result != 0 ? EAGAIN : 0);
+}
diff --git a/libs/pthreads/src/pthread_win32_attach_detach_np.c b/libs/pthreads/src/pthread_win32_attach_detach_np.c
new file mode 100644
index 0000000000..bfad450653
--- /dev/null
+++ b/libs/pthreads/src/pthread_win32_attach_detach_np.c
@@ -0,0 +1,256 @@
+/*
+ * pthread_win32_attach_detach_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Handle to quserex.dll
+ */
+static HINSTANCE ptw32_h_quserex;
+
+BOOL
+pthread_win32_process_attach_np ()
+{
+ TCHAR QuserExDLLPathBuf[1024];
+ BOOL result = TRUE;
+
+ result = ptw32_processInitialize ();
+
+#if defined(_UWIN)
+ pthread_count++;
+#endif
+
+#if defined(__GNUC__)
+ ptw32_features = 0;
+#else
+ /*
+ * This is obsolete now.
+ */
+ ptw32_features = PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE;
+#endif
+
+ /*
+ * Load QUSEREX.DLL and try to get address of QueueUserAPCEx.
+ * Because QUSEREX.DLL requires a driver to be installed we will
+ * assume the DLL is in the system directory.
+ *
+ * This should take care of any security issues.
+ */
+#if defined(__GNUC__) || _MSC_VER < 1400
+ if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf)))
+ {
+ (void) strncat(QuserExDLLPathBuf,
+ "\\QUSEREX.DLL",
+ sizeof(QuserExDLLPathBuf) - strlen(QuserExDLLPathBuf) - 1);
+ ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf);
+ }
+#else
+ /* strncat is secure - this is just to avoid a warning */
+ if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf)) &&
+ 0 == strncat_s(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf), "\\QUSEREX.DLL", 12))
+ {
+ ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf);
+ }
+#endif
+
+ if (ptw32_h_quserex != NULL)
+ {
+ ptw32_register_cancelation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD))
+#if defined(NEED_UNICODE_CONSTS)
+ GetProcAddress (ptw32_h_quserex,
+ (const TCHAR *) TEXT ("QueueUserAPCEx"));
+#else
+ GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx");
+#endif
+ }
+
+ if (NULL == ptw32_register_cancelation)
+ {
+ ptw32_register_cancelation = ptw32_RegisterCancelation;
+
+ if (ptw32_h_quserex != NULL)
+ {
+ (void) FreeLibrary (ptw32_h_quserex);
+ }
+ ptw32_h_quserex = 0;
+ }
+ else
+ {
+ /* Initialise QueueUserAPCEx */
+ BOOL (*queue_user_apc_ex_init) (VOID);
+
+ queue_user_apc_ex_init = (BOOL (*)(VOID))
+#if defined(NEED_UNICODE_CONSTS)
+ GetProcAddress (ptw32_h_quserex,
+ (const TCHAR *) TEXT ("QueueUserAPCEx_Init"));
+#else
+ GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init");
+#endif
+
+ if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ())
+ {
+ ptw32_register_cancelation = ptw32_RegisterCancelation;
+
+ (void) FreeLibrary (ptw32_h_quserex);
+ ptw32_h_quserex = 0;
+ }
+ }
+
+ if (ptw32_h_quserex)
+ {
+ ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL;
+ }
+
+ return result;
+}
+
+
+BOOL
+pthread_win32_process_detach_np ()
+{
+ if (ptw32_processInitialized)
+ {
+ ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+ if (sp != NULL)
+ {
+ /*
+ * Detached threads have their resources automatically
+ * cleaned up upon exit (others must be 'joined').
+ */
+ if (sp->detachState == PTHREAD_CREATE_DETACHED)
+ {
+ ptw32_threadDestroy (sp->ptHandle);
+ TlsSetValue (ptw32_selfThreadKey->key, NULL);
+ }
+ }
+
+ /*
+ * The DLL is being unmapped from the process's address space
+ */
+ ptw32_processTerminate ();
+
+ if (ptw32_h_quserex)
+ {
+ /* Close QueueUserAPCEx */
+ BOOL (*queue_user_apc_ex_fini) (VOID);
+
+ queue_user_apc_ex_fini = (BOOL (*)(VOID))
+#if defined(NEED_UNICODE_CONSTS)
+ GetProcAddress (ptw32_h_quserex,
+ (const TCHAR *) TEXT ("QueueUserAPCEx_Fini"));
+#else
+ GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Fini");
+#endif
+
+ if (queue_user_apc_ex_fini != NULL)
+ {
+ (void) queue_user_apc_ex_fini ();
+ }
+ (void) FreeLibrary (ptw32_h_quserex);
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL
+pthread_win32_thread_attach_np ()
+{
+ return TRUE;
+}
+
+BOOL
+pthread_win32_thread_detach_np ()
+{
+ if (ptw32_processInitialized)
+ {
+ /*
+ * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle
+ * unnecessarily.
+ */
+ ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+ if (sp != NULL) // otherwise Win32 thread with no implicit POSIX handle.
+ {
+ ptw32_mcs_local_node_t stateLock;
+ ptw32_callUserDestroyRoutines (sp->ptHandle);
+
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+ sp->state = PThreadStateLast;
+ /*
+ * If the thread is joinable at this point then it MUST be joined
+ * or detached explicitly by the application.
+ */
+ ptw32_mcs_lock_release (&stateLock);
+
+ /*
+ * Robust Mutexes
+ */
+ while (sp->robustMxList != NULL)
+ {
+ pthread_mutex_t mx = sp->robustMxList->mx;
+ ptw32_robust_mutex_remove(&mx, sp);
+ (void) PTW32_INTERLOCKED_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent,
+ (PTW32_INTERLOCKED_LONG)-1);
+ /*
+ * If there are no waiters then the next thread to block will
+ * sleep, wakeup immediately and then go back to sleep.
+ * See pthread_mutex_lock.c.
+ */
+ SetEvent(mx->event);
+ }
+
+
+ if (sp->detachState == PTHREAD_CREATE_DETACHED)
+ {
+ ptw32_threadDestroy (sp->ptHandle);
+
+ TlsSetValue (ptw32_selfThreadKey->key, NULL);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL
+pthread_win32_test_features_np (int feature_mask)
+{
+ return ((ptw32_features & feature_mask) == feature_mask);
+}
diff --git a/libs/pthreads/src/ptw32_MCS_lock.c b/libs/pthreads/src/ptw32_MCS_lock.c
new file mode 100644
index 0000000000..659cda60de
--- /dev/null
+++ b/libs/pthreads/src/ptw32_MCS_lock.c
@@ -0,0 +1,278 @@
+/*
+ * ptw32_MCS_lock.c
+ *
+ * Description:
+ * This translation unit implements queue-based locks.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * About MCS locks:
+ *
+ * MCS locks are queue-based locks, where the queue nodes are local to the
+ * thread. The 'lock' is nothing more than a global pointer that points to
+ * the last node in the queue, or is NULL if the queue is empty.
+ *
+ * Originally designed for use as spin locks requiring no kernel resources
+ * for synchronisation or blocking, the implementation below has adapted
+ * the MCS spin lock for use as a general mutex that will suspend threads
+ * when there is lock contention.
+ *
+ * Because the queue nodes are thread-local, most of the memory read/write
+ * operations required to add or remove nodes from the queue do not trigger
+ * cache-coherence updates.
+ *
+ * Like 'named' mutexes, MCS locks consume system resources transiently -
+ * they are able to acquire and free resources automatically - but MCS
+ * locks do not require any unique 'name' to identify the lock to all
+ * threads using it.
+ *
+ * Usage of MCS locks:
+ *
+ * - you need a global ptw32_mcs_lock_t instance initialised to 0 or NULL.
+ * - you need a local thread-scope ptw32_mcs_local_node_t instance, which
+ * may serve several different locks but you need at least one node for
+ * every lock held concurrently by a thread.
+ *
+ * E.g.:
+ *
+ * ptw32_mcs_lock_t lock1 = 0;
+ * ptw32_mcs_lock_t lock2 = 0;
+ *
+ * void *mythread(void *arg)
+ * {
+ * ptw32_mcs_local_node_t node;
+ *
+ * ptw32_mcs_acquire (&lock1, &node);
+ * ptw32_mcs_lock_release (&node);
+ *
+ * ptw32_mcs_lock_acquire (&lock2, &node);
+ * ptw32_mcs_lock_release (&node);
+ * {
+ * ptw32_mcs_local_node_t nodex;
+ *
+ * ptw32_mcs_lock_acquire (&lock1, &node);
+ * ptw32_mcs_lock_acquire (&lock2, &nodex);
+ *
+ * ptw32_mcs_lock_release (&nodex);
+ * ptw32_mcs_lock_release (&node);
+ * }
+ * return (void *)0;
+ * }
+ */
+
+#include "pthread.h"
+#include "sched.h"
+#include "implement.h"
+
+/*
+ * ptw32_mcs_flag_set -- notify another thread about an event.
+ *
+ * Set event if an event handle has been stored in the flag, and
+ * set flag to -1 otherwise. Note that -1 cannot be a valid handle value.
+ */
+INLINE void
+ptw32_mcs_flag_set (HANDLE * flag)
+{
+ HANDLE e = (HANDLE)(PTW32_INTERLOCKED_SIZE)PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)flag,
+ (PTW32_INTERLOCKED_SIZE)-1,
+ (PTW32_INTERLOCKED_SIZE)0);
+ if ((HANDLE)0 != e)
+ {
+ /* another thread has already stored an event handle in the flag */
+ SetEvent(e);
+ }
+}
+
+/*
+ * ptw32_mcs_flag_set -- wait for notification from another.
+ *
+ * Store an event handle in the flag and wait on it if the flag has not been
+ * set, and proceed without creating an event otherwise.
+ */
+INLINE void
+ptw32_mcs_flag_wait (HANDLE * flag)
+{
+ if ((PTW32_INTERLOCKED_LONG)0 ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)flag,
+ (PTW32_INTERLOCKED_SIZE)0)) /* MBR fence */
+ {
+ /* the flag is not set. create event. */
+
+ HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL);
+
+ if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)flag,
+ (PTW32_INTERLOCKED_SIZE)e,
+ (PTW32_INTERLOCKED_SIZE)0))
+ {
+ /* stored handle in the flag. wait on it now. */
+ WaitForSingleObject(e, INFINITE);
+ }
+
+ CloseHandle(e);
+ }
+}
+
+/*
+ * ptw32_mcs_lock_acquire -- acquire an MCS lock.
+ *
+ * See:
+ * J. M. Mellor-Crummey and M. L. Scott.
+ * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
+ * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
+ */
+#if defined(PTW32_BUILD_INLINED)
+INLINE
+#endif /* PTW32_BUILD_INLINED */
+void
+ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
+{
+ ptw32_mcs_local_node_t *pred;
+
+ node->lock = lock;
+ node->nextFlag = 0;
+ node->readyFlag = 0;
+ node->next = 0; /* initially, no successor */
+
+ /* queue for the lock */
+ pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
+ (PTW32_INTERLOCKED_PVOID)node);
+
+ if (0 != pred)
+ {
+ /* the lock was not free. link behind predecessor. */
+ pred->next = node;
+ ptw32_mcs_flag_set(&pred->nextFlag);
+ ptw32_mcs_flag_wait(&node->readyFlag);
+ }
+}
+
+/*
+ * ptw32_mcs_lock_release -- release an MCS lock.
+ *
+ * See:
+ * J. M. Mellor-Crummey and M. L. Scott.
+ * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
+ * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
+ */
+#if defined(PTW32_BUILD_INLINED)
+INLINE
+#endif /* PTW32_BUILD_INLINED */
+void
+ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node)
+{
+ ptw32_mcs_lock_t *lock = node->lock;
+ ptw32_mcs_local_node_t *next =
+ (ptw32_mcs_local_node_t *)
+ PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */
+
+ if (0 == next)
+ {
+ /* no known successor */
+
+ if (node == (ptw32_mcs_local_node_t *)
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
+ (PTW32_INTERLOCKED_PVOID)0,
+ (PTW32_INTERLOCKED_PVOID)node))
+ {
+ /* no successor, lock is free now */
+ return;
+ }
+
+ /* A successor has started enqueueing behind us so wait for them to link to us */
+ ptw32_mcs_flag_wait(&node->nextFlag);
+ next = (ptw32_mcs_local_node_t *)
+ PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */
+ }
+
+ /* pass the lock */
+ ptw32_mcs_flag_set(&next->readyFlag);
+}
+
+/*
+ * ptw32_mcs_lock_try_acquire
+ */
+#if defined(PTW32_BUILD_INLINED)
+INLINE
+#endif /* PTW32_BUILD_INLINED */
+int
+ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
+{
+ node->lock = lock;
+ node->nextFlag = 0;
+ node->readyFlag = 0;
+ node->next = 0; /* initially, no successor */
+
+ return ((PTW32_INTERLOCKED_PVOID)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock,
+ (PTW32_INTERLOCKED_PVOID)node,
+ (PTW32_INTERLOCKED_PVOID)0)
+ == (PTW32_INTERLOCKED_PVOID)0) ? 0 : EBUSY;
+}
+
+/*
+ * ptw32_mcs_node_transfer -- move an MCS lock local node, usually from thread
+ * space to, for example, global space so that another thread can release
+ * the lock on behalf of the current lock owner.
+ *
+ * Example: used in pthread_barrier_wait where we want the last thread out of
+ * the barrier to release the lock owned by the last thread to enter the barrier
+ * (the one that releases all threads but not necessarily the last to leave).
+ *
+ * Should only be called by the thread that has the lock.
+ */
+#if defined(PTW32_BUILD_INLINED)
+INLINE
+#endif /* PTW32_BUILD_INLINED */
+void
+ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node)
+{
+ new_node->lock = old_node->lock;
+ new_node->nextFlag = 0; /* Not needed - used only in initial Acquire */
+ new_node->readyFlag = 0; /* Not needed - we were waiting on this */
+ new_node->next = 0;
+
+ if ((ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)new_node->lock,
+ (PTW32_INTERLOCKED_PVOID)new_node,
+ (PTW32_INTERLOCKED_PVOID)old_node)
+ != old_node)
+ {
+ /*
+ * A successor has queued after us, so wait for them to link to us
+ */
+ while (old_node->next == 0)
+ {
+ sched_yield();
+ }
+ new_node->next = old_node->next;
+ }
+}
diff --git a/libs/pthreads/src/ptw32_OLL_lock.c b/libs/pthreads/src/ptw32_OLL_lock.c
new file mode 100644
index 0000000000..789d0ad8c6
--- /dev/null
+++ b/libs/pthreads/src/ptw32_OLL_lock.c
@@ -0,0 +1,734 @@
+/*
+ * ptw32_OLL_lock.c
+ *
+ * Description:
+ * This translation unit implements extended reader/writer queue-based locks.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * About the OLL lock (Scalable Reader-Writer Lock):
+ *
+ * OLL locks are queue-based locks similar to the MCS queue lock, where the queue
+ * nodes are local to the thread but where reader threads can enter the critical
+ * section immediately without going through a central guard lock if there are
+ * already readers holding the lock.
+ *
+ * Covered by United States Patent Application 20100241774 (Oracle)
+ */
+
+#include "pthread.h"
+#include "sched.h"
+#include "implement.h"
+
+/*
+ * C-SNZI support
+ */
+typedef union ptw32_oll_counter_t_ ptw32_oll_counter_t;
+typedef struct ptw32_oll_snziRoot_t_ ptw32_oll_snziRoot_t;
+typedef struct ptw32_oll_snziNode_t_ ptw32_oll_snziNode_t;
+typedef union ptw32_oll_snziNodeOrRoot_t_ ptw32_oll_snziNodeOrRoot_t;
+typedef struct ptw32_oll_queryResult_t_ ptw32_oll_queryResult_t;
+typedef struct ptw32_oll_ticket_t_ ptw32_oll_ticket_t;
+typedef struct ptw32_oll_csnzi_t_ ptw32_oll_csnzi_t;
+
+enum
+{
+ ptw32_archWidth = sizeof(size_t)*8,
+ ptw32_oll_countWidth = ptw32_archWidth-2
+};
+
+#define PTW32_OLL_MAXREADERS (((size_t)2<<(ptw32_oll_countWidth-1))-1)
+
+union ptw32_oll_counter_t_
+{
+ size_t word : ptw32_archWidth;
+ struct
+ {
+ /*
+ * This needs to be a single word
+ *
+ * ------------------------------------
+ * | STATE | ROOT | COUNT (readers) |
+ * ------------------------------------
+ * 63 / 31 62 / 30 61 / 29 .. 0
+ */
+ size_t count : ptw32_oll_countWidth;
+ size_t root : 1; /* ROOT or NODE */
+ size_t state : 1; /* OPEN or CLOSED (root only) */
+ } internal;
+};
+
+struct ptw32_oll_snziRoot_t_
+{
+ /*
+ * "counter" must be at same offset in both
+ * ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
+ */
+ ptw32_oll_counter_t counter;
+};
+
+enum
+{
+ ptw32_oll_snziRoot_open = 0,
+ ptw32_oll_snziRoot_closed = 1
+};
+
+enum
+{
+ ptw32_oll_snzi_root = 0,
+ ptw32_oll_snzi_node = 1
+};
+
+/*
+ * Some common SNZI root whole-word states that can be used to set or compare
+ * root words with a single operation.
+ */
+ptw32_oll_snziRoot_t ptw32_oll_snziRoot_openAndZero = {.counter.internal.count = 0,
+ .counter.internal.root = ptw32_oll_snzi_root,
+ .counter.internal.state = ptw32_oll_snziRoot_open};
+ptw32_oll_snziRoot_t ptw32_oll_snziRoot_closedAndZero = {.counter.internal.count = 0,
+ .counter.internal.root = ptw32_oll_snzi_root,
+ .counter.internal.state = ptw32_oll_snziRoot_closed};
+
+struct ptw32_oll_queryResult_t_
+{
+ BOOL nonZero;
+ BOOL open;
+};
+
+union ptw32_oll_snziNodeOrRoot_t_
+{
+ ptw32_oll_snziRoot_t* rootPtr;
+ ptw32_oll_snziNode_t* nodePtr;
+};
+
+struct ptw32_oll_snziNode_t_
+{
+ /* "counter" must be at same offset in both
+ * ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
+ */
+ ptw32_oll_counter_t counter;
+ ptw32_oll_snziNodeOrRoot_t parentPtr;
+};
+
+struct ptw32_oll_ticket_t_
+{
+ ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot;
+};
+
+ptw32_oll_ticket_t ptw32_oll_ticket_null = {NULL};
+
+struct ptw32_oll_csnzi_t_
+{
+ ptw32_oll_snziRoot_t proxyRoot;
+ ptw32_oll_snziNode_t leafs[];
+};
+
+/*
+ * FOLL lock support
+ */
+
+typedef struct ptw32_foll_node_t_ ptw32_foll_node_t;
+typedef struct ptw32_foll_local_t_ ptw32_foll_local_t;
+typedef struct ptw32_foll_rwlock_t_ ptw32_foll_rwlock_t;
+
+enum
+{
+ ptw32_srwl_reader,
+ ptw32_srwl_writer
+};
+
+enum
+{
+ ptw32_srwl_free,
+ ptw32_srwl_in_use
+};
+
+struct ptw32_foll_node_t_
+{
+ ptw32_foll_node_t* qNextPtr;
+ ptw32_oll_csnzi_t* csnziPtr;
+ ptw32_foll_node_t* nextPtr;
+ int kind;
+ int allocState;
+ BOOL spin;
+};
+
+struct ptw32_foll_local_t_
+{
+ ptw32_foll_node_t* rNodePtr; // Default read node. Immutable
+ ptw32_foll_node_t* wNodePtr; // Write node. Immutable.
+ ptw32_foll_node_t* departFromPtr; // List node we last arrived at.
+ ptw32_oll_ticket_t ticket; // C-SNZI ticket
+};
+
+struct ptw32_foll_rwlock_t_
+{
+ ptw32_foll_node_t* tailPtr;
+ ptw32_foll_node_t* rNodesPtr; // Head of reader node
+};
+
+/*
+ * ShouldArriveAtTree() returns true if:
+ * the compare_exchange in Arrive() fails too often under read access; or
+ * ??
+ * Note that this is measured across all access to
+ * this lock, not just this attempt, so that highly
+ * read-contended locks will use C-SNZI. Lightly
+ * read-contended locks can reduce memory usage and some
+ * processing by using the root directly.
+ */
+BOOL
+ptw32_oll_ShouldArriveAtTree()
+{
+ return PTW32_FALSE;
+}
+
+size_t
+ptw32_oll_GetLeafForThread()
+{
+ return 0;
+}
+
+/*
+ * Only readers call ptw32_oll_Arrive()
+ *
+ * Checks whether the C-SNZI state is OPEN, and if so,
+ * increments the surplus of the C-SNZI by either directly
+ * arriving at the root node, or calling TreeArrive on one
+ * of the leaf nodes. Returns a ticket pointing to the node
+ * that was arrived at. If the state is CLOSED, makes no
+ * change and returns a ticket that contains no pointer.
+ */
+ptw32_oll_ticket_t
+ptw32_oll_Arrive(ptw32_oll_csnzi_t* csnzi)
+{
+ for (;;)
+ {
+ ptw32_oll_ticket_t ticket;
+ ptw32_oll_snziRoot_t oldProxy = csnzi->proxyRoot;
+ if (oldProxy.counter.internal.state != ptw32_oll_snziRoot_open)
+ {
+ ticket.snziNodeOrRoot.rootPtr = (ptw32_oll_snziRoot_t*)NULL;
+ return ticket;
+ }
+ if (!ptw32_oll_ShouldArriveAtTree())
+ {
+ ptw32_oll_snziRoot_t newProxy = oldProxy;
+ newProxy.counter.internal.count++;
+ if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&csnzi->proxyRoot.counter,
+ (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
+ (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
+ == (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
+ {
+ /* Exchange successful */
+ ticket.snziNodeOrRoot.rootPtr = &csnzi->proxyRoot;
+ return ticket;
+ }
+ }
+ else
+ {
+ ptw32_oll_snziNode_t* leafPtr = &csnzi->leafs[ptw32_oll_GetLeafForThread()];
+ ticket.snziNodeOrRoot.nodePtr = (ptw32_oll_TreeArrive(leafPtr) ? leafPtr : (ptw32_oll_snziNode_t*)NULL);
+ return ticket;
+ }
+ }
+}
+
+/*
+ * Decrements the C-SNZI surplus. Returns false iff the
+ * resulting state is CLOSED and the surplus is zero.
+ * Ticket must have been returned by an arrival. Must have
+ * received this ticket from Arrive more times than Depart
+ * has been called with the ticket. (Thus, the surplus
+ * must be greater than zero.)
+ */
+BOOL
+ptw32_oll_Depart(ptw32_oll_ticket_t ticket)
+{
+ return ptw32_oll_TreeDepart(ticket.snziNodeOrRoot);
+}
+
+/*
+ * Increments the C-SNZI surplus and returns true if the
+ * C-SNZI is open or has a surplus. Calls TreeArrive
+ * recursively on the node’s parent if needed.
+ * Otherwise, returns false without making any changes.
+ */
+BOOL
+ptw32_oll_TreeArrive(ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot)
+{
+ if (snziNodeOrRoot.nodePtr->counter.internal.root != ptw32_oll_snzi_root)
+ {
+ /* Non-root node */
+ ptw32_oll_counter_t newCounter, oldCounter;
+ BOOL arrivedAtParent = PTW32_FALSE;
+ do
+ {
+ oldCounter = snziNodeOrRoot.nodePtr->counter;
+ if (0 == oldCounter.internal.count && !arrivedAtParent)
+ {
+ if (ptw32_oll_TreeArrive(snziNodeOrRoot.nodePtr->parentPtr))
+ arrivedAtParent = PTW32_TRUE;
+ else
+ return PTW32_FALSE;
+ }
+ newCounter = oldCounter;
+ newCounter.internal.count++;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.nodePtr->counter,
+ (PTW32_INTERLOCKED_SIZE)newCounter.word,
+ (PTW32_INTERLOCKED_SIZE)oldCounter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldCounter.word);
+ if (newCounter.internal.count != 0 && arrivedAtParent)
+ ptw32_oll_TreeDepart(snziNodeOrRoot.nodePtr->parentPtr);
+ return PTW32_TRUE;
+ }
+ else
+ {
+ /* Root node */
+ ptw32_oll_snziRoot_t newRoot, oldRoot;
+ do
+ {
+ oldRoot = *(ptw32_oll_snziRoot_t*)snziNodeOrRoot.rootPtr;
+ if (oldRoot.counter.word == ptw32_oll_snziRoot_closedAndZero.counter.word)
+ return PTW32_FALSE;
+ newRoot = oldRoot;
+ newRoot.counter.internal.count++;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.rootPtr->counter,
+ (PTW32_INTERLOCKED_SIZE)newRoot.counter.word,
+ (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word);
+ return PTW32_TRUE;
+ }
+}
+
+/*
+ * Decrements the C-SNZI surplus, calling TreeDepart
+ * recursively on the node’s parent if needed. Returns
+ * false iff the resulting state of the C-SNZI is CLOSED
+ * and the surplus is zero. Otherwise, returns true.
+ */
+BOOL
+ptw32_oll_TreeDepart(ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot)
+{
+ if (snziNodeOrRoot.nodePtr->counter.internal.root != ptw32_oll_snzi_root)
+ {
+ /* Non-root node */
+ ptw32_oll_counter_t newCounter, oldCounter;
+ do
+ {
+ newCounter = oldCounter = snziNodeOrRoot.nodePtr->counter;
+ newCounter.internal.count--;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.nodePtr->counter,
+ (PTW32_INTERLOCKED_SIZE)newCounter.word,
+ (PTW32_INTERLOCKED_SIZE)oldCounter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldCounter.word);
+ return (0 == newCounter.internal.count)
+ ? ptw32_oll_TreeDepart(snziNodeOrRoot.nodePtr->parentPtr)
+ : PTW32_TRUE;
+ }
+ else
+ {
+ /* Root node */
+ ptw32_oll_snziRoot_t newRoot, oldRoot;
+ do
+ {
+ newRoot = oldRoot = *(ptw32_oll_snziRoot_t*)snziNodeOrRoot.rootPtr;
+ newRoot.counter.internal.count--;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&snziNodeOrRoot.rootPtr->counter,
+ (PTW32_INTERLOCKED_SIZE)newRoot.counter.word,
+ (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldRoot.counter.word);
+ return (newRoot.counter.word != ptw32_oll_snziRoot_closedAndZero.counter.word);
+ }
+}
+
+/*
+ * Opens a C-SNZI object. Requires C-SNZI state to be
+ * CLOSED and the surplus to be zero.
+ */
+void
+ptw32_oll_Open(ptw32_oll_csnzi_t* csnziPtr)
+{
+ csnziPtr->proxyRoot = ptw32_oll_snziRoot_openAndZero;
+}
+
+/*
+ * Opens a C-SNZI object while atomically performing count
+ * arrivals. Requires C-SNZI state to be CLOSED and
+ * the surplus to be zero.
+ */
+void
+ptw32_oll_OpenWithArrivals(ptw32_oll_csnzi_t* csnziPtr, size_t count, BOOL close)
+{
+ csnziPtr->proxyRoot.counter.internal.count = count;
+ csnziPtr->proxyRoot.counter.internal.state = (close ? ptw32_oll_snziRoot_closed : ptw32_oll_snziRoot_open);
+}
+
+/*
+ * Closes a C-SNZI object. Returns true iff the C-SNZI
+ * state changed from OPEN to CLOSED and the surplus is
+ * zero.
+ */
+BOOL
+ptw32_oll_Close(ptw32_oll_csnzi_t* csnziPtr)
+{
+ ptw32_oll_snziRoot_t newProxy, oldProxy;
+ do
+ {
+ oldProxy = csnziPtr->proxyRoot;
+ if (oldProxy.counter.internal.state != ptw32_oll_snziRoot_open)
+ {
+ return PTW32_FALSE;
+ }
+ newProxy = oldProxy;
+ newProxy.counter.internal.state = ptw32_oll_snziRoot_closed;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&csnziPtr->proxyRoot.counter,
+ (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
+ (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word);
+ return (newProxy.counter.word == ptw32_oll_snziRoot_closedAndZero.counter.word);
+}
+
+/*
+ * Closes a C-SNZI if its surplus is zero. Otherwise, does
+ * nothing. Returns true iff C-SNZI state changed from
+ * OPEN to CLOSED.
+ */
+BOOL
+ptw32_oll_CloseIfEmpty(ptw32_oll_csnzi_t* csnziPtr)
+{
+ ptw32_oll_snziRoot_t newProxy, oldProxy;
+ do
+ {
+ oldProxy = csnziPtr->proxyRoot;
+ if (oldProxy.counter.word != ptw32_oll_snziRoot_openAndZero.counter.word)
+ {
+ return PTW32_FALSE;
+ }
+ newProxy = ptw32_oll_snziRoot_closedAndZero;
+ } while (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
+ (PTW32_INTERLOCKED_SIZEPTR)&csnziPtr->proxyRoot.counter,
+ (PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
+ (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
+ != (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word);
+ return PTW32_TRUE;
+}
+
+/*
+ * Returns whether the C-SNZI has a nonzero surplus and
+ * whether the C-SNZI is open.
+ * "nonZero" doesn't appear to be used anywhere in the algorithms.
+ */
+ptw32_oll_queryResult_t
+ptw32_oll_Query(ptw32_oll_csnzi_t* csnziPtr)
+{
+ ptw32_oll_queryResult_t query;
+ ptw32_oll_snziRoot_t proxy = csnziPtr->proxyRoot;
+
+ query.nonZero = (proxy.counter.internal.count > 0);
+ query.open = (proxy.counter.internal.state == ptw32_oll_snziRoot_open);
+ return query;
+}
+
+/*
+ * Returns whether the Arrive operation that returned
+ * the ticket succeeded.
+ */
+BOOL
+ptw32_oll_Arrived(ptw32_oll_ticket_t t)
+{
+ return (t.snziNodeOrRoot.nodePtr != NULL);
+}
+
+/*
+ * Constructs and returns a ticket that can be used to
+ * depart from the root node.
+ */
+ptw32_oll_ticket_t
+ptw32_oll_DirectTicket(ptw32_oll_csnzi_t* csnziPtr)
+{
+ ptw32_oll_ticket_t ticket;
+ ticket.snziNodeOrRoot.rootPtr = &csnziPtr->proxyRoot;
+ return ticket;
+}
+
+/* Scalable RW Locks */
+
+typedef struct ptw32_srwl_rwlock_t_ ptw32_srwl_rwlock_t;
+typedef struct ptw32_srwl_node_t_ ptw32_srwl_node_t;
+typedef struct ptw32_srwl_local_t_ ptw32_srwl_local_t;
+
+enum
+{
+ ptw32_srwl_reader = 0,
+ ptw32_srwl_writer = 1
+};
+
+enum
+{
+ ptw32_srwl_free = 0,
+ ptw32_srwl_in_use = 1
+};
+
+struct ptw32_srwl_rwlock_t_
+{
+ ptw32_srwl_node_t* tailPtr;
+ ptw32_srwl_node_t* readerNodePtr;
+};
+
+struct ptw32_srwl_node_t_
+{
+ ptw32_srwl_node_t* qNextPtr;
+ ptw32_oll_csnzi_t* csnziPtr;
+ ptw32_srwl_node_t* nextReaderPtr;
+ int kind; /* ptw32_srwl_reader, ptw32_srwl_writer */
+ int allocState; /* ptw32_srwl_free, ptw32_srwl_in_use */
+ BOOL spin;
+};
+
+/*
+ * When a ptw32_srwl_local_t is instantiated the "kind" of each of
+ * rNode and wNode must be set as appropriate. This is the only
+ * time "kind" is set.
+ */
+struct ptw32_srwl_local_t_
+{
+ ptw32_srwl_node_t* rNodePtr;
+ ptw32_srwl_node_t* wNodePtr;
+ ptw32_srwl_node_t* departFromPtr;
+ ptw32_oll_ticket_t ticket;
+};
+
+/* Allocates a new reader node. */
+ptw32_srwl_node_t*
+ptw32_srwl_AllocReaderNode(ptw32_srwl_local_t* local)
+{
+ ptw32_srwl_node_t* currNodePtr = local->rNodePtr;
+ for (;;)
+ {
+ if (currNodePtr->allocState == ptw32_srwl_free)
+ {
+ if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)&currNodePtr->allocState,
+ (PTW32_INTERLOCKED_LONG)ptw32_srwl_in_use,
+ (PTW32_INTERLOCKED_LONG)ptw32_srwl_free)
+ == (PTW32_INTERLOCKED_LONG)ptw32_srwl_in_use)
+ {
+ return currNodePtr;
+ }
+ }
+ currNodePtr = currNodePtr->next;
+ }
+}
+
+/*
+ * Frees a reader node. Requires that its allocState
+ * is ptw32_srwl_in_use.
+ */
+void
+ptw32_srwl_FreeReaderNode(ptw32_srwl_node_t* nodePtr)
+{
+ nodePtr->allocState := ptw32_srwl_free;
+}
+
+void
+ptw32_srwl_WriterLock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
+{
+ oldTailPtr = (ptw32_srwl_rwlock_t*)PTW32_INTERLOCKED_EXCHANGE_PTR(
+ (PTW32_INTERLOCKED_PVOID_PTR)&lockPtr->tailPtr,
+ (PTW32_INTERLOCKED_PVOID)localPtr->wNodePtr);
+ if (oldTailPtr != NULL)
+ {
+ localPtr->wNodePtr->spin := PTW32_TRUE;
+ oldTailPtr->qNextPtr = localPtr->wNodePtr;
+ if (oldTailPtr->kind == ptw32_srwl_writer)
+ {
+ while (localPtr->wNodePtr->spin);
+ }
+ else
+ {
+ /* Wait until node is properly recycled */
+ while (ptw32_oll_Query(oldTailPtr->csnzi).open);
+ /*
+ * Close C-SNZI of previous reader node.
+ * If there are no readers to signal us, spin on
+ * previous node and free it before entering
+ * critical section.
+ */
+ if (ptw32_oll_Close(oldTailPtr->csnzi))
+ {
+ while (oldTailPtr->spin);
+ ptw32_srwl_FreeReaderNode(oldTailPtr);
+ }
+ else
+ {
+ while (localPtr->wNodePtr->spin);
+ }
+ }
+ }
+}
+
+void
+ptw32_srwl_WriterUnlock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
+{
+ if (localPtr->wNodePtr->qNextPtr == NULL)
+ {
+ if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
+ (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
+ (PTW32_INTERLOCKED_PVOID)NULL,
+ (PTW32_INTERLOCKED_PVOID)localPtr->wNodePtr)
+ == (PTW32_INTERLOCKED_PVOID)NULL)
+ {
+ return;
+ }
+ else
+ {
+ while (localPtr->wNodePtr->qNextPtr == NULL);
+ }
+ }
+ /* Clean up */
+ localPtr->wNodePtr->qNextPtr->spin = PTW32_FALSE;
+ localPtr->wNodePtr->qNextPtr = NULL;
+}
+
+void
+ptw32_srwl_ReaderLock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
+{
+ ptw32_srwl_node_t* rNodePtr = NULL;
+ for (;;)
+ {
+ ptw32_srwl_node_t* tailPtr = lockPtr->tailPtr;
+ /* If no nodes are in the queue */
+ if (tailPtr == NULL)
+ {
+ if (rNodePtr == NULL)
+ {
+ rNodePtr = ptw32_srwl_AllocReaderNode(localPtr);
+ }
+ rNodePtr->spin = PTW32_FALSE;
+ if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
+ (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
+ (PTW32_INTERLOCKED_PVOID)rNodePtr,
+ (PTW32_INTERLOCKED_PVOID)NULL)
+ == (PTW32_INTERLOCKED_PVOID)rNodePtr)
+ {
+ ptw32_oll_Open(rNodePtr->csnzi);
+ localPtr->ticket = ptw32_oll_Arrive(rNodePtr->csnzi);
+ if (ptw32_oll_Arrived(localPtr->ticket))
+ {
+ localPtr->departFromPtr = rNodePtr;
+ return;
+ }
+ /* Avoid reusing inserted node */
+ rNodePtr = NULL;
+ }
+ }
+ /* Otherwise, there is a node in the queue */
+ else
+ {
+ /* Is last node a writer node? */
+ if (tailPtr->kind == ptw32_srwl_writer)
+ {
+ if (rNodePtr == NULL)
+ {
+ rNodePtr = ptw32_srwl_AllocReaderNode(localPtr);
+ }
+ rNodePtr->spin = PTW32_TRUE;
+ if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(
+ (PTW32_INTERLOCKED_PVOIDPTR)&lockPtr->tailPtr,
+ (PTW32_INTERLOCKED_PVOID)rNodePtr,
+ (PTW32_INTERLOCKED_PVOID)tailPtr)
+ == (PTW32_INTERLOCKED_PVOID)rNodePtr)
+ {
+ tailPtr->qNextPtr = rNodePtr;
+ localPtr->ticket = ptw32_oll_Arrive(rNodePtr->csnzi);
+ if (ptw32_oll_Arrived(localPtr->ticket))
+ {
+ localPtr->departFromPtr = rNodePtr;
+ while (rNodePtr->spin);
+ return;
+ }
+ /* Avoid reusing inserted node */
+ rNodePtr = NULL;
+ }
+ }
+ /*
+ * Otherwise, last node is a reader node.
+ * (tailPtr->kind == ptw32_srwl_reader)
+ */
+ else
+ {
+ localPtr->ticket = ptw32_oll_Arrive(tailPtr->csnzi);
+ if (ptw32_oll_Arrived(localPtr->ticket))
+ {
+ if (rNodePtr != NULL)
+ {
+ ptw32_srwl_FreeReaderNode(rNodePtr);
+ }
+ localPtr->departFromPtr = tailPtr;
+ while (tailPtr->spin);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void
+ptw32_srwl_ReaderUnlock(ptw32_srwl_rwlock_t* lockPtr, ptw32_srwl_local_t* localPtr)
+{
+ if (ptw32_oll_Depart(localPtr->departFromPtr->csnzi, localPtr->ticket))
+ {
+ return;
+ }
+ /* Clean up */
+ localPtr->departFromPtr->qNextPtr->spin = PTW32_FALSE;
+ localPtr->departFromPtr->qNextPtr = NULL;
+ ptw32_srwl_FreeReaderNode(localPtr->departFromPtr);
+}
+
+
+#include <stdio.h>
+
+int main()
+{
+ printf("%lx\n", PTW32_OLL_MAXREADERS);
+ return 0;
+}
+
diff --git a/libs/pthreads/src/ptw32_callUserDestroyRoutines.c b/libs/pthreads/src/ptw32_callUserDestroyRoutines.c
new file mode 100644
index 0000000000..f290f7ba54
--- /dev/null
+++ b/libs/pthreads/src/ptw32_callUserDestroyRoutines.c
@@ -0,0 +1,232 @@
+/*
+ * ptw32_callUserDestroyRoutines.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#if defined(__CLEANUP_CXX)
+# if defined(_MSC_VER)
+# include <eh.h>
+# elif defined(__WATCOMC__)
+# include <eh.h>
+# include <exceptio.h>
+# else
+# if defined(__GNUC__) && __GNUC__ < 3
+# include <new.h>
+# else
+# include <new>
+ using
+ std::terminate;
+# endif
+# endif
+#endif
+
+void
+ptw32_callUserDestroyRoutines (pthread_t thread)
+ /*
+ * -------------------------------------------------------------------
+ * DOCPRIVATE
+ *
+ * This the routine runs through all thread keys and calls
+ * the destroy routines on the user's data for the current thread.
+ * It simulates the behaviour of POSIX Threads.
+ *
+ * PARAMETERS
+ * thread
+ * an instance of pthread_t
+ *
+ * RETURNS
+ * N/A
+ * -------------------------------------------------------------------
+ */
+{
+ ThreadKeyAssoc * assoc;
+
+ if (thread.p != NULL)
+ {
+ ptw32_mcs_local_node_t threadLock;
+ ptw32_mcs_local_node_t keyLock;
+ int assocsRemaining;
+ int iterations = 0;
+ ptw32_thread_t * sp = (ptw32_thread_t *) thread.p;
+
+ /*
+ * Run through all Thread<-->Key associations
+ * for the current thread.
+ *
+ * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times.
+ */
+ do
+ {
+ assocsRemaining = 0;
+ iterations++;
+
+ ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
+ /*
+ * The pointer to the next assoc is stored in the thread struct so that
+ * the assoc destructor in pthread_key_delete can adjust it
+ * if it deletes this assoc. This can happen if we fail to acquire
+ * both locks below, and are forced to release all of our locks,
+ * leaving open the opportunity for pthread_key_delete to get in
+ * before us.
+ */
+ sp->nextAssoc = sp->keys;
+ ptw32_mcs_lock_release(&threadLock);
+
+ for (;;)
+ {
+ void * value;
+ pthread_key_t k;
+ void (*destructor) (void *);
+
+ /*
+ * First we need to serialise with pthread_key_delete by locking
+ * both assoc guards, but in the reverse order to our convention,
+ * so we must be careful to avoid deadlock.
+ */
+ ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock);
+
+ if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL)
+ {
+ /* Finished */
+ ptw32_mcs_lock_release(&threadLock);
+ break;
+ }
+ else
+ {
+ /*
+ * assoc->key must be valid because assoc can't change or be
+ * removed from our chain while we hold at least one lock. If
+ * the assoc was on our key chain then the key has not been
+ * deleted yet.
+ *
+ * Now try to acquire the second lock without deadlocking.
+ * If we fail, we need to relinquish the first lock and the
+ * processor and then try to acquire them all again.
+ */
+ if (ptw32_mcs_lock_try_acquire(&(assoc->key->keyLock), &keyLock) == EBUSY)
+ {
+ ptw32_mcs_lock_release(&threadLock);
+ Sleep(0);
+ /*
+ * Go around again.
+ * If pthread_key_delete has removed this assoc in the meantime,
+ * sp->nextAssoc will point to a new assoc.
+ */
+ continue;
+ }
+ }
+
+ /* We now hold both locks */
+
+ sp->nextAssoc = assoc->nextKey;
+
+ /*
+ * Key still active; pthread_key_delete
+ * will block on these same mutexes before
+ * it can release actual key; therefore,
+ * key is valid and we can call the destroy
+ * routine;
+ */
+ k = assoc->key;
+ destructor = k->destructor;
+ value = TlsGetValue(k->key);
+ TlsSetValue (k->key, NULL);
+
+ // Every assoc->key exists and has a destructor
+ if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS)
+ {
+ /*
+ * Unlock both locks before the destructor runs.
+ * POSIX says pthread_key_delete can be run from destructors,
+ * and that probably includes with this key as target.
+ * pthread_setspecific can also be run from destructors and
+ * also needs to be able to access the assocs.
+ */
+ ptw32_mcs_lock_release(&threadLock);
+ ptw32_mcs_lock_release(&keyLock);
+
+ assocsRemaining++;
+
+#if defined(__cplusplus)
+
+ try
+ {
+ /*
+ * Run the caller's cleanup routine.
+ */
+ destructor (value);
+ }
+ catch (...)
+ {
+ /*
+ * A system unexpected exception has occurred
+ * running the user's destructor.
+ * We get control back within this block in case
+ * the application has set up it's own terminate
+ * handler. Since we are leaving the thread we
+ * should not get any internal pthreads
+ * exceptions.
+ */
+ terminate ();
+ }
+
+#else /* __cplusplus */
+
+ /*
+ * Run the caller's cleanup routine.
+ */
+ destructor (value);
+
+#endif /* __cplusplus */
+
+ }
+ else
+ {
+ /*
+ * Remove association from both the key and thread chains
+ * and reclaim it's memory resources.
+ */
+ ptw32_tkAssocDestroy (assoc);
+ ptw32_mcs_lock_release(&threadLock);
+ ptw32_mcs_lock_release(&keyLock);
+ }
+ }
+ }
+ while (assocsRemaining);
+ }
+} /* ptw32_callUserDestroyRoutines */
diff --git a/libs/pthreads/src/ptw32_calloc.c b/libs/pthreads/src/ptw32_calloc.c
new file mode 100644
index 0000000000..e7b9e64fe6
--- /dev/null
+++ b/libs/pthreads/src/ptw32_calloc.c
@@ -0,0 +1,56 @@
+/*
+ * ptw32_calloc.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#if defined(NEED_CALLOC)
+void *
+ptw32_calloc (size_t n, size_t s)
+{
+ unsigned int m = n * s;
+ void *p;
+
+ p = malloc (m);
+ if (p == NULL)
+ return NULL;
+
+ memset (p, 0, m);
+
+ return p;
+}
+#endif
diff --git a/libs/pthreads/src/ptw32_cond_check_need_init.c b/libs/pthreads/src/ptw32_cond_check_need_init.c
new file mode 100644
index 0000000000..ec3e8bbd69
--- /dev/null
+++ b/libs/pthreads/src/ptw32_cond_check_need_init.c
@@ -0,0 +1,78 @@
+/*
+ * ptw32_cond_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+INLINE int
+ptw32_cond_check_need_init (pthread_cond_t * cond)
+{
+ int result = 0;
+ ptw32_mcs_local_node_t node;
+
+ /*
+ * The following guarded test is specifically for statically
+ * initialised condition variables (via PTHREAD_OBJECT_INITIALIZER).
+ */
+ ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section.
+ * If a static cv has been destroyed, the application can
+ * re-initialise it only by calling pthread_cond_init()
+ * explicitly.
+ */
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ {
+ result = pthread_cond_init (cond, NULL);
+ }
+ else if (*cond == NULL)
+ {
+ /*
+ * The cv has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return result;
+}
diff --git a/libs/pthreads/src/ptw32_getprocessors.c b/libs/pthreads/src/ptw32_getprocessors.c
new file mode 100644
index 0000000000..e60c3143f9
--- /dev/null
+++ b/libs/pthreads/src/ptw32_getprocessors.c
@@ -0,0 +1,91 @@
+/*
+ * ptw32_getprocessors.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * ptw32_getprocessors()
+ *
+ * Get the number of CPUs available to the process.
+ *
+ * If the available number of CPUs is 1 then pthread_spin_lock()
+ * will block rather than spin if the lock is already owned.
+ *
+ * pthread_spin_init() calls this routine when initialising
+ * a spinlock. If the number of available processors changes
+ * (after a call to SetProcessAffinityMask()) then only
+ * newly initialised spinlocks will notice.
+ */
+int
+ptw32_getprocessors (int *count)
+{
+ DWORD_PTR vProcessCPUs;
+ DWORD_PTR vSystemCPUs;
+ int result = 0;
+
+#if defined(NEED_PROCESS_AFFINITY_MASK)
+
+ *count = 1;
+
+#else
+
+ if (GetProcessAffinityMask (GetCurrentProcess (),
+ &vProcessCPUs, &vSystemCPUs))
+ {
+ DWORD_PTR bit;
+ int CPUs = 0;
+
+ for (bit = 1; bit != 0; bit <<= 1)
+ {
+ if (vProcessCPUs & bit)
+ {
+ CPUs++;
+ }
+ }
+ *count = CPUs;
+ }
+ else
+ {
+ result = EAGAIN;
+ }
+
+#endif
+
+ return (result);
+}
diff --git a/libs/pthreads/src/ptw32_is_attr.c b/libs/pthreads/src/ptw32_is_attr.c
new file mode 100644
index 0000000000..36395f81f0
--- /dev/null
+++ b/libs/pthreads/src/ptw32_is_attr.c
@@ -0,0 +1,47 @@
+/*
+ * ptw32_is_attr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+ptw32_is_attr (const pthread_attr_t * attr)
+{
+ /* Return 0 if the attr object is valid, non-zero otherwise. */
+
+ return (attr == NULL ||
+ *attr == NULL || (*attr)->valid != PTW32_ATTR_VALID);
+}
diff --git a/libs/pthreads/src/ptw32_mutex_check_need_init.c b/libs/pthreads/src/ptw32_mutex_check_need_init.c
new file mode 100644
index 0000000000..897db3c68e
--- /dev/null
+++ b/libs/pthreads/src/ptw32_mutex_check_need_init.c
@@ -0,0 +1,92 @@
+/*
+ * ptw32_mutex_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static struct pthread_mutexattr_t_ ptw32_recursive_mutexattr_s =
+ {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_RECURSIVE};
+static struct pthread_mutexattr_t_ ptw32_errorcheck_mutexattr_s =
+ {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK};
+static pthread_mutexattr_t ptw32_recursive_mutexattr = &ptw32_recursive_mutexattr_s;
+static pthread_mutexattr_t ptw32_errorcheck_mutexattr = &ptw32_errorcheck_mutexattr_s;
+
+
+INLINE int
+ptw32_mutex_check_need_init (pthread_mutex_t * mutex)
+{
+ register int result = 0;
+ register pthread_mutex_t mtx;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the mutex is valid (not been destroyed).
+ * If a static mutex has been destroyed, the application can
+ * re-initialise it only by calling pthread_mutex_init()
+ * explicitly.
+ */
+ mtx = *mutex;
+
+ if (mtx == PTHREAD_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, NULL);
+ }
+ else if (mtx == PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, &ptw32_recursive_mutexattr);
+ }
+ else if (mtx == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, &ptw32_errorcheck_mutexattr);
+ }
+ else if (mtx == NULL)
+ {
+ /*
+ * The mutex has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return (result);
+}
diff --git a/libs/pthreads/src/ptw32_new.c b/libs/pthreads/src/ptw32_new.c
new file mode 100644
index 0000000000..ac836ead3a
--- /dev/null
+++ b/libs/pthreads/src/ptw32_new.c
@@ -0,0 +1,94 @@
+/*
+ * ptw32_new.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+pthread_t
+ptw32_new (void)
+{
+ pthread_t t;
+ pthread_t nil = {NULL, 0};
+ ptw32_thread_t * tp;
+
+ /*
+ * If there's a reusable pthread_t then use it.
+ */
+ t = ptw32_threadReusePop ();
+
+ if (NULL != t.p)
+ {
+ tp = (ptw32_thread_t *) t.p;
+ }
+ else
+ {
+ /* No reuse threads available */
+ tp = (ptw32_thread_t *) calloc (1, sizeof(ptw32_thread_t));
+
+ if (tp == NULL)
+ {
+ return nil;
+ }
+
+ /* ptHandle.p needs to point to it's parent ptw32_thread_t. */
+ t.p = tp->ptHandle.p = tp;
+ t.x = tp->ptHandle.x = 0;
+ }
+
+ /* Set default state. */
+ tp->seqNumber = ++ptw32_threadSeqNumber;
+ tp->sched_priority = THREAD_PRIORITY_NORMAL;
+ tp->detachState = PTHREAD_CREATE_JOINABLE;
+ tp->cancelState = PTHREAD_CANCEL_ENABLE;
+ tp->cancelType = PTHREAD_CANCEL_DEFERRED;
+ tp->stateLock = 0;
+ tp->threadLock = 0;
+ tp->robustMxListLock = 0;
+ tp->robustMxList = NULL;
+ tp->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */
+ (int) PTW32_FALSE, /* setSignaled */
+ NULL);
+
+ if (tp->cancelEvent == NULL)
+ {
+ ptw32_threadReusePush (tp->ptHandle);
+ return nil;
+ }
+
+ return t;
+
+}
diff --git a/libs/pthreads/src/ptw32_processInitialize.c b/libs/pthreads/src/ptw32_processInitialize.c
new file mode 100644
index 0000000000..8da3e41fa1
--- /dev/null
+++ b/libs/pthreads/src/ptw32_processInitialize.c
@@ -0,0 +1,92 @@
+/*
+ * ptw32_processInitialize.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+ptw32_processInitialize (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPRIVATE
+ * This function performs process wide initialization for
+ * the pthread library.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ * DESCRIPTION
+ * This function performs process wide initialization for
+ * the pthread library.
+ * If successful, this routine sets the global variable
+ * ptw32_processInitialized to TRUE.
+ *
+ * RESULTS
+ * TRUE if successful,
+ * FALSE otherwise
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_processInitialized)
+ {
+ /*
+ * Ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. Such programs must call ptw32_processInitialize() explicitly,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return PTW32_TRUE;
+ }
+
+ ptw32_processInitialized = PTW32_TRUE;
+
+ /*
+ * Initialize Keys
+ */
+ if ((pthread_key_create (&ptw32_selfThreadKey, NULL) != 0) ||
+ (pthread_key_create (&ptw32_cleanupKey, NULL) != 0))
+ {
+
+ ptw32_processTerminate ();
+ }
+
+ return (ptw32_processInitialized);
+
+} /* processInitialize */
diff --git a/libs/pthreads/src/ptw32_processTerminate.c b/libs/pthreads/src/ptw32_processTerminate.c
new file mode 100644
index 0000000000..83f0f23cab
--- /dev/null
+++ b/libs/pthreads/src/ptw32_processTerminate.c
@@ -0,0 +1,105 @@
+/*
+ * ptw32_processTerminate.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void
+ptw32_processTerminate (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPRIVATE
+ * This function performs process wide termination for
+ * the pthread library.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ * DESCRIPTION
+ * This function performs process wide termination for
+ * the pthread library.
+ * This routine sets the global variable
+ * ptw32_processInitialized to FALSE
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_processInitialized)
+ {
+ ptw32_thread_t * tp, * tpNext;
+ ptw32_mcs_local_node_t node;
+
+ if (ptw32_selfThreadKey != NULL)
+ {
+ /*
+ * Release ptw32_selfThreadKey
+ */
+ pthread_key_delete (ptw32_selfThreadKey);
+
+ ptw32_selfThreadKey = NULL;
+ }
+
+ if (ptw32_cleanupKey != NULL)
+ {
+ /*
+ * Release ptw32_cleanupKey
+ */
+ pthread_key_delete (ptw32_cleanupKey);
+
+ ptw32_cleanupKey = NULL;
+ }
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ tp = ptw32_threadReuseTop;
+ while (tp != PTW32_THREAD_REUSE_EMPTY)
+ {
+ tpNext = tp->prevReuse;
+ free (tp);
+ tp = tpNext;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ ptw32_processInitialized = PTW32_FALSE;
+ }
+
+} /* processTerminate */
diff --git a/libs/pthreads/src/ptw32_relmillisecs.c b/libs/pthreads/src/ptw32_relmillisecs.c
new file mode 100644
index 0000000000..894d5c9d46
--- /dev/null
+++ b/libs/pthreads/src/ptw32_relmillisecs.c
@@ -0,0 +1,132 @@
+/*
+ * ptw32_relmillisecs.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#if !defined(NEED_FTIME)
+#include <sys/timeb.h>
+#endif
+
+
+#if defined(PTW32_BUILD_INLINED)
+INLINE
+#endif /* PTW32_BUILD_INLINED */
+DWORD
+ptw32_relmillisecs (const struct timespec * abstime)
+{
+ const int64_t NANOSEC_PER_MILLISEC = 1000000;
+ const int64_t MILLISEC_PER_SEC = 1000;
+ DWORD milliseconds;
+ int64_t tmpAbsMilliseconds;
+ int64_t tmpCurrMilliseconds;
+#if defined(NEED_FTIME)
+ struct timespec currSysTime;
+ FILETIME ft;
+ SYSTEMTIME st;
+#else /* ! NEED_FTIME */
+#if ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \
+ ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 )
+ struct __timeb64 currSysTime;
+#else
+ struct _timeb currSysTime;
+#endif
+#endif /* NEED_FTIME */
+
+
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+
+ /*
+ * subtract current system time from abstime in a way that checks
+ * that abstime is never in the past, or is never equivalent to the
+ * defined INFINITE value (0xFFFFFFFF).
+ *
+ * Assume all integers are unsigned, i.e. cannot test if less than 0.
+ */
+ tmpAbsMilliseconds = (int64_t)abstime->tv_sec * MILLISEC_PER_SEC;
+ tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
+
+ /* get current system time */
+
+#if defined(NEED_FTIME)
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ /*
+ * GetSystemTimeAsFileTime(&ft); would be faster,
+ * but it does not exist on WinCE
+ */
+
+ ptw32_filetime_to_timespec(&ft, &currSysTime);
+
+ tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC;
+ tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2))
+ / NANOSEC_PER_MILLISEC;
+
+#else /* ! NEED_FTIME */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ _ftime64_s(&currSysTime);
+#elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \
+ ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 )
+ _ftime64(&currSysTime);
+#else
+ _ftime(&currSysTime);
+#endif
+
+ tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC;
+ tmpCurrMilliseconds += (int64_t) currSysTime.millitm;
+
+#endif /* NEED_FTIME */
+
+ if (tmpAbsMilliseconds > tmpCurrMilliseconds)
+ {
+ milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds);
+ if (milliseconds == INFINITE)
+ {
+ /* Timeouts must be finite */
+ milliseconds--;
+ }
+ }
+ else
+ {
+ /* The abstime given is in the past */
+ milliseconds = 0;
+ }
+
+ return milliseconds;
+}
diff --git a/libs/pthreads/src/ptw32_reuse.c b/libs/pthreads/src/ptw32_reuse.c
new file mode 100644
index 0000000000..7325857ba2
--- /dev/null
+++ b/libs/pthreads/src/ptw32_reuse.c
@@ -0,0 +1,151 @@
+/*
+ * ptw32_threadReuse.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * How it works:
+ * A pthread_t is a struct (2x32 bit scalar types on IA-32, 2x64 bit on IA-64)
+ * which is normally passed/returned by value to/from pthreads routines.
+ * Applications are therefore storing a copy of the struct as it is at that
+ * time.
+ *
+ * The original pthread_t struct plus all copies of it contain the address of
+ * the thread state struct ptw32_thread_t_ (p), plus a reuse counter (x). Each
+ * ptw32_thread_t contains the original copy of it's pthread_t.
+ * Once malloced, a ptw32_thread_t_ struct is not freed until the process exits.
+ *
+ * The thread reuse stack is a simple LILO stack managed through a singly
+ * linked list element in the ptw32_thread_t.
+ *
+ * Each time a thread is destroyed, the ptw32_thread_t address is pushed onto the
+ * reuse stack after it's ptHandle's reuse counter has been incremented.
+ *
+ * The following can now be said from this:
+ * - two pthread_t's are identical if their ptw32_thread_t reference pointers
+ * are equal and their reuse counters are equal. That is,
+ *
+ * equal = (a.p == b.p && a.x == b.x)
+ *
+ * - a pthread_t copy refers to a destroyed thread if the reuse counter in
+ * the copy is not equal to the reuse counter in the original.
+ *
+ * threadDestroyed = (copy.x != ((ptw32_thread_t *)copy.p)->ptHandle.x)
+ *
+ */
+
+/*
+ * Pop a clean pthread_t struct off the reuse stack.
+ */
+pthread_t
+ptw32_threadReusePop (void)
+{
+ pthread_t t = {NULL, 0};
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop)
+ {
+ ptw32_thread_t * tp;
+
+ tp = ptw32_threadReuseTop;
+
+ ptw32_threadReuseTop = tp->prevReuse;
+
+ if (PTW32_THREAD_REUSE_EMPTY == ptw32_threadReuseTop)
+ {
+ ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
+ }
+
+ tp->prevReuse = NULL;
+
+ t = tp->ptHandle;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return t;
+
+}
+
+/*
+ * Push a clean pthread_t struct onto the reuse stack.
+ * Must be re-initialised when reused.
+ * All object elements (mutexes, events etc) must have been either
+ * detroyed before this, or never initialised.
+ */
+void
+ptw32_threadReusePush (pthread_t thread)
+{
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ pthread_t t;
+ ptw32_mcs_local_node_t node;
+
+ ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node);
+
+ t = tp->ptHandle;
+ memset(tp, 0, sizeof(ptw32_thread_t));
+
+ /* Must restore the original POSIX handle that we just wiped. */
+ tp->ptHandle = t;
+
+ /* Bump the reuse counter now */
+#if defined(PTW32_THREAD_ID_REUSE_INCREMENT)
+ tp->ptHandle.x += PTW32_THREAD_ID_REUSE_INCREMENT;
+#else
+ tp->ptHandle.x++;
+#endif
+
+ tp->state = PThreadStateReuse;
+
+ tp->prevReuse = PTW32_THREAD_REUSE_EMPTY;
+
+ if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseBottom)
+ {
+ ptw32_threadReuseBottom->prevReuse = tp;
+ }
+ else
+ {
+ ptw32_threadReuseTop = tp;
+ }
+
+ ptw32_threadReuseBottom = tp;
+
+ ptw32_mcs_lock_release(&node);
+}
diff --git a/libs/pthreads/src/ptw32_rwlock_cancelwrwait.c b/libs/pthreads/src/ptw32_rwlock_cancelwrwait.c
new file mode 100644
index 0000000000..a057bd1d72
--- /dev/null
+++ b/libs/pthreads/src/ptw32_rwlock_cancelwrwait.c
@@ -0,0 +1,50 @@
+/*
+ * ptw32_rwlock_cancelwrwait.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+void
+ptw32_rwlock_cancelwrwait (void *arg)
+{
+ pthread_rwlock_t rwl = (pthread_rwlock_t) arg;
+
+ rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ (void) pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+}
diff --git a/libs/pthreads/src/ptw32_rwlock_check_need_init.c b/libs/pthreads/src/ptw32_rwlock_check_need_init.c
new file mode 100644
index 0000000000..858ee271ce
--- /dev/null
+++ b/libs/pthreads/src/ptw32_rwlock_check_need_init.c
@@ -0,0 +1,77 @@
+/*
+ * pthread_rwlock_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+INLINE int
+ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock)
+{
+ int result = 0;
+ ptw32_mcs_local_node_t node;
+
+ /*
+ * The following guarded test is specifically for statically
+ * initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER).
+ */
+ ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the rwlock is valid (not been destroyed).
+ * If a static rwlock has been destroyed, the application can
+ * re-initialise it only by calling pthread_rwlock_init()
+ * explicitly.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = pthread_rwlock_init (rwlock, NULL);
+ }
+ else if (*rwlock == NULL)
+ {
+ /*
+ * The rwlock has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return result;
+}
diff --git a/libs/pthreads/src/ptw32_semwait.c b/libs/pthreads/src/ptw32_semwait.c
new file mode 100644
index 0000000000..c3c4fd0e5e
--- /dev/null
+++ b/libs/pthreads/src/ptw32_semwait.c
@@ -0,0 +1,135 @@
+/*
+ * ptw32_semwait.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined(_UWIN)
+/*# include <process.h> */
+#endif
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+ptw32_semwait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DESCRIPTION
+ * This function waits on a POSIX semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value.
+ *
+ * Unlike sem_wait(), this routine is non-cancelable.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno.
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ int v;
+
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ v = --s->value;
+ (void) pthread_mutex_unlock (&s->lock);
+
+ if (v < 0)
+ {
+ /* Must wait */
+ if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0)
+ {
+#if defined(NEED_SEM)
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (s->leftToUnblock > 0)
+ {
+ --s->leftToUnblock;
+ SetEvent(s->sem);
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+#endif
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* ptw32_semwait */
diff --git a/libs/pthreads/src/ptw32_spinlock_check_need_init.c b/libs/pthreads/src/ptw32_spinlock_check_need_init.c
new file mode 100644
index 0000000000..8808454ee8
--- /dev/null
+++ b/libs/pthreads/src/ptw32_spinlock_check_need_init.c
@@ -0,0 +1,78 @@
+/*
+ * ptw32_spinlock_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+INLINE int
+ptw32_spinlock_check_need_init (pthread_spinlock_t * lock)
+{
+ int result = 0;
+ ptw32_mcs_local_node_t node;
+
+ /*
+ * The following guarded test is specifically for statically
+ * initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER).
+ */
+ ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the spinlock is valid (not been destroyed).
+ * If a static spinlock has been destroyed, the application can
+ * re-initialise it only by calling pthread_spin_init()
+ * explicitly.
+ */
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ result = pthread_spin_init (lock, PTHREAD_PROCESS_PRIVATE);
+ }
+ else if (*lock == NULL)
+ {
+ /*
+ * The spinlock has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ ptw32_mcs_lock_release(&node);
+
+ return (result);
+}
diff --git a/libs/pthreads/src/ptw32_threadDestroy.c b/libs/pthreads/src/ptw32_threadDestroy.c
new file mode 100644
index 0000000000..41499b11b6
--- /dev/null
+++ b/libs/pthreads/src/ptw32_threadDestroy.c
@@ -0,0 +1,79 @@
+/*
+ * ptw32_threadDestroy.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void
+ptw32_threadDestroy (pthread_t thread)
+{
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_thread_t threadCopy;
+
+ if (tp != NULL)
+ {
+ /*
+ * Copy thread state so that the thread can be atomically NULLed.
+ */
+ memcpy (&threadCopy, tp, sizeof (threadCopy));
+
+ /*
+ * Thread ID structs are never freed. They're NULLed and reused.
+ * This also sets the thread to PThreadStateInitial (invalid).
+ */
+ ptw32_threadReusePush (thread);
+
+ /* Now work on the copy. */
+ if (threadCopy.cancelEvent != NULL)
+ {
+ CloseHandle (threadCopy.cancelEvent);
+ }
+
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ /*
+ * See documentation for endthread vs endthreadex.
+ */
+ if (threadCopy.threadH != 0)
+ {
+ CloseHandle (threadCopy.threadH);
+ }
+#endif
+
+ }
+} /* ptw32_threadDestroy */
+
diff --git a/libs/pthreads/src/ptw32_threadStart.c b/libs/pthreads/src/ptw32_threadStart.c
new file mode 100644
index 0000000000..e83ede0ec4
--- /dev/null
+++ b/libs/pthreads/src/ptw32_threadStart.c
@@ -0,0 +1,357 @@
+/*
+ * ptw32_threadStart.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include <stdio.h>
+
+#if defined(__CLEANUP_C)
+# include <setjmp.h>
+#endif
+
+#if defined(__CLEANUP_SEH)
+
+static DWORD
+ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei)
+{
+ switch (ep->ExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_PTW32_SERVICES:
+ {
+ DWORD param;
+ DWORD numParams = ep->ExceptionRecord->NumberParameters;
+
+ numParams = (numParams > 3) ? 3 : numParams;
+
+ for (param = 0; param < numParams; param++)
+ {
+ ei[param] = ep->ExceptionRecord->ExceptionInformation[param];
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ break;
+ }
+ default:
+ {
+ /*
+ * A system unexpected exception has occurred running the user's
+ * routine. We need to cleanup before letting the exception
+ * out of thread scope.
+ */
+ pthread_t self = pthread_self ();
+
+ ptw32_callUserDestroyRoutines (self);
+
+ return EXCEPTION_CONTINUE_SEARCH;
+ break;
+ }
+ }
+}
+
+#elif defined(__CLEANUP_CXX)
+
+#if defined(_MSC_VER)
+# include <eh.h>
+#elif defined(__WATCOMC__)
+# include <eh.h>
+# include <exceptio.h>
+typedef terminate_handler
+ terminate_function;
+#else
+# if defined(__GNUC__) && __GNUC__ < 3
+# include <new.h>
+# else
+# include <new>
+using
+ std::terminate_handler;
+using
+ std::terminate;
+using
+ std::set_terminate;
+# endif
+typedef terminate_handler
+ terminate_function;
+#endif
+
+static terminate_function
+ ptw32_oldTerminate;
+
+void
+ptw32_terminate ()
+{
+ set_terminate (ptw32_oldTerminate);
+ (void) pthread_win32_thread_detach_np ();
+ terminate ();
+}
+
+#endif
+
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || (defined (__MSVCRT__) && ! defined (__DMC__))
+unsigned
+ __stdcall
+#else
+void
+#endif
+ptw32_threadStart (void *vthreadParms)
+{
+ ThreadParms * threadParms = (ThreadParms *) vthreadParms;
+ pthread_t self;
+ ptw32_thread_t * sp;
+ void * (PTW32_CDECL *start) (void *);
+ void * arg;
+
+#if defined(__CLEANUP_SEH)
+ DWORD
+ ei[] = { 0, 0, 0 };
+#endif
+
+#if defined(__CLEANUP_C)
+ int setjmp_rc;
+#endif
+
+ ptw32_mcs_local_node_t stateLock;
+ void * status = (void *) 0;
+
+ self = threadParms->tid;
+ sp = (ptw32_thread_t *) self.p;
+ start = threadParms->start;
+ arg = threadParms->arg;
+
+ free (threadParms);
+
+#if (defined(__MINGW64__) || defined(__MINGW32__)) && ! defined (__MSVCRT__)
+ /*
+ * beginthread does not return the thread id and is running
+ * before it returns us the thread handle, and so we do it here.
+ */
+ sp->thread = GetCurrentThreadId ();
+ /*
+ * Here we're using stateLock as a general-purpose lock
+ * to make the new thread wait until the creating thread
+ * has the new handle.
+ */
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+ pthread_setspecific (ptw32_selfThreadKey, sp);
+#else
+ pthread_setspecific (ptw32_selfThreadKey, sp);
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+#endif
+
+ sp->state = PThreadStateRunning;
+ ptw32_mcs_lock_release (&stateLock);
+
+#if defined(__CLEANUP_SEH)
+
+ __try
+ {
+ /*
+ * Run the caller's routine;
+ */
+ status = sp->exitStatus = (*start) (arg);
+ sp->state = PThreadStateExiting;
+
+#if defined(_UWIN)
+ if (--pthread_count <= 0)
+ exit (0);
+#endif
+
+ }
+ __except (ExceptionFilter (GetExceptionInformation (), ei))
+ {
+ switch (ei[0])
+ {
+ case PTW32_EPS_CANCEL:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+#if defined(_UWIN)
+ if (--pthread_count <= 0)
+ exit (0);
+#endif
+ break;
+ case PTW32_EPS_EXIT:
+ status = sp->exitStatus;
+ break;
+ default:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ }
+ }
+
+#else /* __CLEANUP_SEH */
+
+#if defined(__CLEANUP_C)
+
+ setjmp_rc = setjmp (sp->start_mark);
+
+ if (0 == setjmp_rc)
+ {
+
+ /*
+ * Run the caller's routine;
+ */
+ status = sp->exitStatus = (*start) (arg);
+ sp->state = PThreadStateExiting;
+ }
+ else
+ {
+ switch (setjmp_rc)
+ {
+ case PTW32_EPS_CANCEL:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ case PTW32_EPS_EXIT:
+ status = sp->exitStatus;
+ break;
+ default:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ }
+ }
+
+#else /* __CLEANUP_C */
+
+#if defined(__CLEANUP_CXX)
+
+ ptw32_oldTerminate = set_terminate (&ptw32_terminate);
+
+ try
+ {
+ /*
+ * Run the caller's routine in a nested try block so that we
+ * can run the user's terminate function, which may call
+ * pthread_exit() or be canceled.
+ */
+ try
+ {
+ status = sp->exitStatus = (*start) (arg);
+ sp->state = PThreadStateExiting;
+ }
+ catch (ptw32_exception &)
+ {
+ /*
+ * Pass these through to the outer block.
+ */
+ throw;
+ }
+ catch (...)
+ {
+ /*
+ * We want to run the user's terminate function if supplied.
+ * That function may call pthread_exit() or be canceled, which will
+ * be handled by the outer try block.
+ *
+ * ptw32_terminate() will be called if there is no user
+ * supplied function.
+ */
+ terminate_function
+ term_func = set_terminate (0);
+ set_terminate (term_func);
+
+ if (term_func != 0)
+ {
+ term_func ();
+ }
+ throw;
+ }
+ }
+ catch (ptw32_exception_cancel &)
+ {
+ /*
+ * Thread was canceled.
+ */
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ }
+ catch (ptw32_exception_exit &)
+ {
+ /*
+ * Thread was exited via pthread_exit().
+ */
+ status = sp->exitStatus;
+ }
+ catch (...)
+ {
+ /*
+ * A system unexpected exception has occurred running the user's
+ * terminate routine. We get control back within this block
+ * and exit with a substitute status. If the thread was not
+ * cancelled then this indicates the unhandled exception.
+ */
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ }
+
+ (void) set_terminate (ptw32_oldTerminate);
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* __CLEANUP_CXX */
+#endif /* __CLEANUP_C */
+#endif /* __CLEANUP_SEH */
+
+#if defined(PTW32_STATIC_LIB)
+ /*
+ * We need to cleanup the pthread now if we have
+ * been statically linked, in which case the cleanup
+ * in dllMain won't get done. Joinable threads will
+ * only be partially cleaned up and must be fully cleaned
+ * up by pthread_join() or pthread_detach().
+ *
+ * Note: if this library has been statically linked,
+ * implicitly created pthreads (those created
+ * for Win32 threads which have called pthreads routines)
+ * must be cleaned up explicitly by the application
+ * (by calling pthread_win32_thread_detach_np()).
+ * For the dll, dllMain will do the cleanup automatically.
+ */
+ (void) pthread_win32_thread_detach_np ();
+#endif
+
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ _endthreadex ((unsigned)(size_t) status);
+#else
+ _endthread ();
+#endif
+
+ /*
+ * Never reached.
+ */
+
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ return (unsigned)(size_t) status;
+#endif
+
+} /* ptw32_threadStart */
diff --git a/libs/pthreads/src/ptw32_throw.c b/libs/pthreads/src/ptw32_throw.c
new file mode 100644
index 0000000000..1404e940f5
--- /dev/null
+++ b/libs/pthreads/src/ptw32_throw.c
@@ -0,0 +1,189 @@
+/*
+ * ptw32_throw.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#if defined(__CLEANUP_C)
+# include <setjmp.h>
+#endif
+
+/*
+ * ptw32_throw
+ *
+ * All canceled and explicitly exited POSIX threads go through
+ * here. This routine knows how to exit both POSIX initiated threads and
+ * 'implicit' POSIX threads for each of the possible language modes (C,
+ * C++, and SEH).
+ */
+#if defined(_MSC_VER)
+/*
+ * Ignore the warning:
+ * "C++ exception specification ignored except to indicate that
+ * the function is not __declspec(nothrow)."
+ */
+#pragma warning(disable:4290)
+#endif
+void
+ptw32_throw (DWORD exception)
+#if defined(__CLEANUP_CXX)
+ throw(ptw32_exception_cancel,ptw32_exception_exit)
+#endif
+{
+ /*
+ * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
+ * unnecessarily.
+ */
+ ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+#if defined(__CLEANUP_SEH)
+ DWORD exceptionInformation[3];
+#endif
+
+ sp->state = PThreadStateExiting;
+
+ if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT)
+ {
+ /* Should never enter here */
+ exit (1);
+ }
+
+ if (NULL == sp || sp->implicit)
+ {
+ /*
+ * We're inside a non-POSIX initialised Win32 thread
+ * so there is no point to jump or throw back to. Just do an
+ * explicit thread exit here after cleaning up POSIX
+ * residue (i.e. cleanup handlers, POSIX thread handle etc).
+ */
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ unsigned exitCode = 0;
+
+ switch (exception)
+ {
+ case PTW32_EPS_CANCEL:
+ exitCode = (unsigned)(size_t) PTHREAD_CANCELED;
+ break;
+ case PTW32_EPS_EXIT:
+ if (NULL != sp)
+ {
+ exitCode = (unsigned)(size_t) sp->exitStatus;
+ }
+ break;
+ }
+#endif
+
+#if defined(PTW32_STATIC_LIB)
+
+ pthread_win32_thread_detach_np ();
+
+#endif
+
+#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
+ _endthreadex (exitCode);
+#else
+ _endthread ();
+#endif
+
+ }
+
+#if defined(__CLEANUP_SEH)
+
+
+ exceptionInformation[0] = (DWORD) (exception);
+ exceptionInformation[1] = (DWORD) (0);
+ exceptionInformation[2] = (DWORD) (0);
+
+ RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation);
+
+#else /* __CLEANUP_SEH */
+
+#if defined(__CLEANUP_C)
+
+ ptw32_pop_cleanup_all (1);
+ longjmp (sp->start_mark, exception);
+
+#else /* __CLEANUP_C */
+
+#if defined(__CLEANUP_CXX)
+
+ switch (exception)
+ {
+ case PTW32_EPS_CANCEL:
+ throw ptw32_exception_cancel ();
+ break;
+ case PTW32_EPS_EXIT:
+ throw ptw32_exception_exit ();
+ break;
+ }
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* __CLEANUP_C */
+
+#endif /* __CLEANUP_SEH */
+
+ /* Never reached */
+}
+
+
+void
+ptw32_pop_cleanup_all (int execute)
+{
+ while (NULL != ptw32_pop_cleanup (execute))
+ {
+ }
+}
+
+
+DWORD
+ptw32_get_exception_services_code (void)
+{
+#if defined(__CLEANUP_SEH)
+
+ return EXCEPTION_PTW32_SERVICES;
+
+#else
+
+ return (DWORD)0;
+
+#endif
+}
diff --git a/libs/pthreads/src/ptw32_timespec.c b/libs/pthreads/src/ptw32_timespec.c
new file mode 100644
index 0000000000..6318957a89
--- /dev/null
+++ b/libs/pthreads/src/ptw32_timespec.c
@@ -0,0 +1,83 @@
+/*
+ * ptw32_timespec.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#if defined(NEED_FTIME)
+
+/*
+ * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds
+ */
+#define PTW32_TIMESPEC_TO_FILETIME_OFFSET \
+ ( ((int64_t) 27111902 << 32) + (int64_t) 3577643008 )
+
+INLINE void
+ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft)
+ /*
+ * -------------------------------------------------------------------
+ * converts struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * into FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * -------------------------------------------------------------------
+ */
+{
+ *(int64_t *) ft = ts->tv_sec * 10000000
+ + (ts->tv_nsec + 50) / 100 + PTW32_TIMESPEC_TO_FILETIME_OFFSET;
+}
+
+INLINE void
+ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts)
+ /*
+ * -------------------------------------------------------------------
+ * converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * into struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * -------------------------------------------------------------------
+ */
+{
+ ts->tv_sec =
+ (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
+ ts->tv_nsec =
+ (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET -
+ ((int64_t) ts->tv_sec * (int64_t) 10000000)) * 100);
+}
+
+#endif /* NEED_FTIME */
diff --git a/libs/pthreads/src/ptw32_tkAssocCreate.c b/libs/pthreads/src/ptw32_tkAssocCreate.c
new file mode 100644
index 0000000000..50d6c500c3
--- /dev/null
+++ b/libs/pthreads/src/ptw32_tkAssocCreate.c
@@ -0,0 +1,118 @@
+/*
+ * ptw32_tkAssocCreate.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+ptw32_tkAssocCreate (ptw32_thread_t * sp, pthread_key_t key)
+ /*
+ * -------------------------------------------------------------------
+ * This routine creates an association that
+ * is unique for the given (thread,key) combination.The association
+ * is referenced by both the thread and the key.
+ * This association allows us to determine what keys the
+ * current thread references and what threads a given key
+ * references.
+ * See the detailed description
+ * at the beginning of this file for further details.
+ *
+ * Notes:
+ * 1) New associations are pushed to the beginning of the
+ * chain so that the internal ptw32_selfThreadKey association
+ * is always last, thus allowing selfThreadExit to
+ * be implicitly called last by pthread_exit.
+ * 2)
+ *
+ * Parameters:
+ * thread
+ * current running thread.
+ * key
+ * key on which to create an association.
+ * Returns:
+ * 0 - if successful,
+ * ENOMEM - not enough memory to create assoc or other object
+ * EINVAL - an internal error occurred
+ * ENOSYS - an internal error occurred
+ * -------------------------------------------------------------------
+ */
+{
+ ThreadKeyAssoc *assoc;
+
+ /*
+ * Have to create an association and add it
+ * to both the key and the thread.
+ *
+ * Both key->keyLock and thread->threadLock are locked before
+ * entry to this routine.
+ */
+ assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc));
+
+ if (assoc == NULL)
+ {
+ return ENOMEM;
+ }
+
+ assoc->thread = sp;
+ assoc->key = key;
+
+ /*
+ * Register assoc with key
+ */
+ assoc->prevThread = NULL;
+ assoc->nextThread = (ThreadKeyAssoc *) key->threads;
+ if (assoc->nextThread != NULL)
+ {
+ assoc->nextThread->prevThread = assoc;
+ }
+ key->threads = (void *) assoc;
+
+ /*
+ * Register assoc with thread
+ */
+ assoc->prevKey = NULL;
+ assoc->nextKey = (ThreadKeyAssoc *) sp->keys;
+ if (assoc->nextKey != NULL)
+ {
+ assoc->nextKey->prevKey = assoc;
+ }
+ sp->keys = (void *) assoc;
+
+ return (0);
+
+} /* ptw32_tkAssocCreate */
diff --git a/libs/pthreads/src/ptw32_tkAssocDestroy.c b/libs/pthreads/src/ptw32_tkAssocDestroy.c
new file mode 100644
index 0000000000..fedebf5935
--- /dev/null
+++ b/libs/pthreads/src/ptw32_tkAssocDestroy.c
@@ -0,0 +1,114 @@
+/*
+ * ptw32_tkAssocDestroy.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void
+ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc)
+ /*
+ * -------------------------------------------------------------------
+ * This routine releases all resources for the given ThreadKeyAssoc
+ * once it is no longer being referenced
+ * ie) either the key or thread has stopped referencing it.
+ *
+ * Parameters:
+ * assoc
+ * an instance of ThreadKeyAssoc.
+ * Returns:
+ * N/A
+ * -------------------------------------------------------------------
+ */
+{
+
+ /*
+ * Both key->keyLock and thread->threadLock are locked before
+ * entry to this routine.
+ */
+ if (assoc != NULL)
+ {
+ ThreadKeyAssoc * prev, * next;
+
+ /* Remove assoc from thread's keys chain */
+ prev = assoc->prevKey;
+ next = assoc->nextKey;
+ if (prev != NULL)
+ {
+ prev->nextKey = next;
+ }
+ if (next != NULL)
+ {
+ next->prevKey = prev;
+ }
+
+ if (assoc->thread->keys == assoc)
+ {
+ /* We're at the head of the thread's keys chain */
+ assoc->thread->keys = next;
+ }
+ if (assoc->thread->nextAssoc == assoc)
+ {
+ /*
+ * Thread is exiting and we're deleting the assoc to be processed next.
+ * Hand thread the assoc after this one.
+ */
+ assoc->thread->nextAssoc = next;
+ }
+
+ /* Remove assoc from key's threads chain */
+ prev = assoc->prevThread;
+ next = assoc->nextThread;
+ if (prev != NULL)
+ {
+ prev->nextThread = next;
+ }
+ if (next != NULL)
+ {
+ next->prevThread = prev;
+ }
+
+ if (assoc->key->threads == assoc)
+ {
+ /* We're at the head of the key's threads chain */
+ assoc->key->threads = next;
+ }
+
+ free (assoc);
+ }
+
+} /* ptw32_tkAssocDestroy */
diff --git a/libs/pthreads/src/rwlock.c b/libs/pthreads/src/rwlock.c
new file mode 100644
index 0000000000..4a3cd2594c
--- /dev/null
+++ b/libs/pthreads/src/rwlock.c
@@ -0,0 +1,51 @@
+/*
+ * rwlock.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "ptw32_rwlock_check_need_init.c"
+#include "ptw32_rwlock_cancelwrwait.c"
+#include "pthread_rwlock_init.c"
+#include "pthread_rwlock_destroy.c"
+#include "pthread_rwlockattr_init.c"
+#include "pthread_rwlockattr_destroy.c"
+#include "pthread_rwlockattr_getpshared.c"
+#include "pthread_rwlockattr_setpshared.c"
+#include "pthread_rwlock_rdlock.c"
+#include "pthread_rwlock_timedrdlock.c"
+#include "pthread_rwlock_wrlock.c"
+#include "pthread_rwlock_timedwrlock.c"
+#include "pthread_rwlock_unlock.c"
+#include "pthread_rwlock_tryrdlock.c"
+#include "pthread_rwlock_trywrlock.c"
diff --git a/libs/pthreads/src/sched.c b/libs/pthreads/src/sched.c
new file mode 100644
index 0000000000..ed30ea7b24
--- /dev/null
+++ b/libs/pthreads/src/sched.c
@@ -0,0 +1,53 @@
+/*
+ * sched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+#include "pthread_attr_setschedpolicy.c"
+#include "pthread_attr_getschedpolicy.c"
+#include "pthread_attr_setschedparam.c"
+#include "pthread_attr_getschedparam.c"
+#include "pthread_attr_setinheritsched.c"
+#include "pthread_attr_getinheritsched.c"
+#include "pthread_setschedparam.c"
+#include "pthread_getschedparam.c"
+#include "sched_get_priority_max.c"
+#include "sched_get_priority_min.c"
+#include "sched_setscheduler.c"
+#include "sched_getscheduler.c"
+#include "sched_yield.c"
diff --git a/libs/pthreads/src/sched.h b/libs/pthreads/src/sched.h
new file mode 100644
index 0000000000..f36a97a66b
--- /dev/null
+++ b/libs/pthreads/src/sched.h
@@ -0,0 +1,183 @@
+/*
+ * Module: sched.h
+ *
+ * Purpose:
+ * Provides an implementation of POSIX realtime extensions
+ * as defined in
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined(_SCHED_H)
+#define _SCHED_H
+
+#undef PTW32_SCHED_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_SCHED_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_SCHED_LEVEL
+#define PTW32_SCHED_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_SCHED_LEVEL
+#define PTW32_SCHED_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_SCHED_LEVEL_MAX 3
+
+#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL)
+#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX
+/* Include everything */
+#endif
+
+
+#if defined(__GNUC__) && !defined(__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the library, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the library,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#if !defined(PTW32_STATIC_LIB)
+# if defined(PTW32_BUILD)
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#if !defined(PTW32_CONFIG_H)
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(__MINGW64__)
+# define HAVE_STRUCT_TIMESPEC
+# define HAVE_MODE_T
+# elif defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
+#if defined(NEED_ERRNO)
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */
+
+#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN)
+# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
+/* For pid_t */
+# include <sys/types.h>
+/* Required by Unix 98 */
+# include <time.h>
+# else
+ typedef int pid_t;
+# endif
+#else
+ typedef int pid_t;
+#endif
+
+/* Thread scheduling policies */
+
+enum {
+ SCHED_OTHER = 0,
+ SCHED_FIFO,
+ SCHED_RR,
+ SCHED_MIN = SCHED_OTHER,
+ SCHED_MAX = SCHED_RR
+};
+
+struct sched_param {
+ int sched_priority;
+};
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* __cplusplus */
+
+PTW32_DLLPORT int __cdecl sched_yield (void);
+
+PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy);
+
+PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy);
+
+PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
+
+PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
+
+/*
+ * Note that this macro returns ENOTSUP rather than
+ * ENOSYS as might be expected. However, returning ENOSYS
+ * should mean that sched_get_priority_{min,max} are
+ * not implemented as well as sched_rr_get_interval.
+ * This is not the case, since we just don't support
+ * round-robin scheduling. Therefore I have chosen to
+ * return the same value as sched_setscheduler when
+ * SCHED_RR is passed to it.
+ */
+#define sched_rr_get_interval(_pid, _interval) \
+ ( errno = ENOTSUP, (int) -1 )
+
+
+#if defined(__cplusplus)
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#undef PTW32_SCHED_LEVEL
+#undef PTW32_SCHED_LEVEL_MAX
+
+#endif /* !_SCHED_H */
+
diff --git a/libs/pthreads/src/sched_get_priority_max.c b/libs/pthreads/src/sched_get_priority_max.c
new file mode 100644
index 0000000000..cabf2320a7
--- /dev/null
+++ b/libs/pthreads/src/sched_get_priority_max.c
@@ -0,0 +1,134 @@
+/*
+ * sched_get_priority_max.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+/*
+ * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and
+ * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
+ *
+ * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
+ * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
+ * highest priority use smaller numbers) and the following happens:
+ *
+ * sched_get_priority_min() returns 5
+ * sched_get_priority_max() returns 1
+ *
+ * The following table shows the base priority levels for combinations
+ * of priority class and priority value in Win32.
+ *
+ * Process Priority Class Thread Priority Level
+ * -----------------------------------------------------------------
+ * 1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 17 REALTIME_PRIORITY_CLASS -7
+ * 18 REALTIME_PRIORITY_CLASS -6
+ * 19 REALTIME_PRIORITY_CLASS -5
+ * 20 REALTIME_PRIORITY_CLASS -4
+ * 21 REALTIME_PRIORITY_CLASS -3
+ * 22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 27 REALTIME_PRIORITY_CLASS 3
+ * 28 REALTIME_PRIORITY_CLASS 4
+ * 29 REALTIME_PRIORITY_CLASS 5
+ * 30 REALTIME_PRIORITY_CLASS 6
+ * 31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ *
+ * Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
+ */
+
+
+int
+sched_get_priority_max (int policy)
+{
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+ /* WinCE? */
+ return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#else
+ /* This is independent of scheduling policy in Win32. */
+ return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+}
diff --git a/libs/pthreads/src/sched_get_priority_min.c b/libs/pthreads/src/sched_get_priority_min.c
new file mode 100644
index 0000000000..9c4f8591e5
--- /dev/null
+++ b/libs/pthreads/src/sched_get_priority_min.c
@@ -0,0 +1,135 @@
+/*
+ * sched_get_priority_min.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+/*
+ * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and
+ * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
+ *
+ * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
+ * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
+ * highest priority use smaller numbers) and the following happens:
+ *
+ * sched_get_priority_min() returns 5
+ * sched_get_priority_max() returns 1
+ *
+ * The following table shows the base priority levels for combinations
+ * of priority class and priority value in Win32.
+ *
+ * Process Priority Class Thread Priority Level
+ * -----------------------------------------------------------------
+ * 1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 17 REALTIME_PRIORITY_CLASS -7
+ * 18 REALTIME_PRIORITY_CLASS -6
+ * 19 REALTIME_PRIORITY_CLASS -5
+ * 20 REALTIME_PRIORITY_CLASS -4
+ * 21 REALTIME_PRIORITY_CLASS -3
+ * 22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 27 REALTIME_PRIORITY_CLASS 3
+ * 28 REALTIME_PRIORITY_CLASS 4
+ * 29 REALTIME_PRIORITY_CLASS 5
+ * 30 REALTIME_PRIORITY_CLASS 6
+ * 31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ *
+ * Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
+ *
+ */
+
+
+int
+sched_get_priority_min (int policy)
+{
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+ /* WinCE? */
+ return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#else
+ /* This is independent of scheduling policy in Win32. */
+ return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+}
diff --git a/libs/pthreads/src/sched_getscheduler.c b/libs/pthreads/src/sched_getscheduler.c
new file mode 100644
index 0000000000..8769c15e5a
--- /dev/null
+++ b/libs/pthreads/src/sched_getscheduler.c
@@ -0,0 +1,71 @@
+/*
+ * sched_getscheduler.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+sched_getscheduler (pid_t pid)
+{
+ /*
+ * Win32 only has one policy which we call SCHED_OTHER.
+ * However, we try to provide other valid side-effects
+ * such as EPERM and ESRCH errors.
+ */
+ if (0 != pid)
+ {
+ int selfPid = (int) GetCurrentProcessId ();
+
+ if (pid != selfPid)
+ {
+ HANDLE h =
+ OpenProcess (PROCESS_QUERY_INFORMATION, PTW32_FALSE, (DWORD) pid);
+
+ if (NULL == h)
+ {
+ errno =
+ (GetLastError () ==
+ (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
+ return -1;
+ }
+ else
+ CloseHandle(h);
+ }
+ }
+
+ return SCHED_OTHER;
+}
diff --git a/libs/pthreads/src/sched_setscheduler.c b/libs/pthreads/src/sched_setscheduler.c
new file mode 100644
index 0000000000..8691316371
--- /dev/null
+++ b/libs/pthreads/src/sched_setscheduler.c
@@ -0,0 +1,83 @@
+/*
+ * sched_setscheduler.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+sched_setscheduler (pid_t pid, int policy)
+{
+ /*
+ * Win32 only has one policy which we call SCHED_OTHER.
+ * However, we try to provide other valid side-effects
+ * such as EPERM and ESRCH errors. Choosing to check
+ * for a valid policy last allows us to get the most value out
+ * of this function.
+ */
+ if (0 != pid)
+ {
+ int selfPid = (int) GetCurrentProcessId ();
+
+ if (pid != selfPid)
+ {
+ HANDLE h =
+ OpenProcess (PROCESS_SET_INFORMATION, PTW32_FALSE, (DWORD) pid);
+
+ if (NULL == h)
+ {
+ errno =
+ (GetLastError () ==
+ (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
+ return -1;
+ }
+ else
+ CloseHandle(h);
+ }
+ }
+
+ if (SCHED_OTHER != policy)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ /*
+ * Don't set anything because there is nothing to set.
+ * Just return the current (the only possible) value.
+ */
+ return SCHED_OTHER;
+}
diff --git a/libs/pthreads/src/sched_yield.c b/libs/pthreads/src/sched_yield.c
new file mode 100644
index 0000000000..6ac5ed9263
--- /dev/null
+++ b/libs/pthreads/src/sched_yield.c
@@ -0,0 +1,71 @@
+/*
+ * sched_yield.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+sched_yield (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function indicates that the calling thread is
+ * willing to give up some time slices to other threads.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ *
+ * DESCRIPTION
+ * This function indicates that the calling thread is
+ * willing to give up some time slices to other threads.
+ * NOTE: Since this is part of POSIX 1003.1b
+ * (realtime extensions), it is defined as returning
+ * -1 if an error occurs and sets errno to the actual
+ * error.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * ENOSYS sched_yield not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ Sleep (0);
+
+ return 0;
+}
diff --git a/libs/pthreads/src/sem_close.c b/libs/pthreads/src/sem_close.c
new file mode 100644
index 0000000000..6d7280f299
--- /dev/null
+++ b/libs/pthreads/src/sem_close.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_close.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_close (sem_t * sem)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_close */
diff --git a/libs/pthreads/src/sem_destroy.c b/libs/pthreads/src/sem_destroy.c
new file mode 100644
index 0000000000..6c98e80b93
--- /dev/null
+++ b/libs/pthreads/src/sem_destroy.c
@@ -0,0 +1,144 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_destroy.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_destroy (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function destroys an unnamed semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function destroys an unnamed semaphore.
+ *
+ * RESULTS
+ * 0 successfully destroyed semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EBUSY threads (or processes) are currently
+ * blocked on 'sem'
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = NULL;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ s = *sem;
+
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ if (s->value < 0)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EBUSY;
+ }
+ else
+ {
+ /* There are no threads currently blocked on this semaphore. */
+
+ if (!CloseHandle (s->sem))
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ }
+ else
+ {
+ /*
+ * Invalidate the semaphore handle when we have the lock.
+ * Other sema operations should test this after acquiring the lock
+ * to check that the sema is still valid, i.e. before performing any
+ * operations. This may only be necessary before the sema op routine
+ * returns so that the routine can return EINVAL - e.g. if setting
+ * s->value to SEM_VALUE_MAX below does force a fall-through.
+ */
+ *sem = NULL;
+
+ /* Prevent anyone else actually waiting on or posting this sema.
+ */
+ s->value = SEM_VALUE_MAX;
+
+ (void) pthread_mutex_unlock (&s->lock);
+
+ do
+ {
+ /* Give other threads a chance to run and exit any sema op
+ * routines. Due to the SEM_VALUE_MAX value, if sem_post or
+ * sem_wait were blocked by us they should fall through.
+ */
+ Sleep(0);
+ }
+ while (pthread_mutex_destroy (&s->lock) == EBUSY);
+ }
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ free (s);
+
+ return 0;
+
+} /* sem_destroy */
diff --git a/libs/pthreads/src/sem_getvalue.c b/libs/pthreads/src/sem_getvalue.c
new file mode 100644
index 0000000000..baafb02cf0
--- /dev/null
+++ b/libs/pthreads/src/sem_getvalue.c
@@ -0,0 +1,110 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_getvalue.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of PThreads.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1-2001
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_getvalue (sem_t * sem, int *sval)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function stores the current count value of the
+ * semaphore.
+ * RESULTS
+ *
+ * Return value
+ *
+ * 0 sval has been set.
+ * -1 failed, error in errno
+ *
+ * in global errno
+ *
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS this function is not supported,
+ *
+ *
+ * PARAMETERS
+ *
+ * sem pointer to an instance of sem_t
+ *
+ * sval pointer to int.
+ *
+ * DESCRIPTION
+ * This function stores the current count value of the semaphore
+ * pointed to by sem in the int pointed to by sval.
+ */
+{
+ if (sem == NULL || *sem == NULL || sval == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ else
+ {
+ long value;
+ register sem_t s = *sem;
+ int result = 0;
+
+ if ((result = pthread_mutex_lock(&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ value = s->value;
+ (void) pthread_mutex_unlock(&s->lock);
+ *sval = value;
+ }
+
+ return result;
+ }
+
+} /* sem_getvalue */
diff --git a/libs/pthreads/src/sem_init.c b/libs/pthreads/src/sem_init.c
new file mode 100644
index 0000000000..f682f4b204
--- /dev/null
+++ b/libs/pthreads/src/sem_init.c
@@ -0,0 +1,169 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_init.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of PThreads.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1-2001
+ *
+ * -------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+int
+sem_init (sem_t * sem, int pshared, unsigned int value)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function initializes a semaphore. The
+ * initial value of the semaphore is 'value'
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * pshared
+ * if zero, this semaphore may only be shared between
+ * threads in the same process.
+ * if nonzero, the semaphore can be shared between
+ * processes
+ *
+ * value
+ * initial value of the semaphore counter
+ *
+ * DESCRIPTION
+ * This function initializes a semaphore. The
+ * initial value of the semaphore is set to 'value'.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore, or
+ * 'value' >= SEM_VALUE_MAX
+ * ENOMEM out of memory,
+ * ENOSPC a required resource has been exhausted,
+ * ENOSYS semaphores are not supported,
+ * EPERM the process lacks appropriate privilege
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = NULL;
+
+ if (pshared != 0)
+ {
+ /*
+ * Creating a semaphore that can be shared between
+ * processes
+ */
+ result = EPERM;
+ }
+ else if (value > (unsigned int)SEM_VALUE_MAX)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ s = (sem_t) calloc (1, sizeof (*s));
+
+ if (NULL == s)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+
+ s->value = value;
+ if (pthread_mutex_init(&s->lock, NULL) == 0)
+ {
+
+#if defined(NEED_SEM)
+
+ s->sem = CreateEvent (NULL,
+ PTW32_FALSE, /* auto (not manual) reset */
+ PTW32_FALSE, /* initial state is unset */
+ NULL);
+
+ if (0 == s->sem)
+ {
+ free (s);
+ (void) pthread_mutex_destroy(&s->lock);
+ result = ENOSPC;
+ }
+ else
+ {
+ s->leftToUnblock = 0;
+ }
+
+#else /* NEED_SEM */
+
+ if ((s->sem = CreateSemaphore (NULL, /* Always NULL */
+ (long) 0, /* Force threads to wait */
+ (long) SEM_VALUE_MAX, /* Maximum value */
+ NULL)) == 0) /* Name */
+ {
+ (void) pthread_mutex_destroy(&s->lock);
+ result = ENOSPC;
+ }
+
+#endif /* NEED_SEM */
+
+ }
+ else
+ {
+ result = ENOSPC;
+ }
+
+ if (result != 0)
+ {
+ free(s);
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ *sem = s;
+
+ return 0;
+
+} /* sem_init */
diff --git a/libs/pthreads/src/sem_open.c b/libs/pthreads/src/sem_open.c
new file mode 100644
index 0000000000..fb1cc541f8
--- /dev/null
+++ b/libs/pthreads/src/sem_open.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_open.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_open (const char *name, int oflag, mode_t mode, unsigned int value)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_open */
diff --git a/libs/pthreads/src/sem_post.c b/libs/pthreads/src/sem_post.c
new file mode 100644
index 0000000000..34832527b8
--- /dev/null
+++ b/libs/pthreads/src/sem_post.c
@@ -0,0 +1,128 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_post.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_post (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts a wakeup to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function posts a wakeup to a semaphore. If there
+ * are waiting threads (or processes), one is awakened;
+ * otherwise, the semaphore value is incremented by one.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * ERANGE semaphore count is too big
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ return -1;
+ }
+
+ if (s->value < SEM_VALUE_MAX)
+ {
+#if defined(NEED_SEM)
+ if (++s->value <= 0
+ && !SetEvent(s->sem))
+ {
+ s->value--;
+ result = EINVAL;
+ }
+#else
+ if (++s->value <= 0
+ && !ReleaseSemaphore (s->sem, 1, NULL))
+ {
+ s->value--;
+ result = EINVAL;
+ }
+#endif /* NEED_SEM */
+ }
+ else
+ {
+ result = ERANGE;
+ }
+
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post */
diff --git a/libs/pthreads/src/sem_post_multiple.c b/libs/pthreads/src/sem_post_multiple.c
new file mode 100644
index 0000000000..44c168c6cf
--- /dev/null
+++ b/libs/pthreads/src/sem_post_multiple.c
@@ -0,0 +1,142 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_post_multiple.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_post_multiple (sem_t * sem, int count)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts multiple wakeups to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * count
+ * counter, must be greater than zero.
+ *
+ * DESCRIPTION
+ * This function posts multiple wakeups to a semaphore. If there
+ * are waiting threads (or processes), n <= count are awakened;
+ * the semaphore value is incremented by count - n.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore
+ * or count is less than or equal to zero.
+ * ERANGE semaphore count is too big
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ long waiters;
+ sem_t s = *sem;
+
+ if (s == NULL || count <= 0)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ return -1;
+ }
+
+ if (s->value <= (SEM_VALUE_MAX - count))
+ {
+ waiters = -s->value;
+ s->value += count;
+ if (waiters > 0)
+ {
+#if defined(NEED_SEM)
+ if (SetEvent(s->sem))
+ {
+ waiters--;
+ s->leftToUnblock += count - 1;
+ if (s->leftToUnblock > waiters)
+ {
+ s->leftToUnblock = waiters;
+ }
+ }
+#else
+ if (ReleaseSemaphore (s->sem, (waiters<=count)?waiters:count, 0))
+ {
+ /* No action */
+ }
+#endif
+ else
+ {
+ s->value -= count;
+ result = EINVAL;
+ }
+ }
+ }
+ else
+ {
+ result = ERANGE;
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post_multiple */
diff --git a/libs/pthreads/src/sem_timedwait.c b/libs/pthreads/src/sem_timedwait.c
new file mode 100644
index 0000000000..638431cf1f
--- /dev/null
+++ b/libs/pthreads/src/sem_timedwait.c
@@ -0,0 +1,238 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_timedwait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+typedef struct {
+ sem_t sem;
+ int * resultPtr;
+} sem_timedwait_cleanup_args_t;
+
+
+static void PTW32_CDECL
+ptw32_sem_timedwait_cleanup (void * args)
+{
+ sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args;
+ sem_t s = a->sem;
+
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ /*
+ * We either timed out or were cancelled.
+ * If someone has posted between then and now we try to take the semaphore.
+ * Otherwise the semaphore count may be wrong after we
+ * return. In the case of a cancellation, it is as if we
+ * were cancelled just before we return (after taking the semaphore)
+ * which is ok.
+ */
+ if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)
+ {
+ /* We got the semaphore on the second attempt */
+ *(a->resultPtr) = 0;
+ }
+ else
+ {
+ /* Indicate we're no longer waiting */
+ s->value++;
+#if defined(NEED_SEM)
+ if (s->value > 0)
+ {
+ s->leftToUnblock = 0;
+ }
+#else
+ /*
+ * Don't release the W32 sema, it doesn't need adjustment
+ * because it doesn't record the number of waiters.
+ */
+#endif
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+}
+
+
+int
+sem_timedwait (sem_t * sem, const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a semaphore possibly until
+ * 'abstime' time.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * abstime
+ * pointer to an instance of struct timespec
+ *
+ * DESCRIPTION
+ * This function waits on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value or until interrupted by
+ * a signal.
+ *
+ * If 'abstime' is a NULL pointer then this function will
+ * block until it can successfully decrease the value or
+ * until interrupted by a signal.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ * ETIMEDOUT abstime elapsed before success.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ pthread_testcancel();
+
+ if (sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ DWORD milliseconds;
+
+ if (abstime == NULL)
+ {
+ milliseconds = INFINITE;
+ }
+ else
+ {
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+ milliseconds = ptw32_relmillisecs (abstime);
+ }
+
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ int v;
+
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ v = --s->value;
+ (void) pthread_mutex_unlock (&s->lock);
+
+ if (v < 0)
+ {
+#if defined(NEED_SEM)
+ int timedout;
+#endif
+ sem_timedwait_cleanup_args_t cleanup_args;
+
+ cleanup_args.sem = s;
+ cleanup_args.resultPtr = &result;
+
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+ /* Must wait */
+ pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args);
+#if defined(NEED_SEM)
+ timedout =
+#endif
+ result = pthreadCancelableTimedWait (s->sem, milliseconds);
+ pthread_cleanup_pop(result);
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+
+#if defined(NEED_SEM)
+
+ if (!timedout && pthread_mutex_lock (&s->lock) == 0)
+ {
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (s->leftToUnblock > 0)
+ {
+ --s->leftToUnblock;
+ SetEvent(s->sem);
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+#endif /* NEED_SEM */
+
+ }
+ }
+
+ }
+
+ if (result != 0)
+ {
+
+ errno = result;
+ return -1;
+
+ }
+
+ return 0;
+
+} /* sem_timedwait */
diff --git a/libs/pthreads/src/sem_trywait.c b/libs/pthreads/src/sem_trywait.c
new file mode 100644
index 0000000000..63614ba2b8
--- /dev/null
+++ b/libs/pthreads/src/sem_trywait.c
@@ -0,0 +1,117 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_trywait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_trywait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function tries to wait on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function tries to wait on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * this function returns immediately with the error EAGAIN
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EAGAIN the semaphore was already locked,
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOTSUP sem_trywait is not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (s->value > 0)
+ {
+ s->value--;
+ }
+ else
+ {
+ result = EAGAIN;
+ }
+
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_trywait */
diff --git a/libs/pthreads/src/sem_unlink.c b/libs/pthreads/src/sem_unlink.c
new file mode 100644
index 0000000000..fb80569a0a
--- /dev/null
+++ b/libs/pthreads/src/sem_unlink.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_unlink.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#if defined(_MSC_VER)
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_unlink (const char *name)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_unlink */
diff --git a/libs/pthreads/src/sem_wait.c b/libs/pthreads/src/sem_wait.c
new file mode 100644
index 0000000000..50c11d8080
--- /dev/null
+++ b/libs/pthreads/src/sem_wait.c
@@ -0,0 +1,187 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_wait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+static void PTW32_CDECL
+ptw32_sem_wait_cleanup(void * sem)
+{
+ sem_t s = (sem_t) sem;
+
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ /*
+ * If sema is destroyed do nothing, otherwise:-
+ * If the sema is posted between us being cancelled and us locking
+ * the sema again above then we need to consume that post but cancel
+ * anyway. If we don't get the semaphore we indicate that we're no
+ * longer waiting.
+ */
+ if (*((sem_t *)sem) != NULL && !(WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0))
+ {
+ ++s->value;
+#if defined(NEED_SEM)
+ if (s->value > 0)
+ {
+ s->leftToUnblock = 0;
+ }
+#else
+ /*
+ * Don't release the W32 sema, it doesn't need adjustment
+ * because it doesn't record the number of waiters.
+ */
+#endif /* NEED_SEM */
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+}
+
+int
+sem_wait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function waits on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value or until interrupted by
+ * a signal.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ pthread_testcancel();
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ int v;
+
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ v = --s->value;
+ (void) pthread_mutex_unlock (&s->lock);
+
+ if (v < 0)
+ {
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth(0)
+#endif
+ /* Must wait */
+ pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s);
+ result = pthreadCancelableWait (s->sem);
+ /* Cleanup if we're canceled or on any other error */
+ pthread_cleanup_pop(result);
+#if defined(_MSC_VER) && _MSC_VER < 1400
+#pragma inline_depth()
+#endif
+ }
+#if defined(NEED_SEM)
+
+ if (!result && pthread_mutex_lock (&s->lock) == 0)
+ {
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (s->leftToUnblock > 0)
+ {
+ --s->leftToUnblock;
+ SetEvent(s->sem);
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+#endif /* NEED_SEM */
+
+ }
+
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_wait */
diff --git a/libs/pthreads/src/semaphore.c b/libs/pthreads/src/semaphore.c
new file mode 100644
index 0000000000..64fc0e366d
--- /dev/null
+++ b/libs/pthreads/src/semaphore.c
@@ -0,0 +1,69 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: semaphore.c
+ *
+ * Purpose:
+ * Concatenated version of separate modules to allow
+ * inlining optimisation, which it is assumed can only
+ * be effective within a single module.
+ *
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined(NEED_FTIME)
+# include <sys/timeb.h>
+#endif
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+#include "sem_init.c"
+#include "sem_destroy.c"
+#include "sem_trywait.c"
+#include "sem_wait.c"
+#include "sem_timedwait.c"
+#include "sem_post.c"
+#include "sem_post_multiple.c"
+#include "sem_getvalue.c"
+#include "sem_open.c"
+#include "sem_close.c"
+#include "sem_unlink.c"
diff --git a/libs/pthreads/src/semaphore.h b/libs/pthreads/src/semaphore.h
new file mode 100644
index 0000000000..c6e9407e25
--- /dev/null
+++ b/libs/pthreads/src/semaphore.h
@@ -0,0 +1,169 @@
+/*
+ * Module: semaphore.h
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined( SEMAPHORE_H )
+#define SEMAPHORE_H
+
+#undef PTW32_SEMAPHORE_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_SEMAPHORE_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_SEMAPHORE_LEVEL
+#define PTW32_SEMAPHORE_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_SEMAPHORE_LEVEL
+#define PTW32_SEMAPHORE_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_SEMAPHORE_LEVEL_MAX 3
+
+#if !defined(PTW32_SEMAPHORE_LEVEL)
+#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX
+/* Include everything */
+#endif
+
+#if defined(__GNUC__) && ! defined (__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the library, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the library,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#if !defined(PTW32_STATIC_LIB)
+# if defined(PTW32_BUILD)
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#if !defined(PTW32_CONFIG_H)
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(__MINGW64__)
+# define HAVE_STRUCT_TIMESPEC
+# define HAVE_MODE_T
+# elif defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX
+#if defined(NEED_ERRNO)
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */
+
+#define _POSIX_SEMAPHORES
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* __cplusplus */
+
+#if !defined(HAVE_MODE_T)
+typedef unsigned int mode_t;
+#endif
+
+
+typedef struct sem_t_ * sem_t;
+
+PTW32_DLLPORT int __cdecl sem_init (sem_t * sem,
+ int pshared,
+ unsigned int value);
+
+PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem,
+ const struct timespec * abstime);
+
+PTW32_DLLPORT int __cdecl sem_post (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem,
+ int count);
+
+PTW32_DLLPORT int __cdecl sem_open (const char * name,
+ int oflag,
+ mode_t mode,
+ unsigned int value);
+
+PTW32_DLLPORT int __cdecl sem_close (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_unlink (const char * name);
+
+PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem,
+ int * sval);
+
+#if defined(__cplusplus)
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#undef PTW32_SEMAPHORE_LEVEL
+#undef PTW32_SEMAPHORE_LEVEL_MAX
+
+#endif /* !SEMAPHORE_H */
diff --git a/libs/pthreads/src/signal.c b/libs/pthreads/src/signal.c
new file mode 100644
index 0000000000..eef466962b
--- /dev/null
+++ b/libs/pthreads/src/signal.c
@@ -0,0 +1,179 @@
+/*
+ * signal.c
+ *
+ * Description:
+ * Thread-aware signal functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * Possible future strategy for implementing pthread_kill()
+ * ========================================================
+ *
+ * Win32 does not implement signals.
+ * Signals are simply software interrupts.
+ * pthread_kill() asks the system to deliver a specified
+ * signal (interrupt) to a specified thread in the same
+ * process.
+ * Signals are always asynchronous (no deferred signals).
+ * Pthread-win32 has an async cancelation mechanism.
+ * A similar system can be written to deliver signals
+ * within the same process (on ix86 processors at least).
+ *
+ * Each thread maintains information about which
+ * signals it will respond to. Handler routines
+ * are set on a per-process basis - not per-thread.
+ * When signalled, a thread will check it's sigmask
+ * and, if the signal is not being ignored, call the
+ * handler routine associated with the signal. The
+ * thread must then (except for some signals) return to
+ * the point where it was interrupted.
+ *
+ * Ideally the system itself would check the target thread's
+ * mask before possibly needlessly bothering the thread
+ * itself. This could be done by pthread_kill(), that is,
+ * in the signaling thread since it has access to
+ * all pthread_t structures. It could also retrieve
+ * the handler routine address to minimise the target
+ * threads response overhead. This may also simplify
+ * serialisation of the access to the per-thread signal
+ * structures.
+ *
+ * pthread_kill() eventually calls a routine similar to
+ * ptw32_cancel_thread() which manipulates the target
+ * threads processor context to cause the thread to
+ * run the handler launcher routine. pthread_kill() must
+ * save the target threads current context so that the
+ * handler launcher routine can restore the context after
+ * the signal handler has returned. Some handlers will not
+ * return, eg. the default SIGKILL handler may simply
+ * call pthread_exit().
+ *
+ * The current context is saved in the target threads
+ * pthread_t structure.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#if defined(HAVE_SIGSET_T)
+
+static void
+ptw32_signal_thread ()
+{
+}
+
+static void
+ptw32_signal_callhandler ()
+{
+}
+
+int
+pthread_sigmask (int how, sigset_t const *set, sigset_t * oset)
+{
+ pthread_t thread = pthread_self ();
+
+ if (thread.p == NULL)
+ {
+ return ENOENT;
+ }
+
+ /* Validate the `how' argument. */
+ if (set != NULL)
+ {
+ switch (how)
+ {
+ case SIG_BLOCK:
+ break;
+ case SIG_UNBLOCK:
+ break;
+ case SIG_SETMASK:
+ break;
+ default:
+ /* Invalid `how' argument. */
+ return EINVAL;
+ }
+ }
+
+ /* Copy the old mask before modifying it. */
+ if (oset != NULL)
+ {
+ memcpy (oset, &(thread.p->sigmask), sizeof (sigset_t));
+ }
+
+ if (set != NULL)
+ {
+ unsigned int i;
+
+ /* FIXME: this code assumes that sigmask is an even multiple of
+ the size of a long integer. */
+
+ unsigned long *src = (unsigned long const *) set;
+ unsigned long *dest = (unsigned long *) &(thread.p->sigmask);
+
+ switch (how)
+ {
+ case SIG_BLOCK:
+ for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
+ {
+ /* OR the bit field longword-wise. */
+ *dest++ |= *src++;
+ }
+ break;
+ case SIG_UNBLOCK:
+ for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
+ {
+ /* XOR the bitfield longword-wise. */
+ *dest++ ^= *src++;
+ }
+ case SIG_SETMASK:
+ /* Replace the whole sigmask. */
+ memcpy (&(thread.p->sigmask), set, sizeof (sigset_t));
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+sigwait (const sigset_t * set, int *sig)
+{
+ /* This routine is a cancellation point */
+ pthread_test_cancel();
+}
+
+int
+sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
+{
+}
+
+#endif /* HAVE_SIGSET_T */
diff --git a/libs/pthreads/src/spin.c b/libs/pthreads/src/spin.c
new file mode 100644
index 0000000000..41b5aa5251
--- /dev/null
+++ b/libs/pthreads/src/spin.c
@@ -0,0 +1,46 @@
+/*
+ * spin.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "ptw32_spinlock_check_need_init.c"
+#include "pthread_spin_init.c"
+#include "pthread_spin_destroy.c"
+#include "pthread_spin_lock.c"
+#include "pthread_spin_unlock.c"
+#include "pthread_spin_trylock.c"
diff --git a/libs/pthreads/src/sync.c b/libs/pthreads/src/sync.c
new file mode 100644
index 0000000000..5e56fa9a1f
--- /dev/null
+++ b/libs/pthreads/src/sync.c
@@ -0,0 +1,43 @@
+/*
+ * sync.c
+ *
+ * Description:
+ * This translation unit implements functions related to thread
+ * synchronisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "pthread_detach.c"
+#include "pthread_join.c"
diff --git a/libs/pthreads/src/tsd.c b/libs/pthreads/src/tsd.c
new file mode 100644
index 0000000000..ed44fe6cb4
--- /dev/null
+++ b/libs/pthreads/src/tsd.c
@@ -0,0 +1,44 @@
+/*
+ * tsd.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#include "pthread_key_create.c"
+#include "pthread_key_delete.c"
+#include "pthread_setspecific.c"
+#include "pthread_getspecific.c"
diff --git a/libs/pthreads/src/w32_CancelableWait.c b/libs/pthreads/src/w32_CancelableWait.c
new file mode 100644
index 0000000000..070633e0f9
--- /dev/null
+++ b/libs/pthreads/src/w32_CancelableWait.c
@@ -0,0 +1,161 @@
+/*
+ * w32_CancelableWait.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+static INLINE int
+ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)
+ /*
+ * -------------------------------------------------------------------
+ * This provides an extra hook into the pthread_cancel
+ * mechanism that will allow you to wait on a Windows handle and make it a
+ * cancellation point. This function blocks until the given WIN32 handle is
+ * signaled or pthread_cancel has been called. It is implemented using
+ * WaitForMultipleObjects on 'waitHandle' and a manually reset WIN32
+ * event used to implement pthread_cancel.
+ *
+ * Given this hook it would be possible to implement more of the cancellation
+ * points.
+ * -------------------------------------------------------------------
+ */
+{
+ int result;
+ pthread_t self;
+ ptw32_thread_t * sp;
+ HANDLE handles[2];
+ DWORD nHandles = 1;
+ DWORD status;
+
+ handles[0] = waitHandle;
+
+ self = pthread_self();
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp != NULL)
+ {
+ /*
+ * Get cancelEvent handle
+ */
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+ {
+
+ if ((handles[1] = sp->cancelEvent) != NULL)
+ {
+ nHandles++;
+ }
+ }
+ }
+ else
+ {
+ handles[1] = NULL;
+ }
+
+ status = WaitForMultipleObjects (nHandles, handles, PTW32_FALSE, timeout);
+
+ switch (status - WAIT_OBJECT_0)
+ {
+ case 0:
+ /*
+ * Got the handle.
+ * In the event that both handles are signalled, the smallest index
+ * value (us) is returned. As it has been arranged, this ensures that
+ * we don't drop a signal that we should act on (i.e. semaphore,
+ * mutex, or condition variable etc).
+ */
+ result = 0;
+ break;
+
+ case 1:
+ /*
+ * Got cancel request.
+ * In the event that both handles are signaled, the cancel will
+ * be ignored (see case 0 comment).
+ */
+ ResetEvent (handles[1]);
+
+ if (sp != NULL)
+ {
+ ptw32_mcs_local_node_t stateLock;
+ /*
+ * Should handle POSIX and implicit POSIX threads..
+ * Make sure we haven't been async-canceled in the meantime.
+ */
+ ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
+ if (sp->state < PThreadStateCanceling)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ptw32_mcs_lock_release (&stateLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+ ptw32_mcs_lock_release (&stateLock);
+ }
+
+ /* Should never get to here. */
+ result = EINVAL;
+ break;
+
+ default:
+ if (status == WAIT_TIMEOUT)
+ {
+ result = ETIMEDOUT;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+ break;
+ }
+
+ return (result);
+
+} /* CancelableWait */
+
+int
+pthreadCancelableWait (HANDLE waitHandle)
+{
+ return (ptw32_cancelable_wait (waitHandle, INFINITE));
+}
+
+int
+pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)
+{
+ return (ptw32_cancelable_wait (waitHandle, timeout));
+}
diff --git a/libs/win32/libjson.lib b/libs/win32/libjson.lib
index 933a1a240e..b7787d39d1 100644
--- a/libs/win32/libjson.lib
+++ b/libs/win32/libjson.lib
Binary files differ
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 98c7ad2967..1ad4944bc5 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib
index 2e3ef00691..cb83c2c2b2 100644
--- a/libs/win32/mir_core.lib
+++ b/libs/win32/mir_core.lib
Binary files differ
diff --git a/libs/win64/libjson.lib b/libs/win64/libjson.lib
index 840159782d..75de0f2cab 100644
--- a/libs/win64/libjson.lib
+++ b/libs/win64/libjson.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index a24d42c3c8..3a4f05d465 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib
index c1328f007e..189b02e354 100644
--- a/libs/win64/mir_core.lib
+++ b/libs/win64/mir_core.lib
Binary files differ