diff --git a/.clang-format b/.clang-format index 43032d44e2..3ccecaac1f 100644 --- a/.clang-format +++ b/.clang-format @@ -2,3 +2,10 @@ BasedOnStyle: Google MaxEmptyLinesToKeep: 3 AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false +DerivePointerAlignment: false +PointerAlignment: Right +# TODO(davidben): The default for Google style is now Regroup, but the default +# IncludeCategories does not recognize . We should +# reconfigure IncludeCategories to match. For now, keep it at Preserve. +IncludeBlocks: Preserve + diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000000..cf27a37024 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +service_name: travis-pro diff --git a/.gitattributes b/.gitattributes index bf4e88576e..0271bc950c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,7 @@ * text=auto !eol -*.sln eol=crlf -*.vcxproj eol=crlf -*.vcxproj.filters eol=crlf -*.props eol=crlf -*.bat eol=crlf -*.rc eol=crlf -*.pl linguist-language=Assembly +crypto/**/*.pl linguist-language=Assembly +crypto/perlasm/*.pl linguist-language=Perl *.bin binary *.der binary +**/*.h linguist-language=C +**/*.inl linguist-language=C diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..a9261f441f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,422 @@ +name: ci +on: + pull_request: + push: +jobs: + rustfmt: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-18.04 + + steps: + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + components: rustfmt + - uses: actions/checkout@v2 + - run: cargo fmt --all -- --check + + clippy: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-18.04 + + steps: + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + components: clippy + + - uses: actions/checkout@v2 + + - run: cargo clippy --all-features ---all-targets -- --deny warnings + + audit: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-18.04 + + steps: + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + + - uses: actions/cache@v2 + with: + path: | + ~/.cargo/bin/cargo-audit + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + key: ${{ runner.os }}-v2-cargo-audit-0.13.1 + + - run: cargo install cargo-audit --vers "0.13.1" + + - uses: actions/checkout@v2 + + - run: cargo generate-lockfile + + - run: cargo audit --deny warnings + + deny: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-18.04 + + steps: + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + + - uses: actions/cache@v2 + with: + path: | + ~/.cargo/bin/cargo-deny + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + key: ${{ runner.os }}-v2-cargo-deny-0.8.4 + + - run: cargo install cargo-deny --vers "0.8.4" + + - uses: actions/checkout@v2 + + - run: cargo deny check + + # Verify that documentation builds. + rustdoc: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-18.04 + + strategy: + matrix: + rust_channel: + - stable + - beta + - nightly + + include: + - target: x86_64-unknown-linux-gnu + + steps: + - uses: actions-rs/toolchain@v1 + with: + override: true + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust_channel }} + + - uses: actions/checkout@v2 + + - run: | + cargo doc --all-features + + package: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - run: powershell -ExecutionPolicy Bypass ./mk/install-build-tools.ps1 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + + - run: sh mk/package.sh + shell: bash + + test: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ${{ matrix.host_os }} + + strategy: + matrix: + features: + - # Default + + target: + - aarch64-apple-ios + - aarch64-apple-darwin + - aarch64-linux-android + - aarch64-unknown-linux-gnu + - aarch64-unknown-linux-musl + - arm-unknown-linux-gnueabihf + - armv7-linux-androideabi + - armv7-unknown-linux-musleabihf + - i686-pc-windows-msvc + - i686-unknown-linux-gnu + - i686-unknown-linux-musl + - x86_64-pc-windows-gnu + - x86_64-pc-windows-msvc + - x86_64-apple-darwin + - x86_64-unknown-linux-musl + - x86_64-unknown-linux-gnu + + mode: + - # debug + - --release + + rust_channel: + - stable + - nightly + - 1.37.0 # MSRV + - beta + + exclude: + # The stable channel doesn't have aarch64-apple-darwin support yet. + - target: aarch64-apple-darwin + rust_channel: stable + + # The MSRV channel doesn't have aarch64-apple-darwin support yet. + - target: aarch64-apple-darwin + rust_channel: 1.37.0 + + # Only do MSRV testing on release builds. + - mode: # debug + rust_channel: 1.37.0 + + # 1.37.0 doesn't support `-Clink-self-contained`. + - target: aarch64-unknown-linux-musl + rust_channel: 1.37.0 + + # 1.37.0 doesn't support `-Clink-self-contained`. + - target: armv7-unknown-linux-musleabihf + rust_channel: 1.37.0 + + # 1.37.0 doesn't support `-Clink-self-contained`. + - target: i686-unknown-linux-musl + rust_channel: 1.37.0 + + # 1.37.0 doesn't support `-Clink-self-contained`. + - target: x86_64-unknown-linux-musl + rust_channel: 1.37.0 + + # https://github.com/rust-lang/rust/pull/67429 + - target: x86_64-pc-windows-gnu + rust_channel: 1.37.0 + + include: + - target: aarch64-apple-darwin + # macos-latest didn't work. + host_os: macos-11.0 + # GitHub Actions doesn't have a way to run this target yet. + cargo_options: --no-run + + - target: aarch64-apple-ios + host_os: macos-latest + # GitHub Actions doesn't have a way to run this target yet. + cargo_options: --no-run + + - target: aarch64-linux-android + host_os: ubuntu-18.04 + # TODO: https://github.com/briansmith/ring/issues/486 + cargo_options: --no-run + + - target: aarch64-unknown-linux-gnu + host_os: ubuntu-18.04 + + - target: aarch64-unknown-linux-musl + host_os: ubuntu-18.04 + + - target: arm-unknown-linux-gnueabihf + host_os: ubuntu-18.04 + + - target: armv7-linux-androideabi + host_os: ubuntu-18.04 + # TODO: https://github.com/briansmith/ring/issues/838 + cargo_options: --no-run + + - target: armv7-unknown-linux-musleabihf + host_os: ubuntu-18.04 + # TODO: https://github.com/briansmith/ring/issues/1115 + cargo_options: --no-run + + - target: i686-pc-windows-msvc + host_os: windows-latest + + - target: i686-unknown-linux-gnu + host_os: ubuntu-18.04 + + - target: i686-unknown-linux-musl + host_os: ubuntu-18.04 + + - target: x86_64-pc-windows-gnu + host_os: windows-latest + + - target: x86_64-pc-windows-msvc + host_os: windows-latest + + - target: x86_64-apple-darwin + host_os: macos-latest + + - target: x86_64-unknown-linux-musl + host_os: ubuntu-18.04 + + - target: x86_64-unknown-linux-gnu + host_os: ubuntu-18.04 + + steps: + - if: ${{ contains(matrix.host_os, 'ubuntu') }} + run: sudo apt-get update -y + + - uses: actions/checkout@v2 + + - if: ${{ !contains(matrix.host_os, 'windows') }} + run: mk/install-build-tools.sh --target=${{ matrix.target }} ${{ matrix.features }} + + - if: ${{ contains(matrix.host_os, 'windows') }} + run: > + (powershell -ExecutionPolicy Bypass ./mk/install-build-tools.ps1) -and + ("$pwd\target\tools" >> $env:GITHUB_PATH) + + - uses: actions-rs/toolchain@v1 + with: + override: true + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust_channel }} + + - if: ${{ matrix.target == 'aarch64-apple-darwin' }} + run: echo "DEVELOPER_DIR=/Applications/Xcode_12.2.app/Contents/Developer" >> $GITHUB_ENV + + - if: ${{ !contains(matrix.host_os, 'windows') }} + run: | + mk/cargo.sh test -vv --target=${{ matrix.target }} ${{ matrix.cargo_options }} ${{ matrix.features }} ${{ matrix.mode }} + + - if: ${{ contains(matrix.host_os, 'windows') }} + run: | + cargo test -vv --target=${{ matrix.target }} ${{ matrix.cargo_options }} ${{ matrix.features }} ${{ matrix.mode }} + + # The wasm32-unknown-unknown targets have a different set of feature sets and + # an additional `webdriver` dimension. + test-wasm32: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ${{ matrix.host_os }} + + strategy: + matrix: + features: + - # Default + - --features=wasm32_c + host_os: + - ubuntu-18.04 + mode: + - # debug + - --release + rust_channel: + - stable + - beta + - nightly + target: + - wasm32-unknown-unknown + webdriver: + - GECKODRIVER=geckodriver + - CHROMEDRIVER=chromedriver + + steps: + - if: ${{ contains(matrix.host_os, 'ubuntu') }} + run: sudo apt-get update -y + + - uses: actions/checkout@v2 + + - run: cargo generate-lockfile + + - run: mk/install-build-tools.sh --target=${{ matrix.target }} ${{ matrix.features }} + + - uses: actions-rs/toolchain@v1 + with: + override: true + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust_channel }} + + - run: | + ${{ matrix.webdriver }} mk/cargo.sh test -vv --target=${{ matrix.target }} ${{ matrix.features }} ${{ matrix.mode }} + + coverage: + # Don't run duplicate `push` jobs for the repo owner's PRs. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ${{ matrix.host_os }} + + strategy: + matrix: + features: + - --all-features + + # TODO: targets + target: + - aarch64-unknown-linux-gnu + - i686-unknown-linux-gnu + - x86_64-unknown-linux-musl + + mode: + - # debug + + # Coverage collection is Nightly-only + rust_channel: + - nightly + + # TODO: targets + include: + # TODO: Use the -musl target after + # https://github.com/rust-lang/rust/issues/79556 and + # https://github.com/rust-lang/rust/issues/79555 are fixed. + - target: aarch64-unknown-linux-gnu + host_os: ubuntu-18.04 + + # TODO: Use the -musl target after + # https://github.com/rust-lang/rust/issues/79556 and + # https://github.com/rust-lang/rust/issues/79555 are fixed. + - target: i686-unknown-linux-gnu + host_os: ubuntu-18.04 + + - target: x86_64-unknown-linux-musl + host_os: ubuntu-18.04 + + # TODO: Add an ARM target after + # https://github.com/rust-lang/rust/issues/79555 is fixed. This may + # require https://github.com/rust-lang/rust/issues/79555 to be fixed + # too. + + steps: + - if: ${{ contains(matrix.host_os, 'ubuntu') }} + run: sudo apt-get update -y + + - uses: actions/checkout@v2 + + - if: ${{ !contains(matrix.host_os, 'windows') }} + run: RING_COVERAGE=1 mk/install-build-tools.sh --target=${{ matrix.target }} ${{ matrix.features }} + + - uses: actions-rs/toolchain@v1 + with: + override: true + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust_channel }} + + - if: ${{ matrix.target == 'aarch64-apple-darwin' }} + run: echo "DEVELOPER_DIR=/Applications/Xcode_12.2.app/Contents/Developer" >> $GITHUB_ENV + + - if: ${{ !contains(matrix.host_os, 'windows') }} + run: | + RING_COVERAGE=1 mk/cargo.sh +${{ matrix.rust_channel }} test -vv --target=${{ matrix.target }} ${{ matrix.cargo_options }} ${{ matrix.features }} ${{ matrix.mode }} + + - uses: codecov/codecov-action@v1 + with: + directory: ./target/${{ matrix.target }}/debug/coverage/reports + fail_ci_if_error: true + verbose: true diff --git a/.gitignore b/.gitignore index 7219d6bd38..3b63d5972c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,29 +7,6 @@ ssl/test/runner/runner doc/*.html doc/doc.css -util/bot/android_ndk -util/bot/android_tools -util/bot/cmake-linux64 -util/bot/cmake-linux64.tar.gz -util/bot/cmake-mac -util/bot/cmake-mac.tar.gz -util/bot/cmake-win32 -util/bot/cmake-win32.zip -util/bot/golang -util/bot/gyp -util/bot/libcxx -util/bot/libcxxabi -util/bot/llvm-build -util/bot/nasm-win32.exe -util/bot/perl-win32 -util/bot/perl-win32.zip -util/bot/sde-linux64 -util/bot/sde-linux64.tar.bz2 -util/bot/sde-win32 -util/bot/sde-win32.tar.bz2 -util/bot/win_toolchain.json -util/bot/yasm-win32.exe - *.bk *.orig *~ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dbbe8ac24a..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,683 +0,0 @@ -language: rust -cache: - directories: - - $HOME/kcov-i686-unknown-linux-gnu - - $HOME/kcov-x86_64-unknown-linux-gnu -matrix: - fast_finish: true - allow_failures: - - rust: nightly - include: - # The lines from "# BEGIN GENERATED" through "# END GENERATED" are - # generated by running |python mk/update-travis-yml.py|. Any changes - # made to those lines will be overwritten while other lines will be left - # untouched. - # - # BEGIN GENERATED - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - - gcc-7-multilib - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - - gcc-7-multilib - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=stable - rust: stable - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=1 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - binutils-dev - - g++-7 - - gcc-7 - - libcurl4-openssl-dev - - libdw-dev - - libelf-dev - - libiberty-dev - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=1 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - g++-7 - - g++-7-multilib - - gcc-7 - - gcc-7-multilib - - libcurl3:i386 - - libcurl4-openssl-dev:i386 - - libdw-dev:i386 - - libelf-dev:i386 - - libiberty-dev:i386 - - libkrb5-dev:i386 - - libssl-dev:i386 - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - - gcc-7-multilib - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=nightly - rust: nightly - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=x86_64-apple-darwin FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: osx - osx_image: xcode10.1 - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=aarch64-linux-android CC_X=aarch64-linux-android21-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - language: android - android: - components: - - android-21 - - build-tools-26.0.2 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=armv7-linux-androideabi CC_X=armv7a-linux-androideabi18-clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18 - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=x86_64-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=aarch64-unknown-linux-gnu CC_X=aarch64-linux-gnu-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=clang FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-multilib - - libc6-dev-i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - - gcc-7-multilib - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=i686-unknown-linux-gnu CC_X=gcc-7 FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-7 - - gcc-7-multilib - - linux-libc-dev:i386 - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=DEBUG KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - - env: TARGET_X=arm-unknown-linux-gnueabihf CC_X=arm-linux-gnueabihf-gcc FEATURES_X= MODE_X=RELWITHDEBINFO KCOV=0 RUST_X=beta - rust: beta - os: linux - dist: trusty - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - sources: - - ubuntu-toolchain-r-test - - # END GENERATED - -script: if [[ "$TARGET_X" =~ ^a*.*linux-.* && "$MODE_X" == "RELWITHDEBINFO" ]]; then travis_wait 60 mk/travis.sh; else mk/travis.sh; fi diff --git a/BUILDING.md b/BUILDING.md index ab6d89558c..e5f6b7e548 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -26,15 +26,16 @@ Builds directly from Git ------------------------ If you want to hack on *ring* then you need to build it directly from its Git -repository. In this case, you must also have Perl installed, because the -assembly language modules inherited from BoringSSL (inherited from OpenSSL) -use Perl as a macro assembly language. +repository. There are some additional requirements for doing this that do not +apply when building from crates.io: -When building from Git for Windows, directories containing yasm.exe and -perl.exe must be in `%PATH%`, where yasm.exe is -[Yasm](http://yasm.tortall.net/Download.html) 1.3 or later and where perl.exe -is recommended to be [Strawberry Perl](http://strawberryperl.com). +* For any target for which *ring* has assembly language implementations of + primitives (32- and 64- bit Intel, and 32- and 64-bit ARM), Perl must be + installed and in `$PATH`. +* For Windows targets, `target/tools/nasm[.exe]` is used as the assembler; + [mk/install-build-tools.ps1](mk/install-build-tools.ps1) downloads it for + Windows hosts. Cross Compiling --------------- @@ -79,11 +80,6 @@ e.g. export `CFLAGS=-D__ANDROID_API__=21`. Additional Features that are Useful for Development --------------------------------------------------- -The `internal_benches` feature enable benchmarks of internal functions. These -benchmarks are only useful for people hacking on the implementation of *ring*. -(The benchmarks for the *ring* API are in the -[crypto-bench](https://github.com/briansmith/crypto-bench) project.) - The `slow_tests` feature runs additional tests that are too slow to run during a normal edit-compile-test cycle. diff --git a/Cargo.toml b/Cargo.toml index 0fd61ca314..a5f1e83417 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license-file = "LICENSE" name = "ring" readme = "doc/link-to-readme.md" repository = "https://github.com/briansmith/ring" -version = "0.16.15" +version = "0.16.20" # Prevent multiple versions of *ring* from being linked into the same program. links = "ring-asm" @@ -72,7 +72,6 @@ include = [ "crypto/fipsmodule/modes/asm/ghash-x86.pl", "crypto/fipsmodule/modes/asm/ghash-x86_64.pl", "crypto/fipsmodule/modes/asm/ghashv8-armx.pl", - "crypto/fipsmodule/modes/internal.h", "crypto/fipsmodule/sha/asm/sha256-armv4.pl", "crypto/fipsmodule/sha/asm/sha512-armv4.pl", "crypto/fipsmodule/sha/asm/sha512-armv8.pl", @@ -87,10 +86,12 @@ include = [ "crypto/perlasm/x86gas.pl", "crypto/perlasm/x86nasm.pl", "crypto/perlasm/x86_64-xlate.pl", - "crypto/poly1305/asm/poly1305-armv4.pl", - "crypto/poly1305/asm/poly1305-armv8.pl", - "crypto/poly1305/asm/poly1305-x86.pl", - "crypto/poly1305/asm/poly1305-x86_64.pl", + "crypto/poly1305/internal.h", + "crypto/poly1305/poly1305.c", + "crypto/poly1305/poly1305_arm.c", + "crypto/poly1305/poly1305_arm_asm.S", + "crypto/poly1305/poly1305_vec.c", + "crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl", "doc/link-to-readme.md", "examples/checkdigest.rs", "include/GFp/aes.h", @@ -99,6 +100,7 @@ include = [ "include/GFp/check.h", "include/GFp/cpu.h", "include/GFp/mem.h", + "include/GFp/poly1305.h", "include/GFp/type_check.h", "src/aead.rs", "src/aead/aes.rs", @@ -292,20 +294,24 @@ include = [ "third_party/NIST/SHAVS/SHA512ShortMsg.rsp", ] +[package.metadata.docs.rs] +all-features = true + [lib] name = "ring" [dependencies] untrusted = { version = "0.7.1" } -[target.'cfg(all(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86", target_arch = "x86_64"), not(target_os = "ios")))'.dependencies] +[target.'cfg(any(target_arch = "x86",target_arch = "x86_64", all(any(target_arch = "aarch64", target_arch = "arm"), any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))'.dependencies] spin = { version = "0.5.2", default-features = false } [target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies] libc = { version = "0.2.69", default-features = false } +once_cell = { version = "1.5.2", default-features = false, features=["std"], optional = true } -[target.'cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", target_os = "solaris"))'.dependencies] -once_cell = { version = "1.3.1", default-features = false, features=["std"], optional = true } +[target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "solaris"))'.dependencies] +once_cell = { version = "1.5.2", default-features = false, features=["std"] } [target.'cfg(all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown", target_env = ""))'.dependencies] web-sys = { version = "0.3.37", default-features = false, features = ["Crypto", "Window"] } @@ -314,17 +320,17 @@ web-sys = { version = "0.3.37", default-features = false, features = ["Crypto", winapi = { version = "0.3.8", default-features = false, features = ["ntsecapi", "wtypesbase"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] -wasm-bindgen-test = { version = "0.3.10", default-features = false } +wasm-bindgen-test = { version = "0.3.18", default-features = false } [target.'cfg(any(unix, windows))'.dev-dependencies] -libc = { version = "0.2.69", default-features = false } +libc = { version = "0.2.80", default-features = false } [target.'cfg(target_os = "switch")'.dependencies] -nnsdk = "0.1" +nnsdk = "0.2" # Keep this in sync with `[dependencies]` in pregenerate_asm/Cargo.toml. [build-dependencies] -cc = { version = "1.0.52", default-features = false } +cc = { version = "1.0.62", default-features = false } [features] # These features are documented in the top-level module's documentation. diff --git a/README.md b/README.md index 50c8b77722..47ae07be03 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Users of *ring* should always use the latest released version, and users should upgrade to the latest released version as soon as it is released. *ring* has a linear release model that favors users of the latest released version. We have never backported fixes to earlier releases and we don't -maintain branches other than the master branch. Further, for some obscure +maintain branches other than the main branch. Further, for some obscure technical reasons it's currently not possible to link two different versions of *ring* into the same program; for policy reasons we don't bother to try to work around that. Thus it is important that libraries using *ring* update @@ -169,8 +169,8 @@ source libraries use. The idea behind *our* model is to encourage all users to work together to ensure that the latest version is good *as it is being developed*. In particular, because users know that correctness/security fixes (if any) aren't going to get backported, they have a strong incentive to help -review pull requests before they are merged and/or review commits on the master -branch after they've landed to ensure that code quality on the master branch +review pull requests before they are merged and/or review commits on the main +branch after they've landed to ensure that code quality on the main branch stays high. The more common model, where there are stable versions that have important @@ -198,41 +198,31 @@ any security vulnerability in this code privately to anybody.** Online Automated Testing ------------------------ -Travis CI is used for Android, Linux, and macOS. Appveyor is used for Windows. -The tests are run in debug and release configurations, for the current release -of each Rust channel (Stable, Beta, Nightly), for each configuration listed in -the table below. The C compilers listed are used for compiling the C portions. - - - - - - - - - - - - - - - - - - - - - - - - -
OSArch.CompilersStatus
Linuxx86, x86_64GCC 4.8, GCC 7, Clang 5Build Status
32‑bit ARM, AAarch64GCC (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.1), tested using - qemu-user-arm.
AndroidARMv7, Aarch64*ring* for ARMv7 Android is built in CI using SDK version 26 targeting - API level 18 (Android 4.3+); it is tested in the emulator using the - corresponding system image. *ring* for AArch64 Android is built in CI - using SDK version 26 targeting API level 21 (Android 5.0).
Mac OS Xx64Apple LLVM version 9.0.0 (clang-900.0.39.2) from Xcode 9.3
Windowsx86, x86_64MSVC 2015 Update 3 (14.0)Build Status
- - +The following targets are tested in GitHub Actions. The tests are run in debug +and release configurations, for the current release of each Rust channel +(Stable, Beta, Nightly). A C compiler is currently required to compile some +parts of *ring*; *ring* should be compatible with GCC 4.8+, Clang 10+, and MSVC +2019+, at least. + +| Target | Notes | +| -------------------------------| ----- | +| aarch64-apple-darwin | Build-only (GitHub Actions doesn't have a way to run the tests) +| aarch64-apple-ios | Build-only (GitHub Actions doesn't have a way to run the tests) +| aarch64-unknown-linux-gnu | Tested on 64-bit Linux using QEMU user emulation +| aarch64-unknown-linux-musl | Tested on 64-bit Linux using QEMU user emulation. [Needs more work; issue 713](https://github.com/briansmith/ring/issues/713) +| aarch64-linux-android | API level 21 (Android 5.0+); [Build-only; issue 486](https://github.com/briansmith/ring/issues/486) +| arm-unknown-linux-gnueabihf | Tested on 64-bit Linux using QEMU user emulation +| armv7-linux-androideabi | API level 18 (Android 4.3+); [Build-only; issue 838](https://github.com/briansmith/ring/issues/838) +| armv7-unknown-linux-musleabihf | Tested on 64-bit Linux using QEMU user emulation. [Needs more work; issue 713](https://github.com/briansmith/ring/issues/713) +| i686-pc-windows-msvc | Tested on 64-bit Windows Server 2019 Datacenter +| i686-unknown-linux-gnu | Tested on 64-bit Linux using multilib support +| i686-unknown-linux-musl | Tested on 64-bit Linux using multilib support. [Needs more work; issue 713](https://github.com/briansmith/ring/issues/713) +| x86_64-apple-darwin | +| x86_64-pc-windows-gnu | +| x86_64-pc-windows-msvc | Tested on 64-bit Windows Server 2019 Datacenter +| x86_64-unknown-linux-gnu | +| x86_64-unknown-linux-musl | [Needs more work; issue 713](https://github.com/briansmith/ring/issues/713) +| wasm32-unknown-unknown | Tested using wasm-bindgen-test-runner on Linux in Chrome and Firefox. License ------- diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 97988f1f17..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,20 +0,0 @@ -version: 1.0.{build} -os: - - Visual Studio 2019 -clone_depth: 1 -configuration: - - Debug - - Release -platform: - - Win32 - - x64 -environment: - matrix: - - TOOLCHAIN_VERSION: 14.0 - RUST: stable - - TOOLCHAIN_VERSION: 14.0 - RUST: beta - - TOOLCHAIN_VERSION: 14.0 - RUST: nightly - -build_script: mk/appveyor.bat diff --git a/build.rs b/build.rs index 703ea7ab3b..96e30c6cc5 100644 --- a/build.rs +++ b/build.rs @@ -19,24 +19,6 @@ // another for the concrete logging implementation). Instead we use `eprintln!` // to log everything to stderr. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - // In the `pregenerate_asm_main()` case we don't want to access (Cargo) // environment variables at all, so avoid `use std::env` here. @@ -52,13 +34,14 @@ const X86_64: &str = "x86_64"; const AARCH64: &str = "aarch64"; const ARM: &str = "arm"; -#[cfg_attr(rustfmt, rustfmt_skip)] +#[rustfmt::skip] const RING_SRCS: &[(&[&str], &str)] = &[ (&[], "crypto/fipsmodule/aes/aes_nohw.c"), (&[], "crypto/fipsmodule/bn/montgomery.c"), (&[], "crypto/fipsmodule/bn/montgomery_inv.c"), (&[], "crypto/limbs/limbs.c"), (&[], "crypto/mem.c"), + (&[], "crypto/poly1305/poly1305.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/crypto.c"), (&[AARCH64, ARM, X86_64, X86], "crypto/curve25519/curve25519.c"), @@ -75,7 +58,6 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[X86], "crypto/chacha/asm/chacha-x86.pl"), (&[X86], "crypto/fipsmodule/ec/asm/ecp_nistz256-x86.pl"), (&[X86], "crypto/fipsmodule/modes/asm/ghash-x86.pl"), - (&[X86], "crypto/poly1305/asm/poly1305-x86.pl"), (&[X86_64], "crypto/fipsmodule/aes/asm/aesni-x86_64.pl"), (&[X86_64], "crypto/fipsmodule/aes/asm/vpaes-x86_64.pl"), @@ -85,8 +67,9 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[X86_64], "crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl"), (&[X86_64], "crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl"), (&[X86_64], "crypto/fipsmodule/modes/asm/ghash-x86_64.pl"), - (&[X86_64], "crypto/poly1305/asm/poly1305-x86_64.pl"), + (&[X86_64], "crypto/poly1305/poly1305_vec.c"), (&[X86_64], SHA512_X86_64), + (&[X86_64], "crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl"), (&[AARCH64, ARM], "crypto/fipsmodule/aes/asm/aesv8-armx.pl"), (&[AARCH64, ARM], "crypto/fipsmodule/modes/asm/ghashv8-armx.pl"), @@ -98,7 +81,8 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[ARM], "crypto/curve25519/asm/x25519-asm-arm.S"), (&[ARM], "crypto/fipsmodule/ec/asm/ecp_nistz256-armv4.pl"), (&[ARM], "crypto/fipsmodule/modes/asm/ghash-armv4.pl"), - (&[ARM], "crypto/poly1305/asm/poly1305-armv4.pl"), + (&[ARM], "crypto/poly1305/poly1305_arm.c"), + (&[ARM], "crypto/poly1305/poly1305_arm_asm.S"), (&[ARM], "crypto/fipsmodule/sha/asm/sha256-armv4.pl"), (&[ARM], "crypto/fipsmodule/sha/asm/sha512-armv4.pl"), @@ -107,7 +91,6 @@ const RING_SRCS: &[(&[&str], &str)] = &[ (&[AARCH64], "crypto/chacha/asm/chacha-armv8.pl"), (&[AARCH64], "crypto/fipsmodule/ec/asm/ecp_nistz256-armv8.pl"), (&[AARCH64], "crypto/fipsmodule/modes/asm/ghash-neon-armv8.pl"), - (&[AARCH64], "crypto/poly1305/asm/poly1305-armv8.pl"), (&[AARCH64], SHA512_ARMV8), ]; @@ -119,7 +102,7 @@ const SHA512_ARMV8: &str = "crypto/fipsmodule/sha/asm/sha512-armv8.pl"; const RING_TEST_SRCS: &[&str] = &[("crypto/constant_time_test.c")]; -#[cfg_attr(rustfmt, rustfmt_skip)] +#[rustfmt::skip] const RING_INCLUDES: &[&str] = &[ "crypto/curve25519/curve25519_tables.h", @@ -133,19 +116,20 @@ const RING_INCLUDES: &[&str] = "crypto/internal.h", "crypto/limbs/limbs.h", "crypto/limbs/limbs.inl", - "crypto/fipsmodule/modes/internal.h", + "crypto/poly1305/internal.h", "include/GFp/aes.h", "include/GFp/arm_arch.h", "include/GFp/base.h", "include/GFp/check.h", "include/GFp/cpu.h", "include/GFp/mem.h", + "include/GFp/poly1305.h", "include/GFp/type_check.h", "third_party/fiat/curve25519_32.h", "third_party/fiat/curve25519_64.h", ]; -#[cfg_attr(rustfmt, rustfmt_skip)] +#[rustfmt::skip] const RING_PERL_INCLUDES: &[&str] = &["crypto/perlasm/arm-xlate.pl", "crypto/perlasm/x86gas.pl", @@ -235,6 +219,7 @@ const ASM_TARGETS: &[(&str, Option<&str>, Option<&str>)] = &[ ("x86_64", Some(WINDOWS), Some("nasm")), ("x86_64", None, Some("elf")), ("aarch64", Some("ios"), Some("ios64")), + ("aarch64", Some("macos"), Some("ios64")), ("aarch64", None, Some("linux64")), ("x86", Some(WINDOWS), Some("win32n")), ("x86", Some("ios"), Some("macosx")), @@ -263,10 +248,6 @@ fn main() { fn ring_build_rs_main() { use std::env; - for (key, value) in env::vars() { - eprintln!("ENV {}={}", key, value); - } - let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = PathBuf::from(out_dir); @@ -323,9 +304,8 @@ fn pregenerate_asm_main() { if target_os == Some(WINDOWS) { let srcs = asm_srcs(perlasm_src_dsts); for src in srcs { - let src_path = PathBuf::from(src); - let obj_path = obj_path(&pregenerated, &src_path, MSVC_OBJ_EXT); - run_command(yasm(&src_path, target_arch, &obj_path)); + let obj_path = obj_path(&pregenerated, &src, MSVC_OBJ_EXT); + run_command(nasm(&src, target_arch, &obj_path)); } } } @@ -373,7 +353,7 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) { .iter() .find(|entry| { let &(entry_arch, entry_os, _) = *entry; - entry_arch == &target.arch && is_none_or_equals(entry_os, &target.os) + entry_arch == target.arch && is_none_or_equals(entry_os, &target.os) }) .unwrap(); @@ -404,7 +384,7 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) { // For Windows we also pregenerate the object files for non-Git builds so // the user doesn't need to install the assembler. On other platforms we // assume the C compiler also assembles. - if use_pregenerated && &target.os == WINDOWS { + if use_pregenerated && target.os == WINDOWS { // The pregenerated object files always use ".obj" as the extension, // even when the C/C++ compiler outputs files with the ".o" extension. asm_srcs = asm_srcs @@ -461,8 +441,8 @@ fn build_library( ) { // Compile all the (dirty) source files into object files. let objs = additional_srcs - .into_iter() - .chain(srcs.into_iter()) + .iter() + .chain(srcs.iter()) .filter(|f| &target.env != "msvc" || f.extension().unwrap().to_str().unwrap() != "S") .map(|f| compile(f, target, warnings_are_errors, out_dir, includes_modified)) .collect::>(); @@ -486,7 +466,7 @@ fn build_library( let _ = c.flag("-Wl,-dead_strip"); } _ => { - let _ = c.flag("-Wl,--gc-sections".into()); + let _ = c.flag("-Wl,--gc-sections"); } } for o in objs { @@ -496,15 +476,26 @@ fn build_library( // Handled below. let _ = c.cargo_metadata(false); - c - .compiler("aarch64-none-elf-gcc") - .compile( - lib_path - .file_name() - .and_then(|f| f.to_str() - ) - .expect("No filename"), - ); + if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "switch" { + c + .compiler("aarch64-none-elf-gcc") + .compile( + lib_path + .file_name() + .and_then(|f| f.to_str() + ) + .expect("No filename"), + ); + } else { + c + .compile( + lib_path + .file_name() + .and_then(|f| f.to_str() + ) + .expect("No filename"), + ); + } } // Link the library. This works even when the library doesn't need to be @@ -523,13 +514,13 @@ fn compile( if ext == "obj" { p.to_str().expect("Invalid path").into() } else { - let mut out_path = out_dir.clone().join(p.file_name().unwrap()); + let mut out_path = out_dir.join(p.file_name().unwrap()); assert!(out_path.set_extension(target.obj_ext)); if need_run(&p, &out_path, includes_modified) { - let cmd = if &target.os != WINDOWS || ext != "asm" { + let cmd = if target.os != WINDOWS || ext != "asm" { cc(p, ext, target, warnings_are_errors, &out_path) } else { - yasm(p, &target.arch, &out_path) + nasm(p, &target.arch, &out_path) }; run_command(cmd); @@ -539,7 +530,7 @@ fn compile( } fn obj_path(out_dir: &Path, src: &Path, obj_ext: &str) -> PathBuf { - let mut out_path = out_dir.clone().join(src.file_name().unwrap()); + let mut out_path = out_dir.join(src.file_name().unwrap()); assert!(out_path.set_extension(obj_ext)); out_path } @@ -551,6 +542,8 @@ fn cc( warnings_are_errors: bool, out_dir: &Path, ) -> Command { + let is_musl = target.env.starts_with("musl"); + let mut c = cc::Build::new(); let _ = c.include("include"); match ext { @@ -565,9 +558,9 @@ fn cc( for f in cpp_flags(target) { let _ = c.flag(&f); } - if &target.os != "none" - && &target.os != "redox" - && &target.os != "windows" + if target.os != "none" + && target.os != "redox" + && target.os != "windows" && target.arch != "wasm32" { let _ = c.flag("-fstack-protector"); @@ -597,8 +590,19 @@ fn cc( } } - if (target.arch.as_str(), target.os.as_str()) == ("wasm32", "unknown") { - let _ = c.flag("--no-standard-libraries"); + // Allow cross-compiling without a target sysroot for these targets. + // + // poly1305_vec.c requires which requires . + if (target.arch == "wasm32" && target.os == "unknown") + || (target.os == "linux" && is_musl && target.arch != "x86_64") + { + if let Ok(compiler) = c.try_get_compiler() { + // TODO: Expand this to non-clang compilers in 0.17.0 if practical. + if compiler.is_like_clang() { + let _ = c.flag("-nostdlibinc"); + let _ = c.define("GFp_NOSTDLIBINC", "1"); + } + } } if warnings_are_errors { @@ -609,7 +613,7 @@ fn cc( }; let _ = c.flag(flag); } - if &target.env == "musl" { + if is_musl { // Some platforms enable _FORTIFY_SOURCE by default, but musl // libc doesn't support it yet. See // http://wiki.musl-libc.org/wiki/Future_Ideas#Fortify @@ -618,33 +622,45 @@ fn cc( let _ = c.flag("-U_FORTIFY_SOURCE"); } - let mut c = c.compiler("aarch64-none-elf-gcc").get_compiler().to_command(); - let _ = c - .arg("-c") - .arg(format!( - "{}{}", - target.obj_opt, - out_dir.to_str().expect("Invalid path") - )) - .arg(file); - c + if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "switch" { + let mut c = c.compiler("aarch64-none-elf-gcc").get_compiler().to_command(); + let _ = c + .arg("-c") + .arg(format!( + "{}{}", + target.obj_opt, + out_dir.to_str().expect("Invalid path") + )) + .arg(file); + c + } else { + let mut c = c.get_compiler().to_command(); + let _ = c + .arg("-c") + .arg(format!( + "{}{}", + target.obj_opt, + out_dir.to_str().expect("Invalid path") + )) + .arg(file); + c + } } -fn yasm(file: &Path, arch: &str, out_file: &Path) -> Command { - let (oformat, machine) = match arch { - "x86_64" => ("--oformat=win64", "--machine=amd64"), - "x86" => ("--oformat=win32", "--machine=x86"), +fn nasm(file: &Path, arch: &str, out_file: &Path) -> Command { + let oformat = match arch { + "x86_64" => ("win64"), + "x86" => ("win32"), _ => panic!("unsupported arch: {}", arch), }; - let mut c = Command::new("yasm.exe"); + let mut c = Command::new("./target/tools/nasm"); let _ = c - .arg("-X") - .arg("vc") - .arg("--dformat=cv8") - .arg(oformat) - .arg(machine) .arg("-o") .arg(out_file.to_str().expect("Invalid path")) + .arg("-f") + .arg(oformat) + .arg("-Xgnu") + .arg("-gcv8") .arg(file); c } @@ -783,7 +799,7 @@ fn file_modified(path: &Path) -> SystemTime { } fn get_command(var: &str, default: &str) -> String { - std::env::var(var).unwrap_or(default.into()) + std::env::var(var).unwrap_or_else(|_| default.into()) } fn check_all_files_tracked() { diff --git a/crypto/.gitattributes b/crypto/.gitattributes deleted file mode 100644 index 15a5c58091..0000000000 --- a/crypto/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.h linguist-language=C diff --git a/crypto/chacha/asm/chacha-armv4.pl b/crypto/chacha/asm/chacha-armv4.pl index 1d6f60aa69..90fa2c777b 100755 --- a/crypto/chacha/asm/chacha-armv4.pl +++ b/crypto/chacha/asm/chacha-armv4.pl @@ -197,6 +197,8 @@ sub ROUND { .Lone: .long 1,0,0,0 #if __ARM_MAX_ARCH__>=7 +.extern GFp_armcap_P +.hidden GFp_armcap_P .LOPENSSL_armcap: .word GFp_armcap_P-.LChaCha20_ctr32 #else @@ -1151,7 +1153,6 @@ sub NEONROUND { add sp,sp,#4*(16+3) ldmia sp!,{r4-r11,pc} .size ChaCha20_neon,.-ChaCha20_neon -.comm GFp_armcap_P,4,4 #endif ___ }}} diff --git a/crypto/chacha/asm/chacha-armv8.pl b/crypto/chacha/asm/chacha-armv8.pl index 4644cfd1a8..80ec882c57 100755 --- a/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/chacha/asm/chacha-armv8.pl @@ -123,6 +123,7 @@ sub ROUND { #include .extern GFp_armcap_P +.hidden GFp_armcap_P .section .rodata @@ -139,6 +140,7 @@ sub ROUND { .type GFp_ChaCha20_ctr32,%function .align 5 GFp_ChaCha20_ctr32: + AARCH64_VALID_CALL_TARGET cbz $len,.Labort #if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 adrp @x[0],:pg_hi21_nc:GFp_armcap_P @@ -152,6 +154,7 @@ sub ROUND { b.ne ChaCha20_neon .Lshort: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -272,6 +275,7 @@ sub ROUND { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER .Labort: ret @@ -328,6 +332,7 @@ sub ROUND { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER ret .size GFp_ChaCha20_ctr32,.-GFp_ChaCha20_ctr32 ___ @@ -373,6 +378,7 @@ sub NEONROUND { .type ChaCha20_neon,%function .align 5 ChaCha20_neon: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -572,6 +578,7 @@ sub NEONROUND { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER ret .Ltail_neon: @@ -681,6 +688,7 @@ sub NEONROUND { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER ret .size ChaCha20_neon,.-ChaCha20_neon ___ @@ -693,6 +701,7 @@ sub NEONROUND { .type ChaCha20_512_neon,%function .align 5 ChaCha20_512_neon: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-96]! add x29,sp,#0 @@ -1112,6 +1121,7 @@ sub NEONROUND { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER ret .size ChaCha20_512_neon,.-ChaCha20_512_neon ___ diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl index 98b4ae7106..c85bfa89cf 100755 --- a/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/chacha/asm/chacha-x86_64.pl @@ -233,10 +233,6 @@ sub ROUND { # critical path is 24 cycles per round je .Lno_data mov GFp_ia32cap_P+4(%rip),%r10 ___ -$code.=<<___ if ($avx>2); - bt \$48,%r10 # check for AVX512F - jc .LChaCha20_avx512 -___ $code.=<<___; test \$`1<<(41-32)`,%r10d jnz .LChaCha20_ssse3 @@ -1807,733 +1803,7 @@ sub AVX2_lane_ROUND { } ######################################################################## -# AVX512 code paths -if ($avx>2) { -# This one handles shorter inputs... - -my ($a,$b,$c,$d, $a_,$b_,$c_,$d_,$fourz) = map("%zmm$_",(0..3,16..20)); -my ($t0,$t1,$t2,$t3) = map("%xmm$_",(4..7)); - -sub AVX512ROUND { # critical path is 14 "SIMD ticks" per round - &vpaddd ($a,$a,$b); - &vpxord ($d,$d,$a); - &vprold ($d,$d,16); - - &vpaddd ($c,$c,$d); - &vpxord ($b,$b,$c); - &vprold ($b,$b,12); - - &vpaddd ($a,$a,$b); - &vpxord ($d,$d,$a); - &vprold ($d,$d,8); - - &vpaddd ($c,$c,$d); - &vpxord ($b,$b,$c); - &vprold ($b,$b,7); -} - -my $xframe = $win64 ? 32+8 : 8; - -$code.=<<___; -.type ChaCha20_avx512,\@function,5 -.align 32 -ChaCha20_avx512: -.LChaCha20_avx512: -.cfi_startproc - mov %rsp,%r9 # frame pointer -.cfi_def_cfa_register r9 - cmp \$512,$len - ja .LChaCha20_16x - - sub \$64+$xframe,%rsp -___ -$code.=<<___ if ($win64); - movaps %xmm6,-0x28(%r9) - movaps %xmm7,-0x18(%r9) -.Lavx512_body: -___ -$code.=<<___; - vbroadcasti32x4 .Lsigma(%rip),$a - vbroadcasti32x4 ($key),$b - vbroadcasti32x4 16($key),$c - vbroadcasti32x4 ($counter),$d - - vmovdqa32 $a,$a_ - vmovdqa32 $b,$b_ - vmovdqa32 $c,$c_ - vpaddd .Lzeroz(%rip),$d,$d - vmovdqa32 .Lfourz(%rip),$fourz - mov \$10,$counter # reuse $counter - vmovdqa32 $d,$d_ - jmp .Loop_avx512 - -.align 16 -.Loop_outer_avx512: - vmovdqa32 $a_,$a - vmovdqa32 $b_,$b - vmovdqa32 $c_,$c - vpaddd $fourz,$d_,$d - mov \$10,$counter - vmovdqa32 $d,$d_ - jmp .Loop_avx512 - -.align 32 -.Loop_avx512: -___ - &AVX512ROUND(); - &vpshufd ($c,$c,0b01001110); - &vpshufd ($b,$b,0b00111001); - &vpshufd ($d,$d,0b10010011); - - &AVX512ROUND(); - &vpshufd ($c,$c,0b01001110); - &vpshufd ($b,$b,0b10010011); - &vpshufd ($d,$d,0b00111001); - - &dec ($counter); - &jnz (".Loop_avx512"); - -$code.=<<___; - vpaddd $a_,$a,$a - vpaddd $b_,$b,$b - vpaddd $c_,$c,$c - vpaddd $d_,$d,$d - - sub \$64,$len - jb .Ltail64_avx512 - - vpxor 0x00($inp),%x#$a,$t0 # xor with input - vpxor 0x10($inp),%x#$b,$t1 - vpxor 0x20($inp),%x#$c,$t2 - vpxor 0x30($inp),%x#$d,$t3 - lea 0x40($inp),$inp # inp+=64 - - vmovdqu $t0,0x00($out) # write output - vmovdqu $t1,0x10($out) - vmovdqu $t2,0x20($out) - vmovdqu $t3,0x30($out) - lea 0x40($out),$out # out+=64 - - jz .Ldone_avx512 - - vextracti32x4 \$1,$a,$t0 - vextracti32x4 \$1,$b,$t1 - vextracti32x4 \$1,$c,$t2 - vextracti32x4 \$1,$d,$t3 - - sub \$64,$len - jb .Ltail_avx512 - - vpxor 0x00($inp),$t0,$t0 # xor with input - vpxor 0x10($inp),$t1,$t1 - vpxor 0x20($inp),$t2,$t2 - vpxor 0x30($inp),$t3,$t3 - lea 0x40($inp),$inp # inp+=64 - - vmovdqu $t0,0x00($out) # write output - vmovdqu $t1,0x10($out) - vmovdqu $t2,0x20($out) - vmovdqu $t3,0x30($out) - lea 0x40($out),$out # out+=64 - - jz .Ldone_avx512 - - vextracti32x4 \$2,$a,$t0 - vextracti32x4 \$2,$b,$t1 - vextracti32x4 \$2,$c,$t2 - vextracti32x4 \$2,$d,$t3 - - sub \$64,$len - jb .Ltail_avx512 - - vpxor 0x00($inp),$t0,$t0 # xor with input - vpxor 0x10($inp),$t1,$t1 - vpxor 0x20($inp),$t2,$t2 - vpxor 0x30($inp),$t3,$t3 - lea 0x40($inp),$inp # inp+=64 - - vmovdqu $t0,0x00($out) # write output - vmovdqu $t1,0x10($out) - vmovdqu $t2,0x20($out) - vmovdqu $t3,0x30($out) - lea 0x40($out),$out # out+=64 - - jz .Ldone_avx512 - - vextracti32x4 \$3,$a,$t0 - vextracti32x4 \$3,$b,$t1 - vextracti32x4 \$3,$c,$t2 - vextracti32x4 \$3,$d,$t3 - - sub \$64,$len - jb .Ltail_avx512 - - vpxor 0x00($inp),$t0,$t0 # xor with input - vpxor 0x10($inp),$t1,$t1 - vpxor 0x20($inp),$t2,$t2 - vpxor 0x30($inp),$t3,$t3 - lea 0x40($inp),$inp # inp+=64 - - vmovdqu $t0,0x00($out) # write output - vmovdqu $t1,0x10($out) - vmovdqu $t2,0x20($out) - vmovdqu $t3,0x30($out) - lea 0x40($out),$out # out+=64 - - jnz .Loop_outer_avx512 - - jmp .Ldone_avx512 - -.align 16 -.Ltail64_avx512: - vmovdqa %x#$a,0x00(%rsp) - vmovdqa %x#$b,0x10(%rsp) - vmovdqa %x#$c,0x20(%rsp) - vmovdqa %x#$d,0x30(%rsp) - add \$64,$len - jmp .Loop_tail_avx512 - -.align 16 -.Ltail_avx512: - vmovdqa $t0,0x00(%rsp) - vmovdqa $t1,0x10(%rsp) - vmovdqa $t2,0x20(%rsp) - vmovdqa $t3,0x30(%rsp) - add \$64,$len - -.Loop_tail_avx512: - movzb ($inp,$counter),%eax - movzb (%rsp,$counter),%ecx - lea 1($counter),$counter - xor %ecx,%eax - mov %al,-1($out,$counter) - dec $len - jnz .Loop_tail_avx512 - - vmovdqa32 $a_,0x00(%rsp) - -.Ldone_avx512: - vzeroall -___ -$code.=<<___ if ($win64); - movaps -0x28(%r9),%xmm6 - movaps -0x18(%r9),%xmm7 -___ -$code.=<<___; - lea (%r9),%rsp -.cfi_def_cfa_register rsp -.Lavx512_epilogue: - ret -.cfi_endproc -.size ChaCha20_avx512,.-ChaCha20_avx512 -___ -} -if ($avx>2) { -# This one handles longer inputs... - -my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, - $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3)=map("%zmm$_",(0..15)); -my @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, - $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3); -my @key=map("%zmm$_",(16..31)); -my ($xt0,$xt1,$xt2,$xt3)=@key[0..3]; - -sub AVX512_lane_ROUND { -my ($a0,$b0,$c0,$d0)=@_; -my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0)); -my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1)); -my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2)); -my @x=map("\"$_\"",@xx); - - ( - "&vpaddd (@x[$a0],@x[$a0],@x[$b0])", # Q1 - "&vpaddd (@x[$a1],@x[$a1],@x[$b1])", # Q2 - "&vpaddd (@x[$a2],@x[$a2],@x[$b2])", # Q3 - "&vpaddd (@x[$a3],@x[$a3],@x[$b3])", # Q4 - "&vpxord (@x[$d0],@x[$d0],@x[$a0])", - "&vpxord (@x[$d1],@x[$d1],@x[$a1])", - "&vpxord (@x[$d2],@x[$d2],@x[$a2])", - "&vpxord (@x[$d3],@x[$d3],@x[$a3])", - "&vprold (@x[$d0],@x[$d0],16)", - "&vprold (@x[$d1],@x[$d1],16)", - "&vprold (@x[$d2],@x[$d2],16)", - "&vprold (@x[$d3],@x[$d3],16)", - - "&vpaddd (@x[$c0],@x[$c0],@x[$d0])", - "&vpaddd (@x[$c1],@x[$c1],@x[$d1])", - "&vpaddd (@x[$c2],@x[$c2],@x[$d2])", - "&vpaddd (@x[$c3],@x[$c3],@x[$d3])", - "&vpxord (@x[$b0],@x[$b0],@x[$c0])", - "&vpxord (@x[$b1],@x[$b1],@x[$c1])", - "&vpxord (@x[$b2],@x[$b2],@x[$c2])", - "&vpxord (@x[$b3],@x[$b3],@x[$c3])", - "&vprold (@x[$b0],@x[$b0],12)", - "&vprold (@x[$b1],@x[$b1],12)", - "&vprold (@x[$b2],@x[$b2],12)", - "&vprold (@x[$b3],@x[$b3],12)", - - "&vpaddd (@x[$a0],@x[$a0],@x[$b0])", - "&vpaddd (@x[$a1],@x[$a1],@x[$b1])", - "&vpaddd (@x[$a2],@x[$a2],@x[$b2])", - "&vpaddd (@x[$a3],@x[$a3],@x[$b3])", - "&vpxord (@x[$d0],@x[$d0],@x[$a0])", - "&vpxord (@x[$d1],@x[$d1],@x[$a1])", - "&vpxord (@x[$d2],@x[$d2],@x[$a2])", - "&vpxord (@x[$d3],@x[$d3],@x[$a3])", - "&vprold (@x[$d0],@x[$d0],8)", - "&vprold (@x[$d1],@x[$d1],8)", - "&vprold (@x[$d2],@x[$d2],8)", - "&vprold (@x[$d3],@x[$d3],8)", - - "&vpaddd (@x[$c0],@x[$c0],@x[$d0])", - "&vpaddd (@x[$c1],@x[$c1],@x[$d1])", - "&vpaddd (@x[$c2],@x[$c2],@x[$d2])", - "&vpaddd (@x[$c3],@x[$c3],@x[$d3])", - "&vpxord (@x[$b0],@x[$b0],@x[$c0])", - "&vpxord (@x[$b1],@x[$b1],@x[$c1])", - "&vpxord (@x[$b2],@x[$b2],@x[$c2])", - "&vpxord (@x[$b3],@x[$b3],@x[$c3])", - "&vprold (@x[$b0],@x[$b0],7)", - "&vprold (@x[$b1],@x[$b1],7)", - "&vprold (@x[$b2],@x[$b2],7)", - "&vprold (@x[$b3],@x[$b3],7)" - ); -} - -my $xframe = $win64 ? 0xa8 : 8; - -$code.=<<___; -.type ChaCha20_16x,\@function,5 -.align 32 -ChaCha20_16x: -.LChaCha20_16x: -.cfi_startproc - mov %rsp,%r9 # frame register -.cfi_def_cfa_register r9 - sub \$64+$xframe,%rsp - and \$-64,%rsp -___ -$code.=<<___ if ($win64); - movaps %xmm6,-0xa8(%r9) - movaps %xmm7,-0x98(%r9) - movaps %xmm8,-0x88(%r9) - movaps %xmm9,-0x78(%r9) - movaps %xmm10,-0x68(%r9) - movaps %xmm11,-0x58(%r9) - movaps %xmm12,-0x48(%r9) - movaps %xmm13,-0x38(%r9) - movaps %xmm14,-0x28(%r9) - movaps %xmm15,-0x18(%r9) -.L16x_body: -___ -$code.=<<___; - vzeroupper - - lea .Lsigma(%rip),%r10 - vbroadcasti32x4 (%r10),$xa3 # key[0] - vbroadcasti32x4 ($key),$xb3 # key[1] - vbroadcasti32x4 16($key),$xc3 # key[2] - vbroadcasti32x4 ($counter),$xd3 # key[3] - - vpshufd \$0x00,$xa3,$xa0 # smash key by lanes... - vpshufd \$0x55,$xa3,$xa1 - vpshufd \$0xaa,$xa3,$xa2 - vpshufd \$0xff,$xa3,$xa3 - vmovdqa64 $xa0,@key[0] - vmovdqa64 $xa1,@key[1] - vmovdqa64 $xa2,@key[2] - vmovdqa64 $xa3,@key[3] - - vpshufd \$0x00,$xb3,$xb0 - vpshufd \$0x55,$xb3,$xb1 - vpshufd \$0xaa,$xb3,$xb2 - vpshufd \$0xff,$xb3,$xb3 - vmovdqa64 $xb0,@key[4] - vmovdqa64 $xb1,@key[5] - vmovdqa64 $xb2,@key[6] - vmovdqa64 $xb3,@key[7] - - vpshufd \$0x00,$xc3,$xc0 - vpshufd \$0x55,$xc3,$xc1 - vpshufd \$0xaa,$xc3,$xc2 - vpshufd \$0xff,$xc3,$xc3 - vmovdqa64 $xc0,@key[8] - vmovdqa64 $xc1,@key[9] - vmovdqa64 $xc2,@key[10] - vmovdqa64 $xc3,@key[11] - - vpshufd \$0x00,$xd3,$xd0 - vpshufd \$0x55,$xd3,$xd1 - vpshufd \$0xaa,$xd3,$xd2 - vpshufd \$0xff,$xd3,$xd3 - vpaddd .Lincz(%rip),$xd0,$xd0 # don't save counters yet - vmovdqa64 $xd0,@key[12] - vmovdqa64 $xd1,@key[13] - vmovdqa64 $xd2,@key[14] - vmovdqa64 $xd3,@key[15] - - mov \$10,%eax - jmp .Loop16x - -.align 32 -.Loop_outer16x: - vpbroadcastd 0(%r10),$xa0 # reload key - vpbroadcastd 4(%r10),$xa1 - vpbroadcastd 8(%r10),$xa2 - vpbroadcastd 12(%r10),$xa3 - vpaddd .Lsixteen(%rip),@key[12],@key[12] # next SIMD counters - vmovdqa64 @key[4],$xb0 - vmovdqa64 @key[5],$xb1 - vmovdqa64 @key[6],$xb2 - vmovdqa64 @key[7],$xb3 - vmovdqa64 @key[8],$xc0 - vmovdqa64 @key[9],$xc1 - vmovdqa64 @key[10],$xc2 - vmovdqa64 @key[11],$xc3 - vmovdqa64 @key[12],$xd0 - vmovdqa64 @key[13],$xd1 - vmovdqa64 @key[14],$xd2 - vmovdqa64 @key[15],$xd3 - - vmovdqa64 $xa0,@key[0] - vmovdqa64 $xa1,@key[1] - vmovdqa64 $xa2,@key[2] - vmovdqa64 $xa3,@key[3] - - mov \$10,%eax - jmp .Loop16x - -.align 32 -.Loop16x: -___ - foreach (&AVX512_lane_ROUND(0, 4, 8,12)) { eval; } - foreach (&AVX512_lane_ROUND(0, 5,10,15)) { eval; } -$code.=<<___; - dec %eax - jnz .Loop16x - - vpaddd @key[0],$xa0,$xa0 # accumulate key - vpaddd @key[1],$xa1,$xa1 - vpaddd @key[2],$xa2,$xa2 - vpaddd @key[3],$xa3,$xa3 - - vpunpckldq $xa1,$xa0,$xt2 # "de-interlace" data - vpunpckldq $xa3,$xa2,$xt3 - vpunpckhdq $xa1,$xa0,$xa0 - vpunpckhdq $xa3,$xa2,$xa2 - vpunpcklqdq $xt3,$xt2,$xa1 # "a0" - vpunpckhqdq $xt3,$xt2,$xt2 # "a1" - vpunpcklqdq $xa2,$xa0,$xa3 # "a2" - vpunpckhqdq $xa2,$xa0,$xa0 # "a3" -___ - ($xa0,$xa1,$xa2,$xa3,$xt2)=($xa1,$xt2,$xa3,$xa0,$xa2); -$code.=<<___; - vpaddd @key[4],$xb0,$xb0 - vpaddd @key[5],$xb1,$xb1 - vpaddd @key[6],$xb2,$xb2 - vpaddd @key[7],$xb3,$xb3 - - vpunpckldq $xb1,$xb0,$xt2 - vpunpckldq $xb3,$xb2,$xt3 - vpunpckhdq $xb1,$xb0,$xb0 - vpunpckhdq $xb3,$xb2,$xb2 - vpunpcklqdq $xt3,$xt2,$xb1 # "b0" - vpunpckhqdq $xt3,$xt2,$xt2 # "b1" - vpunpcklqdq $xb2,$xb0,$xb3 # "b2" - vpunpckhqdq $xb2,$xb0,$xb0 # "b3" -___ - ($xb0,$xb1,$xb2,$xb3,$xt2)=($xb1,$xt2,$xb3,$xb0,$xb2); -$code.=<<___; - vshufi32x4 \$0x44,$xb0,$xa0,$xt3 # "de-interlace" further - vshufi32x4 \$0xee,$xb0,$xa0,$xb0 - vshufi32x4 \$0x44,$xb1,$xa1,$xa0 - vshufi32x4 \$0xee,$xb1,$xa1,$xb1 - vshufi32x4 \$0x44,$xb2,$xa2,$xa1 - vshufi32x4 \$0xee,$xb2,$xa2,$xb2 - vshufi32x4 \$0x44,$xb3,$xa3,$xa2 - vshufi32x4 \$0xee,$xb3,$xa3,$xb3 -___ - ($xa0,$xa1,$xa2,$xa3,$xt3)=($xt3,$xa0,$xa1,$xa2,$xa3); -$code.=<<___; - vpaddd @key[8],$xc0,$xc0 - vpaddd @key[9],$xc1,$xc1 - vpaddd @key[10],$xc2,$xc2 - vpaddd @key[11],$xc3,$xc3 - - vpunpckldq $xc1,$xc0,$xt2 - vpunpckldq $xc3,$xc2,$xt3 - vpunpckhdq $xc1,$xc0,$xc0 - vpunpckhdq $xc3,$xc2,$xc2 - vpunpcklqdq $xt3,$xt2,$xc1 # "c0" - vpunpckhqdq $xt3,$xt2,$xt2 # "c1" - vpunpcklqdq $xc2,$xc0,$xc3 # "c2" - vpunpckhqdq $xc2,$xc0,$xc0 # "c3" -___ - ($xc0,$xc1,$xc2,$xc3,$xt2)=($xc1,$xt2,$xc3,$xc0,$xc2); -$code.=<<___; - vpaddd @key[12],$xd0,$xd0 - vpaddd @key[13],$xd1,$xd1 - vpaddd @key[14],$xd2,$xd2 - vpaddd @key[15],$xd3,$xd3 - - vpunpckldq $xd1,$xd0,$xt2 - vpunpckldq $xd3,$xd2,$xt3 - vpunpckhdq $xd1,$xd0,$xd0 - vpunpckhdq $xd3,$xd2,$xd2 - vpunpcklqdq $xt3,$xt2,$xd1 # "d0" - vpunpckhqdq $xt3,$xt2,$xt2 # "d1" - vpunpcklqdq $xd2,$xd0,$xd3 # "d2" - vpunpckhqdq $xd2,$xd0,$xd0 # "d3" -___ - ($xd0,$xd1,$xd2,$xd3,$xt2)=($xd1,$xt2,$xd3,$xd0,$xd2); -$code.=<<___; - vshufi32x4 \$0x44,$xd0,$xc0,$xt3 # "de-interlace" further - vshufi32x4 \$0xee,$xd0,$xc0,$xd0 - vshufi32x4 \$0x44,$xd1,$xc1,$xc0 - vshufi32x4 \$0xee,$xd1,$xc1,$xd1 - vshufi32x4 \$0x44,$xd2,$xc2,$xc1 - vshufi32x4 \$0xee,$xd2,$xc2,$xd2 - vshufi32x4 \$0x44,$xd3,$xc3,$xc2 - vshufi32x4 \$0xee,$xd3,$xc3,$xd3 -___ - ($xc0,$xc1,$xc2,$xc3,$xt3)=($xt3,$xc0,$xc1,$xc2,$xc3); -$code.=<<___; - vshufi32x4 \$0x88,$xc0,$xa0,$xt0 # "de-interlace" further - vshufi32x4 \$0xdd,$xc0,$xa0,$xa0 - vshufi32x4 \$0x88,$xd0,$xb0,$xc0 - vshufi32x4 \$0xdd,$xd0,$xb0,$xd0 - vshufi32x4 \$0x88,$xc1,$xa1,$xt1 - vshufi32x4 \$0xdd,$xc1,$xa1,$xa1 - vshufi32x4 \$0x88,$xd1,$xb1,$xc1 - vshufi32x4 \$0xdd,$xd1,$xb1,$xd1 - vshufi32x4 \$0x88,$xc2,$xa2,$xt2 - vshufi32x4 \$0xdd,$xc2,$xa2,$xa2 - vshufi32x4 \$0x88,$xd2,$xb2,$xc2 - vshufi32x4 \$0xdd,$xd2,$xb2,$xd2 - vshufi32x4 \$0x88,$xc3,$xa3,$xt3 - vshufi32x4 \$0xdd,$xc3,$xa3,$xa3 - vshufi32x4 \$0x88,$xd3,$xb3,$xc3 - vshufi32x4 \$0xdd,$xd3,$xb3,$xd3 -___ - ($xa0,$xa1,$xa2,$xa3,$xb0,$xb1,$xb2,$xb3)= - ($xt0,$xt1,$xt2,$xt3,$xa0,$xa1,$xa2,$xa3); - - ($xa0,$xb0,$xc0,$xd0, $xa1,$xb1,$xc1,$xd1, - $xa2,$xb2,$xc2,$xd2, $xa3,$xb3,$xc3,$xd3) = - ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3, - $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3); -$code.=<<___; - cmp \$64*16,$len - jb .Ltail16x - - vpxord 0x00($inp),$xa0,$xa0 # xor with input - vpxord 0x40($inp),$xb0,$xb0 - vpxord 0x80($inp),$xc0,$xc0 - vpxord 0xc0($inp),$xd0,$xd0 - vmovdqu32 $xa0,0x00($out) - vmovdqu32 $xb0,0x40($out) - vmovdqu32 $xc0,0x80($out) - vmovdqu32 $xd0,0xc0($out) - - vpxord 0x100($inp),$xa1,$xa1 - vpxord 0x140($inp),$xb1,$xb1 - vpxord 0x180($inp),$xc1,$xc1 - vpxord 0x1c0($inp),$xd1,$xd1 - vmovdqu32 $xa1,0x100($out) - vmovdqu32 $xb1,0x140($out) - vmovdqu32 $xc1,0x180($out) - vmovdqu32 $xd1,0x1c0($out) - - vpxord 0x200($inp),$xa2,$xa2 - vpxord 0x240($inp),$xb2,$xb2 - vpxord 0x280($inp),$xc2,$xc2 - vpxord 0x2c0($inp),$xd2,$xd2 - vmovdqu32 $xa2,0x200($out) - vmovdqu32 $xb2,0x240($out) - vmovdqu32 $xc2,0x280($out) - vmovdqu32 $xd2,0x2c0($out) - - vpxord 0x300($inp),$xa3,$xa3 - vpxord 0x340($inp),$xb3,$xb3 - vpxord 0x380($inp),$xc3,$xc3 - vpxord 0x3c0($inp),$xd3,$xd3 - lea 0x400($inp),$inp - vmovdqu32 $xa3,0x300($out) - vmovdqu32 $xb3,0x340($out) - vmovdqu32 $xc3,0x380($out) - vmovdqu32 $xd3,0x3c0($out) - lea 0x400($out),$out - - sub \$64*16,$len - jnz .Loop_outer16x - - jmp .Ldone16x - -.align 32 -.Ltail16x: - xor %r10,%r10 - sub $inp,$out - cmp \$64*1,$len - jb .Less_than_64_16x - vpxord ($inp),$xa0,$xa0 # xor with input - vmovdqu32 $xa0,($out,$inp) - je .Ldone16x - vmovdqa32 $xb0,$xa0 - lea 64($inp),$inp - - cmp \$64*2,$len - jb .Less_than_64_16x - vpxord ($inp),$xb0,$xb0 - vmovdqu32 $xb0,($out,$inp) - je .Ldone16x - vmovdqa32 $xc0,$xa0 - lea 64($inp),$inp - - cmp \$64*3,$len - jb .Less_than_64_16x - vpxord ($inp),$xc0,$xc0 - vmovdqu32 $xc0,($out,$inp) - je .Ldone16x - vmovdqa32 $xd0,$xa0 - lea 64($inp),$inp - - cmp \$64*4,$len - jb .Less_than_64_16x - vpxord ($inp),$xd0,$xd0 - vmovdqu32 $xd0,($out,$inp) - je .Ldone16x - vmovdqa32 $xa1,$xa0 - lea 64($inp),$inp - - cmp \$64*5,$len - jb .Less_than_64_16x - vpxord ($inp),$xa1,$xa1 - vmovdqu32 $xa1,($out,$inp) - je .Ldone16x - vmovdqa32 $xb1,$xa0 - lea 64($inp),$inp - - cmp \$64*6,$len - jb .Less_than_64_16x - vpxord ($inp),$xb1,$xb1 - vmovdqu32 $xb1,($out,$inp) - je .Ldone16x - vmovdqa32 $xc1,$xa0 - lea 64($inp),$inp - - cmp \$64*7,$len - jb .Less_than_64_16x - vpxord ($inp),$xc1,$xc1 - vmovdqu32 $xc1,($out,$inp) - je .Ldone16x - vmovdqa32 $xd1,$xa0 - lea 64($inp),$inp - - cmp \$64*8,$len - jb .Less_than_64_16x - vpxord ($inp),$xd1,$xd1 - vmovdqu32 $xd1,($out,$inp) - je .Ldone16x - vmovdqa32 $xa2,$xa0 - lea 64($inp),$inp - - cmp \$64*9,$len - jb .Less_than_64_16x - vpxord ($inp),$xa2,$xa2 - vmovdqu32 $xa2,($out,$inp) - je .Ldone16x - vmovdqa32 $xb2,$xa0 - lea 64($inp),$inp - - cmp \$64*10,$len - jb .Less_than_64_16x - vpxord ($inp),$xb2,$xb2 - vmovdqu32 $xb2,($out,$inp) - je .Ldone16x - vmovdqa32 $xc2,$xa0 - lea 64($inp),$inp - - cmp \$64*11,$len - jb .Less_than_64_16x - vpxord ($inp),$xc2,$xc2 - vmovdqu32 $xc2,($out,$inp) - je .Ldone16x - vmovdqa32 $xd2,$xa0 - lea 64($inp),$inp - - cmp \$64*12,$len - jb .Less_than_64_16x - vpxord ($inp),$xd2,$xd2 - vmovdqu32 $xd2,($out,$inp) - je .Ldone16x - vmovdqa32 $xa3,$xa0 - lea 64($inp),$inp - - cmp \$64*13,$len - jb .Less_than_64_16x - vpxord ($inp),$xa3,$xa3 - vmovdqu32 $xa3,($out,$inp) - je .Ldone16x - vmovdqa32 $xb3,$xa0 - lea 64($inp),$inp - - cmp \$64*14,$len - jb .Less_than_64_16x - vpxord ($inp),$xb3,$xb3 - vmovdqu32 $xb3,($out,$inp) - je .Ldone16x - vmovdqa32 $xc3,$xa0 - lea 64($inp),$inp - - cmp \$64*15,$len - jb .Less_than_64_16x - vpxord ($inp),$xc3,$xc3 - vmovdqu32 $xc3,($out,$inp) - je .Ldone16x - vmovdqa32 $xd3,$xa0 - lea 64($inp),$inp - -.Less_than_64_16x: - vmovdqa32 $xa0,0x00(%rsp) - lea ($out,$inp),$out - and \$63,$len - -.Loop_tail16x: - movzb ($inp,%r10),%eax - movzb (%rsp,%r10),%ecx - lea 1(%r10),%r10 - xor %ecx,%eax - mov %al,-1($out,%r10) - dec $len - jnz .Loop_tail16x - - vpxord $xa0,$xa0,$xa0 - vmovdqa32 $xa0,0(%rsp) - -.Ldone16x: - vzeroall -___ -$code.=<<___ if ($win64); - movaps -0xa8(%r9),%xmm6 - movaps -0x98(%r9),%xmm7 - movaps -0x88(%r9),%xmm8 - movaps -0x78(%r9),%xmm9 - movaps -0x68(%r9),%xmm10 - movaps -0x58(%r9),%xmm11 - movaps -0x48(%r9),%xmm12 - movaps -0x38(%r9),%xmm13 - movaps -0x28(%r9),%xmm14 - movaps -0x18(%r9),%xmm15 -___ -$code.=<<___; - lea (%r9),%rsp -.cfi_def_cfa_register rsp -.L16x_epilogue: - ret -.cfi_endproc -.size ChaCha20_16x,.-ChaCha20_16x -___ -} +# AVX512 code paths were removed # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, # CONTEXT *context,DISPATCHER_CONTEXT *disp) @@ -2729,15 +1999,6 @@ sub AVX512_lane_ROUND { .rva .LSEH_end_ChaCha20_8x .rva .LSEH_info_ChaCha20_8x ___ -$code.=<<___ if ($avx>2); - .rva .LSEH_begin_ChaCha20_avx512 - .rva .LSEH_end_ChaCha20_avx512 - .rva .LSEH_info_ChaCha20_avx512 - - .rva .LSEH_begin_ChaCha20_16x - .rva .LSEH_end_ChaCha20_16x - .rva .LSEH_info_ChaCha20_16x -___ $code.=<<___; .section .xdata .align 8 @@ -2761,17 +2022,6 @@ sub AVX512_lane_ROUND { .rva full_handler .rva .L8x_body,.L8x_epilogue # HandlerData[] ___ -$code.=<<___ if ($avx>2); -.LSEH_info_ChaCha20_avx512: - .byte 9,0,0,0 - .rva ssse3_handler - .rva .Lavx512_body,.Lavx512_epilogue # HandlerData[] - -.LSEH_info_ChaCha20_16x: - .byte 9,0,0,0 - .rva full_handler - .rva .L16x_body,.L16x_epilogue # HandlerData[] -___ } foreach (split("\n",$code)) { diff --git a/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl b/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl new file mode 100644 index 0000000000..017570b856 --- /dev/null +++ b/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl @@ -0,0 +1,2561 @@ +#!/usr/bin/env perl + +# Copyright (c) 2015, CloudFlare Ltd. +# +# 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. */ + +############################################################################## +# # +# Author: Vlad Krasnov # +# # +############################################################################## + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; +*STDOUT=*OUT; + +$avx = 2; + +$code.=<<___; +.text +.extern GFp_ia32cap_P + +chacha20_poly1305_constants: + +.align 64 +.Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.Lrol16: +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +.byte 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 +.Lavx2_init: +.long 0,0,0,0 +.Lsse_inc: +.long 1,0,0,0 +.Lavx2_inc: +.long 2,0,0,0,2,0,0,0 +.Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC +.quad 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF +.align 16 +.Land_masks: +.byte 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 +.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +___ + +my ($oup,$inp,$inl,$adp,$keyp,$itr1,$itr2,$adl)=("%rdi","%rsi","%rbx","%rcx","%r9","%rcx","%r8","%r8"); +my ($acc0,$acc1,$acc2)=map("%r$_",(10..12)); +my ($t0,$t1,$t2,$t3)=("%r13","%r14","%r15","%r9"); +my ($A0,$A1,$A2,$A3,$B0,$B1,$B2,$B3,$C0,$C1,$C2,$C3,$D0,$D1,$D2,$D3)=map("%xmm$_",(0..15)); +my ($T0,$T1,$T2,$T3)=($A3,$B3,$C3,$D3); +my $xmm_storage = 0; +if ($win64) { + $xmm_storage = 10*16; +} +my $xmm_store="0*16(%rbp)"; +my $r_store="$xmm_storage+0*16(%rbp)"; +my $s_store="$xmm_storage+1*16(%rbp)"; +my $len_store="$xmm_storage+2*16(%rbp)"; +my $state1_store="$xmm_storage+3*16(%rbp)"; +my $state2_store="$xmm_storage+4*16(%rbp)"; +my $tmp_store="$xmm_storage+5*16(%rbp)"; +my $ctr0_store="$xmm_storage+6*16(%rbp)"; +my $ctr1_store="$xmm_storage+7*16(%rbp)"; +my $ctr2_store="$xmm_storage+8*16(%rbp)"; +my $ctr3_store="$xmm_storage+9*16(%rbp)"; + +sub chacha_qr { +my ($a,$b,$c,$d,$t,$dir)=@_; +$code.="movdqa $t, $tmp_store\n" if ($dir =~ /store/); +$code.="paddd $b, $a + pxor $a, $d + pshufb .Lrol16(%rip), $d + paddd $d, $c + pxor $c, $b + movdqa $b, $t + pslld \$12, $t + psrld \$20, $b + pxor $t, $b + paddd $b, $a + pxor $a, $d + pshufb .Lrol8(%rip), $d + paddd $d, $c + pxor $c, $b + movdqa $b, $t + pslld \$7, $t + psrld \$25, $b + pxor $t, $b\n"; +$code.="palignr \$4, $b, $b + palignr \$8, $c, $c + palignr \$12, $d, $d\n" if ($dir =~ /left/); +$code.="palignr \$12, $b, $b + palignr \$8, $c, $c + palignr \$4, $d, $d\n" if ($dir =~ /right/); +$code.="movdqa $tmp_store, $t\n" if ($dir =~ /load/); +} + +sub poly_add { +my ($src)=@_; +$code.="add 0+$src, $acc0 + adc 8+$src, $acc1 + adc \$1, $acc2\n"; +} + +sub poly_stage1 { +$code.="mov 0+$r_store, %rax + mov %rax, $t2 + mul $acc0 + mov %rax, $t0 + mov %rdx, $t1 + mov 0+$r_store, %rax + mul $acc1 + imulq $acc2, $t2 + add %rax, $t1 + adc %rdx, $t2\n"; +} + +sub poly_stage2 { +$code.="mov 8+$r_store, %rax + mov %rax, $t3 + mul $acc0 + add %rax, $t1 + adc \$0, %rdx + mov %rdx, $acc0 + mov 8+$r_store, %rax + mul $acc1 + add %rax, $t2 + adc \$0, %rdx\n"; +} + +sub poly_stage3 { +$code.="imulq $acc2, $t3 + add $acc0, $t2 + adc %rdx, $t3\n"; +} + +# At the beginning of the reduce stage t = [t3:t2:t1:t0] is a product of +# r = [r1:r0] and acc = [acc2:acc1:acc0] +# r is 124 bits at most (due to clamping) and acc is 131 bits at most +# (acc2 is at most 4 before the addition and can be at most 6 when we add in +# the next block) therefore t is at most 255 bits big, and t3 is 63 bits. +sub poly_reduce_stage { +$code.="mov $t0, $acc0 + mov $t1, $acc1 + mov $t2, $acc2 + and \$3, $acc2 # At this point acc2 is 2 bits at most (value of 3) + mov $t2, $t0 + and \$-4, $t0 + mov $t3, $t1 + shrd \$2, $t3, $t2 + shr \$2, $t3 + add $t0, $t2 + adc $t1, $t3 # No carry out since t3 is 61 bits and t1 is 63 bits + add $t2, $acc0 + adc $t3, $acc1 + adc \$0, $acc2\n"; # At this point acc2 has the value of 4 at most +} + +sub poly_mul { + &poly_stage1(); + &poly_stage2(); + &poly_stage3(); + &poly_reduce_stage(); +} + +sub prep_state { +my ($n)=@_; +$code.="movdqa .Lchacha20_consts(%rip), $A0 + movdqa $state1_store, $B0 + movdqa $state2_store, $C0\n"; +$code.="movdqa $A0, $A1 + movdqa $B0, $B1 + movdqa $C0, $C1\n" if ($n ge 2); +$code.="movdqa $A0, $A2 + movdqa $B0, $B2 + movdqa $C0, $C2\n" if ($n ge 3); +$code.="movdqa $A0, $A3 + movdqa $B0, $B3 + movdqa $C0, $C3\n" if ($n ge 4); +$code.="movdqa $ctr0_store, $D0 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $ctr0_store\n" if ($n eq 1); +$code.="movdqa $ctr0_store, $D1 + paddd .Lsse_inc(%rip), $D1 + movdqa $D1, $D0 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $ctr0_store + movdqa $D1, $ctr1_store\n" if ($n eq 2); +$code.="movdqa $ctr0_store, $D2 + paddd .Lsse_inc(%rip), $D2 + movdqa $D2, $D1 + paddd .Lsse_inc(%rip), $D1 + movdqa $D1, $D0 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $ctr0_store + movdqa $D1, $ctr1_store + movdqa $D2, $ctr2_store\n" if ($n eq 3); +$code.="movdqa $ctr0_store, $D3 + paddd .Lsse_inc(%rip), $D3 + movdqa $D3, $D2 + paddd .Lsse_inc(%rip), $D2 + movdqa $D2, $D1 + paddd .Lsse_inc(%rip), $D1 + movdqa $D1, $D0 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $ctr0_store + movdqa $D1, $ctr1_store + movdqa $D2, $ctr2_store + movdqa $D3, $ctr3_store\n" if ($n eq 4); +} + +sub finalize_state { +my ($n)=@_; +$code.="paddd .Lchacha20_consts(%rip), $A3 + paddd $state1_store, $B3 + paddd $state2_store, $C3 + paddd $ctr3_store, $D3\n" if ($n eq 4); +$code.="paddd .Lchacha20_consts(%rip), $A2 + paddd $state1_store, $B2 + paddd $state2_store, $C2 + paddd $ctr2_store, $D2\n" if ($n ge 3); +$code.="paddd .Lchacha20_consts(%rip), $A1 + paddd $state1_store, $B1 + paddd $state2_store, $C1 + paddd $ctr1_store, $D1\n" if ($n ge 2); +$code.="paddd .Lchacha20_consts(%rip), $A0 + paddd $state1_store, $B0 + paddd $state2_store, $C0 + paddd $ctr0_store, $D0\n"; +} + +sub xor_stream { +my ($A, $B, $C, $D, $offset)=@_; +$code.="movdqu 0*16 + $offset($inp), $A3 + movdqu 1*16 + $offset($inp), $B3 + movdqu 2*16 + $offset($inp), $C3 + movdqu 3*16 + $offset($inp), $D3 + pxor $A3, $A + pxor $B3, $B + pxor $C3, $C + pxor $D, $D3 + movdqu $A, 0*16 + $offset($oup) + movdqu $B, 1*16 + $offset($oup) + movdqu $C, 2*16 + $offset($oup) + movdqu $D3, 3*16 + $offset($oup)\n"; +} + +sub xor_stream_using_temp { +my ($A, $B, $C, $D, $offset, $temp)=@_; +$code.="movdqa $temp, $tmp_store + movdqu 0*16 + $offset($inp), $temp + pxor $A, $temp + movdqu $temp, 0*16 + $offset($oup) + movdqu 1*16 + $offset($inp), $temp + pxor $B, $temp + movdqu $temp, 1*16 + $offset($oup) + movdqu 2*16 + $offset($inp), $temp + pxor $C, $temp + movdqu $temp, 2*16 + $offset($oup) + movdqu 3*16 + $offset($inp), $temp + pxor $D, $temp + movdqu $temp, 3*16 + $offset($oup)\n"; +} + +sub gen_chacha_round { +my ($rot1, $rot2, $shift)=@_; +my $round=""; +$round.="movdqa $C0, $tmp_store\n" if ($rot1 eq 20); +$round.="movdqa $rot2, $C0 + paddd $B3, $A3 + paddd $B2, $A2 + paddd $B1, $A1 + paddd $B0, $A0 + pxor $A3, $D3 + pxor $A2, $D2 + pxor $A1, $D1 + pxor $A0, $D0 + pshufb $C0, $D3 + pshufb $C0, $D2 + pshufb $C0, $D1 + pshufb $C0, $D0 + movdqa $tmp_store, $C0 + paddd $D3, $C3 + paddd $D2, $C2 + paddd $D1, $C1 + paddd $D0, $C0 + pxor $C3, $B3 + pxor $C2, $B2 + pxor $C1, $B1 + pxor $C0, $B0 + movdqa $C0, $tmp_store + movdqa $B3, $C0 + psrld \$$rot1, $C0 + pslld \$32-$rot1, $B3 + pxor $C0, $B3 + movdqa $B2, $C0 + psrld \$$rot1, $C0 + pslld \$32-$rot1, $B2 + pxor $C0, $B2 + movdqa $B1, $C0 + psrld \$$rot1, $C0 + pslld \$32-$rot1, $B1 + pxor $C0, $B1 + movdqa $B0, $C0 + psrld \$$rot1, $C0 + pslld \$32-$rot1, $B0 + pxor $C0, $B0\n"; +($s1,$s2,$s3)=(4,8,12) if ($shift =~ /left/); +($s1,$s2,$s3)=(12,8,4) if ($shift =~ /right/); +$round.="movdqa $tmp_store, $C0 + palignr \$$s1, $B3, $B3 + palignr \$$s2, $C3, $C3 + palignr \$$s3, $D3, $D3 + palignr \$$s1, $B2, $B2 + palignr \$$s2, $C2, $C2 + palignr \$$s3, $D2, $D2 + palignr \$$s1, $B1, $B1 + palignr \$$s2, $C1, $C1 + palignr \$$s3, $D1, $D1 + palignr \$$s1, $B0, $B0 + palignr \$$s2, $C0, $C0 + palignr \$$s3, $D0, $D0\n" +if (($shift =~ /left/) || ($shift =~ /right/)); +return $round; +}; + +$chacha_body = &gen_chacha_round(20, ".Lrol16(%rip)") . + &gen_chacha_round(25, ".Lrol8(%rip)", "left") . + &gen_chacha_round(20, ".Lrol16(%rip)") . + &gen_chacha_round(25, ".Lrol8(%rip)", "right"); + +my @loop_body = split /\n/, $chacha_body; + +sub emit_body { +my ($n)=@_; + for (my $i=0; $i < $n; $i++) { + $code=$code.shift(@loop_body)."\n"; + }; +} + +{ +################################################################################ +# void poly_hash_ad_internal(); +$code.=" +.type poly_hash_ad_internal,\@abi-omnipotent +.align 64 +poly_hash_ad_internal: +.cfi_startproc +.cfi_def_cfa rsp, 8 + xor $acc0, $acc0 + xor $acc1, $acc1 + xor $acc2, $acc2 + cmp \$13, $itr2 + jne .Lhash_ad_loop +.Lpoly_fast_tls_ad: + # Special treatment for the TLS case of 13 bytes + mov ($adp), $acc0 + mov 5($adp), $acc1 + shr \$24, $acc1 + mov \$1, $acc2\n"; + &poly_mul(); $code.=" + ret +.Lhash_ad_loop: + # Hash in 16 byte chunk + cmp \$16, $itr2 + jb .Lhash_ad_tail\n"; + &poly_add("0($adp)"); + &poly_mul(); $code.=" + lea 1*16($adp), $adp + sub \$16, $itr2 + jmp .Lhash_ad_loop +.Lhash_ad_tail: + cmp \$0, $itr2 + je .Lhash_ad_done + # Hash last < 16 byte tail + xor $t0, $t0 + xor $t1, $t1 + xor $t2, $t2 + add $itr2, $adp +.Lhash_ad_tail_loop: + shld \$8, $t0, $t1 + shl \$8, $t0 + movzxb -1($adp), $t2 + xor $t2, $t0 + dec $adp + dec $itr2 + jne .Lhash_ad_tail_loop + + add $t0, $acc0 + adc $t1, $acc1 + adc \$1, $acc2\n"; + &poly_mul(); $code.=" + # Finished AD +.Lhash_ad_done: + ret +.cfi_endproc +.size poly_hash_ad_internal, .-poly_hash_ad_internal\n"; +} + +{ +################################################################################ +# void GFp_chacha20_poly1305_open(uint8_t *out_plaintext, const uint8_t *ciphertext, +# size_t plaintext_len, const uint8_t *ad, +# size_t ad_len, +# union chacha20_poly1305_open_data *aead_data) +# +$code.=" +.globl GFp_chacha20_poly1305_open +.type GFp_chacha20_poly1305_open,\@function,6 +.align 64 +GFp_chacha20_poly1305_open: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 + # We write the calculated authenticator back to keyp at the end, so save + # the pointer on the stack too. + push $keyp +.cfi_push $keyp + sub \$288 + $xmm_storage + 32, %rsp +.cfi_adjust_cfa_offset 288 + 32 + + lea 32(%rsp), %rbp + and \$-32, %rbp\n"; +$code.=" + movaps %xmm6,16*0+$xmm_store + movaps %xmm7,16*1+$xmm_store + movaps %xmm8,16*2+$xmm_store + movaps %xmm9,16*3+$xmm_store + movaps %xmm10,16*4+$xmm_store + movaps %xmm11,16*5+$xmm_store + movaps %xmm12,16*6+$xmm_store + movaps %xmm13,16*7+$xmm_store + movaps %xmm14,16*8+$xmm_store + movaps %xmm15,16*9+$xmm_store\n" if ($win64); +$code.=" + mov %rdx, $inl + mov $adl, 0+$len_store + mov $inl, 8+$len_store\n"; +$code.=" + mov GFp_ia32cap_P+8(%rip), %eax + and \$`(1<<5) + (1<<8)`, %eax # Check both BMI2 and AVX2 are present + xor \$`(1<<5) + (1<<8)`, %eax + jz chacha20_poly1305_open_avx2\n" if ($avx>1); +$code.=" + cmp \$128, $inl + jbe .Lopen_sse_128 + # For long buffers, prepare the poly key first + movdqa .Lchacha20_consts(%rip), $A0 + movdqu 0*16($keyp), $B0 + movdqu 1*16($keyp), $C0 + movdqu 2*16($keyp), $D0 + + movdqa $D0, $T1 + # Store on stack, to free keyp + movdqa $B0, $state1_store + movdqa $C0, $state2_store + movdqa $D0, $ctr0_store + mov \$10, $acc0 +.Lopen_sse_init_rounds:\n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); $code.=" + dec $acc0 + jne .Lopen_sse_init_rounds + # A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded + paddd .Lchacha20_consts(%rip), $A0 + paddd $state1_store, $B0 + # Clamp and store the key + pand .Lclamp(%rip), $A0 + movdqa $A0, $r_store + movdqa $B0, $s_store + # Hash + mov $adl, $itr2 + call poly_hash_ad_internal +.Lopen_sse_main_loop: + cmp \$16*16, $inl + jb .Lopen_sse_tail + # Load state, increment counter blocks\n"; + &prep_state(4); $code.=" + # There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we + # hash 2 blocks, and for the remaining 4 only 1 block - for a total of 16 + mov \$4, $itr1 + mov $inp, $itr2 +.Lopen_sse_main_loop_rounds:\n"; + &emit_body(20); + &poly_add("0($itr2)"); $code.=" + lea 2*8($itr2), $itr2\n"; + &emit_body(20); + &poly_stage1(); + &emit_body(20); + &poly_stage2(); + &emit_body(20); + &poly_stage3(); + &emit_body(20); + &poly_reduce_stage(); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + dec $itr1 + jge .Lopen_sse_main_loop_rounds\n"; + &poly_add("0($itr2)"); + &poly_mul(); $code.=" + lea 2*8($itr2), $itr2 + cmp \$-6, $itr1 + jg .Lopen_sse_main_loop_rounds\n"; + &finalize_state(4); + &xor_stream_using_temp($A3, $B3, $C3, $D3, "0*16", $D0); + &xor_stream($A2, $B2, $C2, $D2, "4*16"); + &xor_stream($A1, $B1, $C1, $D1, "8*16"); + &xor_stream($A0, $B0, $C0, $tmp_store, "12*16"); $code.=" + lea 16*16($inp), $inp + lea 16*16($oup), $oup + sub \$16*16, $inl + jmp .Lopen_sse_main_loop +.Lopen_sse_tail: + # Handle the various tail sizes efficiently + test $inl, $inl + jz .Lopen_sse_finalize + cmp \$12*16, $inl + ja .Lopen_sse_tail_256 + cmp \$8*16, $inl + ja .Lopen_sse_tail_192 + cmp \$4*16, $inl + ja .Lopen_sse_tail_128\n"; +############################################################################### + # At most 64 bytes are left + &prep_state(1); $code.=" + xor $itr2, $itr2 + mov $inl, $itr1 + cmp \$16, $itr1 + jb .Lopen_sse_tail_64_rounds +.Lopen_sse_tail_64_rounds_and_x1hash: \n"; + &poly_add("0($inp,$itr2)"); + &poly_mul(); $code.=" + sub \$16, $itr1 +.Lopen_sse_tail_64_rounds: + add \$16, $itr2\n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); $code.=" + cmp \$16, $itr1 + jae .Lopen_sse_tail_64_rounds_and_x1hash + cmp \$10*16, $itr2 + jne .Lopen_sse_tail_64_rounds\n"; + &finalize_state(1); $code.=" + jmp .Lopen_sse_tail_64_dec_loop +############################################################################### +.Lopen_sse_tail_128:\n"; + # 65 - 128 bytes are left + &prep_state(2); $code.=" + mov $inl, $itr1 + and \$-16, $itr1 + xor $itr2, $itr2 +.Lopen_sse_tail_128_rounds_and_x1hash: \n"; + &poly_add("0($inp,$itr2)"); + &poly_mul(); $code.=" +.Lopen_sse_tail_128_rounds: + add \$16, $itr2\n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right");$code.=" + cmp $itr1, $itr2 + jb .Lopen_sse_tail_128_rounds_and_x1hash + cmp \$10*16, $itr2 + jne .Lopen_sse_tail_128_rounds\n"; + &finalize_state(2); + &xor_stream($A1, $B1, $C1, $D1, "0*16"); $code.=" + sub \$4*16, $inl + lea 4*16($inp), $inp + lea 4*16($oup), $oup + jmp .Lopen_sse_tail_64_dec_loop +############################################################################### +.Lopen_sse_tail_192:\n"; + # 129 - 192 bytes are left + &prep_state(3); $code.=" + mov $inl, $itr1 + mov \$10*16, $itr2 + cmp \$10*16, $itr1 + cmovg $itr2, $itr1 + and \$-16, $itr1 + xor $itr2, $itr2 +.Lopen_sse_tail_192_rounds_and_x1hash: \n"; + &poly_add("0($inp,$itr2)"); + &poly_mul(); $code.=" +.Lopen_sse_tail_192_rounds: + add \$16, $itr2\n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + cmp $itr1, $itr2 + jb .Lopen_sse_tail_192_rounds_and_x1hash + cmp \$10*16, $itr2 + jne .Lopen_sse_tail_192_rounds + cmp \$11*16, $inl + jb .Lopen_sse_tail_192_finish\n"; + &poly_add("10*16($inp)"); + &poly_mul(); $code.=" + cmp \$12*16, $inl + jb .Lopen_sse_tail_192_finish\n"; + &poly_add("11*16($inp)"); + &poly_mul(); $code.=" +.Lopen_sse_tail_192_finish: \n"; + &finalize_state(3); + &xor_stream($A2, $B2, $C2, $D2, "0*16"); + &xor_stream($A1, $B1, $C1, $D1, "4*16"); $code.=" + sub \$8*16, $inl + lea 8*16($inp), $inp + lea 8*16($oup), $oup + jmp .Lopen_sse_tail_64_dec_loop +############################################################################### +.Lopen_sse_tail_256:\n"; + # 193 - 255 bytes are left + &prep_state(4); $code.=" + xor $itr2, $itr2 +.Lopen_sse_tail_256_rounds_and_x1hash: \n"; + &poly_add("0($inp,$itr2)"); + &chacha_qr($A0,$B0,$C0,$D0,$C3,"store_left"); + &chacha_qr($A1,$B1,$C1,$D1,$C3,"left"); + &chacha_qr($A2,$B2,$C2,$D2,$C3,"left_load"); + &poly_stage1(); + &chacha_qr($A3,$B3,$C3,$D3,$C1,"store_left_load"); + &poly_stage2(); + &chacha_qr($A0,$B0,$C0,$D0,$C3,"store_right"); + &chacha_qr($A1,$B1,$C1,$D1,$C3,"right"); + &poly_stage3(); + &chacha_qr($A2,$B2,$C2,$D2,$C3,"right_load"); + &poly_reduce_stage(); + &chacha_qr($A3,$B3,$C3,$D3,$C1,"store_right_load"); $code.=" + add \$16, $itr2 + cmp \$10*16, $itr2 + jb .Lopen_sse_tail_256_rounds_and_x1hash + + mov $inl, $itr1 + and \$-16, $itr1 +.Lopen_sse_tail_256_hash: \n"; + &poly_add("0($inp,$itr2)"); + &poly_mul(); $code.=" + add \$16, $itr2 + cmp $itr1, $itr2 + jb .Lopen_sse_tail_256_hash\n"; + &finalize_state(4); + &xor_stream_using_temp($A3, $B3, $C3, $D3, "0*16", $D0); + &xor_stream($A2, $B2, $C2, $D2, "4*16"); + &xor_stream($A1, $B1, $C1, $D1, "8*16"); $code.=" + movdqa $tmp_store, $D0 + sub \$12*16, $inl + lea 12*16($inp), $inp + lea 12*16($oup), $oup +############################################################################### + # Decrypt the remaining data, 16B at a time, using existing stream +.Lopen_sse_tail_64_dec_loop: + cmp \$16, $inl + jb .Lopen_sse_tail_16_init + sub \$16, $inl + movdqu ($inp), $T0 + pxor $T0, $A0 + movdqu $A0, ($oup) + lea 16($inp), $inp + lea 16($oup), $oup + movdqa $B0, $A0 + movdqa $C0, $B0 + movdqa $D0, $C0 + jmp .Lopen_sse_tail_64_dec_loop +.Lopen_sse_tail_16_init: + movdqa $A0, $A1 + + # Decrypt up to 16 bytes at the end. +.Lopen_sse_tail_16: + test $inl, $inl + jz .Lopen_sse_finalize + + # Read the final bytes into $T0. They need to be read in reverse order so + # that they end up in the correct order in $T0. + pxor $T0, $T0 + lea -1($inp,$inl), $inp + movq $inl, $itr2 +.Lopen_sse_tail_16_compose: + pslldq \$1, $T0 + pinsrb \$0, ($inp), $T0 + sub \$1, $inp + sub \$1, $itr2 + jnz .Lopen_sse_tail_16_compose + + movq $T0, $t0 + pextrq \$1, $T0, $t1 + # The final bytes of keystream are in $A1. + pxor $A1, $T0 + + # Copy the plaintext bytes out. +.Lopen_sse_tail_16_extract: + pextrb \$0, $T0, ($oup) + psrldq \$1, $T0 + add \$1, $oup + sub \$1, $inl + jne .Lopen_sse_tail_16_extract + + add $t0, $acc0 + adc $t1, $acc1 + adc \$1, $acc2\n"; + &poly_mul(); $code.=" + +.Lopen_sse_finalize:\n"; + &poly_add($len_store); + &poly_mul(); $code.=" + # Final reduce + mov $acc0, $t0 + mov $acc1, $t1 + mov $acc2, $t2 + sub \$-5, $acc0 + sbb \$-1, $acc1 + sbb \$3, $acc2 + cmovc $t0, $acc0 + cmovc $t1, $acc1 + cmovc $t2, $acc2 + # Add in s part of the key + add 0+$s_store, $acc0 + adc 8+$s_store, $acc1\n"; + +$code.=" + movaps 16*0+$xmm_store, %xmm6 + movaps 16*1+$xmm_store, %xmm7 + movaps 16*2+$xmm_store, %xmm8 + movaps 16*3+$xmm_store, %xmm9 + movaps 16*4+$xmm_store, %xmm10 + movaps 16*5+$xmm_store, %xmm11 + movaps 16*6+$xmm_store, %xmm12 + movaps 16*7+$xmm_store, %xmm13 + movaps 16*8+$xmm_store, %xmm14 + movaps 16*9+$xmm_store, %xmm15\n" if ($win64); +$code.=" +.cfi_remember_state + add \$288 + $xmm_storage + 32, %rsp +.cfi_adjust_cfa_offset -(288 + 32) + # The tag replaces the key on return + pop $keyp +.cfi_pop $keyp + mov $acc0, ($keyp) + mov $acc1, 8($keyp) + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +############################################################################### +.Lopen_sse_128: +.cfi_restore_state + movdqu .Lchacha20_consts(%rip), $A0\nmovdqa $A0, $A1\nmovdqa $A0, $A2 + movdqu 0*16($keyp), $B0\nmovdqa $B0, $B1\nmovdqa $B0, $B2 + movdqu 1*16($keyp), $C0\nmovdqa $C0, $C1\nmovdqa $C0, $C2 + movdqu 2*16($keyp), $D0 + movdqa $D0, $D1\npaddd .Lsse_inc(%rip), $D1 + movdqa $D1, $D2\npaddd .Lsse_inc(%rip), $D2 + movdqa $B0, $T1\nmovdqa $C0, $T2\nmovdqa $D1, $T3 + mov \$10, $acc0 + +.Lopen_sse_128_rounds: \n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + dec $acc0 + jnz .Lopen_sse_128_rounds + paddd .Lchacha20_consts(%rip), $A0 + paddd .Lchacha20_consts(%rip), $A1 + paddd .Lchacha20_consts(%rip), $A2 + paddd $T1, $B0\npaddd $T1, $B1\npaddd $T1, $B2 + paddd $T2, $C1\npaddd $T2, $C2 + paddd $T3, $D1 + paddd .Lsse_inc(%rip), $T3 + paddd $T3, $D2 + # Clamp and store the key + pand .Lclamp(%rip), $A0 + movdqa $A0, $r_store + movdqa $B0, $s_store + # Hash + mov $adl, $itr2 + call poly_hash_ad_internal +.Lopen_sse_128_xor_hash: + cmp \$16, $inl + jb .Lopen_sse_tail_16 + sub \$16, $inl\n"; + # Load for hashing + &poly_add("0*8($inp)"); $code.=" + # Load for decryption + movdqu 0*16($inp), $T0 + pxor $T0, $A1 + movdqu $A1, 0*16($oup) + lea 1*16($inp), $inp + lea 1*16($oup), $oup\n"; + &poly_mul(); $code.=" + # Shift the stream left + movdqa $B1, $A1 + movdqa $C1, $B1 + movdqa $D1, $C1 + movdqa $A2, $D1 + movdqa $B2, $A2 + movdqa $C2, $B2 + movdqa $D2, $C2 + jmp .Lopen_sse_128_xor_hash +.size GFp_chacha20_poly1305_open, .-GFp_chacha20_poly1305_open +.cfi_endproc + +################################################################################ +# void GFp_chacha20_poly1305_seal(uint8_t *out_ciphertext, const uint8_t *plaintext, +# size_t plaintext_len, const uint8_t *ad, +# size_t ad_len, +# union chacha20_poly1305_seal_data *data); +.globl GFp_chacha20_poly1305_seal +.type GFp_chacha20_poly1305_seal,\@function,6 +.align 64 +GFp_chacha20_poly1305_seal: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 +# We write the calculated authenticator back to keyp at the end, so save +# the pointer on the stack too. + push $keyp +.cfi_push $keyp + sub \$288 + $xmm_storage + 32, %rsp +.cfi_adjust_cfa_offset 288 + 32 + lea 32(%rsp), %rbp + and \$-32, %rbp\n"; +$code.=" + movaps %xmm6,16*0+$xmm_store + movaps %xmm7,16*1+$xmm_store + movaps %xmm8,16*2+$xmm_store + movaps %xmm9,16*3+$xmm_store + movaps %xmm10,16*4+$xmm_store + movaps %xmm11,16*5+$xmm_store + movaps %xmm12,16*6+$xmm_store + movaps %xmm13,16*7+$xmm_store + movaps %xmm14,16*8+$xmm_store + movaps %xmm15,16*9+$xmm_store\n" if ($win64); +$code.=" + mov 56($keyp), $inl # extra_in_len + addq %rdx, $inl + mov $adl, 0+$len_store + mov $inl, 8+$len_store + mov %rdx, $inl\n"; +$code.=" + mov GFp_ia32cap_P+8(%rip), %eax + and \$`(1<<5) + (1<<8)`, %eax # Check both BMI2 and AVX2 are present + xor \$`(1<<5) + (1<<8)`, %eax + jz chacha20_poly1305_seal_avx2\n" if ($avx>1); +$code.=" + cmp \$128, $inl + jbe .Lseal_sse_128 + # For longer buffers, prepare the poly key + some stream + movdqa .Lchacha20_consts(%rip), $A0 + movdqu 0*16($keyp), $B0 + movdqu 1*16($keyp), $C0 + movdqu 2*16($keyp), $D0 + + movdqa $A0, $A1 + movdqa $A0, $A2 + movdqa $A0, $A3 + movdqa $B0, $B1 + movdqa $B0, $B2 + movdqa $B0, $B3 + movdqa $C0, $C1 + movdqa $C0, $C2 + movdqa $C0, $C3 + movdqa $D0, $D3 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $D2 + paddd .Lsse_inc(%rip), $D0 + movdqa $D0, $D1 + paddd .Lsse_inc(%rip), $D0 + # Store on stack + movdqa $B0, $state1_store + movdqa $C0, $state2_store + movdqa $D0, $ctr0_store + movdqa $D1, $ctr1_store + movdqa $D2, $ctr2_store + movdqa $D3, $ctr3_store + mov \$10, $acc0 +.Lseal_sse_init_rounds: \n"; + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + dec $acc0 + jnz .Lseal_sse_init_rounds\n"; + &finalize_state(4); $code.=" + # Clamp and store the key + pand .Lclamp(%rip), $A3 + movdqa $A3, $r_store + movdqa $B3, $s_store + # Hash + mov $adl, $itr2 + call poly_hash_ad_internal\n"; + &xor_stream($A2,$B2,$C2,$D2,"0*16"); + &xor_stream($A1,$B1,$C1,$D1,"4*16"); $code.=" + cmp \$12*16, $inl + ja .Lseal_sse_main_init + mov \$8*16, $itr1 + sub \$8*16, $inl + lea 8*16($inp), $inp + jmp .Lseal_sse_128_tail_hash +.Lseal_sse_main_init:\n"; + &xor_stream($A0, $B0, $C0, $D0, "8*16"); $code.=" + mov \$12*16, $itr1 + sub \$12*16, $inl + lea 12*16($inp), $inp + mov \$2, $itr1 + mov \$8, $itr2 + cmp \$4*16, $inl + jbe .Lseal_sse_tail_64 + cmp \$8*16, $inl + jbe .Lseal_sse_tail_128 + cmp \$12*16, $inl + jbe .Lseal_sse_tail_192 + +.Lseal_sse_main_loop: \n"; + # The main loop + &prep_state(4); $code.=" +.align 32 +.Lseal_sse_main_rounds: \n"; + &emit_body(20); + &poly_add("0($oup)"); + &emit_body(20); + &poly_stage1(); + &emit_body(20); + &poly_stage2(); + &emit_body(20); + &poly_stage3(); + &emit_body(20); + &poly_reduce_stage(); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + lea 16($oup), $oup + dec $itr2 + jge .Lseal_sse_main_rounds\n"; + &poly_add("0*8($oup)"); + &poly_mul(); $code.=" + lea 16($oup), $oup + dec $itr1 + jg .Lseal_sse_main_rounds\n"; + + &finalize_state(4);$code.=" + movdqa $D2, $tmp_store\n"; + &xor_stream_using_temp($A3,$B3,$C3,$D3,0*16,$D2); $code.=" + movdqa $tmp_store, $D2\n"; + &xor_stream($A2,$B2,$C2,$D2, 4*16); + &xor_stream($A1,$B1,$C1,$D1, 8*16); $code.=" + cmp \$16*16, $inl + ja .Lseal_sse_main_loop_xor + + mov \$12*16, $itr1 + sub \$12*16, $inl + lea 12*16($inp), $inp + jmp .Lseal_sse_128_tail_hash +.Lseal_sse_main_loop_xor: \n"; + &xor_stream($A0,$B0,$C0,$D0,"12*16"); $code.=" + lea 16*16($inp), $inp + sub \$16*16, $inl + mov \$6, $itr1 + mov \$4, $itr2 + cmp \$12*16, $inl + jg .Lseal_sse_main_loop + mov $inl, $itr1 + test $inl, $inl + je .Lseal_sse_128_tail_hash + mov \$6, $itr1 + cmp \$8*16, $inl + ja .Lseal_sse_tail_192 + cmp \$4*16, $inl + ja .Lseal_sse_tail_128 +############################################################################### +.Lseal_sse_tail_64: \n"; + &prep_state(1); $code.=" +.Lseal_sse_tail_64_rounds_and_x2hash: \n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 16($oup), $oup +.Lseal_sse_tail_64_rounds_and_x1hash: \n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 16($oup), $oup + dec $itr1 + jg .Lseal_sse_tail_64_rounds_and_x2hash + dec $itr2 + jge .Lseal_sse_tail_64_rounds_and_x1hash\n"; + &finalize_state(1); $code.=" + jmp .Lseal_sse_128_tail_xor +############################################################################### +.Lseal_sse_tail_128:\n"; + &prep_state(2); $code.=" +.Lseal_sse_tail_128_rounds_and_x2hash: \n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 16($oup), $oup +.Lseal_sse_tail_128_rounds_and_x1hash: \n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &poly_add("0($oup)"); + &poly_mul(); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right"); $code.=" + lea 16($oup), $oup + dec $itr1 + jg .Lseal_sse_tail_128_rounds_and_x2hash + dec $itr2 + jge .Lseal_sse_tail_128_rounds_and_x1hash\n"; + &finalize_state(2); + &xor_stream($A1,$B1,$C1,$D1,0*16); $code.=" + mov \$4*16, $itr1 + sub \$4*16, $inl + lea 4*16($inp), $inp + jmp .Lseal_sse_128_tail_hash +############################################################################### +.Lseal_sse_tail_192:\n"; + &prep_state(3); $code.=" +.Lseal_sse_tail_192_rounds_and_x2hash: \n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 16($oup), $oup +.Lseal_sse_tail_192_rounds_and_x1hash: \n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"left"); + &poly_add("0($oup)"); + &poly_mul(); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + lea 16($oup), $oup + dec $itr1 + jg .Lseal_sse_tail_192_rounds_and_x2hash + dec $itr2 + jge .Lseal_sse_tail_192_rounds_and_x1hash\n"; + &finalize_state(3); + &xor_stream($A2,$B2,$C2,$D2,0*16); + &xor_stream($A1,$B1,$C1,$D1,4*16); $code.=" + mov \$8*16, $itr1 + sub \$8*16, $inl + lea 8*16($inp), $inp +############################################################################### +.Lseal_sse_128_tail_hash: + cmp \$16, $itr1 + jb .Lseal_sse_128_tail_xor\n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + sub \$16, $itr1 + lea 16($oup), $oup + jmp .Lseal_sse_128_tail_hash + +.Lseal_sse_128_tail_xor: + cmp \$16, $inl + jb .Lseal_sse_tail_16 + sub \$16, $inl + # Load for decryption + movdqu 0*16($inp), $T0 + pxor $T0, $A0 + movdqu $A0, 0*16($oup) + # Then hash + add 0*8($oup), $acc0 + adc 1*8($oup), $acc1 + adc \$1, $acc2 + lea 1*16($inp), $inp + lea 1*16($oup), $oup\n"; + &poly_mul(); $code.=" + # Shift the stream left + movdqa $B0, $A0 + movdqa $C0, $B0 + movdqa $D0, $C0 + movdqa $A1, $D0 + movdqa $B1, $A1 + movdqa $C1, $B1 + movdqa $D1, $C1 + jmp .Lseal_sse_128_tail_xor + +.Lseal_sse_tail_16: + test $inl, $inl + jz .Lprocess_blocks_of_extra_in + # We can only load the PT one byte at a time to avoid buffer overread + mov $inl, $itr2 + mov $inl, $itr1 + lea -1($inp,$inl), $inp + pxor $T3, $T3 +.Lseal_sse_tail_16_compose: + pslldq \$1, $T3 + pinsrb \$0, ($inp), $T3 + lea -1($inp), $inp + dec $itr1 + jne .Lseal_sse_tail_16_compose + + # XOR the keystream with the plaintext. + pxor $A0, $T3 + + # Write ciphertext out, byte-by-byte. + movq $inl, $itr1 + movdqu $T3, $A0 +.Lseal_sse_tail_16_extract: + pextrb \$0, $A0, ($oup) + psrldq \$1, $A0 + add \$1, $oup + sub \$1, $itr1 + jnz .Lseal_sse_tail_16_extract + + # $T3 contains the final (partial, non-empty) block of ciphertext which + # needs to be fed into the Poly1305 state. The right-most $inl bytes of it + # are valid. We need to fill it with extra_in bytes until full, or until we + # run out of bytes. + # + # $keyp points to the tag output, which is actually a struct with the + # extra_in pointer and length at offset 48. + movq 288 + $xmm_storage + 32(%rsp), $keyp + movq 56($keyp), $t1 # extra_in_len + movq 48($keyp), $t0 # extra_in + test $t1, $t1 + jz .Lprocess_partial_block # Common case: no bytes of extra_in + + movq \$16, $t2 + subq $inl, $t2 # 16-$inl is the number of bytes that fit into $T3. + cmpq $t2, $t1 # if extra_in_len < 16-$inl, only copy extra_in_len + # (note that AT&T syntax reverses the arguments) + jge .Lload_extra_in + movq $t1, $t2 + +.Lload_extra_in: + # $t2 contains the number of bytes of extra_in (pointed to by $t0) to load + # into $T3. They are loaded in reverse order. + leaq -1($t0,$t2), $inp + # Update extra_in and extra_in_len to reflect the bytes that are about to + # be read. + addq $t2, $t0 + subq $t2, $t1 + movq $t0, 48($keyp) + movq $t1, 56($keyp) + + # Update $itr2, which is used to select the mask later on, to reflect the + # extra bytes about to be added. + addq $t2, $itr2 + + # Load $t2 bytes of extra_in into $T2. + pxor $T2, $T2 +.Lload_extra_load_loop: + pslldq \$1, $T2 + pinsrb \$0, ($inp), $T2 + lea -1($inp), $inp + sub \$1, $t2 + jnz .Lload_extra_load_loop + + # Shift $T2 up the length of the remainder from the main encryption. Sadly, + # the shift for an XMM register has to be a constant, thus we loop to do + # this. + movq $inl, $t2 + +.Lload_extra_shift_loop: + pslldq \$1, $T2 + sub \$1, $t2 + jnz .Lload_extra_shift_loop + + # Mask $T3 (the remainder from the main encryption) so that superfluous + # bytes are zero. This means that the non-zero bytes in $T2 and $T3 are + # disjoint and so we can merge them with an OR. + lea .Land_masks(%rip), $t2 + shl \$4, $inl + pand -16($t2,$inl), $T3 + + # Merge $T2 into $T3, forming the remainder block. + por $T2, $T3 + + # The block of ciphertext + extra_in is ready to be included in the + # Poly1305 state. + movq $T3, $t0 + pextrq \$1, $T3, $t1 + add $t0, $acc0 + adc $t1, $acc1 + adc \$1, $acc2\n"; + &poly_mul(); $code.=" + +.Lprocess_blocks_of_extra_in: + # There may be additional bytes of extra_in to process. + movq 288+32+$xmm_storage (%rsp), $keyp + movq 48($keyp), $inp # extra_in + movq 56($keyp), $itr2 # extra_in_len + movq $itr2, $itr1 + shr \$4, $itr2 # number of blocks + +.Lprocess_extra_hash_loop: + jz process_extra_in_trailer\n"; + &poly_add("0($inp)"); + &poly_mul(); $code.=" + leaq 16($inp), $inp + subq \$1, $itr2 + jmp .Lprocess_extra_hash_loop +process_extra_in_trailer: + andq \$15, $itr1 # remaining num bytes (<16) of extra_in + movq $itr1, $inl + jz .Ldo_length_block + leaq -1($inp,$itr1), $inp + +.Lprocess_extra_in_trailer_load: + pslldq \$1, $T3 + pinsrb \$0, ($inp), $T3 + lea -1($inp), $inp + sub \$1, $itr1 + jnz .Lprocess_extra_in_trailer_load + +.Lprocess_partial_block: + # $T3 contains $inl bytes of data to be fed into Poly1305. $inl != 0 + lea .Land_masks(%rip), $t2 + shl \$4, $inl + pand -16($t2,$inl), $T3 + movq $T3, $t0 + pextrq \$1, $T3, $t1 + add $t0, $acc0 + adc $t1, $acc1 + adc \$1, $acc2\n"; + &poly_mul(); $code.=" + +.Ldo_length_block:\n"; + &poly_add($len_store); + &poly_mul(); $code.=" + # Final reduce + mov $acc0, $t0 + mov $acc1, $t1 + mov $acc2, $t2 + sub \$-5, $acc0 + sbb \$-1, $acc1 + sbb \$3, $acc2 + cmovc $t0, $acc0 + cmovc $t1, $acc1 + cmovc $t2, $acc2 + # Add in s part of the key + add 0+$s_store, $acc0 + adc 8+$s_store, $acc1\n"; + +$code.=" + movaps 16*0+$xmm_store, %xmm6 + movaps 16*1+$xmm_store, %xmm7 + movaps 16*2+$xmm_store, %xmm8 + movaps 16*3+$xmm_store, %xmm9 + movaps 16*4+$xmm_store, %xmm10 + movaps 16*5+$xmm_store, %xmm11 + movaps 16*6+$xmm_store, %xmm12 + movaps 16*7+$xmm_store, %xmm13 + movaps 16*8+$xmm_store, %xmm14 + movaps 16*9+$xmm_store, %xmm15\n" if ($win64); +$code.=" +.cfi_remember_state + add \$288 + $xmm_storage + 32, %rsp +.cfi_adjust_cfa_offset -(288 + 32) + # The tag replaces the key on return + pop $keyp +.cfi_pop $keyp + mov $acc0, ($keyp) + mov $acc1, 8($keyp) + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +################################################################################ +.Lseal_sse_128: +.cfi_restore_state + movdqu .Lchacha20_consts(%rip), $A0\nmovdqa $A0, $A1\nmovdqa $A0, $A2 + movdqu 0*16($keyp), $B0\nmovdqa $B0, $B1\nmovdqa $B0, $B2 + movdqu 1*16($keyp), $C0\nmovdqa $C0, $C1\nmovdqa $C0, $C2 + movdqu 2*16($keyp), $D2 + movdqa $D2, $D0\npaddd .Lsse_inc(%rip), $D0 + movdqa $D0, $D1\npaddd .Lsse_inc(%rip), $D1 + movdqa $B0, $T1\nmovdqa $C0, $T2\nmovdqa $D0, $T3 + mov \$10, $acc0 + +.Lseal_sse_128_rounds:\n"; + &chacha_qr($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + dec $acc0 + jnz .Lseal_sse_128_rounds + paddd .Lchacha20_consts(%rip), $A0 + paddd .Lchacha20_consts(%rip), $A1 + paddd .Lchacha20_consts(%rip), $A2 + paddd $T1, $B0\npaddd $T1, $B1\npaddd $T1, $B2 + paddd $T2, $C0\npaddd $T2, $C1 + paddd $T3, $D0 + paddd .Lsse_inc(%rip), $T3 + paddd $T3, $D1 + # Clamp and store the key + pand .Lclamp(%rip), $A2 + movdqa $A2, $r_store + movdqa $B2, $s_store + # Hash + mov %r8, $itr2 + call poly_hash_ad_internal + jmp .Lseal_sse_128_tail_xor +.size GFp_chacha20_poly1305_seal, .-GFp_chacha20_poly1305_seal +.cfi_endproc\n"; +} + +if ($avx>1) { + +($A0,$A1,$A2,$A3,$B0,$B1,$B2,$B3,$C0,$C1,$C2,$C3,$D0,$D1,$D2,$D3)=map("%ymm$_",(0..15)); +my ($A0x,$A1x,$A2x,$A3x,$B0x,$B1x,$B2x,$B3x,$C0x,$C1x,$C2x,$C3x,$D0x,$D1x,$D2x,$D3x)=map("%xmm$_",(0..15)); +($T0,$T1,$T2,$T3)=($A3,$B3,$C3,$D3); +$state1_store="$xmm_storage+2*32(%rbp)"; +$state2_store="$xmm_storage+3*32(%rbp)"; +$tmp_store="$xmm_storage+4*32(%rbp)"; +$ctr0_store="$xmm_storage+5*32(%rbp)"; +$ctr1_store="$xmm_storage+6*32(%rbp)"; +$ctr2_store="$xmm_storage+7*32(%rbp)"; +$ctr3_store="$xmm_storage+8*32(%rbp)"; + +sub chacha_qr_avx2 { +my ($a,$b,$c,$d,$t,$dir)=@_; +$code.=<<___ if ($dir =~ /store/); + vmovdqa $t, $tmp_store +___ +$code.=<<___; + vpaddd $b, $a, $a + vpxor $a, $d, $d + vpshufb .Lrol16(%rip), $d, $d + vpaddd $d, $c, $c + vpxor $c, $b, $b + vpsrld \$20, $b, $t + vpslld \$12, $b, $b + vpxor $t, $b, $b + vpaddd $b, $a, $a + vpxor $a, $d, $d + vpshufb .Lrol8(%rip), $d, $d + vpaddd $d, $c, $c + vpxor $c, $b, $b + vpslld \$7, $b, $t + vpsrld \$25, $b, $b + vpxor $t, $b, $b +___ +$code.=<<___ if ($dir =~ /left/); + vpalignr \$12, $d, $d, $d + vpalignr \$8, $c, $c, $c + vpalignr \$4, $b, $b, $b +___ +$code.=<<___ if ($dir =~ /right/); + vpalignr \$4, $d, $d, $d + vpalignr \$8, $c, $c, $c + vpalignr \$12, $b, $b, $b +___ +$code.=<<___ if ($dir =~ /load/); + vmovdqa $tmp_store, $t +___ +} + +sub prep_state_avx2 { +my ($n)=@_; +$code.=<<___; + vmovdqa .Lchacha20_consts(%rip), $A0 + vmovdqa $state1_store, $B0 + vmovdqa $state2_store, $C0 +___ +$code.=<<___ if ($n ge 2); + vmovdqa $A0, $A1 + vmovdqa $B0, $B1 + vmovdqa $C0, $C1 +___ +$code.=<<___ if ($n ge 3); + vmovdqa $A0, $A2 + vmovdqa $B0, $B2 + vmovdqa $C0, $C2 +___ +$code.=<<___ if ($n ge 4); + vmovdqa $A0, $A3 + vmovdqa $B0, $B3 + vmovdqa $C0, $C3 +___ +$code.=<<___ if ($n eq 1); + vmovdqa .Lavx2_inc(%rip), $D0 + vpaddd $ctr0_store, $D0, $D0 + vmovdqa $D0, $ctr0_store +___ +$code.=<<___ if ($n eq 2); + vmovdqa .Lavx2_inc(%rip), $D0 + vpaddd $ctr0_store, $D0, $D1 + vpaddd $D1, $D0, $D0 + vmovdqa $D0, $ctr0_store + vmovdqa $D1, $ctr1_store +___ +$code.=<<___ if ($n eq 3); + vmovdqa .Lavx2_inc(%rip), $D0 + vpaddd $ctr0_store, $D0, $D2 + vpaddd $D2, $D0, $D1 + vpaddd $D1, $D0, $D0 + vmovdqa $D0, $ctr0_store + vmovdqa $D1, $ctr1_store + vmovdqa $D2, $ctr2_store +___ +$code.=<<___ if ($n eq 4); + vmovdqa .Lavx2_inc(%rip), $D0 + vpaddd $ctr0_store, $D0, $D3 + vpaddd $D3, $D0, $D2 + vpaddd $D2, $D0, $D1 + vpaddd $D1, $D0, $D0 + vmovdqa $D3, $ctr3_store + vmovdqa $D2, $ctr2_store + vmovdqa $D1, $ctr1_store + vmovdqa $D0, $ctr0_store +___ +} + +sub finalize_state_avx2 { +my ($n)=@_; +$code.=<<___ if ($n eq 4); + vpaddd .Lchacha20_consts(%rip), $A3, $A3 + vpaddd $state1_store, $B3, $B3 + vpaddd $state2_store, $C3, $C3 + vpaddd $ctr3_store, $D3, $D3 +___ +$code.=<<___ if ($n ge 3); + vpaddd .Lchacha20_consts(%rip), $A2, $A2 + vpaddd $state1_store, $B2, $B2 + vpaddd $state2_store, $C2, $C2 + vpaddd $ctr2_store, $D2, $D2 +___ +$code.=<<___ if ($n ge 2); + vpaddd .Lchacha20_consts(%rip), $A1, $A1 + vpaddd $state1_store, $B1, $B1 + vpaddd $state2_store, $C1, $C1 + vpaddd $ctr1_store, $D1, $D1 +___ +$code.=<<___; + vpaddd .Lchacha20_consts(%rip), $A0, $A0 + vpaddd $state1_store, $B0, $B0 + vpaddd $state2_store, $C0, $C0 + vpaddd $ctr0_store, $D0, $D0 +___ +} + +sub xor_stream_avx2 { +my ($A, $B, $C, $D, $offset, $hlp)=@_; +$code.=<<___; + vperm2i128 \$0x02, $A, $B, $hlp + vperm2i128 \$0x13, $A, $B, $B + vperm2i128 \$0x02, $C, $D, $A + vperm2i128 \$0x13, $C, $D, $C + vpxor 0*32+$offset($inp), $hlp, $hlp + vpxor 1*32+$offset($inp), $A, $A + vpxor 2*32+$offset($inp), $B, $B + vpxor 3*32+$offset($inp), $C, $C + vmovdqu $hlp, 0*32+$offset($oup) + vmovdqu $A, 1*32+$offset($oup) + vmovdqu $B, 2*32+$offset($oup) + vmovdqu $C, 3*32+$offset($oup) +___ +} + +sub finish_stream_avx2 { +my ($A, $B, $C, $D, $hlp)=@_; +$code.=<<___; + vperm2i128 \$0x13, $A, $B, $hlp + vperm2i128 \$0x02, $A, $B, $A + vperm2i128 \$0x02, $C, $D, $B + vperm2i128 \$0x13, $C, $D, $D + vmovdqa $hlp, $C +___ +} + +sub poly_stage1_mulx { +$code.=<<___; + mov 0+$r_store, %rdx + mov %rdx, $t2 + mulx $acc0, $t0, $t1 + mulx $acc1, %rax, %rdx + imulq $acc2, $t2 + add %rax, $t1 + adc %rdx, $t2 +___ +} + +sub poly_stage2_mulx { +$code.=<<___; + mov 8+$r_store, %rdx + mulx $acc0, $acc0, %rax + add $acc0, $t1 + mulx $acc1, $acc1, $t3 + adc $acc1, $t2 + adc \$0, $t3 + imulq $acc2, %rdx +___ +} + +sub poly_stage3_mulx { +$code.=<<___; + add %rax, $t2 + adc %rdx, $t3 +___ +} + +sub poly_mul_mulx { + &poly_stage1_mulx(); + &poly_stage2_mulx(); + &poly_stage3_mulx(); + &poly_reduce_stage(); +} + +sub gen_chacha_round_avx2 { +my ($rot1, $rot2, $shift)=@_; +my $round=""; +$round=$round ."vmovdqa $C0, $tmp_store\n" if ($rot1 eq 20); +$round=$round ."vmovdqa $rot2, $C0 + vpaddd $B3, $A3, $A3 + vpaddd $B2, $A2, $A2 + vpaddd $B1, $A1, $A1 + vpaddd $B0, $A0, $A0 + vpxor $A3, $D3, $D3 + vpxor $A2, $D2, $D2 + vpxor $A1, $D1, $D1 + vpxor $A0, $D0, $D0 + vpshufb $C0, $D3, $D3 + vpshufb $C0, $D2, $D2 + vpshufb $C0, $D1, $D1 + vpshufb $C0, $D0, $D0 + vpaddd $D3, $C3, $C3 + vpaddd $D2, $C2, $C2 + vpaddd $D1, $C1, $C1 + vpaddd $tmp_store, $D0, $C0 + vpxor $C3, $B3, $B3 + vpxor $C2, $B2, $B2 + vpxor $C1, $B1, $B1 + vpxor $C0, $B0, $B0 + vmovdqa $C0, $tmp_store + vpsrld \$$rot1, $B3, $C0 + vpslld \$32-$rot1, $B3, $B3 + vpxor $C0, $B3, $B3 + vpsrld \$$rot1, $B2, $C0 + vpslld \$32-$rot1, $B2, $B2 + vpxor $C0, $B2, $B2 + vpsrld \$$rot1, $B1, $C0 + vpslld \$32-$rot1, $B1, $B1 + vpxor $C0, $B1, $B1 + vpsrld \$$rot1, $B0, $C0 + vpslld \$32-$rot1, $B0, $B0 + vpxor $C0, $B0, $B0\n"; +($s1,$s2,$s3)=(4,8,12) if ($shift =~ /left/); +($s1,$s2,$s3)=(12,8,4) if ($shift =~ /right/); +$round=$round ."vmovdqa $tmp_store, $C0 + vpalignr \$$s1, $B3, $B3, $B3 + vpalignr \$$s2, $C3, $C3, $C3 + vpalignr \$$s3, $D3, $D3, $D3 + vpalignr \$$s1, $B2, $B2, $B2 + vpalignr \$$s2, $C2, $C2, $C2 + vpalignr \$$s3, $D2, $D2, $D2 + vpalignr \$$s1, $B1, $B1, $B1 + vpalignr \$$s2, $C1, $C1, $C1 + vpalignr \$$s3, $D1, $D1, $D1 + vpalignr \$$s1, $B0, $B0, $B0 + vpalignr \$$s2, $C0, $C0, $C0 + vpalignr \$$s3, $D0, $D0, $D0\n" +if (($shift =~ /left/) || ($shift =~ /right/)); +return $round; +}; + +$chacha_body = &gen_chacha_round_avx2(20, ".Lrol16(%rip)") . + &gen_chacha_round_avx2(25, ".Lrol8(%rip)", "left") . + &gen_chacha_round_avx2(20, ".Lrol16(%rip)") . + &gen_chacha_round_avx2(25, ".Lrol8(%rip)", "right"); + +@loop_body = split /\n/, $chacha_body; + +$code.=" +############################################################################### +.type chacha20_poly1305_open_avx2,\@abi-omnipotent +.align 64 +chacha20_poly1305_open_avx2: +.cfi_startproc + +# Since the AVX2 function operates in the frame of the SSE function, we just copy the frame state to over here +.cfi_push %rbp +.cfi_push %rbx +.cfi_push %r12 +.cfi_push %r13 +.cfi_push %r14 +.cfi_push %r15 +.cfi_push $keyp +.cfi_adjust_cfa_offset 288 + 32 + + vzeroupper + vmovdqa .Lchacha20_consts(%rip), $A0 + vbroadcasti128 0*16($keyp), $B0 + vbroadcasti128 1*16($keyp), $C0 + vbroadcasti128 2*16($keyp), $D0 + vpaddd .Lavx2_init(%rip), $D0, $D0 + cmp \$6*32, $inl + jbe .Lopen_avx2_192 + cmp \$10*32, $inl + jbe .Lopen_avx2_320 + + vmovdqa $B0, $state1_store + vmovdqa $C0, $state2_store + vmovdqa $D0, $ctr0_store + mov \$10, $acc0 +.Lopen_avx2_init_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); $code.=" + dec $acc0 + jne .Lopen_avx2_init_rounds + vpaddd .Lchacha20_consts(%rip), $A0, $A0 + vpaddd $state1_store, $B0, $B0 + vpaddd $state2_store, $C0, $C0 + vpaddd $ctr0_store, $D0, $D0 + + vperm2i128 \$0x02, $A0, $B0, $T0 + # Clamp and store key + vpand .Lclamp(%rip), $T0, $T0 + vmovdqa $T0, $r_store + # Stream for the first 64 bytes + vperm2i128 \$0x13, $A0, $B0, $A0 + vperm2i128 \$0x13, $C0, $D0, $B0 + # Hash AD + first 64 bytes + mov $adl, $itr2 + call poly_hash_ad_internal + # Hash first 64 bytes + xor $itr1, $itr1 +.Lopen_avx2_init_hash: \n"; + &poly_add("0($inp,$itr1)"); + &poly_mul(); $code.=" + add \$16, $itr1 + cmp \$2*32, $itr1 + jne .Lopen_avx2_init_hash + # Decrypt first 64 bytes + vpxor 0*32($inp), $A0, $A0 + vpxor 1*32($inp), $B0, $B0 + # Store first 64 bytes of decrypted data + vmovdqu $A0, 0*32($oup) + vmovdqu $B0, 1*32($oup) + lea 2*32($inp), $inp + lea 2*32($oup), $oup + sub \$2*32, $inl +.Lopen_avx2_main_loop: + # Hash and decrypt 512 bytes each iteration + cmp \$16*32, $inl + jb .Lopen_avx2_main_loop_done\n"; + &prep_state_avx2(4); $code.=" + xor $itr1, $itr1 +.Lopen_avx2_main_loop_rounds: \n"; + &poly_add("0*8($inp,$itr1)"); + &emit_body(10); + &poly_stage1_mulx(); + &emit_body(9); + &poly_stage2_mulx(); + &emit_body(12); + &poly_stage3_mulx(); + &emit_body(10); + &poly_reduce_stage(); + &emit_body(9); + &poly_add("2*8($inp,$itr1)"); + &emit_body(8); + &poly_stage1_mulx(); + &emit_body(18); + &poly_stage2_mulx(); + &emit_body(18); + &poly_stage3_mulx(); + &emit_body(9); + &poly_reduce_stage(); + &emit_body(8); + &poly_add("4*8($inp,$itr1)"); $code.=" + lea 6*8($itr1), $itr1\n"; + &emit_body(18); + &poly_stage1_mulx(); + &emit_body(8); + &poly_stage2_mulx(); + &emit_body(8); + &poly_stage3_mulx(); + &emit_body(18); + &poly_reduce_stage(); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + cmp \$10*6*8, $itr1 + jne .Lopen_avx2_main_loop_rounds\n"; + &finalize_state_avx2(4); $code.=" + vmovdqa $A0, $tmp_store\n"; + &poly_add("10*6*8($inp)"); + &xor_stream_avx2($A3, $B3, $C3, $D3, 0*32, $A0); $code.=" + vmovdqa $tmp_store, $A0\n"; + &poly_mul(); + &xor_stream_avx2($A2, $B2, $C2, $D2, 4*32, $A3); + &poly_add("10*6*8+2*8($inp)"); + &xor_stream_avx2($A1, $B1, $C1, $D1, 8*32, $A3); + &poly_mul(); + &xor_stream_avx2($A0, $B0, $C0, $D0, 12*32, $A3); $code.=" + lea 16*32($inp), $inp + lea 16*32($oup), $oup + sub \$16*32, $inl + jmp .Lopen_avx2_main_loop +.Lopen_avx2_main_loop_done: + test $inl, $inl + vzeroupper + je .Lopen_sse_finalize + + cmp \$12*32, $inl + ja .Lopen_avx2_tail_512 + cmp \$8*32, $inl + ja .Lopen_avx2_tail_384 + cmp \$4*32, $inl + ja .Lopen_avx2_tail_256\n"; +############################################################################### + # 1-128 bytes left + &prep_state_avx2(1); $code.=" + xor $itr2, $itr2 + mov $inl, $itr1 + and \$-16, $itr1 + test $itr1, $itr1 + je .Lopen_avx2_tail_128_rounds # Have nothing to hash +.Lopen_avx2_tail_128_rounds_and_x1hash: \n"; + &poly_add("0*8($inp,$itr2)"); + &poly_mul(); $code.=" +.Lopen_avx2_tail_128_rounds: + add \$16, $itr2\n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); $code.=" + cmp $itr1, $itr2 + jb .Lopen_avx2_tail_128_rounds_and_x1hash + cmp \$160, $itr2 + jne .Lopen_avx2_tail_128_rounds\n"; + &finalize_state_avx2(1); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T0); $code.=" + jmp .Lopen_avx2_tail_128_xor +############################################################################### +.Lopen_avx2_tail_256: \n"; + # 129-256 bytes left + &prep_state_avx2(2); $code.=" + mov $inl, $tmp_store + mov $inl, $itr1 + sub \$4*32, $itr1 + shr \$4, $itr1 + mov \$10, $itr2 + cmp \$10, $itr1 + cmovg $itr2, $itr1 + mov $inp, $inl + xor $itr2, $itr2 +.Lopen_avx2_tail_256_rounds_and_x1hash: \n"; + &poly_add("0*8($inl)"); + &poly_mul_mulx(); $code.=" + lea 16($inl), $inl +.Lopen_avx2_tail_256_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); $code.=" + inc $itr2\n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + cmp $itr1, $itr2 + jb .Lopen_avx2_tail_256_rounds_and_x1hash + cmp \$10, $itr2 + jne .Lopen_avx2_tail_256_rounds + mov $inl, $itr2 + sub $inp, $inl + mov $inl, $itr1 + mov $tmp_store, $inl +.Lopen_avx2_tail_256_hash: + add \$16, $itr1 + cmp $inl, $itr1 + jg .Lopen_avx2_tail_256_done\n"; + &poly_add("0*8($itr2)"); + &poly_mul_mulx(); $code.=" + lea 16($itr2), $itr2 + jmp .Lopen_avx2_tail_256_hash +.Lopen_avx2_tail_256_done: \n"; + &finalize_state_avx2(2); + &xor_stream_avx2($A1, $B1, $C1, $D1, 0*32, $T0); + &finish_stream_avx2($A0, $B0, $C0, $D0, $T0); $code.=" + lea 4*32($inp), $inp + lea 4*32($oup), $oup + sub \$4*32, $inl + jmp .Lopen_avx2_tail_128_xor +############################################################################### +.Lopen_avx2_tail_384: \n"; + # 257-383 bytes left + &prep_state_avx2(3); $code.=" + mov $inl, $tmp_store + mov $inl, $itr1 + sub \$8*32, $itr1 + shr \$4, $itr1 + add \$6, $itr1 + mov \$10, $itr2 + cmp \$10, $itr1 + cmovg $itr2, $itr1 + mov $inp, $inl + xor $itr2, $itr2 +.Lopen_avx2_tail_384_rounds_and_x2hash: \n"; + &poly_add("0*8($inl)"); + &poly_mul_mulx(); $code.=" + lea 16($inl), $inl +.Lopen_avx2_tail_384_rounds_and_x1hash: \n"; + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &poly_add("0*8($inl)"); + &poly_mul(); $code.=" + lea 16($inl), $inl + inc $itr2\n"; + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); $code.=" + cmp $itr1, $itr2 + jb .Lopen_avx2_tail_384_rounds_and_x2hash + cmp \$10, $itr2 + jne .Lopen_avx2_tail_384_rounds_and_x1hash + mov $inl, $itr2 + sub $inp, $inl + mov $inl, $itr1 + mov $tmp_store, $inl +.Lopen_avx2_384_tail_hash: + add \$16, $itr1 + cmp $inl, $itr1 + jg .Lopen_avx2_384_tail_done\n"; + &poly_add("0*8($itr2)"); + &poly_mul_mulx(); $code.=" + lea 16($itr2), $itr2 + jmp .Lopen_avx2_384_tail_hash +.Lopen_avx2_384_tail_done: \n"; + &finalize_state_avx2(3); + &xor_stream_avx2($A2, $B2, $C2, $D2, 0*32, $T0); + &xor_stream_avx2($A1, $B1, $C1, $D1, 4*32, $T0); + &finish_stream_avx2($A0, $B0, $C0, $D0, $T0); $code.=" + lea 8*32($inp), $inp + lea 8*32($oup), $oup + sub \$8*32, $inl + jmp .Lopen_avx2_tail_128_xor +############################################################################### +.Lopen_avx2_tail_512: \n"; + # 384-512 bytes left + &prep_state_avx2(4); $code.=" + xor $itr1, $itr1 + mov $inp, $itr2 +.Lopen_avx2_tail_512_rounds_and_x2hash: \n"; + &poly_add("0*8($itr2)"); + &poly_mul(); $code.=" + lea 2*8($itr2), $itr2 +.Lopen_avx2_tail_512_rounds_and_x1hash: \n"; + &emit_body(37); + &poly_add("0*8($itr2)"); + &poly_mul_mulx(); + &emit_body(48); + &poly_add("2*8($itr2)"); + &poly_mul_mulx(); $code.=" + lea 4*8($itr2), $itr2\n"; + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + inc $itr1 + cmp \$4, $itr1 + jl .Lopen_avx2_tail_512_rounds_and_x2hash + cmp \$10, $itr1 + jne .Lopen_avx2_tail_512_rounds_and_x1hash + mov $inl, $itr1 + sub \$12*32, $itr1 + and \$-16, $itr1 +.Lopen_avx2_tail_512_hash: + test $itr1, $itr1 + je .Lopen_avx2_tail_512_done\n"; + &poly_add("0*8($itr2)"); + &poly_mul_mulx(); $code.=" + lea 2*8($itr2), $itr2 + sub \$2*8, $itr1 + jmp .Lopen_avx2_tail_512_hash +.Lopen_avx2_tail_512_done: \n"; + &finalize_state_avx2(4); $code.=" + vmovdqa $A0, $tmp_store\n"; + &xor_stream_avx2($A3, $B3, $C3, $D3, 0*32, $A0); $code.=" + vmovdqa $tmp_store, $A0\n"; + &xor_stream_avx2($A2, $B2, $C2, $D2, 4*32, $A3); + &xor_stream_avx2($A1, $B1, $C1, $D1, 8*32, $A3); + &finish_stream_avx2($A0, $B0, $C0, $D0, $A3); $code.=" + lea 12*32($inp), $inp + lea 12*32($oup), $oup + sub \$12*32, $inl +.Lopen_avx2_tail_128_xor: + cmp \$32, $inl + jb .Lopen_avx2_tail_32_xor + sub \$32, $inl + vpxor ($inp), $A0, $A0 + vmovdqu $A0, ($oup) + lea 1*32($inp), $inp + lea 1*32($oup), $oup + vmovdqa $B0, $A0 + vmovdqa $C0, $B0 + vmovdqa $D0, $C0 + jmp .Lopen_avx2_tail_128_xor +.Lopen_avx2_tail_32_xor: + cmp \$16, $inl + vmovdqa $A0x, $A1x + jb .Lopen_avx2_exit + sub \$16, $inl + #load for decryption + vpxor ($inp), $A0x, $A1x + vmovdqu $A1x, ($oup) + lea 1*16($inp), $inp + lea 1*16($oup), $oup + vperm2i128 \$0x11, $A0, $A0, $A0 + vmovdqa $A0x, $A1x +.Lopen_avx2_exit: + vzeroupper + jmp .Lopen_sse_tail_16 +############################################################################### +.Lopen_avx2_192: + vmovdqa $A0, $A1 + vmovdqa $A0, $A2 + vmovdqa $B0, $B1 + vmovdqa $B0, $B2 + vmovdqa $C0, $C1 + vmovdqa $C0, $C2 + vpaddd .Lavx2_inc(%rip), $D0, $D1 + vmovdqa $D0, $T2 + vmovdqa $D1, $T3 + mov \$10, $acc0 +.Lopen_avx2_192_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); $code.=" + dec $acc0 + jne .Lopen_avx2_192_rounds + vpaddd $A2, $A0, $A0 + vpaddd $A2, $A1, $A1 + vpaddd $B2, $B0, $B0 + vpaddd $B2, $B1, $B1 + vpaddd $C2, $C0, $C0 + vpaddd $C2, $C1, $C1 + vpaddd $T2, $D0, $D0 + vpaddd $T3, $D1, $D1 + vperm2i128 \$0x02, $A0, $B0, $T0 + # Clamp and store the key + vpand .Lclamp(%rip), $T0, $T0 + vmovdqa $T0, $r_store + # Stream for up to 192 bytes + vperm2i128 \$0x13, $A0, $B0, $A0 + vperm2i128 \$0x13, $C0, $D0, $B0 + vperm2i128 \$0x02, $A1, $B1, $C0 + vperm2i128 \$0x02, $C1, $D1, $D0 + vperm2i128 \$0x13, $A1, $B1, $A1 + vperm2i128 \$0x13, $C1, $D1, $B1 +.Lopen_avx2_short: + mov $adl, $itr2 + call poly_hash_ad_internal +.Lopen_avx2_short_hash_and_xor_loop: + cmp \$32, $inl + jb .Lopen_avx2_short_tail_32 + sub \$32, $inl\n"; + # Load + hash + &poly_add("0*8($inp)"); + &poly_mul(); + &poly_add("2*8($inp)"); + &poly_mul(); $code.=" + # Load + decrypt + vpxor ($inp), $A0, $A0 + vmovdqu $A0, ($oup) + lea 1*32($inp), $inp + lea 1*32($oup), $oup + # Shift stream + vmovdqa $B0, $A0 + vmovdqa $C0, $B0 + vmovdqa $D0, $C0 + vmovdqa $A1, $D0 + vmovdqa $B1, $A1 + vmovdqa $C1, $B1 + vmovdqa $D1, $C1 + vmovdqa $A2, $D1 + vmovdqa $B2, $A2 + jmp .Lopen_avx2_short_hash_and_xor_loop +.Lopen_avx2_short_tail_32: + cmp \$16, $inl + vmovdqa $A0x, $A1x + jb .Lopen_avx2_short_tail_32_exit + sub \$16, $inl\n"; + &poly_add("0*8($inp)"); + &poly_mul(); $code.=" + vpxor ($inp), $A0x, $A3x + vmovdqu $A3x, ($oup) + lea 1*16($inp), $inp + lea 1*16($oup), $oup + vextracti128 \$1, $A0, $A1x +.Lopen_avx2_short_tail_32_exit: + vzeroupper + jmp .Lopen_sse_tail_16 +############################################################################### +.Lopen_avx2_320: + vmovdqa $A0, $A1 + vmovdqa $A0, $A2 + vmovdqa $B0, $B1 + vmovdqa $B0, $B2 + vmovdqa $C0, $C1 + vmovdqa $C0, $C2 + vpaddd .Lavx2_inc(%rip), $D0, $D1 + vpaddd .Lavx2_inc(%rip), $D1, $D2 + vmovdqa $B0, $T1 + vmovdqa $C0, $T2 + vmovdqa $D0, $ctr0_store + vmovdqa $D1, $ctr1_store + vmovdqa $D2, $ctr2_store + mov \$10, $acc0 +.Lopen_avx2_320_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + dec $acc0 + jne .Lopen_avx2_320_rounds + vpaddd .Lchacha20_consts(%rip), $A0, $A0 + vpaddd .Lchacha20_consts(%rip), $A1, $A1 + vpaddd .Lchacha20_consts(%rip), $A2, $A2 + vpaddd $T1, $B0, $B0 + vpaddd $T1, $B1, $B1 + vpaddd $T1, $B2, $B2 + vpaddd $T2, $C0, $C0 + vpaddd $T2, $C1, $C1 + vpaddd $T2, $C2, $C2 + vpaddd $ctr0_store, $D0, $D0 + vpaddd $ctr1_store, $D1, $D1 + vpaddd $ctr2_store, $D2, $D2 + vperm2i128 \$0x02, $A0, $B0, $T0 + # Clamp and store the key + vpand .Lclamp(%rip), $T0, $T0 + vmovdqa $T0, $r_store + # Stream for up to 320 bytes + vperm2i128 \$0x13, $A0, $B0, $A0 + vperm2i128 \$0x13, $C0, $D0, $B0 + vperm2i128 \$0x02, $A1, $B1, $C0 + vperm2i128 \$0x02, $C1, $D1, $D0 + vperm2i128 \$0x13, $A1, $B1, $A1 + vperm2i128 \$0x13, $C1, $D1, $B1 + vperm2i128 \$0x02, $A2, $B2, $C1 + vperm2i128 \$0x02, $C2, $D2, $D1 + vperm2i128 \$0x13, $A2, $B2, $A2 + vperm2i128 \$0x13, $C2, $D2, $B2 + jmp .Lopen_avx2_short +.size chacha20_poly1305_open_avx2, .-chacha20_poly1305_open_avx2 +.cfi_endproc +############################################################################### +############################################################################### +.type chacha20_poly1305_seal_avx2,\@abi-omnipotent +.align 64 +chacha20_poly1305_seal_avx2: +.cfi_startproc + +# Since the AVX2 function operates in the frame of the SSE function, we just copy the frame state to over here +.cfi_push %rbp +.cfi_push %rbx +.cfi_push %r12 +.cfi_push %r13 +.cfi_push %r14 +.cfi_push %r15 +.cfi_push $keyp +.cfi_adjust_cfa_offset 288 + 32 + + vzeroupper + vmovdqa .Lchacha20_consts(%rip), $A0 + vbroadcasti128 0*16($keyp), $B0 + vbroadcasti128 1*16($keyp), $C0 + vbroadcasti128 2*16($keyp), $D0 + vpaddd .Lavx2_init(%rip), $D0, $D0 + cmp \$6*32, $inl + jbe .Lseal_avx2_192 + cmp \$10*32, $inl + jbe .Lseal_avx2_320 + vmovdqa $A0, $A1 + vmovdqa $A0, $A2 + vmovdqa $A0, $A3 + vmovdqa $B0, $B1 + vmovdqa $B0, $B2 + vmovdqa $B0, $B3 + vmovdqa $B0, $state1_store + vmovdqa $C0, $C1 + vmovdqa $C0, $C2 + vmovdqa $C0, $C3 + vmovdqa $C0, $state2_store + vmovdqa $D0, $D3 + vpaddd .Lavx2_inc(%rip), $D3, $D2 + vpaddd .Lavx2_inc(%rip), $D2, $D1 + vpaddd .Lavx2_inc(%rip), $D1, $D0 + vmovdqa $D0, $ctr0_store + vmovdqa $D1, $ctr1_store + vmovdqa $D2, $ctr2_store + vmovdqa $D3, $ctr3_store + mov \$10, $acc0 +.Lseal_avx2_init_rounds: \n"; + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + dec $acc0 + jnz .Lseal_avx2_init_rounds\n"; + &finalize_state_avx2(4); $code.=" + vperm2i128 \$0x13, $C3, $D3, $C3 + vperm2i128 \$0x02, $A3, $B3, $D3 + vperm2i128 \$0x13, $A3, $B3, $A3 + vpand .Lclamp(%rip), $D3, $D3 + vmovdqa $D3, $r_store + mov $adl, $itr2 + call poly_hash_ad_internal + # Safely store 320 bytes (otherwise would handle with optimized call) + vpxor 0*32($inp), $A3, $A3 + vpxor 1*32($inp), $C3, $C3 + vmovdqu $A3, 0*32($oup) + vmovdqu $C3, 1*32($oup)\n"; + &xor_stream_avx2($A2,$B2,$C2,$D2,2*32,$T3); + &xor_stream_avx2($A1,$B1,$C1,$D1,6*32,$T3); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T3); $code.=" + lea 10*32($inp), $inp + sub \$10*32, $inl + mov \$10*32, $itr1 + cmp \$4*32, $inl + jbe .Lseal_avx2_short_hash_remainder + vpxor 0*32($inp), $A0, $A0 + vpxor 1*32($inp), $B0, $B0 + vpxor 2*32($inp), $C0, $C0 + vpxor 3*32($inp), $D0, $D0 + vmovdqu $A0, 10*32($oup) + vmovdqu $B0, 11*32($oup) + vmovdqu $C0, 12*32($oup) + vmovdqu $D0, 13*32($oup) + lea 4*32($inp), $inp + sub \$4*32, $inl + mov \$8, $itr1 + mov \$2, $itr2 + cmp \$4*32, $inl + jbe .Lseal_avx2_tail_128 + cmp \$8*32, $inl + jbe .Lseal_avx2_tail_256 + cmp \$12*32, $inl + jbe .Lseal_avx2_tail_384 + cmp \$16*32, $inl + jbe .Lseal_avx2_tail_512\n"; + # We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop + &prep_state_avx2(4); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; + &emit_body(41); + @loop_body = split /\n/, $chacha_body; $code.=" + sub \$16, $oup + mov \$9, $itr1 + jmp .Lseal_avx2_main_loop_rounds_entry +.align 32 +.Lseal_avx2_main_loop: \n"; + &prep_state_avx2(4); $code.=" + mov \$10, $itr1 +.align 32 +.Lseal_avx2_main_loop_rounds: \n"; + &poly_add("0*8($oup)"); + &emit_body(10); + &poly_stage1_mulx(); + &emit_body(9); + &poly_stage2_mulx(); + &emit_body(12); + &poly_stage3_mulx(); + &emit_body(10); + &poly_reduce_stage(); $code.=" +.Lseal_avx2_main_loop_rounds_entry: \n"; + &emit_body(9); + &poly_add("2*8($oup)"); + &emit_body(8); + &poly_stage1_mulx(); + &emit_body(18); + &poly_stage2_mulx(); + &emit_body(18); + &poly_stage3_mulx(); + &emit_body(9); + &poly_reduce_stage(); + &emit_body(8); + &poly_add("4*8($oup)"); $code.=" + lea 6*8($oup), $oup\n"; + &emit_body(18); + &poly_stage1_mulx(); + &emit_body(8); + &poly_stage2_mulx(); + &emit_body(8); + &poly_stage3_mulx(); + &emit_body(18); + &poly_reduce_stage(); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + dec $itr1 + jne .Lseal_avx2_main_loop_rounds\n"; + &finalize_state_avx2(4); $code.=" + vmovdqa $A0, $tmp_store\n"; + &poly_add("0*8($oup)"); + &poly_mul_mulx(); + &poly_add("2*8($oup)"); + &poly_mul_mulx(); $code.=" + lea 4*8($oup), $oup\n"; + &xor_stream_avx2($A3, $B3, $C3, $D3, 0*32, $A0); $code.=" + vmovdqa $tmp_store, $A0\n"; + &xor_stream_avx2($A2, $B2, $C2, $D2, 4*32, $A3); + &xor_stream_avx2($A1, $B1, $C1, $D1, 8*32, $A3); + &xor_stream_avx2($A0, $B0, $C0, $D0, 12*32, $A3); $code.=" + lea 16*32($inp), $inp + sub \$16*32, $inl + cmp \$16*32, $inl + jg .Lseal_avx2_main_loop +\n"; + &poly_add("0*8($oup)"); + &poly_mul_mulx(); + &poly_add("2*8($oup)"); + &poly_mul_mulx(); $code.=" + lea 4*8($oup), $oup + mov \$10, $itr1 + xor $itr2, $itr2 + + cmp \$12*32, $inl + ja .Lseal_avx2_tail_512 + cmp \$8*32, $inl + ja .Lseal_avx2_tail_384 + cmp \$4*32, $inl + ja .Lseal_avx2_tail_256 +############################################################################### +.Lseal_avx2_tail_128:\n"; + &prep_state_avx2(1); $code.=" +.Lseal_avx2_tail_128_rounds_and_3xhash: \n"; + &poly_add("0($oup)"); + &poly_mul_mulx(); $code.=" + lea 2*8($oup), $oup +.Lseal_avx2_tail_128_rounds_and_2xhash: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &poly_add("0*8($oup)"); + &poly_mul_mulx(); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &poly_add("2*8($oup)"); + &poly_mul_mulx(); $code.=" + lea 4*8($oup), $oup + dec $itr1 + jg .Lseal_avx2_tail_128_rounds_and_3xhash + dec $itr2 + jge .Lseal_avx2_tail_128_rounds_and_2xhash\n"; + &finalize_state_avx2(1); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T0); $code.=" + jmp .Lseal_avx2_short_loop +############################################################################### +.Lseal_avx2_tail_256:\n"; + &prep_state_avx2(2); $code.=" +.Lseal_avx2_tail_256_rounds_and_3xhash: \n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 2*8($oup), $oup +.Lseal_avx2_tail_256_rounds_and_2xhash: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &poly_add("0*8($oup)"); + &poly_mul(); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &poly_add("2*8($oup)"); + &poly_mul(); $code.=" + lea 4*8($oup), $oup + dec $itr1 + jg .Lseal_avx2_tail_256_rounds_and_3xhash + dec $itr2 + jge .Lseal_avx2_tail_256_rounds_and_2xhash\n"; + &finalize_state_avx2(2); + &xor_stream_avx2($A1,$B1,$C1,$D1,0*32,$T0); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T0); $code.=" + mov \$4*32, $itr1 + lea 4*32($inp), $inp + sub \$4*32, $inl + jmp .Lseal_avx2_short_hash_remainder +############################################################################### +.Lseal_avx2_tail_384:\n"; + &prep_state_avx2(3); $code.=" +.Lseal_avx2_tail_384_rounds_and_3xhash: \n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + lea 2*8($oup), $oup +.Lseal_avx2_tail_384_rounds_and_2xhash: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &poly_add("0*8($oup)"); + &poly_mul(); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &poly_add("2*8($oup)"); + &poly_mul(); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + lea 4*8($oup), $oup + dec $itr1 + jg .Lseal_avx2_tail_384_rounds_and_3xhash + dec $itr2 + jge .Lseal_avx2_tail_384_rounds_and_2xhash\n"; + &finalize_state_avx2(3); + &xor_stream_avx2($A2,$B2,$C2,$D2,0*32,$T0); + &xor_stream_avx2($A1,$B1,$C1,$D1,4*32,$T0); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T0); $code.=" + mov \$8*32, $itr1 + lea 8*32($inp), $inp + sub \$8*32, $inl + jmp .Lseal_avx2_short_hash_remainder +############################################################################### +.Lseal_avx2_tail_512:\n"; + &prep_state_avx2(4); $code.=" +.Lseal_avx2_tail_512_rounds_and_3xhash: \n"; + &poly_add("0($oup)"); + &poly_mul_mulx(); $code.=" + lea 2*8($oup), $oup +.Lseal_avx2_tail_512_rounds_and_2xhash: \n"; + &emit_body(20); + &poly_add("0*8($oup)"); + &emit_body(20); + &poly_stage1_mulx(); + &emit_body(20); + &poly_stage2_mulx(); + &emit_body(20); + &poly_stage3_mulx(); + &emit_body(20); + &poly_reduce_stage(); + &emit_body(20); + &poly_add("2*8($oup)"); + &emit_body(20); + &poly_stage1_mulx(); + &emit_body(20); + &poly_stage2_mulx(); + &emit_body(20); + &poly_stage3_mulx(); + &emit_body(20); + &poly_reduce_stage(); + foreach $l (@loop_body) {$code.=$l."\n";} + @loop_body = split /\n/, $chacha_body; $code.=" + lea 4*8($oup), $oup + dec $itr1 + jg .Lseal_avx2_tail_512_rounds_and_3xhash + dec $itr2 + jge .Lseal_avx2_tail_512_rounds_and_2xhash\n"; + &finalize_state_avx2(4); $code.=" + vmovdqa $A0, $tmp_store\n"; + &xor_stream_avx2($A3, $B3, $C3, $D3, 0*32, $A0); $code.=" + vmovdqa $tmp_store, $A0\n"; + &xor_stream_avx2($A2, $B2, $C2, $D2, 4*32, $A3); + &xor_stream_avx2($A1, $B1, $C1, $D1, 8*32, $A3); + &finish_stream_avx2($A0,$B0,$C0,$D0,$T0); $code.=" + mov \$12*32, $itr1 + lea 12*32($inp), $inp + sub \$12*32, $inl + jmp .Lseal_avx2_short_hash_remainder +################################################################################ +.Lseal_avx2_320: + vmovdqa $A0, $A1 + vmovdqa $A0, $A2 + vmovdqa $B0, $B1 + vmovdqa $B0, $B2 + vmovdqa $C0, $C1 + vmovdqa $C0, $C2 + vpaddd .Lavx2_inc(%rip), $D0, $D1 + vpaddd .Lavx2_inc(%rip), $D1, $D2 + vmovdqa $B0, $T1 + vmovdqa $C0, $T2 + vmovdqa $D0, $ctr0_store + vmovdqa $D1, $ctr1_store + vmovdqa $D2, $ctr2_store + mov \$10, $acc0 +.Lseal_avx2_320_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); + &chacha_qr_avx2($A2,$B2,$C2,$D2,$T0,"right"); $code.=" + dec $acc0 + jne .Lseal_avx2_320_rounds + vpaddd .Lchacha20_consts(%rip), $A0, $A0 + vpaddd .Lchacha20_consts(%rip), $A1, $A1 + vpaddd .Lchacha20_consts(%rip), $A2, $A2 + vpaddd $T1, $B0, $B0 + vpaddd $T1, $B1, $B1 + vpaddd $T1, $B2, $B2 + vpaddd $T2, $C0, $C0 + vpaddd $T2, $C1, $C1 + vpaddd $T2, $C2, $C2 + vpaddd $ctr0_store, $D0, $D0 + vpaddd $ctr1_store, $D1, $D1 + vpaddd $ctr2_store, $D2, $D2 + vperm2i128 \$0x02, $A0, $B0, $T0 + # Clamp and store the key + vpand .Lclamp(%rip), $T0, $T0 + vmovdqa $T0, $r_store + # Stream for up to 320 bytes + vperm2i128 \$0x13, $A0, $B0, $A0 + vperm2i128 \$0x13, $C0, $D0, $B0 + vperm2i128 \$0x02, $A1, $B1, $C0 + vperm2i128 \$0x02, $C1, $D1, $D0 + vperm2i128 \$0x13, $A1, $B1, $A1 + vperm2i128 \$0x13, $C1, $D1, $B1 + vperm2i128 \$0x02, $A2, $B2, $C1 + vperm2i128 \$0x02, $C2, $D2, $D1 + vperm2i128 \$0x13, $A2, $B2, $A2 + vperm2i128 \$0x13, $C2, $D2, $B2 + jmp .Lseal_avx2_short +################################################################################ +.Lseal_avx2_192: + vmovdqa $A0, $A1 + vmovdqa $A0, $A2 + vmovdqa $B0, $B1 + vmovdqa $B0, $B2 + vmovdqa $C0, $C1 + vmovdqa $C0, $C2 + vpaddd .Lavx2_inc(%rip), $D0, $D1 + vmovdqa $D0, $T2 + vmovdqa $D1, $T3 + mov \$10, $acc0 +.Lseal_avx2_192_rounds: \n"; + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"left"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"left"); + &chacha_qr_avx2($A0,$B0,$C0,$D0,$T0,"right"); + &chacha_qr_avx2($A1,$B1,$C1,$D1,$T0,"right"); $code.=" + dec $acc0 + jne .Lseal_avx2_192_rounds + vpaddd $A2, $A0, $A0 + vpaddd $A2, $A1, $A1 + vpaddd $B2, $B0, $B0 + vpaddd $B2, $B1, $B1 + vpaddd $C2, $C0, $C0 + vpaddd $C2, $C1, $C1 + vpaddd $T2, $D0, $D0 + vpaddd $T3, $D1, $D1 + vperm2i128 \$0x02, $A0, $B0, $T0 + # Clamp and store the key + vpand .Lclamp(%rip), $T0, $T0 + vmovdqa $T0, $r_store + # Stream for up to 192 bytes + vperm2i128 \$0x13, $A0, $B0, $A0 + vperm2i128 \$0x13, $C0, $D0, $B0 + vperm2i128 \$0x02, $A1, $B1, $C0 + vperm2i128 \$0x02, $C1, $D1, $D0 + vperm2i128 \$0x13, $A1, $B1, $A1 + vperm2i128 \$0x13, $C1, $D1, $B1 +.Lseal_avx2_short: + mov $adl, $itr2 + call poly_hash_ad_internal + xor $itr1, $itr1 +.Lseal_avx2_short_hash_remainder: + cmp \$16, $itr1 + jb .Lseal_avx2_short_loop\n"; + &poly_add("0($oup)"); + &poly_mul(); $code.=" + sub \$16, $itr1 + add \$16, $oup + jmp .Lseal_avx2_short_hash_remainder +.Lseal_avx2_short_loop: + cmp \$32, $inl + jb .Lseal_avx2_short_tail + sub \$32, $inl + # Encrypt + vpxor ($inp), $A0, $A0 + vmovdqu $A0, ($oup) + lea 1*32($inp), $inp + # Load + hash\n"; + &poly_add("0*8($oup)"); + &poly_mul(); + &poly_add("2*8($oup)"); + &poly_mul(); $code.=" + lea 1*32($oup), $oup + # Shift stream + vmovdqa $B0, $A0 + vmovdqa $C0, $B0 + vmovdqa $D0, $C0 + vmovdqa $A1, $D0 + vmovdqa $B1, $A1 + vmovdqa $C1, $B1 + vmovdqa $D1, $C1 + vmovdqa $A2, $D1 + vmovdqa $B2, $A2 + jmp .Lseal_avx2_short_loop +.Lseal_avx2_short_tail: + cmp \$16, $inl + jb .Lseal_avx2_exit + sub \$16, $inl + vpxor ($inp), $A0x, $A3x + vmovdqu $A3x, ($oup) + lea 1*16($inp), $inp\n"; + &poly_add("0*8($oup)"); + &poly_mul(); $code.=" + lea 1*16($oup), $oup + vextracti128 \$1, $A0, $A0x +.Lseal_avx2_exit: + vzeroupper + jmp .Lseal_sse_tail_16 +.cfi_endproc +.size chacha20_poly1305_seal_avx2, .-chacha20_poly1305_seal_avx2 +"; +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; + +print $code; + +close STDOUT or die "error closing STDOUT"; diff --git a/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt b/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt deleted file mode 100644 index 8587eea1fc..0000000000 --- a/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt +++ /dev/null @@ -1,574 +0,0 @@ -# This is the example from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#section-8 - -KEY: ee8e1ed9ff2540ae8f2ba9f50bc2f27c -NONCE: 752abad3e0afb5f434dc4310 -IN: "Hello world" -AD: "example" -CT: 5d349ead175ef6b1def6fd -TAG: 4fbcdeb7e4793f4a1d7e4faa70100af1 - -# Test vectors from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: -AD: -CT: -TAG: dc20e2d83f25705bb49e439eca56de25 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0100000000000000 -AD: -CT: b5d839330ac7b786 -TAG: 578782fff6013b815b287c22493a364c - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 010000000000000000000000 -AD: -CT: 7323ea61d05932260047d942 -TAG: a4978db357391a0bc4fdec8b0d106639 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 01000000000000000000000000000000 -AD: -CT: 743f7c8077ab25f8624e2e948579cf77 -TAG: 303aaf90f6fe21199c6068577437a0c4 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0100000000000000000000000000000002000000000000000000000000000000 -AD: -CT: 84e07e62ba83a6585417245d7ec413a9fe427d6315c09b57ce45f2e3936a9445 -TAG: 1a8e45dcd4578c667cd86847bf6155ff - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000 -AD: -CT: 3fd24ce1f5a67b75bf2351f181a475c7b800a5b4d3dcf70106b1eea82fa1d64df42bf7226122fa92e17a40eeaac1201b -TAG: 5e6e311dbf395d35b0fe39c2714388f8 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000 -AD: -CT: 2433668f1058190f6d43e360f4f35cd8e475127cfca7028ea8ab5c20f7ab2af02516a2bdcbc08d521be37ff28c152bba36697f25b4cd169c6590d1dd39566d3f -TAG: 8a263dd317aa88d56bdf3936dba75bb8 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0200000000000000 -AD: 01 -CT: 1e6daba35669f427 -TAG: 3b0a1a2560969cdf790d99759abd1508 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 020000000000000000000000 -AD: 01 -CT: 296c7889fd99f41917f44620 -TAG: 08299c5102745aaa3a0c469fad9e075a - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000000000000000000000000000 -AD: 01 -CT: e2b0c5da79a901c1745f700525cb335b -TAG: 8f8936ec039e4e4bb97ebd8c4457441f - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0200000000000000000000000000000003000000000000000000000000000000 -AD: 01 -CT: 620048ef3c1e73e57e02bb8562c416a319e73e4caac8e96a1ecb2933145a1d71 -TAG: e6af6a7f87287da059a71684ed3498e1 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000 -AD: 01 -CT: 50c8303ea93925d64090d07bd109dfd9515a5a33431019c17d93465999a8b0053201d723120a8562b838cdff25bf9d1e -TAG: 6a8cc3865f76897c2e4b245cf31c51f2 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000 -AD: 01 -CT: 2f5c64059db55ee0fb847ed513003746aca4e61c711b5de2e7a77ffd02da42feec601910d3467bb8b36ebbaebce5fba30d36c95f48a3e7980f0e7ac299332a80 -TAG: cdc46ae475563de037001ef84ae21744 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000 -AD: 010000000000000000000000 -CT: a8fe3e87 -TAG: 07eb1f84fb28f8cb73de8e99e2f48a14 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0300000000000000000000000000000004000000 -AD: 010000000000000000000000000000000200 -CT: 6bb0fecf5ded9b77f902c7d5da236a4391dd0297 -TAG: 24afc9805e976f451e6d87f6fe106514 - -KEY: 01000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 030000000000000000000000000000000400 -AD: 0100000000000000000000000000000002000000 -CT: 44d0aaf6fb2f1f34add5e8064e83e12a2ada -TAG: bff9b2ef00fb47920cc72a0c0f13b9fd - -# Random vectors generated by the reference code. - -KEY: e66021d5eb8e4f4066d4adb9c33560e4 -NONCE: f46e44bb3da0015c94f70887 -IN: -AD: -CT: -TAG: a4194b79071b01a87d65f706e3949578 - -KEY: 36864200e0eaf5284d884a0e77d31646 -NONCE: bae8e37fc83441b16034566b -IN: 7a806c46bb91c3c5aedb64a6c590bc84d1 -AD: a5e269e4b47801afc0 -CT: 8092e6d6d729f5ee7e808d77f3b7a89647 -TAG: dec23ae31e3e97bb364fa18ad85cae0b - -KEY: 577e34699b9e671fdd4fbdc66f146545 -NONCE: fc880c94a95198874296d5cc -IN: 1fd161320b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f19549586 -AD: 0f046787f3ea22c127aaf195d1894728b3fe -CT: 7520668ef1b845aabf245e66ca687ca7c5b4f00de71afea392cda124893746ddd4e6 -TAG: db5ad3b398513fe5c8d868e68becd5a8 - -KEY: d1473c528b8426a582995929a1499e9a -NONCE: d8780c8d63d0ab4149c09f57 -IN: 2c614b4745914474e7c7c9882e5386fd9f92ec489c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f614 -AD: 55bfac8308a2d40d8c8451178082355c9e940fea2f582950a70d5a -CT: bdbec524ca37355074899f01b7247b1abc24565b997e000f231f0664be655d8cb75f18112cfaa722e1b2e261710036ff919014 -TAG: 45b9ece29df0dd93941f9454404c8d87 - -KEY: 1db2316fd568378da107b52b0da55210 -NONCE: cc1c1b0abde3b2f204d1e9f8 -IN: b06bc47f9745b3d1ae06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f -AD: f901cfe8a69615a93fdf7a98cad481796245709fb18853f68d833640e42a3c02c25b6486 -CT: d75a5a40ae0ac4343f1a52ee16108332b3563616c207c2b22be277a219e497b7e5bbd5bdecaed87a5216e3e49149ac50a7959957264c222577a07c73fc81f0e579a0fa93 -TAG: b70c26c56e34c7740824f9dfcb8ae6e4 - -KEY: 9e146d7b233987bddfc240871d7576f7 -NONCE: 028ec6eb5ea7e298342a94d4 -IN: b202b370ef9768ec6561c4fe6b7e7296fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de192eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e555 -AD: 40db1872504e1cced532ce4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e7 -CT: 23dea4fb871ab1df6cfb674d2e7efbc969033a11d694c6580aa3e780e4d1db5f1145924b974ce98ea041ecca53c36207fa644b0ae789965084d1ef845cae33aff734113b3eb4d9f1863b780b0f97fb5e3c5ea991cf -TAG: 81da1dfc98517d4cee3ee885a266e814 - -KEY: 2834321f7aa0f70b7282b4f33df23f16 -NONCE: 7541ac15c8417abaf17a282a -IN: c7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b469b0901f2b5da3a956a6e278c940e82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27ff1de -AD: a3b2a7d832ed8ab959d82ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafad -CT: 06d3e558b2f7f8e225d76a41a11122aa29eef02c226616f5264c9c1b821748a8115dd4868dfeacc5d167ceedc824f1f7136e7d7fae783bad83dec468c98747524fc2fcd7b86cbfd1c07078fd1b4b9caaae970c729ee3f2ecfebf048c5aba174fc4eab117bacf -TAG: 5ece142ce1074a09ab8ce810222a471d - -KEY: f0f484fae982019a8ea22efd1358adf7 -NONCE: ad4f5fa0d2acd2f1ee095cdf -IN: c13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0adb4c74 -AD: b73839e13455fd91ddf7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119 -CT: 90046c5ca4a6db850c5cddb14227b5902257e7ed8bc55f85ca24f51558f95037a0567d485b7606d2ec1802de069926e4f69e5ade9453080f84c045438d890290ed69b5e140788d07ed3d38b067900c222ad55b298e240590cb816d90a43ec52203f11ff9496b3dc32d7ac316ac8465496e41b4be5200dd -TAG: 76ae0503f7b43b1d2db24817f2b61ee7 - -KEY: ae0c8a20b679dc40c9908f88fecfafd6 -NONCE: 88b0ebec6a2ac13421012874 -IN: c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b9d0f8621 -AD: 664df31eb95b5e17567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361c91452e7d463338474a400ef9efcaa648e93f -CT: f729ca77733cca181ba8801e001924e20a1d164cc4440a6217a1178dd6b1210837367cf84aa41f92f4123d6740910586f819389d5c750ab15768aed1b163bde5b1fe8862d1621b11485b47182d32bd304ddbf275524c4ece4cfb1361db53dd63e21ac62bb54a77bb5063c869b5f5de1f1b4356845aac79ee6f66d21ff271e02e8bbbae1372b4b8ff -TAG: 52856b3369ecbb7201b1b0f75872e5e2 - -KEY: 38f8784a1598bca461211195d7844de5 -NONCE: 6b91cccc96d89e6471bca6b7 -IN: 374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc2d2c51dc42 -AD: 6b38c308cc574839129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e76 -CT: 350bc8baf35cad823df06eadbb0e30e1e4b5bb8171d14c330e8c488f1076d94b8cb7baa3268a5bf164e23563180b9793ed06bb80079288cd348eeaa8eb33cf31ccf89dec998408baae4c3a7b3d3bd14aa76e99d645da0fba0c29a7ea4baeed741de3a5df5ff4044d9b057c4f3ef1825dd0a47aa0b5e92cfe0321c07333479dc86bed7b7b91e6ef368401392d973404e2914b7d2cb49448c55e -TAG: c974e989ae2b86e92c5da9b0c9b068e0 - -KEY: 59b17f09c56d170ed1ef10d2fadf01e0 -NONCE: c78473d06a1685ef0bb112e4 -IN: ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f5945c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b1a8a8b1f4ab8 -AD: 5be5a4a089f0ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26 -CT: 6b07754b096556462756de94e5941610f1bfd93e6222899516e00eb1830f557d6f629bc61abe0c247ab6aa0f4f816f79544ceb034b5d9e86ab8679ad67f6dbef521f6180a07b0bbbcf174cd9234848f18b8ebba7d6ae3d607e027cb220c7582eb6d496a980ae3883fab88a1dd9e5312842450fcf68640546b49c24a3ffc0c8c4f539e8f9a34a3bbff44b1bb4cdb339d8879fa4e0c2145954e34fbede7483d25a0494c1b9e5b1f70aee7e -TAG: 064c9d25f8795d8151b33f9d32d3ac6d - -KEY: 995577faa109071bee1c87d5e6772ca5 -NONCE: 5fdec02348a625b49c3c881a -IN: ab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e5f2eea2c79702d -AD: ec4cfbee3d1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e -CT: 0610980d938c2f2619bb8b4408156fb53f595d857feae649a6700af296d0411cbb80a6c0b7e2447cc54c3bd3bcfae38b7bb10fa5b91e25686d4482b14a2b62d386175f9f247e48fc3b2215b2da1c065bb00f9f59e8afafc9ef205f5245d27085021f41b9e40c00abaea48286fd914e558f822659207e965855eabf52723148d84b0a2692c48d76f30f3cb530b1beb58ffc4824517cb6772e957bd56394c1d8b70c9fa2b70a670f3fe36d8802b2043905e469b558575c75012901dc -TAG: cb51baaa4672b8ae9745ecee08784d3b - -KEY: 58ebf03ce7ed2f8d5487936311922884 -NONCE: bfd31cf828f3d0ce78f3c698 -IN: 1932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75eab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5322e47a85cc58e75 -AD: 3f00d6f0d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6 -CT: b741fd48fa7634435db2cb05392004d0b588bc7e9ddf79526706e575415c8b3d48a606c5f155130deb77ec7aff93719396797bf6628531d9d061727bcea2b348060b64122cd1a94f999ad1f681847e57c05da0deabd2fe010212dc60ec980ed0ba78ee9160b3776ae9174c6f8b7231d6754a4143c8af129411063315c6517134ca26d5a94a2e8c6e8b7ad9b8e78b694d5251deb34dabc455dd9f2a2b3fb6f67222de61e917a645d366462d6d94cd265f919f237f06f1986fac17bfaf3a97c24b99af884d0fca5d3307caf9bd -TAG: 35777ae50d32c572cb0cd778cbaf55e1 - -KEY: b86fc55f4abb9b65ee1897c262533ccc -NONCE: d118b0f493c849a7aa7f35d2 -IN: 43f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db067856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e82911e842e5c9ae8fb79b -AD: ecf42c3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763 -CT: 87454e6cefc24ba38f01bb791333dd0006cfce165a4247833b182efcdb484b0818aa80f70f29d0ec093455344b8f169262f17be2d1635293bdcca90e21f2c210146f90398f44b35e3f2203c7b5bfecdbd973b568d8ed8444d43cba08d44984a295f62c174ca9ca69c173bb7c43f103ff53a886284af46fde5cbe07b391f9c0b82eec218faecb43dc75372478f2ee1bb267602672a4ff5989ec7251034dd2cfb49677fc82c8b209820be1ed2c429a0491beedbe8c1fc78bd62590ba71fd5da363d6da000e8b7e5bae223c0cf8397d3b5ce7141e8b301ea5a737ae480dc9 -TAG: ad696ab700dd5b71d79f4f6f69034185 - -KEY: edaf7d79c1b83d973f9ba3b29a9b9408 -NONCE: 418f73743ff0546f0d929001 -IN: 0cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a028d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64ad6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a7f567087a5fec5ad1ee3 -AD: e4be5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c461b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad -CT: 9372586624f9a52a91e7ce12f380ca13840f11fad8d9edf10c869042c29514515673b3dfcfe956e8d3550baae1815bb4cd41ed27c7485c723354e557d18119b27431d7527f0d84c6e76baf9afa35a215624c339ad888f27c338240e603b232cd247e77eb1475adcb87d0443265ac0de45b16c67fdab07a0c0dd203d97ac2e19248492c561912e9087cd5fb73445695b43b8dd8c7515f9c958dc64068e31d3cb615038f5eea84a74b5d0c3415b6b1309ea8092614f2bd944a6c3a9e002a95e524efa497c9d3cbdaa764f8cf8aa9fcc7f7d68a623930bebb74e5c234322651edda21e20eb12c16a76839f31f3b30d6 -TAG: 33a31cae0292d0185aa10ba1c2288cda - -KEY: 01dadfe4cc0681384b489f38d25e83c2 -NONCE: c563485fb361f81d44aea205 -IN: e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2cc7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86a2ba1e9cd195a8ecadd315 -AD: 870d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a -CT: 119f74936eaffdc3e5e7e072ce81e0e1ca91054cbfca127b8c4a94ada042a2452b39cdd02ab897da765cc0f8d84089a8cc5af662c1c96aefafeead785ad042b506fc72556182566263e90009a86503595dca0924d87ea6ac61d4e931025420436a8716d0ce379c5e3437b26a12531c0a1abb3a693f3202f5770f1dd7ec1eada8c2d6c747a7161d19ffbb897710a17e7740fc232fcc244f456e962ebe71f7ded8ca73e07dd44f00fbd023b8a72f9005f9bd4d0d44135294258ec14665309e9edcc82d98227474a9202552d31f1d2e7374d49929c2885696e5e3edc1983432f1dbad351f9cae3cd56855878d9a076c6d3a27f2718e32658f2392215915c020db -TAG: 5689d9a73d52266977bfe5c1bb1bca09 - -KEY: 34091633f4aaf225aa02ba9c57b910a7 -NONCE: 6535f0cba67fbab0e6fa0bc8 -IN: 76217fc9a546a97dabc9be41209bdb582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b590a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b57817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021 -AD: b9948afd8818888585a6957eb59680a55a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076 -CT: 3260de6acddb17f93ff06dc7a8955f5d363bcee255bfd40fe5e92e13c7a1c682c6385736284c5cd858ce6ed251b92f5eb10f83970525f56a1ba0b8edba790ddb015307cce877c53a831aaf56f375fb20e58199f6ddb91efdf9983f263c9a746fa2d66bd4790531f85e7ad9a07cbcc00e9c122ddba77b1cc2b37b734a0ffbc29188685227ff42bf33c2e912eb592de1a45381cf6c5c9a36af93af26168c376e8902299e810e07a8ba2e23670c5221110ad4296a581151185553fe366bb4057e61b7a788f12cdfa635d9d6b8ca47a5596a765d58bb7f877242c2e0145d47c300175d7af62a29846830922308b6b69cce8413810184b27a8184bca2d8ef16316f13 -TAG: 7dc47ef9283971e1745fa3ff698c6a04 - -KEY: d829975798d4f24ad243e4aad474fd5e -NONCE: 59e25a6dd133944918709e33 -IN: f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f510e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531 -AD: ce0e6219f75c4c31873d4915b1af3a51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3c -CT: 98bfa05d1dc27d721378bcc25af4899c9c88fcd54d56662282f9b820e540444dbdc57bdc63b60680262aaeb8387e149fc2a759c0246f771dd9a13209c4eaae9f8c7e43439535afd85c9b12fbfc10f8f9f417079857b9e061cd24b7099726528f4ef529d14097239bafdce4d9b51860ad091c8a7d1faf39d44523973cd1df0377339485a89036d62cad090ffb9d05c7c7d79b01a22b7ee5e485e76ca9be9f037a94366968003b73915b027b161ab90fbc6ab78f6ef261ec5789d668fa2b28b1b1937da1d2337507997fd0d80387495d6953b08ac0a3fcd24f1fbea3df9218a9f0f1112d7bd4bb03ffb9dc790306db5e03d67201ab904df0e4ae283ab3d62bf48a6d79a5faac2ab33aa0599c0a6de5677ca0 -TAG: 767e68b063ed300e63df9933d6e10f2e - -KEY: e9e41d154c4c1bca018bbc4d744655af -NONCE: 04ee2cd524db41170f0946df -IN: 225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c -AD: 7bc7b15c68437005a4973a06818738adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a49 -CT: e3a3521e3e99ec595a3d9d0839d8d0cb4c0929e44f693df016da34e0d8a1f3f6aae28fa0ac0f38d46ef06a683adb04df301ebcd6ef0abf9ae3cc220cfdbf36ce8c023714d203ba785e9abb05095c4bf7f07a13f9409a5759428e6c97cd4a8b2e1a471676807cf76131ae471fa4e8d15225e9996ce4c7630c4b0a5ebd85db4bcbd79bdcb641a626773560b591adae5bf582f3e92299a60d081aacac117235d6d8094e97b034d120c6759394ede2a8b67e47864e1f50669e8e926ab6fc5cc696e70bb016de92707d4800b25ad14f9c457baa1e21b4bfef0dfa6d849e0951c81583a711242ba2383efc85381ec7228b8e7950a375df405f820ab5dec8b37572897c6af443667e09d48a18c9bca0322efa409e04f57741305ea7d51ed9018cb5d0f00b5d -TAG: 8aa9505e89a01281f033e9658ddb35c1 - -KEY: 7b1fdb1a720b9510d7d8819b6d946dd8 -NONCE: 5c73be515c6ec00a10a69661 -IN: c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d2 -AD: 078f1c67d44d6e86eff0c96a146bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d -CT: db79e91f4458befa47953312aeaf6aad01c3fb6e2cfa19b0ba21ce6698896e62e7ad2cef344cd324b3f0d317d9fe7ce713d4cf1743adcbfefb65e61ab6b323c5f16762ac527882f214539e034719047f9d3c0bc80480b7f76481e2fa26262b0bf426f1599d3d0947492769ccd65433fe70340d8f74fe31540b48c053eab97984f5f670651746b68617f603ef23117e9a8df0266851ef895b58b847e911508dcdc590f6188aabf37be430bbc72746ed7f5f47f45c90e2400d5be0e323824c5b86a2a0ea7c2156f482f7e0ff42923d6f7efc7f4f2cc77915bf85091216bb0f8c35f5274c0c8469ef03ee78b82cb6a5b510e16793f38fa2582ce249370ddf480e212f1cbcd77f89810b41effc9c87b0a80e5a22059b36e1dad294cd158f03d80ef3ed31b5f3b095cacbe5782986a69d5ff7621609 -TAG: 221274b4be8a4fcc765c2ac319b5186e - -KEY: 50109c383071e4a61ce18f495d98b6c4 -NONCE: bcffd0fc2496b7eb0ba612e2 -IN: a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18 -AD: b4c98f6d51fee205805a50c163beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf -CT: e7a4a201f58f66ddc0b8dfdf95c859879144dfa896406f43cbdc6adc148e0ea8f9a82170c5ab54c77dd0fa6dc209b623f0f5cd4ae358af96ec27c78e7245855e94ed1a1182f9d26d45e0872da3fab9fa9ee3e58aa168925d7f779feb77608067ff45b7ec7f2ef7a48a06ee22747ab96e1b485ce144bb3cf97d1e3cd28823628a2f8e3785d9af28b76c53c3d4c741d1ec56f2bd10939f6c79578c308c5e509ba8b13c820f5912d4ae169da4e04f86ff9b1cb9faa432545f7999ca1014f77c08ae9033712dbbc0e99db6eb604e774d5df8f6b928a0bb59e4c662d778d195aa95194a0cdf7688b309abe223048937691440e5a78cfe0cb75d229634aa49ee54a81fc9a6478c8fa310d524bb15ee8f54f572dee30e44eeb9603c8593f8a7007a1b0dcf2e301becf300f20d2e868b104154651446316414b5b5e9432134c0eba97b4cefb90c32 -TAG: f304266924eef673246b3c14389a82a9 - -KEY: 670cd4d988845b1d41cfeeb1ea740db1 -NONCE: 29c12f66a74e6234ebccf4df -IN: 706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a2e -AD: fffbc936ddfedc527b2c9cb69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0 -CT: cc573518606d6416256cb233c66352086706f7f321fb5d69dc75dc6e11b9f7d053bd722b8d74f6edb023e283ac048570dc23dc34e1d344619dc648199b6bd3627590c7acfc738f10d896c0e3fbc3d3b9ef75c20c616d1dc96a6c3661b4f245ace3083590b1d97b936ede9994b08bf19189f573919eceeff80c25ba1584a1a8744efc1b2efcc264afa045dad460d4a97553d33aadbf6dde24790853a342349446741d65d3551ed343e9dce6b6cf6131c9bb3524597d0ce95e6971c01581fa140caf86ee4b53d17befeeeda4f5ce5b255a429c27a169aa075153bd4f1924df1750332aecbd365d8f65a2fd17f6abe9a054b3a2abf02a5b2031282715386c166dcce653bf3f3fb67aa119459bd5ef3bad4ea97aef40335884175d7fb9bbb3bb7f3114cd68c8136e8d02aa204d282403a34a89305725e2e022a9db9857112350e965d51b7b3de7339cfd3f202d18a07155b5bbd11fd64b -TAG: e3c4a624a012f660f21be3776f20b440 - -KEY: fc5b726bbc23a67015c35a1be5dd125a -NONCE: f812b7661106827f31a1e4c7 -IN: e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bbb55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a3d5b -AD: dc41779816b352803f282410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755 -CT: d64bf4eddf29f08aff3db1225ccc9df5fa92315d70bec762a001a21f564483c43d9fc25e26ef1cd8426f215f4fba46a4fdf5ea96e6ebafddfbbe15ec5a7f8aa6058f8f3b5c48339fae17738b374bda2ae9f0b95d721342d968ccaf1ded6cc9e0d25e4074b722c876565c73a80f9ac25c8ab7c9967b79e5f924697b65ac4f6cd8f1dd6adb5a3c943c5b43d0563ce8656dbe39dacf220e600b82af2b5ef9de009b51fe6ac5707d3b0a15e87ac4c27501e88e9fa4fb84d10cc489b2738fcc751ee5aef230d4b9e4529cd3c580e2c248ce92184fdcccf8d94a5da4ac34acb13156dbc3e676bd26c68e1065990a73adefaa4a58db57dfab709af8539f449d3c49e7172c6ae686e494a92386ab28caf37ebd026d0e670ea85a010a6fe8312fe5a71fe6f0c7c52dc80b2dc39489ccc39c10a7d3d64ad66ccd44638c8c9d83e1b88930d8da56e978090dffb1e04a08303fccf1dbdb1bb160e0f80d4493eccebd984f898ce877454f84b0 -TAG: d69dab4de29ca8e91f2e74888f80b841 - -KEY: e63611c19ca5deb1db80f97a3f5149a8 -NONCE: ad2cd6491caceee3e19782e6 -IN: 6354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cbc3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6d70275 -AD: fa9f177cd36c990d4b22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50e -CT: c22ffa587dd3b6425b81890f8eff36af3c64549c5a5f3e1deb44a7f14c6a179b1f76dd01d546a4273fd6d47b6f9e3ac5e9b641982d1002fda49af071d1dcd88ae5d0ad778d846d3db243ee067f17a91bfd808ddca26bfb67ad28303be8f582de507fb89bfc79c10513327c883bb4c6b97729c1d4aa32ce50703636b2fda0f592174f2ea36b26691e6355ad20bd116619dc728895bbc0cd281f58aff68d39e16087d3cc02ef04dcc93e9bf7695cb15a8f2db51df2e22a2f04be96021b4008f50c94cef256995207ef1dd9c0137d4cf63aba4a0d28aa5ff7240bf20895f8e9585c8c16437edb41e51f6ce5a4f965f0abae8bdb7c7abba2ba82eb5ba1dffe56411e51aa87617c62f7f6af3189647340865f92a16987ab784b1d6549099b1a02b369198ae9f8339e9e197f41e2798076b5b5fa61aa7fd7620bbcb8828b2332829d554f21b83d018b59f785e3a2db359b36fea9a8f085cfb668b3a7d80ad38b85e24472e72916bfa2887036d480f6ca48acfcc7c0f471a9501e -TAG: bd674531985fa355e1ef3b3dbf8f70b3 - -KEY: bd7d9a251a127a4dd736d0f74e68755c -NONCE: 4226110c276cb7870cf1c7b8 -IN: 6617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948e63eabbd -AD: d2f357cff8c172e6652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a98 -CT: 7db6315e1ce8ae23774c2e8826811bc31b2d17c869691248a5b49398465319576c56c2a64e22ab0108c92b52d9a6096f33841643099cf47aa1defed63b7855f3a4586dfb8691c982eaf102aa87888d09b6dade960bf166e48d58999dd08a0802e109186495833a8d8bc5d6d3159824d1b89d4084cb831b8526dfd1c620b4fb6000e45bfc1a101984f3cc51d54c793ab8f034066922905c532dd60c7d96f06989d10c82844f4b20e872538f27333e6d8656b46fd819936124617cddddac8a64d2a81a0cbf21fe91293c8ad6af63536d10c11a63297b620350a6f76e76afbbf2d8c63428d46c9ca123b5022e6d67fccba1011b57aceb10da0878bd873422438cd949df47533eebacee697f9856222344bc9c4876f8435e0b999676d141135a6f42ace8f99b16d86e427f1ea4d4ef524835385ee1cda9f4049c3f6f9226a69b08528bc3970166f6f9067ac30f9d24b7da6bbec4e58286b3b1c5a7711ea7965ecabd02375b38a603d49c12131019a9b2affb801c91d54896c8c29e09f62a5fc0b100b80ed54b70f568d7 -TAG: 9fb615a8c354e10560c3cd37ceb3c3d7 - -KEY: 71bd6158a17dbba101f840c6638ca058 -NONCE: 9434c5b842d5dc501c774114 -IN: 2982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d5205995c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d50599a3b2bbea36250ace162989e3c21249115a402c544aa82c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd126cc8d0d268 -AD: 16561102778d04ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72 -CT: 6da55c8a9c5a29eaf8dd627d7048f0e6cf1d52063bd0a7f8d073e66fc406f37fb397f789e4bea1da21a94ef944a2a0fb9a35a7acee3d3687d8d713090a1f2dc3d118ca10c85f5542f9f6f40a4a79bd8816efc75cddd4a7adc9ba91483ca70daea0c65e975be46f690a2182602b29d7c04991d2fb61f154f8bedc194ffec5983b12c4f4d9abc0a415a517f4b8923a2ccf1d5213952133b82621dfd4a8379cca916f6ed9e58dc94baaa1c1c7d8491c3341e0751d90d131f20722bf2c44d097dfcb6eb49385dfb8c86dc47a7dce3ffc3eb89f32b4f106bf48c0d69aab448ba315145dd7ebadeff3798bfd004369595f48c9e7be596fc181bac4573d994f6d7a778f353e3aff64c3bd5169e8525edb96f1e97a5617345fbac9f58c0885d52ba25a019a4e01deb3ac14c4739c0bc73f28d4a05bc5b0be11477395f706d45ca0f7fd92697e6a8c5eae587dc9cadf62c4e8c283041211c3e51a23b84bf00d3bd4be490cbe9277268fff3f652ac9eea2734fcb016639f3b673b0eddb2691b10713fd5bd606deda19d9429ab17539dfac05b5ef87c018564cea21fcce7a -TAG: 9f64a1a1ec8b09b1e64b258744ac5f7e - -KEY: bb5e6c7b672e7c5d720c2035dfe8d42e -NONCE: daa56f54bd2dab11ce5ebc2f -IN: 95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c857a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6f584f4ab378a -AD: 3dc7d6102a17877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c67 -CT: d5c7b4282f37776c03c6efe2af410b10caef49943001460800fdb6408f3c7a9f7f32d8db36dcdd0694170975536447d84c56f84c966c28decdd607237bc7ddb15176ca20be0993f309d2749db68666b2efbeb4c68cb3982a68f67114c0dab61eb9d4cf4c23f1847fc36bd561b0469ace73c80b0347af5e88f051ec6cb19ff8335dc56cd3bc6cc81893c9234457c0d8189cf1234a6c8a262926402eef262c4c5149fb68053480ab2b1512a91d50c48dabe637aa410d6a164dbe4f8c1e1c0efce8687dc858386c92ed7fd8b8692d67ddf453558d28998ca1b57a6c178f12f4b64479b3367e8dfe53f809fa7baaf8d1efbe3c9e2d83b0377cffd8d8dc172a1eb260762c873af724248011d9e0cef6971ec12e81d70aec923664ff7f7cda9d60b3464ab14488b243930845e38e93a8683787641b85476816dc73d17a593b68935e4cf71d81ed7dcc9202db65e235dd69c1f2ad4fde4d566970923a24bdee799258a3198ff2e126870252584a1949439b7e32318af204ba164f9f3488a669800703f988fe56ea6b0b2cf662c43e103e2e63b377a85fd8024d3b40ff47f30fd3dd6a0e07e751d07d5b0e4afea2 -TAG: ab140e2a4dfe81a064944610e0cda2cb - -KEY: 97b507a2e09cbf5c31f7be6dffc78d88 -NONCE: 3f607f0ec3ddbaaae6b087e8 -IN: 731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309bbcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe16670d77b08988 -AD: 0c962e558fa573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894 -CT: ff28b33337262980b3adc761b8713f01770dabbc1f458516c721c6a19317ed1f1d6520fa7b2859cc577fd92fa3525273f4a87c99575940e941914ed586e7aa5637c4fd2d98e7d198b52924619dd68a214389cd486fbf006ed9c72e6066d92d2278abf1fbf4b4ea1f3d945bb1653eb3c217d7201d5aa40d34c8488532d9818b06e4c0e97c4cca7c9e2ef19ab5a397db27d4465f41585ab60342a3102837cf43c95db008f0689ae7a7970c2ce9fd685e2811393931a4d169701068b6575b47e88bbfba48281ad4b297fc3b265c0590be6b0208f6a27594b0454e55893c68203233b60d08e25fa66d63e76a869a4b84d153c81f1faf46f9a3130f7ba4718a75366af23e4377d60901b960a4926b850f4d4052d6ef1a5c54ffb388acbabecf069a5841a76cf15ced838239a8392149ab2d904b482bc661b3cbf4c74b711778cd61bc38499120b87f0f45f8a5aad51c84595b991d7fe37582b1ff963063770cd0ec9d98d78ef323c8bc939cf3b6035a5e1f5d54cf9af44d49f9cb01b7d1e91c2e0da110a33e372b07402605ae81bb4ef5505ef51b3dc23ef5e48f3f16711d2d72bea5ac90e85a37c97ba2d1a4f5117a616b3865d97a65a08265ea0c8fbf -TAG: fd76a9ef5ce12640f3e782a40c6d0fa4 - -KEY: f46e56f5394bacb222b30fcb3f5d5547 -NONCE: 6fc37c122d6865751212d4f5 -IN: 7651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6addae1c3199da8877 -AD: 8d920a6c79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f -CT: 4877203ae9162588de263a70fd978343e6e2c7efc107064c1a314e210e01633eab9cc234a86f0815e515eb2148fe67023dc7c67616a575c0c1adff2ca1bd7867ca351963728cbcb6a41b5928e83b6ad97e458773e543138f87698c86e6a84725cc6330e3550d40dd3103d0aca5139b2e7f7f7060e34c383280a9276aa44d915460cb664d132056955b2df063a03fe4f844122bc02455ff1558377d8c15419e34417e3c0d5d69b69943027fe32384cd53e121f885293f17cb3f2637261f3c9bf6321406f3f4e59dcd37972e3073573aa5d9f78e021d07b7036405f193c65a2f8d47f9a2193623d403706364f514b1beda6930925c1afa9f294ae625673e41647a94830dbfc45a4d9029d5e028e8997d9f251aa7da65b48e1abe8bca5453482aa6d1dc1168bf4a6ab5644d623ba15dbf10b0f46536b35e30fcc5086184d0eda2af5016f370c9931f1634331458c51b575553686b511f073a2650a1ae9cd2a64d8ccb14194a659bd533e91cac42690d661c5038d0182cd8e52bc751662508d2253460fcfcc4428ba7a55f1db80bc11af7576e6b9ac2a35929bed35ca82fe497a65c24d04c96e6d9fb3bd66fb54f01483b766b614a97e370ff406713d4b811e1327fa52692355e1d307fd2ac67a4 -TAG: e7208823f0abf2571f81c015eac317d9 - -KEY: 4675ade296a8c507fba35f62c82d9230 -NONCE: 51fa718d52a0279ba9971490 -IN: 32b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd823d72dea41a1c1f1611fbab63d339a8dd47a3a31b7790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205cd0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d5465e4e10e9cedaa39 -AD: db35fdd7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726 -CT: e1e44ceef4e08b85ca5fddf58c4d6eeb9785e0ed50be7856e74dc1cfcfcfe92f0e59a4fa62db0ca641b0be4da12a70fb443ffc46c8f5f28ce467cb484a7a302dde2d459da83d8ca6707fb0c6eda6312e37c095276f9e65b44fc9a0ed7546e0224d639a7ae396403b0db8be55276fbc380181cfb32c357e99a4ce0c33e464d1feab4a409651752a05f2dacaf85125005b92a195628bd314205b8d2aa1aba19d32c789d91e565944478e90cd1d4e10c475b79ee5e7f7aa22456773febc5d0684ee0a26ab27cd391fbfa1168ad28f46b114d31c7a3794cc216626eb41655990ecdd93f97a7594330a78426da7f2e8aa21871a1207f769dad7db7dd794382a0f50dd8dc76ec3245576b99a32314d3b6a4046a56fbe178fc4cdf8bf39c86a6ef320f4cc63e5abb6ac53f6b336fff96a22dbe2e836c3ea9f4b39ed58d01d45937c8b5af0df6a44bb78bdd59c1f1ac6643fc710e27a4fcfca031b6435ec2850289605e29db5911cd2b930a4fc28bce98b30cb2b6b9504ebd561e65efa52759e64b435b99ad26b7653c6bdd21c964d20c5761bc3eac9e2986cee13068c627721a90862fe387382af2895efde343e3c9f13a3ed019a144533af765424c7c80795cb30ec132e7aeb9a0c0c75f2b885a4024325a491eabbd30f81592377e040cb9034 -TAG: 5100a3a60ed7d5837ed8adaf78c625b3 - -KEY: e198729362ba96f79d5e0d89fc404b38 -NONCE: 36737445756c6060d9e95d16 -IN: 38a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3eddd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe85940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37597c9a73eb47abcd2aec -AD: 1b2a8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee871638 -CT: 500fd0ba2adea1fc2ced2dce635c5296edc590f961c26c6fe285f4ad84f6e85719ea6bbefff398991c03a423931ff493ea47f97a8aafcb1ec7a34101ee8a378dac29f027c312306f74b6f92a6eabc829c3117ff77b6859e67b37d05d48b2c12bd30251d32ef30ddaa17894373063e2a593ad5139fba87d38a045e2e4e0470dd4c5555ffe6fc70e564502be523737bcd392d0c41e70a594b29f949838f9bfdb6e87fba327c430b75164555d7a01d7bccc33f2736864a2200e4b2c4d7b7192cd22f7549a9dc3ddda269d78a4d98a344cec44508bd930a14edffafbd1f25cfab8a29b75d07d705c3291de774af867e2e595ca8fa2bfb9fb3cf2511552f1c872fcc8b0878c4eec0fd079c7b17bcac2931181897ad50c03880102109a42c34c70d64ae942c73693f85a6d1230a734fb35f70c02c93813700e21b2abc304631ea9d5392c67864eeb47948b7e377bb51e3a5070524aa0abcbe0a624038f6e1b3c062b7661e1471d6cc3dd18143d6237c0e32e80791d39becf94974bd765bcf6bc5a3d764584b025317f64a67d13234399e8e9d10dfee9a77ba887cce119e09c812661b487561acbc718bd200ef97f76a4664fffe64b367bc36f7d03930f020e0b1db0d8d36103da1dc8dc6e0df00b2276d25c8312222c13d8a070b108a1b3a83247d41940681c59e08243a12c623c2f2d2a -TAG: 7c3eba9d36b26d27a7a0325d8c23923b - -KEY: 2167ee6f77730766fe8b4ca6c8f02708 -NONCE: 96bcf14cca5d7c2184dc6eef -IN: 47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc95fc19c449bfc10443c5c1 -AD: 6388d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f47 -CT: 73c6a7d5e4fe14e991680acff32d660639e46cd0ec231ad155750e53d6597bec3070f5e828e420cc2044d5bdaea5acfb48cba1e9dc52258fcc5e937861e9a970cbd04f10fec4bebd6d8cf81a8925e5ae48d8024f7c62e35aa370994760c827a534e0a309655b3085a2ed8619dd0dfe0560c7dd5e175fc5a5971cdd50aeffa073e206d81d1932f350d9b3f40d4eb6929bf7957d25b1b12d6eeade7aae4b7277b6a1896aa0983ad5a5e5cb5e8e86b1eff15ed0b48149872ee4439acfc6fd6381f3d9527f1d1a1452927beaa3e3ff188681408041aea39f28bea779ac28b83a4eaff7406b08df2e60d66121c853800e56b3659329503bc122e6c47c1e1dab53986b2058685409c4a81b057fb6655de0f84ca770ed5600db097efbadc14f07d80cb892ef3ab12ff72e9d60718dfab82625a79168ac262b4069c0ff14bc5ea3baaa4c0559ef23f2535ab273e3bee0b2d1b4049f20e708fac2430af82a1a5d148164c19a956a3db8e44c8fc7c51af9458c066719884f0a192464c668d37372d5ffa4e2a4eff429cd57eff1b374d501e06b9d3cbf8480642bbd141b208ead6fe46d436507099ce460000aa033528a8d813f3cda11c8c03b427228c5b24b1f0fd15f704d7958aebc580bd5d3034667853a67fa51eef18d102d65507047b12a939f8a2cac8bedc027db855f89ffdad34bc726f6c6641e3c8ac8041003f65cce96cac54d -TAG: d93bb140c5ad0362ef819fe04daf051f - -KEY: 1b63e84a8114f73f918aba186239947b -NONCE: bbe2973181d9b48e801e3a55 -IN: 97b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b68d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae170e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e -AD: 7754de0ce06145d6b247742ab582584c3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9c -CT: c1e60f8dbda68c60024730deae746fe9fdcbfb9a3c1f26301a87a3c6bea9f8807ae294b62cb48ebacb01943818bbec06f1c842a3d42aed5a75c8103e07180d76f7e17377afdc4ed56905522be60c9dc5eabd5bd8b9a720b661f631dc214ec1a387016f57085ee3472df5a0d0366210aabfdb1ce23ed9480f8f1eead8780e33af36f9a49b8050749507a8b34b0695606b2cb78788c3da4ef316ecbf9500c257e8acfd36bf600a7ec4f8d2c690db5af0809c5799dc7b7788199601573d8d1a91a7c08cd4bee88885d73998c554ce520fdfe4153af13bcaa485477bcb5f55fffa54a4c71c5e61e1c3551ff7fa39cacafffc5cb00608be2b2d803bdfe43bfc256a7c04f536f4a9c383e6b4a3a0695d7e386f6ca8c8a35a77fc9b1d14e202bab53bfe6bd1d1efe3a4715bd150369403b6696374b4498186fed144f5a6edb9e3a863cdb4de5a6a404a0fc3702192cacfb36538e832b4aebba8c3726224f781c51c1529722d905286a1e01a9bebc54001980acfb9922d91122c9b125d4f6376599f0280651fe9efefad310e97fb06670f4b42df4b3ab1a078df2bf9b880fb91b292984416b70809c09e001e30d285a027f9b370e0764715187b797cb4965e7639a9bbaf915456cc4cc45505853ddfc54a38dc46743adf92afe7f37b174f0108468d772fb2b7ea00e8276663f6c29d3d83f3bf47ed8b1cc86bbe8639a564d936a3b065c4 -TAG: 0a6307fd5192f65b8786f7bef96c17b4 - -KEY: c1ead957027a7303f01622d129eeb876 -NONCE: 04daa5b792d6d2cc4ba08cab -IN: 47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe28b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327 -AD: dacc20b8d41590570fd882012b1207ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc22126 -CT: 1f2614433c137c7579ff19ed5be8e7897eca62f05797266174d4edb5fa4a22c11466b17d97d961564dbf9d1c45d9b6568d330761b9bc04dfdd31da08d3ddd4e5efd3924f53128ed541a6aab87912af60615da6dfc925b67b1aa3f1d285e25514f502eb5e92c7521da3492043fb06172ca74796b811ca42b349e337615f898233944644d229d05f133e35f879471a04efc3321094716c10b6f81ac7d0604096f287655362439e47641307ef49338a70bc87402b1c5ebd931300be51980ae8dec0345beefc59bd250bc53d39b7eed62f93087f3ba83b29ab094ab8d3143b63e905d209150c544e433d5ce41f00b65e0a976f5138db6ba5193245056734c7209ffb256a2f1ac9840f1bbe2e82c04120f591da86e253acf25b3876ab9e6f434489c43f606f264d1672cfd8a43282b41c34357497aa4f3a8c318f93694b4a04f1a0773ed064d4f426350dc7bdf4a59be0fd4154097c09841ec0df9c0e8f2dd31abd8513925d5d3da72624567a609975a815e9ba51df408bee244b4619f8ce981a6be726da484513cac67c2a4f597f6ac8ab0e96d86394cfcb5b6ccf2440a53a7181788a3de730c2e84e64a4131d0e02b8db2ec11f2af61218ce1255310756d98a0d594f09bd1440adea74720ff2745db30741e8f4f7bae0701443f55a078ee3c3bb63411fac0d7c7c0d0cb05ea56f40cf4137de20d9c5224fd4e6c4c6e8a5868116dc850ab713b001713d13e6ae5098c379b72e -TAG: f1271cba346522f88ce93726cfde016f - -KEY: 2a7e7959ff156f3e69dcf4c3db8ccc25 -NONCE: 6d666d3700475874d600d6e7 -IN: f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b6 -AD: 6d3a702bcf31e90cd2ff6a350a94689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e -CT: bce5fbc1719b18299c54d224c2a0212cc904f9f58e7c0d8bbf1b09df0c2c08347cb36f2c8d145b5ebc4896a398b6aeeb2db0ba5aa3df6624a64bce91db2ce843a7549714a20404e869497e593990a1a6e62edaa9827288464bd7b37d2d2f8ecb6d67137f2113982d4ea3c23cb0f4609f04bfd73efddd2e4f05c4561fdd3615d82ccef83c940d39f4f7d548cac2ed181e4a60d1f280e25ef8b617796580069ab2fe8caa3ae4e3722eae649e390d9375b6f1b153e6c542a84eb70241e2272f2530940fa3e0df70528ba07747866fe51c3f844c050cc110cbba10d1f8d3321958e1e833c3f4543d4f8b3d20c8fbb7eb1fec4de7e99464c52d97e7bae8608419f1920c27ea0f479bcbbc61cd5cea10971ae2aac0a73daf4e90c47a023d620c2cb246d5e35908535bb5a0fcad54250a29fe53c1a0090794091fb5b3704c6ed52c8fef11271836250f39d8fd9ac5977cc91175e285192f07fd163d62216fd5530da9a048ea458c47efce109723029992b155809eb73a34b8bd24fa647b006a17e1e315b8a6fcb0e5af6871b4bc6f5d690b3edd10fdcc5391648a64d05f3355bc2a13cbb74d1892eafaad1611c23ff96e7e80f0df0819999977f9a2097617cfd13e8fbef089bedb532b331146d793d224d8f12bf8fa63b3b3d9fa8414d63a7618ce7a4f9c52d8c1b2ccd019e4510dbb3bf71f14c2e13452dc7cf859d18f54d6edad075c37a6ed2f05ce6dfa48421670b757d6a138813503a6ea964707560658861a5b95330e -TAG: 85713c984bb8b5acea392525719dc9c1 - -KEY: 5de639113d920e239a0d1581e179f9e9 -NONCE: 0b5bc077c27b08427f0ec327 -IN: 545c1a235b88be7e8451a5bf405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc5 -AD: 846f6eb4aa086447f4a7e5e8eef4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dab -CT: 04c79662edd08ad017cd48a6dc415f564a67d3d9eb48f1c7910074e6c3ae2d253a5acfa661377ec6ca3ba6693e77f2c97a9484bfbbc3bd261fdd25512a9c1e0d2058b0cd365fdab9c14f602945e142025009f87c13dd1dda03b0c49f76cbc3a93d928eee67627efcd146ab2fbc19d26955a646201800366fb17efa420b7c148399b262164c598cf1b011308989b7dcb699110338649603b58af4cdb5e7c2a306164d7e588fe115b4751ba0a83cf849c869b0155b3f934ebe5382e46db1d2d977769caa63dcbbee9f33568261c6c89856f75d597973d3b2a48508f2773d19252e04350b3c88a6696c3af860f9dc7cfc35e6e96279c92591c09dee7c23c02078e3a51af668ece6c870b7f0f65f6b0f38018be91876011b616fc5630d12ce936b6ab725b808108a472ffe55a5ddce340e5de8a279974c39c64a7f5986ec1e48116bec1b6d040e4e291f429c522ff61dfe74f2f4a075e0a6912bb6a6aa945db933eaa90d9165dfacf087a58245b54c2814086ad5f54795f1c9125988dcf15f906671bdf25da87d145dfb22c0683636c61c44ea9b3120d894e02b0d6f8d021ed8423b0c533a043f263ea3b1b06b5d5d7dba17bcccb1485cc5830e7e5b8520f9a1943a3560083e65806f9a633baa6aa7d5b99e5c5d69db446cb39716c415dde4ba0be14108ce32fbe50ec0605b0845e9469aca76dff75ae1f847dc5e14ce8b5455af8c2f6bbabf889efe1dd6ab408d983f51b143558c73fafd09132e22113b36426535b53ff2294acefa9258a58893d7b3a252f5a7d4 -TAG: 07153351dc975adbfb8b30d77c1be155 - -KEY: f0f31be89acf8d7fcdb2a063de5a9812 -NONCE: a3d6aca502708d448a869bcb -IN: bd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5bee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158 -AD: 2c9c6974f2442b87c02cb723f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcc -CT: 57e32933293f67159efa04c375a4d7b8c8a050b0cc39031a3df3bd4bc82839ae1210da5f10b0723e111ce7d1699c78143671d7986f83fff90992ccfe9fa4367ef9c944cd571a3057a65cc1ae7fd7ccf2c722f11a9ae6756ef0a422ba7cb15a02e27aac6faf78fa2c2b08b228b1be5d3e62a5e995f9d3c5f1cbda1a6ed3f551581cf6693d678f2323e2ca7437715dad965024c8d5eabf68e7ee3ec090f56deadb47dff68e93fd8a38ec2b34d0e774f07793cb03d38921632e42b4a092175f6d602ec637aeb1f134067fb54594f33be2d9dbbae16ec25ea7b86a1a88346e0335d7bd2822a3d209a6561ea396c6128a86307da1c14d25b45e593504fbe38bae1a42689b2b53cf17bca92b4896c2fbdb4625d960bc03da9072910eae59aa17070a368a30e69d072cccc53fca2824fcd83ebf6d65e78c44dcf3333a00cf7eea5b3d311a674be8f46b696376f1fc5d70b727773582bd4a59111cdc41d69d58c52505e51e08e46d75372999f27628631c5d7497607adf4a1c27caf618a6dde1039dd33aa7834eb5164e67a208d473f558b97c3442ab23d22081ce024fe616e00e09a7d14386ec3e0089a0feedac7e6c841da57a13358712b75280f72afd0a28a3f5555e024b59d14ed108ea4fb77510c031fb438e6cdc7b4b6125a387e76081ab8568216a6776b7b52d311f48e882d62abc81453d65c0f5effc4abacec68dda303ecd225ed8afcd5638a9c4f5488d9f8963624934c1abb56ba0071bf11d64a52443aa0f3b607557ff340937a53fa50031775550925b2e8f40c744c36317797a952d70207cff0646 -TAG: 429a50441cf373d8d1cc4b37e15266df - -KEY: e4ffeb5ff128eb3c798dcdec4c665a4e -NONCE: 7b30ac120aace497d03de3d7 -IN: 26638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e1315fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4ebf3 -AD: 14fd627004e9a78d1334822040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce49107 -CT: 7ef2888ba3ecb4c9e0b96414504cd46365885b6fca375534e3dc43d4fe31b61acff2cf2d0b698061ecc1addc1519e00b1f3e59756cf70380e9d83352ebde4fd680fd995157fc12054376c690ee01a11875b3e833de136a8e16ae08e80101caac4e7a43042abd81cae91d2d0f98ec0b6fd7e6232fe351df92aa847cc11044a3e07f3f4d8b8b64f039fac77c95f9057cfefa11cc795fec334051a81dfb7e08cc09496934508423cb75f8b051b811179e37ee63346ff3ce1f1012117b0ad3c03fd113f7f932da558244d5809e6af429084e70b206f4dcddcdfd549246a548d51df1fa68274416b27cc2c12b3a6a86d9bb80184d41a3971c9dc0ed906aec4ec85e9eaf4e8dab1704f6ac3f7602b0aadd1ae4ad91755ef9a08e231535eeab932524b2c228d10b9cca1f88215ab56bf776183b9c14b2888dc7dca590f48ba6fc7e974352da98077d0d3f5de4159025270eae300fba5457611cfc4b52846ea1fdfb29ebe4c260ef2d0d61de644cf8c7390a66d15f806299ecfdac0d6ca83def3873f960bd5b41d05e9a718fa0329e2304dd210f20228d7da87f08bf477deabeb93304133eb38439f49e821ca66474ba065c8c6ceff51717b36297eb17bc739feb166455b79d83ef6b12506c5a877f9e7237ace4e451a17969de2ccefb65af407a1df71ac99856d485aebc6492441366fbabdd11c9ca559bade381672c8497cdc86175d2f186272c9b675cecb365f97dd547d14ebb2bd306d80d83b40e3d4a5ec37812b787b31b2464917aca278bc5c3ac7e78ba6ea0bf3744b70012ba4cb5f1b91703504ab5b0134d5c8071ce1f16218c51207448c894cc1b -TAG: d338cecd6bdd210923d8ed507612ff85 - -KEY: 58ac0726e0bca5d30bf4d0a231fd1242 -NONCE: 0b9b60c3a690e0ce0106c1bc -IN: fc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61ff7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e10628630 -AD: 0bfdb282f9e2db0a43c18132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b -CT: b03db471a65de5cf871ac198ddfedd14e66b6fcb6c42c782a4d3c156beb2024a1dd2cf5efbd87884b029f42c94067a42a165c1e00018f11cbd79f65da02c62fb443ea8a345c34b6411112844eff3572427e45e061913bd578624100e33908ab9737140ae0fea83069fd008af952c776459c6cbd4ab9b02156b3992c0691614567056865b9f39b526f28d11b7707f35ad09d1eb0d2f6adc7c66f8832d8783478166036d082af1a44025a733781cb389612e3c124c31c35ea2a7833bddd053625d96d2ac3fdc69dbb64b9b7fcbcff6c6fb891d974184734d3bb4081d7609d7206067157954b4c6ab68e4a450f01f5941e1702830a58667b947352f1931ef721739be452aa083ea17344cc0a3b5820a90b35bf45ea00fc06df7229080b82b79c3930067f6045c619624958f77096f304d9f31effe42ef405ee4745f1b6c101225062a5bb38665efc428313038a3db8863dcc72de12c8ae41eb1a7b8eb02bd5bfb1f1ccdb1db877ecff08606963d97958ee7cb85b99c5f2ac4f91a922e180d7f3a3b265168d02829b98b7a72c2a2910c0c8c654e354f2e19a53618e4e46501ba8c13e8ee0081901108a75d6b7f601385cf6dbe3f74b3634331aed8eb903119ee96877f90d491dd5d38abd5f002c3cdbd57b04a7ed13fa09c9e2058744e1fa24d3fd87a863a7dd73cca389e40b7aad29a95d6f7eb705827f7308aa4ec9b07b1c98c225f366cc33586bd08e20773bbe0878711b6210392900b8fc933a6a661b8d6fd1a8338d06ec364f9025f1a79ff94bf448b998908c22be5cd6c1aff929037af9b642ff228865137dbe2f3f3813923245c3edc8edd76eefa02d40e7850e502e92e9511571f85fb17 -TAG: 34213558263a230e66e80c4095fbab97 - -KEY: 7b9f65509a00841930c4087093c0e049 -NONCE: 45003751c40e59eeb10f62ec -IN: 33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0cba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8eb8ff9 -AD: 7b4f599c829e412edfae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25eff -CT: 5ba4306c0fc5cbc0028d54a82d2ec3039f78ecefbf3ed98f5b4f83d1b562be3c5ae66756dcd2027a515360274837682ed07c5f1a0dedcfe3d1e63457f9d4020d2b3d57d63401284eac89ef0cd16bef79aa949a5b3c76dab5342e8042e2e0d411816d311aaabd8aa10bd6c18f72620f824156bc71add704e0ac4bc1d4761f9bd1e31f800d0487f3bec7a788b0cea75cc0bb4ebb927e824bbc718236b089c752de68b4fb5b4bc1ca67e166c23274de9992fd30e0752ca561a4c5f469dd123ad45870dc013a47247396afa45ca5b02fbda0fa1c2a89180214814c5bce704ac4dda5be49af225f3a745391d669d7877d1ce173058433b02b714b7f9b43095820b73069e8c3fe621c45e00e41152a413e15bc750fdc517568f021645b6ccc541a9d61237090cfa6e374942adaa1f18d073e627195164fe981853e324d2e97c35819a00cc4d668ab1b8dc86188ba2f5fa76b3ba2303bcad2ce06195d6e853f7e0d257e386764067f244020d9660ce04bea8d61c5a940f502bb68ab6a62fe2e7492c3aaf355d313f4e2e2ca148fa46673848e59d744567bbbf38ab0ec0c799712053d0bc25532ff00f02a3149e6bd9df268ef8e1fa31762efab8102f6fed5768b9abd9bbbac89b40000394158c4c5d2bfe5f3dcbcb5126afb0f753e2a60c8aecc67782fe64f2f35fcc45e6ca4b6751c40adea4998140048456944bb8e2345daa95e989ce48378f8c607182d76b25d12f731b5029c245e804ae19d170a27f35634c64a1bcdd48a6b573959521d388e023650f427cd1839c77e0d56b4511d1986dbafda63cf43b6fe929129602a5314d6216e662cd1659d8d7bc6c271589aa4e01ce45970efd85297f00eb2470567e69a67bdd20fa4ed8b497879fb -TAG: 15966db2d710d52510c55082f0c3cdb9 - -KEY: b4cba7822382ec3aa42a95221eda5980 -NONCE: c488bf7ad0031e1ed9870968 -IN: 19cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d8039a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e96599fe335e0 -AD: 6fff534915999ba3c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f800 -CT: 0fd6ce7a1a51060fd105fc1e5d7c8fcaf4550de865dc0f990217c9e32d354a951bee16f53be1f9768f48d7f76c9f2ece7fc56b9e8c27ede94b5a3250ef27874eeb2dd09d2e50810afb7b9a50985fe28b7aee74303b178a0b74c5422d4f46a59e55bf55d7eb0d16314668b13952998205eb422daedb9f99dc7e04e11e8e077289d1402a1d12608e096afc6283643ca77813730bcee2321cf769c5cdbe5c80836db9814843a0ec72d49ea89ddf5e48e27f1e172423412b78fd91da54b776a132df29fffc5c8b41615fc491c43ffa4596430e55806bacb7e88abde1e20ae43260a1258e7d89ba46fecd08b7330409a08449ade364fb84ad1dff4e71434a3369a1d20158d02949edb9716b021271f73517bd985949d2dd62474a36e57b2682218ffa2d5a982c668a52776343d06ec4bd122d5a1bd5ab5b691e4462d8c52226f834290258a83ecf0847246c92d4339ada867f107589bd8af55cb96461aae47a879f5d81c3931fd653d68cd5139be7ea9b98ad8feb9b453f617cf7b8a4c9def78335d009d4139e66e10f642030b5a66fb44d2c07c8c689383136d580b399f685137b3054e40fd7c90f37ea30d52e09832b66251cc9c31156729e9cc5fa37463d89bf3b61a8f8657f6501ddc3cf1505fad36d4d9075f7a366050de98eeeae0c407b31a5ade0b29b1a7a3cc251ec8a918cc8239c3208b377f2e9a7df8aba3e086c33390bbdb4498ee5d194e43a67206e797d22a7c64849d1eb3921a8323d8a0c7d242f3ad65e52b992007c996dc642b858fb7ea7b1d8d6cb10ed3e9af7595367c26d4b01d6c178a15179ed45d44d83d7709503c85985bc1e2cf6200f4d0ff02e57ae4c53c012633935871028e3c7bf0f5035140290f4cc02afce10718198dac233a6dd7ab4065f07242e173b -TAG: 8ba94213b2a8696d7e203e6bfefc1c99 - -KEY: 4233eba54fe7537d0127b1a062526d33 -NONCE: fed44fbd3475daf5c046123b -IN: efcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99dc75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c20da68ee6ee -AD: 4e0126b67d2a31e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124 -CT: 4b9b468ed1b1b3ff8242f0d2f204e94b0312443ffce789fa9be7c56054c2392868d8826129462bba1b715d87d58eb5521a258af3e9e06d90e26702106242ad01ac6b64908f747306dc4ca142597d3021df591b60cfc2d260d9883f01078ce4db4b11eca4b7b4329962a6e5445857423776b22b802bd0eea8d7ce7d1d47d49a805d9f557b8d67926848668d8bd04cd2a9eaa0b118b9e680e23266785f3641630d2649d952501972d92f2c6e5e7ff9e8805ab3fea94e4d069487ab6767da42a6312c74a7191310cbf58995a94158987a0d3e6778f3f44f21c9e6c1b08029d368daaada4fbefbccca7f49e2f8c6d754286287ea93f69c72f3234acb2e4059aee4ff341730c9deccdda06fb67ab67b81cf5e5213b7c86b03c00ad8e447915284d5fe4e30ee2fe0fb2ac2e5a58c0623c80b40e6ebc2b96a2d5e045419fad0dbd611fc136ca032e71ba2523b5cc45f115389a9c9ef0a28d9b949b84ba637a32fcd3a8687c70c7d0bc4f27949b37d20ed349ad0bf1985e33f74b6974dff70ff72205085c766469b4c32bbd93365e207110b55d477347db18fd003c925b64aa4366212585e882fb5a5643d79cb6a9057e977b554948bf8129ae67ab02ca57d5052cfec2949e86f3c6fbf7fe0e1aeee3ccba5752bac7abce9a396fb6e5ea3af059ecb15937f34aba7fc8edb267ad1ee18c49e5e6f057ea5b0156093c6b042d2e7b2b29bfc9548f91515a6272aa8b2bebc5a0b0d9d610b6c911a69c38d15c2ab3b1d774d68c6d5515012a083dd0cc2fbb420456b8aa174be28502c2bf22c7af3a89686e2997f2015eeb7c33ba40b676b61c84702a3c5c51120dc290e58724d082281b496881a54839e6f0d622dfafec125b381da4823240cd960d63a6890c11fdb9f56a9fc8dc172c98a3764eedf804d1f5f56d4d9fad2d414bc4c58466f -TAG: cd1e49972dc4c4e0ad3bcdcf16e692e8 - -KEY: f79000afa6ad2a10b0dbfa4f34e47542 -NONCE: 0437dd10d487f42d2cc40041 -IN: af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05e83596b9ab4cbfae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf00c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea32b0a22b260ad -AD: 3ffa73ff1c5c481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b37 -CT: 47d6bd87f0ed8dd258b32f01e5c72457dd1d17982f1671310cb329e18fef89f25826f7a6a9abb54d4d216ba214503aed4d7fe36daba69482e4ace4b7c7a91de5a93774732e0bfa001947d8c403165473d77b6b0d53bece68a76cf544583980084ea5ad532b599206b2d618be4e56cc22be645a727a93fd73c434239bc9c0b2d1621e3ba63e625327cdbfb8f7b13997c3d981c340182aa59a4e8cd204c5c86e8c531019f4900410c6870a1bce9c5e4f81bd8134c983f203f7644577da19117a7432c9a7713cf1bfd3bcb055b8601f4f44d33b1191ae1e32ae868bb37ff5efb1a7f67d94d993c0c50074346a6b41da521633be46e299916425fd46bbf4593b1c02df98f68debfcb43fff6a1d7ad6c4b48296207d74a9504670b50368f2f6a2d89f6fa98b39e13cd46fcfa746dc533c8327a0b07cc89b654ff8ceee471eb42f1f07b0abde3ab49478563501e076622c0248bf8e82576e968657fb0efa23a03c3e3013098e86e44a40d21fe0e640cae3da3a461038907f9610d6dce7a1242417bd43d26ba6aeb1e6e3d0e54c1b9839d019ed409eaf801ebb6fb25949a4961b35fbdcac81c9f87ba8e4f7103984ca6d8fbd3d3aa7b13a9ef1bcdfbe4f6d4e6cc48e5cddcb057027f98ffad2a90a7d4fae9427be8e77fb6c30ac38cae71a36b28fb47045fda28a027b1301fa5071a262c5d1e0a695d3244218a88c7182590698b690c42a3cae97ece7b7266aca88dd8fa8f56ef08c28d806e7398691c31f292caf1443508c494007f5de45a95643534f3f0fdd20790f0aff8d9bb432cce36bc857884a28d2dfca0667a2d7a0b0255fe68a2f9cbc28cacfa489fad9d3101a5a6bac3c39fab9a8223bf5de787fc3d9849626cc50466355df2da389c5ed8301e24d2fb6ce3e8081d32340739326b706466897cd40265cbc347121b6e12e04c218420ab7ee760e9eb6b43fb4e4c530 -TAG: a2d58dfc6f1a7aabcc28cdcda713735a - -KEY: 5dacb5173b30a28c99e00eb11181879c -NONCE: bf1fb59bee4e3964b300ce57 -IN: b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14acd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae9061ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd42bdf685c73f9c -AD: 31abdf1d28419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a651 -CT: 173cedc6203b5de9f4950c055399328756c886ba5f8eb4d3dc4cfb5e7681aec1c9ae238d0dbff2af21fdcfc244d20fc310ab0f53894d0f9d7204de4c3fe8d366b3fe075d7c7bddc79a256d54125d493426f56c0f56b0688921a0f9c6128ea6ccb405e7551750780d03f1e4c5d9ed1daa253a35178e85f5214684ed17614dfa8cbbc17c3620b080531dcf8434b7b38d1d45b45759f2f0e1c694d39e9387479aed05dfdada1672b8fb01935ea13a057884341ea164f1e59f8069aa5578845ce60775e4a6166b99eae120212cfaa30de04ed140759dd071c15a3536421b0e0dde31e6cb7d8e7e71aef462db4564803d1f8301f0cd5befffc1c0afd74ee5957d76c0a6bf85e2e57711c0ecde9427cbae0c214a09b69fe55ec49857df822ceee98d3d2cc2194b48fff88d5c4209b8a5aaedaf5c289884f442db3e5a8e441a4da134c3453665e8309b61dfb007cd48fe7f2c1bc612853917a06370cfbf3cff5c6c4d745f134cd5952986ab100dc17436cef8daf917096adb9a0d49889b75cf0306d31b6d6902817e747918ff92f479bee78bf2070a0011aab7c0e734395430604e6c8c2a73c17c4bf10a1146ebde04b04bb12fc6a189faf983e6cab5553ffb92f34a89e8166ecd024d89115e6b77395eec93d62aa3daa2f5b6db3723d25ac747f0833ba89350b23c2f874181a6e64fd3ecf4c07396c8d90be0cc78139d20891eb729e5f22f99d07758fdc00e76e9b082cb456c1e5a7b7704153e16b564f0bddd142d47b51e63a3c540dff5f32eeb786c48b3256b9d655f3098e649af178dcca88413ba50f0f332001d4d686f566250fcec1eaa4b3615604c9f3e8fb1704018d609904af5d2558117f43ffa74171722974053fd468e02f047703224cad8f7eeca77f8aabf9adcdb2e3e6df4f805b2a900591977b7180a029c8b359fe41b31cdce8a748f6967872355688e932bc64a43a12222001bbb4d83fab619db8f933e -TAG: 5609b0874958433df52176247da18dac - -KEY: 87b8cd45737c8446b21301be1d5d02ca -NONCE: 6af5432cffee125756ae7bbe -IN: 2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f972148e9a0bc6c897d4fd -AD: c82bf439bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3 -CT: cfc53c8980c557908f7d3a2c15e7f65da940cd319594b7d8baed9ad7edba0a46987775b004b5fd0c10306677eefeb8105cf124d0c64a2dac05364138fa2c4e49dfccb963a89956f97bb0340a14573e559d9f937b51fda46206f7ec3361ce566ac2ccb418290e070ff2655cbe89e762466c1559fba756c62de1c963afa1ad18ea47a1cf3d021f46bae6c060b19aaebabc900229086dc26fae9fc9da70af5af3acb02b6d5a570e95ba0d2f789fa077fe06553670ddd0c4e8965a3f5532e93e7fb0ab7e0b9f90cc9b483f1fb79ffa67d0cf53596eac25679ab4f8ea75b93f3bd84d8b8270d6d5ae62a5fe8995e9b0384365ad813edbe7fd9743665338cde61f8d0bf82481b9da29f6682795e7178fc79e676c8e3ff641ae25c667f92c849a642abe974d97718f0aca305b57ce7974172477e90e16d804c450b332339c61c327d78abccdba272b85f4da54154f59ce8dd5bd89e38a515bbca07d1526eac34437c66496f05e8582ce654ced3ee07d4e770da1799aa9b6fd42402a47c6d5e0c61592f11e798cfa3bfc20dd601e86e05fe6ed45a475a1b54261f368877e1207029f50b6d54e19c132c5732ec34552c2c559c135ebbebc7be00233126d5e0dc5e20b7bb37f6b25df2ae5ff44ab390ddfa91435c6d8ec09c4916ce8dd3e10509094cb4fab2ee9f67c3eb351ef221f3e67b7ff3dd7292ce01eab7e298343de449a2d4a0a168860bedfa0754717bf6fa0f5e37930db0e70c66976d34c0afd3ed623df2a10b9c02b2e9220534688e640de5d53f3707c2c9ea3de7d339e5530504b3a821cd3097784f325ababae463e9e1b34ab0830d5411c9e04bd48a321be1f8b973fbbc6dc03dc7ca2c31b3d9a800ec9d425881468dd9d8ca7f67ba2ed500d1674118d42ccaa6bb18f0a2c4e5ead86234255d850f58f9ee7ef7f70e2eacba6a053ec2e78c27a45faeb4c90e28687ce0d7cd7f8146a6ce8ab3887408e85563889373b606cd5c968437bddb632d69e8e8fdb -TAG: dce7df76d7d0c0be7f560dcb5a4a00cb - -KEY: ad3ff84d1442224006550f6006be543f -NONCE: 7712c5edceaaeb3360ac7ae2 -IN: e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf836acfa3e2adfcb7f880 -AD: c53c1a8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d4 -CT: f59b5a5d01cf45a8d91c8c53b3d8feb5440b6cb9537d9feb0da69c33827d1a5542e1d2db34f25c399714324b7d31476022778a82a10668a281bcf6e5ef368a2c525a7bc59f46fb9e747424741e8894f86fc157dd748370212f848d23b13dd658c1e2ac1bf99abdf93b53a35b5bcd89cc4406953376187af45ab811e99db9ac2a367f8a55b0fb4acac9a9bcbc1858061860230508de9a777bbfb0f74b2c69a79dc332a4f03d156596576792f43dac2099b1d4af11fa6088a086a25364f62c24969a515e74f29661cc4764842a47cbeda7ff9ef515c7510c16566536273d62109397626a3c2b601bf272e31462ada51a01a69e6fe174082966fc25b6b8b034add7d394717f08df992771696bd51c25c8feb47ce637e23e89feac9679dc753eae62c0ffe7b62d9855ec470904df6bf7b6fb246cd6ca77bf2848f1074f146652461307c5d51b46977ac39c42ac5857b64f9b347a45062500de41a19f2bb03fdb241b309a5b685f408aa4e38e60c667fd4bad4fc3ab9d8b4f2a8735b50d2fb7d7177d2ef9e5c783ccdbbc8e923832117d3ea8cabf40891e8c912d703f37649096ed0e41e0e53cdb19da6467bb1ace8064c7862b6c4829959f7a0780860a598f3c725f3f956259ffd20e9088dcc639a0c947d85a51f6c77e911355ba77fe43e49a1137fccf2d951d4083c7232d095f2e2d003bce91ef9cc9aaeeb046a35bf1b548c78719c553e6ebac55a77509a3f02d71a9fb84ee16a8fdc6b8b1c917f800e053e655860ab17c0254327cfc3dcc9267e2b78dc2082e54895faea0349d9df3eab4b0bd62f5d6114903d8851aa3cc9068f6b03d7924dd6c4fcc08237f05551d528c01f33720c53867cdd375fec867f71fb3b4688eb18ac3647baaa94d2a72391f47e819b4f41e98904322d1b57d4a485fe9c966d4e0967eb415feff49d1baa38ed2505dee1b76bf1fad013918bc282761f9431b1ea4b3ae826470ef72399c86643a308043a2206df7eb354671846962693183df96ba170898fbf304b0ed34b1fd -TAG: 90f99dbe53f5a8531b2a0e8dca2b7492 - -KEY: 39ef8200a13e35000b40e9b0b392c982 -NONCE: a4377557abca18c1f3bf774f -IN: 4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17cb28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea3679bb9a78d035bd8ea9e8 -AD: ad709f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176 -CT: c1545634e7b0db1afb8a166c9f0d81a561841a583d04fec4f1994c7764582f7b11f832ec2de523e4f6ea3a7c1608e1d1a037b7975bea51524bc8f001ea34a2387f7510967cd57be0436529c08144c232ba1f532863255a55b2ea6f860b7db366ec8ea366e62187837ee8aa47cd9a8d687fafc31680c4af60493da7adb7ccb8f751ce6a6e30ec1f78bd169571fcc0f208d3966cd90660b8f7c2969bcaa8368172cff0d0fd27d732d9f7869d764efb36e55ffb96a1f3d8f1e6e5916e3e97e1f5a12f8dd965466a26274804f19dcbc7ec872cf662854501f37ef5fe348c543511feb61dfd96c5d429c83c7ed70a1d5beafc241c697a564897c9fa9819fe91dce3234d7632ffe73dd1f7c3cf0bf6d170334d2c4104a6ff5dd92038ad91e69f2685ccc380a9fdbdfe7f9f47c3a05ed97be25e299b8e71905f71c68b492be8545433c99b64f2d53a9239dde92359cfadb7fed301b8d8162baea533be9c9ea11964ca6f34e4d81b968546988afba059fa4b4e6d9e436137a9d991cfb867949c1bf87b1d61a5429d4bf549e66ca88b309cc65963baccc5449361dcab294d8c817717f848b942dd11fb1a8015a89e9bed4cdf51b4ff3ace0ab474fcfe16ba2da81b59a5dd7958913c92b4f6f067d2d350111c23c477138ebb40a99e0e55e6f609d74565c77bf8460e6360f4bb54220176baffdc96e4c37529ca3a38b3ef959d3ddb3b2759141032e54aaa8e6b2bdc928f01974f1311fdb15ace49d7d5a026e77fcdb5e9d7442f7bfd04584078804fb3aff740af89401771047af2483153b4c79923980cbc5695ebcfebc32ddc522f9da5b1220961555aeeaa2d578538691ef8b9f12b5833cc4f3b18d7c0d8b068e294c82efb95badbf590a3b4094c38f334d7ed32934f7012b87ec4a49bc0c2b7fb98365f22962d1e45d99e190655ce4213275b1e422976bbe36104027b96ce3e52ff931548e10e006c75747c59e3f7136db301eada16585ef15f4589180b368babe64b114e36686282d195d622e89f04d56f17c718d72bc6c577796a639e634a97e7877258 -TAG: 9563db087214b10c64e7cbbb9dd21a83 - -KEY: abbe5e520c0ee79153c976d71e5c6dd5 -NONCE: 76f4857ba2d63e04d6b69a2d -IN: 5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb714e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a78843256913cad2727f9dbc3a8bd51daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c7550220b0b5f3c6fa8db73 -AD: 16337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2 -CT: 76e3480cee9d48b31d5b1e9a01e79e713cfeb73d742f1fc1e8f99c8e0cd82e267c45f4270077e86996a7e5440a781861dbfdb9759a6ce3991fbe6006d0de04658423f54154c8e5945dad96addb8bee044308cdf062ef21fcab25eb9a91f100945f347c865211a1087c01f245448322e77b826a22287df3434af7bee91d7a278fa59689656f7d93270898fc68594a4bea223d365aae03f0dd18a2e525f0c142b28776bd9f66fa2c046e57394488d5526fda62704e90f50e9752bf9d7652b010f8407de91eeb3068b830d0cc9294bee9629161df4cc7a1a216e55dae077864999ae72020346e813ca8fcdf99e417f26b82653908d0d6eb50ec65814f61b1825cc29c4679a9097e9afe294775e498489ca6839096f7bf0b60d3ebd016d83076184b272db1775f5eb3205015fd45fabf0bba9a990518c8d6d0c478221768fd83776253dc843eea8bfb66fbd2b9977632ca0aac7efc9528115fe4394f460d91c1b74fceed2952c6abc46b61fed85eb7414410731106e1a7be792eeac86fd4bf2b1ff2e496417fd8c0c2865e80837b2b73a690a6d9b7fea83687adb3a004a0d9fc9791c572d916a1b72f3ff5485f7d24e08c65a86079dc2bea698c43a3b2f2e5a8f335da4376aeae4d7fcb509bedbfa0e8fd25a711af45225d764534edcee4bca8e1470cc7d187b0bd9c26866baf8169289653aeae9b36277ca22c2a0ce3f69b3a40dd55e745b0b7467c2ef6a8a10151297eac1365ee475239d8f254806c8d92354757df8cb12d3dcfba83e05c303bc157c7be49da40ee072774ea7e4ac7044768418e64d965eb76d14bbd73be18d14701cdb6f8ee32cc1fef468047ef0ac649fb77843f0bb751f543339922bf34eeddb8140220e6b45ef1cd180697c651a352d05c77b705436f61ec9d35f185c5ce83b210c4a4336483f49ecd538dcc42a22b4f77ecdbb8cc36b8a499ed5c39de1fb6e03b0769639670fb2517c57f183eaf56148e1625adea1efb9b888e8fc3d83ba05c35f8509bd4e16285911462d77d9b270ae278cb902f6ff7970211cd53f1c310cd14a1787009cfd041c29933edb6e672d1d5 -TAG: 8954449b3f6a09e92ef2e33cb57c695d - -KEY: 100c6c8d1e88b842aed09cd16a5d78d4 -NONCE: e2d7712e40234292dd1aa27e -IN: cbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c -AD: 0e2825fa3a69b798030cadfb168a1f88dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b073571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0 -CT: 4b7337e4cacd72909775b7b8b77e3a73dca810b4642310f33a58f5548f4876d20b828a303cd85241581372f94d2582f79030e13ce68835836fe194bf8e68c22a39feb10825b80b4e2c69ce430b9b56536334616ea3f4610ed7a8136102fc22e634d5fae28cf518630c5f159ec3bda66fab0896f789c7431c9f6033c52e7082b4b65caf82df07266b39a4f0b93867f0e94e3f5065fa626b4ae90dc70cb3cb5d9225bebdf7de553d364efec3eed41c15481d2ab7f8453af13ee769c6a0af2c0a04b61f74302211e1d201ba91eb73ab2a199c4929b903e91172e4c7256d6b138903a4707f2840952c07f9ed10597d023efabc587d2753b28cb809d678b8306ab50bce2f80b9c5758e8d3bb3be07e7645ee858288eac7072272390dbd2915742ebe44de3e56caa0a9c7ef8d42df94173657a4bcbd183fc3a8ad1764606a8bc98793e240fc5e18f3f86cd082dc4eb11576fd29097ee7109d444aac300dbc930bd1d6d2b7f3c69cc02ccc54a86a627603f3e1f11859efef34bf5d11b16d11f9e5b6e985bbfd3e4e3bdb94a48cc0af7eb6c212c3fd621ea6203a5c2192fe1c25ddafa33ea774da1445191f5bb266683cd150cecbe6e820ce3c8a210bdfe407d203a8d9445c216adf892a0999a026bd8d958589f3a6aefcb5ddacca2285f2dc20ea31f43d6759ed5f46c988587f93d6b90d335bb51c76a3fea6f7513385cb3c1b8087e88dde0cc6ce55e7464e6b0b32e777a4e34416c4ecbe1610658ec0a05550d1dd5cb51b15fc3365f32b948dc28342b2b7ffefe63f4842399d6df28b966510e4aaaf5b5f7e4c470ff065fd30d56d085429f89093a291fd7e516b8e962b0fd2faccb0be3e4c62dcb7e75fa5514f79a07a8f4044cb253074b8085bb925dc8302ad9f7fd0d41e960a55f25f31f4bebe6a04775906b59f124a64f5d55caa55e1b858d1383ac7e4b39fb959cfd61acbf0d64ec6733d15e96137821417829c999ad93fa735f543fc73a94d942384aae4e330cca4a7d694627684267d3a6d74d6c140f84a3e10cf58158ccb3ee9c7ad700b08bdc46698707957e523a81f9e683527bd16ebea1 -TAG: 9ee21a6ce2424d9ab143ceb318e16819 - -KEY: a646ee4b0e0dd43479849864311c3f74 -NONCE: 3f2a6cf9d0dad34111493f0e -IN: 55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a566e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce9 -AD: 7d000237e72e6de6176fec75f5baa6d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c1 -CT: 796320131f438a93c019b4caa40e9f183ab467d30ac181aa5f2a0e07295f1d07946c4f2994a3ed2ad8522d5ef3fcdaf6d58e1eb03f479859b262ca1cb6e950c24b70a5da75b13055022602f39370a48337464ee1100fa9f6a45bbf793226c358fd91ae1b71eefbece73420bfc804a8d6499f044cf250a9c680445aa54639308c10631644ec3367cef458ab24d0dbcea8168563c062af8f282eed1ac778670400c03d30dc4e1a8f3172555ef633adc99b197f16bcdea6c24b2634fc189b8dcd3a52b56b2aa5099c10a830aff238d1bffba89603352946048fb8e9ee72ce2c13e4fb717d83a31ebb67d99049ed49e58d36513fc399f0e05e3693857e00df98707c66c67b87a2a6aa63fa68fc829cc3813f831f06933ed182e103bff8fdb16a6ab5b9ea8f390a2248c9923756f3536f0e699e3af05e7a3483169cb19fbed3f86335a2fc071af6ddcda9c702a584493294d37bfbf1c2d35a3db8b4b905a3f08dc0e691e6d5264446978fa6d85d37bfa0f7c57630afb61e9c67bc130fbadff95cf8d25fdb00e10f4ac451f6780fb763eb5fe9c34abbdfa44e72346a4ba258180c134e9fc5e336e0aed9a0bc7ec3dc22fd0a38b245a512ab7cf0aa888e2b36f02ce8952a0eb69dc28afd70fe9f1bd20b12586d839cd86ea95cb03c8cebb0af0a6d8ca82d6fe853e5664d30db557e28faa695a903e12efb6b6bcaa9c30584121a662ff4a1a6850e9b005dcd194bfc418df2a8919749d8a82fc33ee741ba855caa9f60402bcb9896549ae11131730d7a7bd1011633f759b302cfd8a51afcb29ddd9600927867776e961d8c2a7ce403e1723d11fa92d587c9ceff9f4920bb4ec52ada70ff98d7c1d4b7f84cefba39031f757a86d78c04433b7085a9cbd44ee1cc8c4dc2dec2a938871bf40b2ed113e4234dc5331d536331c5f8552ee39f288028d8d7036d9acf9ff96e385a099a44f51e46cb73a4e9aad3e5b40573018a2023d683f4ee886236d9b3a50edeb69549462a4a496845d08f01e1de332bb2e3d5ab3e9a2adad675fab9eab0205462a097f4ca75bf59363ffa1e2f9dbd2831fa3ccf8b540de72eb613a549129e8d40b8f672b200420afdfb -TAG: 7d11d1e35aa29774756505f036a0c857 - -KEY: 9c73a26fa433bd4437c1018263e7db4b -NONCE: 580a120d1d29775d9d5ced67 -IN: 10ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e0746027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de -AD: 874a859c5637b754a4e7c1ddc3f34dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f -CT: 26e09e3c1c694166c798b8eb3f290e8709de7cacafadef90be45e751ec6f0477f6f72e19bc0343258babd08efb5ff4f82a3aa8e8b50f93c4bed2d1c0bbc07443606487a54f4eae3dd09b3b02232276c8de51b05ac31c64bc960c8d14b953db9e84c05fa9d2c3a286413fadb00f1812ff0a9f49b91de3660fa87e8aa73f11e0bbbecb8ca9be494919631431e29bcadf6883af673149c038a820549883e5d63ec5ddbb5d49817643f29c9665a3b416f67d28c4dbfcfce80132b3e120816c156947a003e36dddf1ac9652f196944c176d6369c25dd136c7880b20e13611dfe52971eafa0055f25cb8969ec688078cc8e7c2395ec27d7d38f0db653b6ab4c987dc9ba33d5cf5d1c05f7fbe19e639ae6baf87792bbd0adb236e4dbf302e93f26ccb2d7a47c8bcacb8f6ca4ed5302a2f461cbb0312d3bff43149a70b8271572797b52bf30cf5ae808b225829e4638fd9f2368021c6205b505406145632a9842ee338a796c435608ad5a92361a19d52b7f8b348d7fa16b3d7775c58e94069aa01bf470338dc28411563e610563ee8a8fc01fff824f63500599a7490f74a59e3ee4612b76871830066c4e3eafcd448822b4c08acf4935f59942bc3cc83e497ee8ad641bf329f6f0d9cf18d40794fe7146987dd6e29c3c862f5252a8767d966e0141b6cf0d166f18b658d8343b698d0a91f5fdba3ac2c32ac24935968959b67f06b985605bff2fc4afc2fb86d6b4e70bb606bc8009f9ab59fe6f6720fdef5f530eede5ee0cc48071fb9d5eb0ac468c820d161a6d09f7d319e3c0da450a9bc6a6bcd37c1f59b3817fc85dbe85ce050d72758f3e01b3e0fe62dd55447b479fb7a09b29122bdeb315589b568ff9a20850b0bfd20f220c05222d784dab107691974e426c83aa12dfdb5693f6c05c423a7c88b72104c0aba00939f9b7d0f92920f8b166512f7ca4d437082011b38fcc3596a125363eb5872722eca03132c8a141227fdf679b8f323ebfe227dded8a2871c1945e0bcfdd8b6c631e293858fa44ea16499144e72797cf82ec32c966c60de4aa921f3b754075a4956c00540cb5800dc97fd0de66936458022ba2498dbee43a99cd8e7c6ca2aadd1f63209d2a24c84a27c13b9d5dff7cd27 -TAG: 68ef1df2583bc3743bd612442589dc24 - -KEY: 6269b478e1d79f3727831086620e79dd -NONCE: 357fea1c84ec4de0bf7d6afa -IN: 2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496baf4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a98e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c3 -AD: 0377ed6ab683ea82545de480b5f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d0340473 -CT: 096e0130b0e57de1c25d51c748ac53ab8eb5f834ca5efcbfb9f9f950393a6bdc9475bc98a224ea22fefa19fb1d9dd5cb06f0bbcc266c78f169dcde51a7864c5a5c5996175b511dd11c6faee4f7afce3c499bea2188dd443c654486ac5a1b4d113e38cc5c2bd730c3ed87696caa6feef8f466a3323679fde56da63048433d78321388125a9a59d8728c40485299fb0a8012dccecfeabbb7a0343d03fcd770c1b5ff13116ba845b90c715403b5b7588094dd554cdcc1a166ed872c75a7719c83e71b9703ee90e4909e18822d5d2e64a851bdc30b2915371903d6748b89af3da42d041d4752fa1b1947ee12c5106404bb6a7a3d47629841da3ca1652666fe15b9ac2ebeba651baed43e6991139f90cd7ad9abbdc89222086da0b9ca7f4e7838fdea61fb815c534a878d7cccae9fc07aba48ba6fa7bd3a3b448e99267eaff2834a2db3084f28685052d2973eb7c74bb319a232eb0e1bef7d2827081310aaf1368656f7c64b1ab1ef3d4197b350154e18595aba352dfcbb7c0187d8ce67a78cdef6af01b3cc7f0f76d8a9de741c87823f1e6e734dc60cae88078e233e4e8a525148a56572d67ddfbbeb9409ac01076b84d9998e2d10ed62e2288f440f5b54fd7a5a1812bca2ffb9319e56b674ea4804ba0f6d92d7aa7a5e1a9f403c3c6fa8dca86ca4149f2d0348150395ffdd382698d0efb7421fe0ef930b5522ffbf122149a5ccb8bb6c3bcaaf935d839b9b820e0f199043105cebb966a6a4e588a99d20d89c61166c257cd6bfa545f0af914416f8fdd53cffc1d99b27b6c3160205c8b71af69cb398b5cf8f72154f612ee0778fca187a574babfcb6a9dd61624f8d6ae247b7c15be83d6cedad267f847a63f58e4ed7136de31126ba114e5bb94e932e3a10be4da821f091ac27b0c3c73d7fa6215bc5b85bf8227f10dc99706644f11c3a0d5ae282477513304c2cbdc1b5dfc6d6314da4b20eaa43a784fb8435c0be578c409291866073c31bb6a210b587ac009ccfc9fcd342e07854fb664b6cab7506d5248f8377314e5fd6dd17ed871ceb5336a5ff7137aa45d211b06a4cb0170ed25838ba8fc1041f516a127c245ccfbed4ccbbff11c0bd557551f86dea82db1f01ab97b9b19a6cf94e405834161421ef056d96f3482b2bda2e -TAG: 143dbbcbbcb66c7ef3ac9e730360669d - -KEY: 58cdc99ac30e78d6238b5478982a2b4c -NONCE: e58537a34e5ebc37ea72f321 -IN: f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d4351c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac257071132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132 -AD: 7840ceed28a572c5186f25462a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c -CT: 9662e1becc3ba86c8edcfb3ee94d3ccf2cd37f7aa1988bd4cb374cb5f3cf4373cbda8c71832fcced0531c35d035fe6de0f0086740a62b07e81b3a0f98fd89f22243a4e2e81263c3d4846a3e54977ce7617702e43adf44783e279b174591fd1fb231f2d5e460a866568c867c8e762716959fdada879c77b7aa613ff15ddae4727cb3a2abf192fb74cd6b1eb5b632953422cae683ec87d6eb69a57c2021232181e8f74883355447643d9fdbf23b00f7ce602bcb1ac3144387610e045049c7cb1bf1babfc18b21ee05da3173bf2a0d8833698e7b3ba5e72996f6dc43db0228c81ce3f1c644090b922bfd72dfc81b60a8378cecd2ce14b9a53a16867476e08bb99f0708477e1c6af6d262f543ba4b3cd5f3309940fb31691b9e50ed2f3159afbe8f3c95a8447af98a76ddf5a531939232273c669231091f15e8f819183d8d13624bbfd6cfb9bf781bc74a9b4ad631de4694e8db879e38508a3b3e26158ae3a897ef6c9ecdc5f64d870964f1d0bd924f2e919e4a3c7ff5beabf589ca4be4093b2a95eddca2f7e09a02d639ba872060d7db147476cc83153f7a5227a1ef58f08dcdf9f821110512424c7e84d62931a73010576f898974cf24f9361d1abb0ea3e84c79925c87544cb11140481fad00dd75581526c0b9d49d74a05398e58d8e94c6c86976dfba9d00440c2bc61aa2de1cb9569bb9c4226c05cf31ecbd4854c2ccc99c1ed9f31a270c0ac57bd43e6c5194f8b2efe49d34095baab0bfe8c3c372b9bb77b974deafa462b08f9e05e027c3ad53a24206eeb5bd4973cad46c0a8157c47ed9ab9d6b0abc571223d4e3c34675f89dc0374da151e2dd6e4dda27479499910a7836a4b638dd32ef7ab1c5712db101aea462c6ea2447f39d38efbf64794c466165723063eec9566f874cff9d6d2e96e51f5c6e0f7349bf4e667e4b3bde503a412a165c8d1381d7024772a273911ddc4186a7c1e9818519d9935cb22452468938fa0321c1bdad488dfa0601680e06404b0533ef7a8bdd0c00fea49fda059f2deb7504fcbf980e13d6c67b0bc3960ede0fde107fc571304a87fb19ceab00ec6cf4e0087b5365e8d43cb08c256de2300b565474076826f381182e6d2e0e9d77be0bcf58ca80f4faa685435604637cd6fc65366dc46d92ca0fb569a5a9b6440e089cd1d8522b20a42 -TAG: 6def2aab9f94f8ceed77295e25f81309 - -KEY: 283d86e8371cf7b34cc9988005575c8e -NONCE: 98ad34184dac039f04f84e5e -IN: 8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d896ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177afcd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa8434 -AD: 73cea023d2c6afdb625b6411ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e -CT: e8df4f21bb8d95211c75b194c30b1f3816715a063b202f8db645da8b826fb45e9af541ca9cbdc7c383d4b5179707f6665f8b2a74c5026243c3c5d9c32e6d309892323440ac0d945875c2665a60be211981d5dcf46a211a4e7b58e0062dc43b87ad3a9c52751f649c2fec404b9f858f4cb3ac9b534c850a8994f26136eb70e90ac44f623aa3bd362069d32a85c65292455946df893376868cfe3b06ef638e56c7defb9b4f0a162bdc8aed6a023836ecc08ed826ae9b818f3db6501ebbf3035159b6341ae703512a8fb8fc3ac0140c3ccfb1ced1ea4b7ff545ef63f76010acd708778d0424b770ffd36f2ddb6009ce5dcc498a9bb8eaec3fbbefc39da3da2f7f07470d051837398160c1c85ac695a519358feb3af9274fd3f6b1d936eb400e0bc5ffcf44ee9c78c730e4f449a008dcc912b6f9fd5d17f5d6dac025be318d5aae77b8858c1effcade42dd360e13b13f35baa64d37535a0ec8cd3a73d0c175be0246da3722db1b64f750c51d6e8da7db1ba8891fb688294124c989cf7d14108ab90a968f0729b6d7c6cc777e470e946b0fdc7b6dabfc6dd7be52b51ba1849cfce2ef2ca70c4a51523a1b0410e8a1a8e1cbfe7f1eb3fe456da81b4de6fb15ae13a39fb5b1c2b4aa9857543c3fb240965578f6b27ab7c69f74af7ec068e8c9238dd4848bf2345ab153730dfa9d1f57060e3e5f88a351f83cc78bab6149bc093ce2b29c706cbf85d35ad1c036d2103c89f1401f4f383d9345759a7be3f72da2eeab56564d98e2514d99192d82ba37ff5ef49a8770712c41e74c08227e3a2f9b516904ecc23c8368e3b46133094121209d57be76dbfee3ea7dc3240bbf1bace4369b09ed97a9080a3dfd93887152d1c03aa267ddbd97568b0538879c8970a62a4cb016e7e80b47bb21645d6a57f9ddb080551a9ca9cdd4fd0cc575bdeaa013150a8a04d05f3ccd19ab0979c9fda569e362f6bdd4b67268a88d88d0fcb9d68c47a0df0bb64048baa0554cf2b0cb4c27bfc0ce8d4a35113aa30ba03f88c73695a5d6c3495b5a15ba407ad75bab597a46170594beb34b7966d6bc7dc4ec2611cc15dd60c475c7d7b1f0922931d00dc93bce697dd4a4f72066d64b1aba029129d3a26c5ed44d19df383802733ca71de86e0a2f8d0ab04307d1a8da7c6f3dbe509fe29935bfc2c09712cd35c229e495ab3b80a447a168d044d163ae -TAG: 05b8694f3ab53f8a0763d0c0a1c5a64a - -KEY: 6611562d15bc2b910f4edcc981c457c0 -NONCE: c20bd2710668b59242f7547d -IN: 2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e334b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72fa399 -AD: 26a47e0b75a771783631e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e4 -CT: 57d4e97b3ec3681ea9dd4fc9ad0aac302b477f081ea56e613c53b9cb9cc467a2042657905b7a5b308bbff6803d33c1e4671d126ecbbcf6739842ec4d552d377dcd25b9089d96d284118ebafd0cf8fc097c35124d900cd69a2fc1f97fe3cb69c6648aa069eec68893ef2d4d8820ffae86677fcaefc50b64c4b53c9f591a0f6a3320afc569b6eb7637e5ca07c2aabc26f85521837f0e3a6435ef5cf9d2ccf4edecc5e0984601f88023f6199456e965457e638c1d6ea87f5041d10c187eaf4dbcd0cbd6e6ecd6043629819af18635caaefe6b0535d8fbacb59a00f4c0bfa8711d32131003a051eabc95c0e7119e0ba819022cd01590edcfaa7543dfd2809768b1e03ba070db5f1cf726d425a6f623d83c454c78118a6dc32ee47528979f6d478a58ee75bedc95e9e74fcbb96fae77353e6f9c8be5727250748627d3187f9408eb131efd62a90a19bb2b19b3b3a478518e49d98609116bdb9b7de7777c8f0bbfdb2d1a9c4788d81fcb548ed51d1be85a603c1744792163bd18aac3d7f20e97e32f806e7a049d3f51384e324055bfd57c5116e48007077e295e0f3d3edbc6f4be1b08d42533327ae6c7464cc45ed184912c1624caec44a0958fbdab3a2a9eb13a6e6e4ac98e40979f4ae4fd7a8560b623bfcc326435df878d643f394d177013f737fbd4971f734876d515a4f2c71fee5a36a632c93095674310a60809240fe03d7c1584a446d536fb6316c9354bd007a4de1b12e155ea6216790ab5694268081f0df280f6402373a50e2d2da82d7399ab88fc9020109e93716fd3b7d83b14bac73e37a60ea805aabc557774c26c3ff906d5946514e222747fe6962500f90765702fa16d7490d9255d74dcc2c097dfac75e9f7f8c090f4d8e8cdcf4449bf5f7d45988f363e4751ffc24cca95d120714c2db59277837ea38e3b385d7d3811bc4fb755e6cd29919654bf3dea7bbe3375bef1a20cc55170ff514522886fa4716d6f99bfbe5801d1f93ce5bf82fee322e54ae1a2342659dbbdea49ff1b20274ce3dd2220945e5142f3152b4c9fc88dec89762b773ea1c87643ebf52b6f6f5f26bc1b8fbd459ef011033f3611646b50ed0b43bcfe2716dc780b8b5757d199e26657aa870fb149bd3f44db61f07a2692ab06ad8e30d40e8f6eaf4daf6a637c38a9e415b73b0bec06eba1a7e5b34d141244eaac717339b6ab052286bfc083ddbfd4ed0a70942bdf73f81b08ac -TAG: a7bf4e198482bf1ddb65779e97c2fd2e - -KEY: 8a7302e5e5e5a3f660bd83aedbf1e2a8 -NONCE: 8ca05db202082d8a59d11b14 -IN: f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e2eebc2 -AD: 343a402e3efdf91f7d63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df466423 -CT: 18e79588195948d25b9beea1b2d1f990e7b87368d4af8c88e6f928f375d98bff2ce973c1e5ac525e1f08fe6e7c29a976181cb5a2a0cf40e3bb24881bcc5391f9c129daeb6c85c5cd8bc1f47f9f92bd25f4b5fb474f7c0b49828dbace32f5f9bfd968cf3871cc4072252f5b600d88a857b4c86c85ace62e56aade90109a118e9813e984dd3027fa4ff6162421e3abd22eb6246c1f9328d85ea7004ea3259fa355031c660c0880893705aa7d672996107fd46c7e6f7ea2d455fd8183a40d41ccb0d50ba627b483f8ec6fc3713010a73dd52053e033a26e5a0daf7bfe3fce8858e63e18ef1201644dc0cea8e723a24e7558ee33e904a0489c3daceac911d2aa83a63f893aa6516f343aec8a9e46c869b38f10d4ba7c4875ad3b092be565669ccdf8370ffaf7c1efddc33f67e5751668f3d75b619369c863c7d3f24b052a46af2fe66a9dea52e2c36dcdc7ed8093d0244179ab7af3c73942e63827e4b301cbc0bc2c1bec14d690e8af1f5c72270f71693d0fd9c065d9267be22d647728d39737761fc46b0a01f98b5a304325ea8967f6983dcfdf9ae87c224fc71bd9a1aec353b28208786124269dd56519e4b0cb058975ebc9803e35cf6d38824b93c78db05f2fd2797af1acbef3c2a74737e15f9d2c8f3b8e6e964043ef53f4ae5a58825fcfb1b525e38ba542836090c5a663a370e9762c89893028572b08fb0005529d44936763486307267e4095a05ea8895de7c20965974b20784c57a175dc71ea738121b24e96e3ff1e7d583894324e17207bd0a72b0baa89987b6884c6133bb3320c35ea3033dbb7051f89000977f055f3a7f1c38ddd0808ce5eccf615532f1fa4fcedf772bc7423209b3eb98de47371b382c72fd8aae5005f42a31126e14317703083b5f83dbe9d61778e221da54899e81f936a9973f0f5cc6aad85aa831071959b307278d085fc830cc6085f5701879aef6736df39a6555fe3546779284f618860924fb02567bda44dc97a4f1277e40171218fd1569ddaf68c4f58697232abcdfa6cde9bf44dc39b0a3e000dc89c7cf8298a5576a57c7047f2103a1dc31ce8267d879d15c41f23addf662f8fa49661669edc1ec06ab426591b406def208ca2854210e9647d9ea5d4bca84c5a687e9f3238fbd7288774f72d947e85ee26094ddbeaca7e135379f678a13aa866a14fd4e9d63de6d33f01e9a668bc3e4a238b9920df22db04ebd5447857422dbc16200144fd306062f605bf9138f817 -TAG: 0b8c9441aae6ac2cea3cbb71a0ac7683 - -KEY: 44f4f7c9ef9a5fae05c10b2e7ac41afd -NONCE: 55e84c213e1d5f58f4c7aae4 -IN: f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f682257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f32487920261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a5168b8e6 -AD: c75f25ac1087b315ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0db -CT: 4e009626a3c4e6ee3a4b55ba06416193a63584551b8d4ed1e88f2b83f549129f329780515703fd0ef24a1039ade05d2dc4a25eb47a3e134579bfd6087b5c0feb9aa9d82e89706658eb54170c992411875bbe176dd0d25c06c2e58cee97e5444a1328b927a3616c32bae60cd8a28a58c35f7aeafc891ae5285759b24fa4b2cb59aa4263a864b89f14316181a5b8e654408eaf85f87b71ac0d14fa023a12cf4c18bbbbed4c0dcd5a93669183a56e3947b9cb72019cdc810af9df3ea68ce836f8a2a80074de9e8e444ac0e7982e0c029926c3ae96fa84711ee5c42ac6528648664deed439d7d7de9c6b207d9ad0f434c59f69690ee14b21c9e1827fd873d51cd2e377fac049d8d59219945de18e262f389709a291fcbcc491b2146ee372882efc0b48fb47c767bf0709cd5450c79948c2f35d1ac0c92ecdf9c338c1d80e5a7e7c9a2cabc78edc331fab75feaeb2e91be109bad562f2d7262be42fcb5bdad42736b9c94a1d5bb2f2d0a3e347b565ff59325a67bf074874639270ee8ea7260bbb7ffb018b88cb61c0f4b476111a6f317dfd7d0f8b9347227b9a260474a448abe10ca0a9615b2eb1708d07b3157f0cb641768ef759512b9d52c86b49925720335ab843db61b9a020cf95afadfd48bc739966d7b13148cd1bd426914700486568dfc1942c6bfcaec6eb4a47ff1531f4a3efdc57ef5c6945f009851925acc31551afad8dbde7d349e43101043af62aafaeb5cf67b6642c9c928a6feb55390a49e019af97b137375245794d794d72a2657f0400954676212428a10c8b75d9d0d64b0d23dec4c7efe5ba1e599f4ef051a050943ba517cf6b6ec438aea973509d1919b903cbcf551f4f2e328cba5b55dd9a5d03eb9e471d63e5ac422c47941d9fd7a27d00c6779ca609ba3dd58c0412e7e4b0740ac9064a6ed4d024918debd342acd03c7be1a6e7c49fea94f0069b19c363095b9ec9b7fbafeae5ff1fa68ae47db3641dd98b7a6d921843707f1795e610198df9b86ea45efdb5ba3fcd37737a06881300733a0a4f1558d562577dcefa0a9e76d17fb3d80385b442f1c07a381bbda05b5854c9c76c10d2c4ffe6e8c808309474ec30d88632a794be4e7002ab9d16eac7e5155b3944089bd482009722150e0e06ed0ec3df814b5fa516bfa019f3064b78ee714a03608167374ab4a290bccc10c76b247086c31f9b4de06d001fcc7158fba4569b71b6774a46a3c1f7f80d00ea315433156fa587ae49204be74d06a949e60867b3d5d38c93eabc1fbf -TAG: a6f01e3b9b29802f017892ef0080642e - -KEY: c3e4bd36e2de49d855196d82175ac395 -NONCE: 16571d209cd5a8579b05fbb0 -IN: bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3febe9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c98345399a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3e040d46d24 -AD: 29ff2b38d4e35a3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f42483 -CT: 9debc22195c3c01c571b369ac186ea10068cf99ae63fcc98c40ec69b3a04503c783cde85be74648786d5a7fe51c74f821992c0a0cdae23f4ed7318a42a6230f7c31045faeb40e880046d6e6bec6857a1e618fb360363872047781c05c38ddd8363c923762e4591f6a906d47e6d74ce365d36e41a3a6efe6e9dcba165a0c081fda577c01eafb1f83d116270c5e467dc7346647b9c0bb1e3b1da43b9cfd5a0f4cb0d3deaab5f3fe8401665fcfe742e686de8c050e8fdf7f594ee4b6c74ed0b210d92ef26e45da5a390f9290643a77b57af4800b25eb4f3ecd45e5eae5aa0dd37097bf24dfc0d1b7315d1787356e84e819de3e099f6bcdd3a269b2001d1da51681f14069ce8375d2f6b543e6fe0e9ceef03119ad96683ac884ca852fb0f88d41102f275d5040bd7f237a123d7a7b7d186d77b2a64b54568b11e70be4cd22324fcb072bd6f59d2a1da48a720feca38f8c164b9f6fc187c0a7bef39e4243aeb8c5d87d460dd9288e3de113250738faa5e82b2b4e672fce93f5294f81716aa8a5fcd43565db4b580ed18e41577fe2bf2c62518c1d4d4c324ae26a65a4bab6e5edfbb98a8eca18b34206705bfb7377c06dce7fed8e76b17c0cd2f061a77900d970594d36bcb15a92d2a09d54806d031c98942cecc0ed7f72c92df73b14740e661de31fdcfbc36f8fc89164b7614c505ce3b909376e827c857cf2b0ef3df86683aadad3112ba20126b36c5bc2c121737fbbbaa14165d511d50612c8d3946c5fd8e1a257a5c7f684dbd3b160d849b7172f4648c935c08d38733792a171cf20ed4b2bcaf98e39d09675b5918e5fe12b4e2be36e4b8463bfe708669c1d01a625d4f572e9f30a5c88d05494711e673c3d23b1003e94d4a75b9477395e8a16944ef0a1726d0388fdbbbed94faa5e78deb16ec471ed75d92772a4e437fa49af393ceaff5606aca86769c860864f62eb9c5801eae1d1fdc79654ed09f2b858718c48f05968a7a09b834c1ab0f31231795d0efe8394b3302fc0f75ac9e7c18e21abbaf6054f7442dd235451d3b884cfa25f6b7018fb18c2bfd5bb0e6d0075c2eb4f9002e30fc7d420268bad52dd916be28663a8ea3b2a0bbe653256314acebec85c7e5d2c1c163b0a15aba1cb8da585c83016d4c3f1c0aed13c20a9539438eef3a426565cd8040b2918d154e689d871a55f19b505ff94f3042b3e7466e21585800952004906abb3d13414134008c7ce1def619eea9cb22f3a44ba7070035d4cfc1d5bffa9e31b6390b4d1da2c76bf687b9bdf899fd23ce6921fa93a47e4156a514 -TAG: 232db78e53f788a11aac05af1041dfc0 - -KEY: 64f49aea2a19ccab66841c438df5ff78 -NONCE: 34ccad859bfdd89fa9af0b99 -IN: 214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fdf56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480ec6e78bc1358c72bbae8fd8dc84038806efbfbca520a9bf9ea1df8ac365a0a95a9865ab3b3556 -AD: ad8da691b07926db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfc -CT: 2873303a8c1b9d3230e38c46f680a7ba273e654fee766beb451f311b3192f16a385ff3c70f124e20f6ebba3bcc288ecaddb2243d3c707b0cf50d09d3c89e67d2a2beebd0ca0be6efebf9dfc519f5149e7c4f0c5fa8ef05cac1d2246f2616c179b4cdb02bfe3d7f394d885dd30f429da8041cbe79fc35dea5d90b903ec27cd09861422d3f185b887ce5e1b1d42d77c254fa003f90d62d980ddb63593e8700a20eb0b7bd930d38ae937ec326116f0b9983c69c322589e79778707856eac07ec42f3497767860d4e072ed28a79e263297896797ace5d32595c8b039ea3684b763a297b30eda2a63e178a713a03ebed0e0bb54c3eeaf41d8940edd2e448533a0258036e41211c835ebde50e9b7fef5c189834dc89cb7aa566c40ec7265c068aa50939e9976d1dfc4cddeb630a4a1f78a9134e10be1868ecd92628d3f8d827f432123dabeb9f45ba4576ae932ed42c6447a7b9f3c9b252719735898c76db75ee8f0fa655fa023cc33fb1ac8974774ce6f23409cfa7a4e936b57b0beffbc6895731a450eed1b4cc795813bb5517997037169af20da701d42d0c9b169e4155a92b4ecee3df6ca6c4a22474c01fc0aad8866e5fc33a8b3ec5a002ada29dd4d284ccd8141e4180df300eed91ab9063bf331cb476d6bbad14fd7b6ec10a3e72833595579d134a642cc556b4e9613499627f0af51f6b22c0f963e4063838809510bcfb801880e455d7b4df9db1841cc2168d659d1997a251368f1c15673ce127033602bd0fd9988eb1bd63e47e8ea863bfce945cd077e486dafa43c7f5e35232c0ee1d00d040dcda1ded51a06ecea68ac635a8faa35361f32d19586450e7a7b7ab1a8861d9f0f4d9508cd2df522dcf04a00ef2dab9ad5ce9dfcd6b018d0f072e9a17cdfbf3772d38da7b799feef2b6bf7cb4f8cfa53a49cbbda15128a17e77f8f7b4d14e64e358a11cd01d5d2137d8719f8b9f66ecb62d97faa3d2f56ba50bf4b9a28bc896c36260748d803fef6e5a6d6f24a00550ed66a2ce672b8d1daa10097c88f81669d09da72a5e62b29494681b7d2389063605e1de349a83ef50b8d57c024b2d558d206a73e49ca7fccf2b1ca685156e63bb591125910e9f72ab2e8d3ed50883ef0bf6d6571cea0f5acaa11e393d15607373f25fc340b9ed6b58322187d6c8fe4ec47666e1ca34526992e7056cc7567397e7ba0c26e1a049eecc356158827f3867171b4c77d408aa24c51513b0dcade9fe2bdf6ec856d4a44112fce5b4c55300c24aa2e9cb7d289744562dd44afa68dc2f14dd25c65d3af78d4bbb781aad5f9fa05367e02327b644563dbd992 -TAG: cebb4182450367713b8f5b047314d8c6 - -KEY: d12cbb53bab8c9884eb83f1d2dec7fae -NONCE: cbb6af3402bf462f965e2c22 -IN: 81c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521cade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa58697121394f11a1b -AD: 1d9caf4e3eb2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302 -CT: 7f22ef21a372702a9fead4339e38ecfa2abe757d8ff986e7287a479a864bc1012d4621203289c8731b189937d50fd6ee79db7ee84a157acbe801bb56e1225dabf13a25b26703ec364f98fac1243ab4a4cada7080a4acb8509969ed8a2e9f309e7e465c43f55d2dc829e2ecd63b8eeb6bb01a621f86b4cd32c9c243c200670e0d9bf71b221de296e3364ca2ed5c73751b74db151176626a69010f136a32a14d47612488f90750316ea7088578bcb84805d331c77d3041af756f2ebfcc4c95c328ab03cd3424f689e410706df8b2e87ffbe24f8025c1ce48e2ff6a0a240f23b09a0378155c2fab57db5d8c0daa296b813ad148e94c8d627715cd2fe8f861e414b3c7f482eaa5ae1eefc6ff86ee30109e27bd75557d70598d7c65bf9bffbecf44a44339b09ffb88a722fd8c19f196b9822ae79cb66fa1c712cbef821d996fec59f5a95c197f70fd34db9e2349a372f43bec0dea764fcd71ff931d34fcdc8d9c9321e6d8984211db1c1987032ad85e1b03519f433ef9db8811fcb24940a320697c739136a77f66e97332b75b33b9097cfa9e224b262c19053ca32afa76a96524861a8aceaa98771efab10c0665533619befac9bca499ad88c9d0f089a7026583e132ccf3a542adffd56996331ded9917d363659562a6b7e45231667b8b3069f327d829489279058b9b89bb7902c1127d7e8d150634b580274b47354edcde999922654def16ed4378f313115f4013d8ffadbde1c8f8c918ff7257175f14ead903c03d5190aeedb2dc9e762e34b3f80d7ee460bbd14ae9c3182660608f033ea073548956b72275f74f704a349a87edb015e6154fba7c0ef4a32a4dc206dc42d5d261ecae22a9f455c409304131859477435b30ba3fad46bd5f69971ba74f1fe82a6d5604e5d7eeae0dc8ff5a170865134c5fbac13bf6cd007a16af86c42dcc887b90664ee5e48edffea8ba46fd84c844cbade00906c36d84373178369fcfb9226654233d2c5339099ae4e723a0c0516742e42e3c40994bd06086e6f030acef01727e7f600f7109000bddbdbba16b9543174c98810d5ef0c95598ededb7ab628323faef1ea4028c0ca414a7cc33239c84de86d53a242b4e8c3f9a20e3a826f0ade00c440b2f792b946a97758a073fbc811f3e22de8acfc9ef1b1a946f6c3cf9eaf4add2ba403941b446686d9bc0524590e2bef8f552dd54d9f69053f647ff0e2371b244d15cf1a5302680ece820df552b374bcd23f784a9c4bd486a71fcdaaf3812efa5a39366542b163294da6a2887796b6d863529dfe76ad88e2b47931de5194a63b9f07f6ec63081c3f97e9c0379c5f44e7496dd23b4c186e3613fdf0d -TAG: dcb7fd2d779be6e82ba1ad90bc79ca3f - -KEY: b243593177cd099dbacd5f8efb412a95 -NONCE: 132b8ab31815dfb463451fbf -IN: f63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b3614ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc762d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac532fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fdcacdf99a3852e9ca -AD: 9516be08987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f0 -CT: 3497d7dab267c401f6754a95b885561c8dbce6c1bdeb8c6877810d6e77afe8e2071ee088890dfa18d8b4de635ebd88188bd1ff3539c7da99905bc955e64fbac216a0776d6ee45169e9959f4aebc6ef987f7d5fefe73aadfc2c6da56155d53b795df61504680886b9ea8bc59558160d9d63e2dec0c5d7795073c04b6191c725d5a881f71cd049b9ba42333f1082ab9733fef2230cfed44c7d827a7e6a8cb07ea58cd8ce96baf00df43ac95e35eb585ba99165b9cc6649b306c3399da8a03134dd45a1b9f1e4ab3aa0399c577104316af55587d5eeb0348271d2467b920a083b4bef6a21033f8428ea816718880da3c29f4332b19030d4270d20a4271169f179df4dcb07e15db1b3d4acb2d9cc9ac90e9877ddc09ee0bdc202e9fe23a844be123fc5b08068c9a6428988de1f2f26f06beaa020f725c072c842c97fa8069d944f80518ad2276cb4aabfea20db3256d35f9533d70c6723e5696cc159127ca671db02bcda89aa17dbf47c33eb863923c0a88f3bba8f79bdfb6eb2d15fcfa9acb68018d4d33417585299e92fe3e4a131dfd123a4edb72c988796c6dec3169cba26ac712cbcd92abc4e1f327f05838abf03bcfdb218d56e2d795eab3d08d5beba1b3492e72626d86b9990e777ffd91ccb30f99713d89d0532a032bf12192a1ac2368dda2c131febae2c11bffd83311fce6d20521e92d458a285fb548ef27158e593f306d99f2e5e521522192037e94aaab02713e3242bb412b362508ff0d4823ca0ff6190c71e31f4ff06f40f8d467182ad43848ee8b8c39280d535c7cde50571f40c366d97f5de703b808aacb5a7369df763518424137d42c59d91fdd365d025f1a747b95eba9f0ff580926891e39ffa2943e28e4cb3981d2cc62e9b975048df0d0708bb7067a67bf1ef6d03692fc5501bb09d562ea9ff3078e454227ae4d6084d21e08cf6c147b205d74fa81b72c1684f60923bc024c072608ea21ce48fa46c41495761d68744953c87c6e064b33d8d43135e43fd5f67322a1d2d9ab0e07e9f8862d6d252197a4fba914aaf4092a4d499a5996d40f143b8f3eae95a5a64b23a17495834e3246f3d0a06756d80bdfee94f2c03c8e5ce0043e9094465f6a3307f8b6f098edd85f863d2de3867b644fb0ff335b83d26958c88960f9913ca3159b61391fb67dd6770321a6971e1fff607c9ab6a2765f4795f53fb8aeb26944f728dc6f66de97136b50d722affbe78e59f00cdeda54e23f46647d024f384ca01f46a39e660df4cf9a2576fa353c7b243c401b429262b14112866fad6e802ad42fa2e509ddeb1ddc70d24e4eff5f7e94b4e9772cfb52b88d81272462087a446b770db1aeeddcf81cf9075b419acf4a3c3cc -TAG: a4b1933381318aee1af76925720ffbdb - -KEY: 5d44b6e557031ed28b60f3a9e73293d0 -NONCE: 3f57c9c636ff9336cee08635 -IN: 8c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de062de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b344a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83130f197a6f35def3e8e2c6598e6c0a8ee -AD: 6b0da01dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2 -CT: 68b1872409e4d6bcc2d218c7a844ec2a78969d25b766a5272ee09a3f0dfe20abba0ea4cf75437e4b759e8586be4defc5146b303b162c4209406c93884c06a163a5743fa6ebb8f649ad8de37194633d18fc4d0bbbb1c74e8297f48e1f532e5ef9ee7c15f07b2e96cfdbce6f583e267658a795ec9c4dcd9916d5dcc08fb5c28277e56dd366a26f92f9680930d63493e2995ce350e6286c2d597273b7ecdd27d2c05b725e32d6c48f7f577ed4098d318fb822cd6413437c44a9ec8feb54959a2e6403484a8aed34e0527cee6838844dc987d933af12b370cc888b6f6ff2a25754caefc1c665751321ab9b9f19bfc17e6903c99dd87fd502065a8ecfc1c29950dd0007ee2f9c3fc752cbe7e661f06ff22a266f564e351a7137a1b96616e31be24c7a13e62b04646ce0a68791e0e1a099b862435065cf7d3203fb32d7d7d8ac4a77642d69f7c27a46973b6bedd5e840f887209d19cbe50504c0a251056c8a83100092a627f73edb421a3f1aa12edfc78d3fc474cd2583808e38d63baf1c5b4b5cb34665e10d4af806bf3abbcf4432df6c9caa76cf0e17a5e0e9af7c8868daff22d84b7b6eb4f299b750ff18b9b17d7412ccafe3e55e5b02af9ad87c03799c2282a9c6377ba42e840440d8c1b19bcd1c8fc35f02fc505a3ce97562b9e660fd488b53c30edb98b91949188903ba2078193c2de05e61c9da7bc056624104471a8231b7fcfdfda4d804b8819888a2c9bde680bae59e438d89778c5a04dff214e9b14ac5b031c378c8beee5ba9b1f91dba760d7621c24c30aee28c4b49e183632d8b450ee6895a47b96cc3c1917af685905691d1ca588db5a21674391238d76ae101c3e83d94dfee4a0656baf4d6cf277e0c7b0512e4ec13d12a5af44c7d19820fe7a74f5d5875321d528976f35a5634e15dcb35a54836370569d5609de0360ea4d2f1937dcb2d68b20cc5a04c13c04d5379a7dcbcb6b711712d7b3b20d255156b7e61e99803a4d767f0438c4fcb166920744c20a08e48dcf5de4ec325439485b51e4c0f08cd22ecf60ace34b93844c2c12bc7b46a8f6b8dbf4de311f1039504a46d9616b41fd58388f458bdb8bb9821a33379cba4f36b416c2eae02f42b736c1cb6e673b9b9dbd230b6a23d944124469bbd2c545f5ab72fa4b3a47b4d0bb0271d615de6c7f182cc92165a84032f59c14f181c093b017a1c7e5887db249b5ea2db39faf7a3cfba08538b91520fc1f3af697c5f4dea7274cd86dc073920280b488a3f66969cfea020a312be1fd111c7847296ec5f5cc91f00188c07c05e4e49cd0667ee16345f794219ed3a80602cc11940aaf9a927805a040419abd20ad8ba0a05c7ca9936997549ed5a3c7e7d9f582c735a424895c5f1aed9a3a2ad3cf7d9f32d3e -TAG: aa69fb97b939fb73703ad4cec6c24fd6 - -KEY: 714f39851c1fe09297c8c69dff0e62be -NONCE: 3383bb6aceea0cbc71cc7783 -IN: cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a94494f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f4fe1fd1359a433240225 -AD: 1d90b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23 -CT: cc11a071e11cf36750fad572fdfefa377b8f0ed6cc47bb8015cb51f0eeb531e5779d233ed224022c5f7ff3181ad1d6a9f7564f41ee919f0435fe49b4266157a68061a1c5d06d8a8075b55efab8c9530266955c179f0a57684459835931cfb2eb1244a730797dcfcd31e7a414ed42990e9a55d439fbb803f2828f92cffb247f8d96896f9b37ce2d029aa15873bf13144cf35eb70d8e27a013513774ede1d37e4aa007a48a12f37385842cb716f60401f638efd2841db6165819eb3c2c58708d92a454344fa64c2d740cb34d4b7dbbc1d86d9e0083432e0e90c074b617402b68e3199d6fc43c454a842da725b49eabf8459b4db90e6553e17f979fc8d6bd03ac382f3a85eb40b64e21787e8e8170372eb0202fd4d78b39fb940829e11270bf6ccce0fb28adcfa8b60659e54a03c7b22491c62982e5673d66791bf6db75edf3836449e918b0c9059de644039063d78b66769d8358349acbaa7f1bef02fbfe49be375f652952f66665df26964b8b8b327683731cf825ad45118fb98f119db977828d96618a4a2fe82105eba7d1c3bca35775dc57a207b5b07c24305829d911bd7d30e3c19b030f6d34f6858593f3a0dbd928fca4b1ca21ce9ea8b63b149aa444bc696864fe2bdcbfdfca33a656db422cd007649d3a3e895b909fac7f9f0d9b15920b1d9dbcb343a2a0fd9382154430f818a9b347dda83e1c1038eb5259ca8714e2f8d3ec13c8c7a96c537fe599b30fe8780c82242f674817e815d56c92e765f3c67bb9591e27640d4880e04fc6afe5f1482422b0de4282df77df798ab7d32372f22dd3dfb0035182fdfd524dc315b0c7607639fcee3b1e12421025964a27bb5926f28c97cd7d74cdb26a779b656491f057eeb3be3eea0097b787ca5d1b1d5abf42fe76b16e565b2c1d15579e761efdcaf04fb18e7a97215e4dd53a164b336921390fed9c4fc1cd0cb0825d4b5c7061db0f4f1cdd950f13646c662bc6837ce2e455bee1758a59fec54d758eb49f040384f27ab6abfbeb7ec52a1a1b3ce63f6b4ded32a41a64b8cade579db95b7d90dcb875e83424d03e9f3bcc2dc45952860f1845632c7550802c957657c9342dc32c64c558944fbaf5f2b6a04b5d48794d140bf4f9de2fcdb1b77a0602f1c97fabb0f2b92b05b6894e665a8fad01dfb2764f673f61b9c6cae68272a5b12a9a8347782c69f5f9c3d4ff932cd713a1e2a49759114563d94261ebd7c0a723a5837a1912cbcc98b6481f6d7bebaf29276bbbd6d0a83bdefe2a0f3d4d60d88d4575e3cff73eba09aa290c2060434f85955597a3431c376f64489f50dd9d1be65b72158b1d6875649da95579b5c88e3d445c7bb95a4ed9452e18ef33bd7dbcd25c5ad6c769a651204e082026742b15b49554133e1539fc516089ce27940c89eb1a68846f13f3 -TAG: 26c14eb5587ec540185a067635e64c29 - -KEY: a406f8b8ee46d958d10d8724d90bb26e -NONCE: 2b38be1c0e8258de3a095418 -IN: 26486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43f62ac96f76e13ab5928147c5e63788bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ece22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6a4c6732e0887f40b5017de -AD: 54e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585f -CT: 4f90cb1e30d5c2c97f46ec00cd8203ca8dc808dc0e862cfdb35b1e92a24f0093fb6b68eea43f04ff1332f942b03aa2dcbe03aafd18b292cbec3cd66d7ab26af3f274a97e599f520a6bb59f5c56fbe858821eaecc297e0cca632addaa5aee071a6cf84910006f158cd1e8a38f185e95dd7f6ad09303636bb6356e400ae70338a8eeae7c22440babe6d9595b2ca008c2e7a471e70e66c49548bab632e87ed36894c6eb97c7de858382cb060277edc91e19b288870b2a472df769393accb07f34a8cd94922582ce351da199a8c5c426b2884bba07fe38da6289ee55537952d53ffced29cf053a9e1b9b37d2e0e3c219f48fe885410e6bf78fea15719f20091e654d44c786f9494e4a71b20f968bbab6f5305af7b8668867cae10eb93904a0e3ec3478fca8d6a231c9b4b84cfc3394716b366c0b1a1bbb8012a298e3a00831791e489b7a2dac6c26ca9e5ad4ab58c4cd71215cdfa2422f49a7b30698ece44972a6dc7dcf9ac40f241085599e71957bc719dc51555312fff4e963832017371980b5087d0f6373e5b52d66d7003525cabcd56bfcc00041bb9f0522a4dc86ecb444497b97d882d122dd8ca1806f1e0c8ed3b1b4810dcfee9b2803d08f43151f5a968c18266d0b956ce26005628780a1c4fe0e25b7dd55e6d4cb6b1427fc56afb278a8cf91d83b952908c295947a5cbfa183816a9fc4400db94a5990e53d99da1694de5941364e7828515544b1074de41c253a3b7bc4b72a3a0173138a025fe758f8d834c7c814f1440407cd1a98aaf15f7f8d5055aa8237c6d93beb53dc84cd4712d0535fd90c180a40ba6cf9880d5104480c18cd9734354c9321eb3ad583caa5eb05edcf288ca5793e288436c175e56c001b473c1486bf36f9d75d71461339f1e063035ded3246166644761816559ba9cc9c26f61f6d02adaa3b4b398fb80906ddbfca2fdfbe57df724adf1f76f995ef7d52468ee2f89785d59c0c8557ab45f07e0da644c0fa9b5a9e1a2280d34a0f65b463e53d09146bd629134b12262f18471eda27ebb5ace095864abe17b95f238c0823dbd11245d89c195eb9ee65f6f97819def971189e43354d4fd811fce3c430cbd4686e50e562ab1e8de214832db1a09a64f9339b8f6dcfd53280a33071e89616148914de8b456408fc18a9f46f61a782857b1e11dfb5f956a5889d60c53dc826ab92153cdad4d935ccd978516c383371352f63edb7211c3da54cf2eafb7ee65f6aa98aa7813de42ec43a4e3c91bc2eac8cbd27fd0a39f109dcc94365bb223f9be11120a9767cfc73e2c315846b675f5e1eabad4e7a970aada798993fb2b11248be37b451a6f8be3ab93dbb0b3a181c49f0b43b402f05221bc97a6c2b5ba9d1e5860a234cbd2c7dcac97ff395ea8ad34229c3b0624eef42f611f90449476d76e816fe391edb539f9adbccd9628dac1e8925 -TAG: d4c3aab4d275dca02cd7912eb71daca0 diff --git a/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt b/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt deleted file mode 100644 index 057b7587a0..0000000000 --- a/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt +++ /dev/null @@ -1,579 +0,0 @@ -# Test vectors from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: -AD: -CT: -TAG: 07f5f4169bbf55a8400cd47ea6fd400f - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0100000000000000 -AD: -CT: c2ef328e5c71c83b -TAG: 843122130f7364b761e0b97427e3df28 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 010000000000000000000000 -AD: -CT: 9aab2aeb3faa0a34aea8e2b1 -TAG: 8ca50da9ae6559e48fd10f6e5c9ca17e - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 01000000000000000000000000000000 -AD: -CT: 85a01b63025ba19b7fd3ddfc033b3e76 -TAG: c9eac6fa700942702e90862383c6c366 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0100000000000000000000000000000002000000000000000000000000000000 -AD: -CT: 4a6a9db4c8c6549201b9edb53006cba821ec9cf850948a7c86c68ac7539d027f -TAG: e819e63abcd020b006a976397632eb5d - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000 -AD: -CT: c00d121893a9fa603f48ccc1ca3c57ce7499245ea0046db16c53c7c66fe717e39cf6c748837b61f6ee3adcee17534ed5 -TAG: 790bc96880a99ba804bd12c0e6a22cc4 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000 -AD: -CT: c2d5160a1f8683834910acdafc41fbb1632d4a353e8b905ec9a5499ac34f96c7e1049eb080883891a4db8caaa1f99dd004d80487540735234e3744512c6f90ce -TAG: 112864c269fc0d9d88c61fa47e39aa08 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0200000000000000 -AD: 01 -CT: 1de22967237a8132 -TAG: 91213f267e3b452f02d01ae33e4ec854 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 020000000000000000000000 -AD: 01 -CT: 163d6f9cc1b346cd453a2e4c -TAG: c1a4a19ae800941ccdc57cc8413c277f - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000000000000000000000000000 -AD: 01 -CT: c91545823cc24f17dbb0e9e807d5ec17 -TAG: b292d28ff61189e8e49f3875ef91aff7 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0200000000000000000000000000000003000000000000000000000000000000 -AD: 01 -CT: 07dad364bfc2b9da89116d7bef6daaaf6f255510aa654f920ac81b94e8bad365 -TAG: aea1bad12702e1965604374aab96dbbc - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000 -AD: 01 -CT: c67a1f0f567a5198aa1fcc8e3f21314336f7f51ca8b1af61feac35a86416fa47fbca3b5f749cdf564527f2314f42fe25 -TAG: 03332742b228c647173616cfd44c54eb - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000 -AD: 01 -CT: 67fd45e126bfb9a79930c43aad2d36967d3f0e4d217c1e551f59727870beefc98cb933a8fce9de887b1e40799988db1fc3f91880ed405b2dd298318858467c89 -TAG: 5bde0285037c5de81e5b570a049b62a0 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 02000000 -AD: 010000000000000000000000 -CT: 22b3f4cd -TAG: 1835e517741dfddccfa07fa4661b74cf - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 0300000000000000000000000000000004000000 -AD: 010000000000000000000000000000000200 -CT: 43dd0163cdb48f9fe3212bf61b201976067f342b -TAG: b879ad976d8242acc188ab59cabfe307 - -KEY: 0100000000000000000000000000000000000000000000000000000000000000 -NONCE: 030000000000000000000000 -IN: 030000000000000000000000000000000400 -AD: 0100000000000000000000000000000002000000 -CT: 462401724b5ce6588d5a54aae5375513a075 -TAG: cfcdf5042112aa29685c912fc2056543 - -# Random vectors generated by the reference code. - -KEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200 -NONCE: e0eaf5284d884a0e77d31646 -IN: -AD: -CT: -TAG: 169fbb2fbf389a995f6390af22228a62 - -KEY: bae8e37fc83441b16034566b7a806c46bb91c3c5aedb64a6c590bc84d1a5e269 -NONCE: e4b47801afc0577e34699b9e -IN: 671fdd4fbdc66f146545fc880c94a95198 -AD: 874296d5cc1fd16132 -CT: 9209cfae7372e0a3ec2e5d072d5e26b7b9 -TAG: f3acb73908e54cddf7be1864914e13cf - -KEY: 0b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f195495860f04 -NONCE: 6787f3ea22c127aaf195d189 -IN: 4728b3fed1473c528b8426a582995929a1499e9ad8780c8d63d0ab4149c09f572c61 -AD: 4b4745914474e7c7c9882e5386fd9f92ec48 -CT: 8ad7deb4be91cdc4e75c77de1c746d816212b109c5a485c6cb79e3005d2e94355104 -TAG: d71002b6a9de0addb173f49e34edab61 - -KEY: 9c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f61455 -NONCE: bfac8308a2d40d8c84511780 -IN: 82355c9e940fea2f582950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0abde3b2f204d1e9f8b06bc47f9745b3d1ae -AD: 06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb -CT: ced477a00135f16006e100b9d7521f9e1bddbc7d339cc41333abe3cc79dd8e3a18e310dd1dd53ac664673ab9090d5dc07b4859 -TAG: fdfb01ef873060efc7c3c32adf3b46cc - -KEY: 6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f -NONCE: f901cfe8a69615a93fdf7a98 -IN: cad481796245709fb18853f68d833640e42a3c02c25b64869e146d7b233987bddfc240871d7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296 -AD: fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de1 -CT: 01fcded8e89997d446236c8e3a77ba755b85b9b5ab8fa8f355be587a3954c4a4231a7c8c198b72525ce4304125a4dabd1574453437f6584790d8cd90d5957b0d5c804a6e -TAG: ecb5e6b6e75d241c221a2f4dbd7d0448 - -KEY: 92eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e5 -NONCE: 5540db1872504e1cced532ce -IN: 4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e72834321f7aa0f70b7282b4f33df23f167541ac15c8417abaf17a282ac7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2 -AD: aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b469b0901f2b5da3a956a6e278c940e -CT: c49082d9a1bb49356f1a9b75b443832a56387066b617b939b60381db47711bfd174324e8d20c9713d562fb8f5c698dab02b5c00ecb652c182ac5544648599fd7fdd042009ed44961efd975972ae3c9aed8a4f58ddb -TAG: 75639e5472bec58e96b358cbe429c4ac - -KEY: 82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27f -NONCE: f1dea3b2a7d832ed8ab959d8 -IN: 2ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafadf0f484fae982019a8ea22efd1358adf7ad4f5fa0d2acd2f1ee095cdfc13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8 -AD: ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f -CT: 6841f9ffed11d165b18917ed0aeed507bfdbea3a57beac2f2e08625e9929d3f2d84373ac3b21813f7dde1b25c93129b541fc640e09f5233cd9f0587edad70b73c423011cccae55a9deff9f29308fbdfc9a73f5fff4a7b0ad308ca9b545223adcf724d3d8b127 -TAG: 479bf5015121d25bf2346429a5c569b4 - -KEY: 2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0a -NONCE: db4c74b73839e13455fd91dd -IN: f7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119ae0c8a20b679dc40c9908f88fecfafd688b0ebec6a2ac13421012874c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b -AD: 8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436 -CT: 97d729cde56ec1f95bfbc16ca5dec6a208543c3255f7a2b97fbf5fcbbb34908ace9ce13bd9e90474ed620715a5e9e43c34802b85feebc4d4a23d1bc8b4b5a6c11da7158765c40d2c863185c5551cb2b10eb0b45c61b939f8274ad84fe0a74e163bfd6afc5759946362adc74b4a7f705827323f8291ec38 -TAG: ea1c9094241c5b75ea880723ccb17ca7 - -KEY: 006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b -NONCE: 9d0f8621664df31eb95b5e17 -IN: 567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361c91452e7d463338474a400ef9efcaa648e93f38f8784a1598bca461211195d7844de56b91cccc96d89e6471bca6b7374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34 -AD: aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e -CT: 85f7411a7f8ab505a7c10c5c1fb9bdabcd9a7826465de96e3b7c762830ce133b33d8956756ec29c00b429d30047040043cd5b3bd87dff60e09e4d7c3a95bcbfa2603ac964be32a82250741e19b6786638be28709ddeae496cba7558b7acbc5545b259e6a1b2ac1f5135f5719987dc547f97f68ffb7b9eac892527a4bf0ffbf59f77327ee763c54d6 -TAG: 3a8cb8fdab2c79aceaef6680daaf3ecc - -KEY: 78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc -NONCE: 2d2c51dc426b38c308cc5748 -IN: 39129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e7659b17f09c56d170ed1ef10d2fadf01e0c78473d06a1685ef0bb112e4ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e -AD: 746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f594 -CT: 142722bf554b8c70e8e76e52b9c0e0bb19b618f7bbc7ffbc91a66031f418d031d3c111eddb9f1ff7c2e64191be8dad4f8cd175079d2ada20c8880d0565c56afe5c9742753cbd50b93620b081f0877f045d0be91ff05a603fdc87e1940ac1e1f0c9aa96d5aaf4a58e0393ced4fad8e83171fa71c397817cd48ce6991e3b73d3356ef0448be1bd8114feff5f23db3b9cacdcfb4d25fd4dbfcae7 -TAG: e489f6c52120c8cfdc0f164b3440de99 - -KEY: 5c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b -NONCE: 1a8a8b1f4ab85be5a4a089f0 -IN: ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26995577faa109071bee1c87d5e6772ca55fdec02348a625b49c3c881aab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982 -AD: f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f -CT: d8355d51bcd69356ec74b9b8657cec57335731cebfe83202c1557fd208480a2c25747625bcc70533d1ef75d2bfbeb9354066a8650f59a575e836339dd45d0d8a5cac221954b77cabba5e95da7437665fe9b48257148b7e8a88cb2cc4e0912f511aba0a013aaaf09255ec13b27cd9cd05ea11fe2ff21c9ab8a3fe86090dfe13166b172ba08e76d30ad48bef0e2325da08835ecc468cc40222db0552834ae94458366f28f6ba63b3e656bf -TAG: 0c7f16d3294d5ef185c2d06ed719ed8d - -KEY: 322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e -NONCE: 5f2eea2c79702dec4cfbee3d -IN: 1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e58ebf03ce7ed2f8d5487936311922884bfd31cf828f3d0ce78f3c6981932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75e -AD: ab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64 -CT: e8d083e25f9332d30bfe60ac071f502909b26393440a848d1f81c3f5fd521de98cd9ad1fc3e806724f5b3732582853cf280f1b99cffdc6b46874d42adb8784cf9ab8e158531b4dbbd76391d48727b585fca0610777fa8ec6a2a7f070627f1ed254e430e55472622289f44089ff22f02b7f3c5e45e228b7b03a5d1e1abdc18b154124f8cdd3b2229e4720cbc1bd3cc3f86f3a6a745de0bffa2536027ee03d447b306ae69b1232e964ca27a6d252c1582422c99373ca2b9541a27081 -TAG: f6b8a72d4235589f7811ee1c6f8d2167 - -KEY: b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5 -NONCE: 322e47a85cc58e753f00d6f0 -IN: d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6b86fc55f4abb9b65ee1897c262533cccd118b0f493c849a7aa7f35d243f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db06 -AD: 7856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019 -CT: 00d34f899f0a8b40fdfe9fcec98a96c5995b4524b144545026aaa55f629c3befbb8ff794b726e759e18b7198bb2fd2a866379418e6dc4f9fa9e4edc84d21454a5cd212f68a7df321b18e9eb2c537e0cf2e0bf65e80218b841ae8a994ea3f6832d667430dc314567267d7f31519fd856d73eaa1d3bfca419abc5001b25cc1fdf860812b077fda4b01abbe8f8a81a16ad2ab5d9299ea9a0d81aa26e1a573504d5fbdf29e6b2098ce975f2f3c8c212939569c8ea8ed63c4847f2d0fd16f47bcb30bd7e00956ab8a9deddc54e009 -TAG: 6152a0401a33257c8148e65440601d5c - -KEY: a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e829 -NONCE: 11e842e5c9ae8fb79becf42c -IN: 3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763edaf7d79c1b83d973f9ba3b29a9b9408418f73743ff0546f0d9290010cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a0 -AD: 28d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64a -CT: 11bd92445b4e43dca339491c8100cf933795ef7cf4c3c4d6c42ae5b729ca22869d443505fbb49ccd29b44046569da104f7ddaf325e71e7f30487e83acd012bd492cb4e98342ac7d64843eb499744b3d17db402d51b5bf8cbcb8995fad4a81dad4221ca30ceb3590df41e124c327fd31aa53c86514a12e22c477489871bfeb38cf71cb3a959f4167402576f142bd88b1221281a94661c8d643f89fc92dffef322ce97f8c19b133e55f8020232dbdf42e4527d9f133b8a5934bf0a2df3754d6455a9d765182691ab94ec7a2e68f3ff59805c7457428ee4af8388f91e88b3 -TAG: 8f1bd0ef9d08299f494054ab9409f663 - -KEY: d6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a -NONCE: 7f567087a5fec5ad1ee3e4be -IN: 5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c461b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad01dadfe4cc0681384b489f38d25e83c2c563485fb361f81d44aea205e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667 -AD: b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2c -CT: ddc900dd582d322c567e3fd7eb23069b9e559bb16639cc79ffc6f3deb6e92cbf71ee66c839b4115e883390646245a42480ae6c638fe7fa04b575b4a8341050e2f3de075f2f19ad9b24d9cc1c39a659b0ffc362d46354da6bee0e41319221cf7cb160017d589413e5c1f07e5f626c2a1f8ae9e8b9ba0320a2de9e1b5f7baa4d551c090521d8ee0b30c8c709fbc00f1fdce999f1f96883e3b83b363cc47665e5a21fcf25afb6aa2bbcd0a374618c3dd8b8f97f21037946dde9bfdc7e907ac39e64f1a5ec8dda60a47148bd066f907a25b9caeb3804c0423836a8d9c35bc58c57882c5b23e00c7f4e3b1743cb14f102 -TAG: 8ac7e104a0165df543c7454223a01f90 - -KEY: c7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86 -NONCE: a2ba1e9cd195a8ecadd31587 -IN: 0d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a34091633f4aaf225aa02ba9c57b910a76535f0cba67fbab0e6fa0bc876217fc9a546a97dabc9be41209bdb582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8 -AD: 729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b590a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b5 -CT: d0e58d936c8b83c253ae9bd29f45afaaba9712647b3da6c6ffd40a9390a4476a0e74a2f2d458c88056bcc0a57fb64597a7c8a5e2be39669dec53c6bf0f7b4a2bacaff9aef36b43fe37b80cccc7d42cc283ba1c1eca739167c07754edec14375d86e88668b156d04c989bcf3fdc70e8a25aa3e6052d6befe3072ec0993d6b520c722dda62b6879324eb4ae016e54d139d816be7fb1bf9c0168d8f7225bc8ed9b7509b45cdb2c8a1db4b3619120c824d0bad7deb7fd0dfdb3674ab15a712f6196a5a840ee8895670cf3b20b8a5e43caa41c5524bf47c2ed4ae7027c2b566dc3e2548244057b880da2a3f1abe5e4eff090f9358970da6568bdb5f8288f9d25829 -TAG: 057ab8d811b5c3819781752230badd5c - -KEY: 7817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021b9948afd -NONCE: 8818888585a6957eb59680a5 -IN: 5a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076d829975798d4f24ad243e4aad474fd5e59e25a6dd133944918709e33f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f51 -AD: 0e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e -CT: 5eb6120cae6df4766b40ffb4d204ade5ae08aa2cda263b39ec7b47756ed7e6b7837fdcde8d01a2bf01367e9398e25991f9da11bc9f8de8e6c1b4e922af05d20d683edb4a245e22eb6cc4fec2375e8d81f9f27af5f118a16fde654b4ceabe770fb3a00bc7a88763b670b5e3a6ca06aea1824e20b9c1a304c4bdb62643fea73030ef6d18ee2e22095b4c73abc51abc4883f2bcce14033608ff7e1ce72ab3382c29069eb75426d283a4a71348123be19f480dba1d1677055de9e82d683c2d6413a6a4e0c6d58f7f2188ca5c8b916aa49975b80630d27a89ac284b971478376ad6e55dc64098951bec2ca7d77ebe790b1ed7fe7f33fe571d8613f143e3d3ab6bc613 -TAG: 6f3f79c6231d7e45ebc1ccbe5d110a0b - -KEY: 4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531ce0e62 -NONCE: 19f75c4c31873d4915b1af3a -IN: 51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3ce9e41d154c4c1bca018bbc4d744655af04ee2cd524db41170f0946df225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49 -AD: bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f -CT: 27bf7ffbf2c9733c3da8947db11ac8801475451b0a65c96a2a3934bf45ff54fd5fb21ff0d51c83ddf0f49b005d424620b04d0c731cb214f4beb6d353a6d6b7bf1a706b070faf5146b562c9f4e6c0ba5dc9ef9ccde79cd162bcdd887dc02bc95e29dd606d22845f35d0cd6d5eb1f1b154607c0c5c2e8c7dac005eeb17c238e3d4d1e1caab72b20a9d7b2676e6491eb84e9cab903bb0c05751a33642e145de8391ca9e598ffe2e579486ce32d5d76a35d440836ede088267e8cecf4b660fc5eaf05f68872b6cd9427607b146e15fae406ae7089ae446cc2172b8ac9e42cbc27d4e5ee38c21d3fd6d4d52b2d43462756d93995b9333a079dc1f2bea9ac4248c448d932c5c0f6b76da4698d15a64f761a7380b -TAG: 7efb02056e18e98960cc5718edd07cb2 - -KEY: 1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c7bc7 -NONCE: b15c68437005a4973a068187 -IN: 38adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a497b1fdb1a720b9510d7d8819b6d946dd85c73be515c6ec00a10a69661c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361 -AD: abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a -CT: 92aa5661d04af60245f6f56153cd86c6a61d5584473979eef596d6d0c205db9e4d928ba4827dbb08d5b34946b8f3e58ff62a976461ea5639fe2ee79839f99f83cde00e3fa3258e21754fa91a17e0d1fa22cc76fbce0bebb7adad09f99bd12e70e519048d96c1f97a183d8ae66445e63a4a1f936821fa7b58f569a16e25a0d0b202231a79eca0e8a2ed21755f496d8b7a9f59f6bfcf47ee4bf35788935cfb1b5ec2af2ce11c002b2843090e2267d5fc5e26f927e8836d6a97dea2a7e508f82a4cb7df375110217f88f4376782626039af166b080e181d8a310ea7fbb4fb11d5b24367f63ae83475269281aa09b7bd259a348fca28f2e1d7938127c888c68bad2608f89a2440add0c644de2b5f08d3477641675cdb428393758317c273536942caad42 -TAG: 4a43c15d469378383e9a9a26dca7083a - -KEY: 03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d207 -NONCE: 8f1c67d44d6e86eff0c96a14 -IN: 6bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d50109c383071e4a61ce18f495d98b6c4bcffd0fc2496b7eb0ba612e2a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820 -AD: a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474 -CT: d64a6980718a5fe833da2e6c1a119f2f16a5bf3cc5089168520603d37998d5fab07a9e18ebdc0b8417cb6a4d34357f8d598753affd51e93b451269dc24354d197885ce9a3b2f575fdc9c572b05bd7bc8df091a6675185ac15bd1c4f2cc0a8a412ff72baa6fbe95065bf2111910f4f004f6c39cd8e7ff5bab5f86abdb231406763233354734807fe0346ff6ad23a1c9c81b9942b370e02bd79eacf703ebcd53a54a5782f13ad3591801d1ece15c6deb56bb5e32d959ed1363875c57cd9d42881dc1799e652bd554059ce059a9d00a126de35f0285d5d82bfdc383b1b37d77cc1180184b2180aa35d46f816fcf125c9e8e3bbdd67c8770da26b89c7e406f02ec515edca3910de72fc76ddad8344ae36fec1d72315e1a568ee69a08154696e4545ec5ca53b3c0f5ec9cfe82792380c1b9a151a8d6 -TAG: a258557d32e1924b3eafceb7b73e43d2 - -KEY: f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18 -NONCE: b4c98f6d51fee205805a50c1 -IN: 63beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf670cd4d988845b1d41cfeeb1ea740db129c12f66a74e6234ebccf4df706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221 -AD: e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048 -CT: 2ac34bf9d0d909a32322cbfb765875297c50110ad859857c641ffba8efd60ca003b8f32d157b6fd8fcfb1c6037b13285be884ae2dbcbc9194e8757560807a14b2219b9f2dac11af7dbbb2f504e3d8ad47ff73657a4d1283c78bcd410acc1399a529f239440db4b72a48bb3ed984565d180015fa7ca9c0ff0281a2e14807cb90631c75506585c18cefa5cba7e0c943e44e85f60d47927339e3685c1fbf1bf497684a6075e0984ddce22e9c130d3cae99ab35394c315bf8e1040a830344c63d3719cd250ce04d818df0e20650f66613439c0c5153b2fad41e10b296e6fb0feb8977532079ceba9361227f69005c9e696f9b04d724074f4aae59dca55c74e87049c8f6bf1b8642e7c4dc73688260c540be50e8d4997d4b68346a0ea7749747dc72e26ac3bff58802cd60e63b3d8c509d0ce0d9886c50ae7f3a1621a077db155ceceba926919 -TAG: 67a891187fe42bd1bc7a6037513760a2 - -KEY: 362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a -NONCE: 2efffbc936ddfedc527b2c9c -IN: b69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0fc5b726bbc23a67015c35a1be5dd125af812b7661106827f31a1e4c7e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bb -AD: b55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6 -CT: ae05b44cd3cd86c828e53930c4a80e01c59a8c1c9ff4b327122cfd325cc4ea0ef4f70e3ac48ede66f4ba7fae9024dd5d78dba260d06f8888aa236e7de50f57ef48ee4b553d42b41ccb8716c59f69f30afad97778f3e48df1d5a57aab3d471fd5079633b3972e2703a86c4e24d0a035b3625a5c7380b963496f9439542b15f4013002445fba9a9f4e9f1a15c5a6bd2894c0f540d264481bd3fb6b8b63d503866edf178d8d6cf007f9c6337bfd900f5c4712d82049a2f82e43fba589a372d44f57c3d260df6f5393d3b182eecdb503e4e35018667e91c4d4362122de3d88971691e7ed05ba7341cb9cd39cc12e12ea114abb6f7cf1bdb9906d3086147a1c22c67a74fb712ba6aba1ae12167a9d77a4e5fc0c19312d20080cb2d39a3a9a8cef7cd286739d5387e1728a2c8450ccca03d0c89332120555f97652d122192374bb4e05bc5839c4c2761de9e2f732a803171a97445f3d70fd -TAG: 7e339b51b4e6395ea01ddd2272e5b185 - -KEY: f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a -NONCE: 3d5bdc41779816b352803f28 -IN: 2410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755e63611c19ca5deb1db80f97a3f5149a8ad2cd6491caceee3e19782e66354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cb -AD: c3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc -CT: 98ce773c72c6d7d40fb8aaafcda02ed688644ac8e9ac868315cfd9db521870b40ef9decb01673aaae0c8f6403f61389c9454784f007bde6a50c3c69cce30efa5d851cde2f019bc9a9bebb79c19b29304ed908db6e45445ca7f785433abfdca7c553e8f6aa4e6670e839b5a9204648fdad4a35c0a6e44151afeff135e7e080626854e68c0afb5bc6be9aeff91d71b33d294ff1c04fda6291ef535972f3020ec70cd31b156a1468c105655561d8755a4a88c380f6c56ec1e1f49c2670454f1493262a753da4d40343b04f91aaa3e69fa4abdc625869f72839623ed8764692c23e1131f6567a1936cb43c238e0dcc2aa093a728fadd5b0e7d04505b9fedb9212218f1b5452183e8cfb366e7583dedc590f16d713948a85bc4462134eff25eb9703b34b5bdbdc63299575cb0e076f3cc7afe35ff3021658d83b526f7b8018cec38d3da93a0ed388ade0941c740da975dc433b74b1b528ff92bf5484149166f97b44e81d083bc40e5 -TAG: fb61d2ad676a0e8961aa9f00a164f294 - -KEY: 5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6 -NONCE: d70275fa9f177cd36c990d4b -IN: 22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50ebd7d9a251a127a4dd736d0f74e68755c4226110c276cb7870cf1c7b86617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433 -AD: bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5 -CT: e919008704bfbe7657974c9e499a3cbcedaee7b813752ddf49a69cfe3ef39a8d6e1ffb1f3bee7065e8b74b28b25b5054d9a0e86ba50d9e6aa4babd075dac7b7a8a0141f0adf9c274eebbd381a3a5f89c287019db217f5b644862319f799ec3f1ffe71e26c1b501eaa56c97a0d679f2c85158531ea41080b4c690ebf7a02ec2016ba260dd6c5fe1cc5084c94ddfb2b897cf597ff36adc11957ee4e4e3f7f7fee3b15df6930ee9bd7a1c1d6a74316194cc4b9e2483acb675def10dbdafc7093c18f46ee3ae155a385a2bf4dfd33db9eb33202d82070cbbf9df7bd6e679f2ef866eb37654c82669434b25764ab8ecf1cbab63ba7b1fdbd5e53bf24f679e321708cae599664a4e5585723df96638bbccc0db568ca8aac82c072e6548cfca1fd978ee1d732f46c6723340625d3a5ae89cb098a35a5ddfea382f1efc3c4b0528af42007c47c76e9baba69833e0219baaf4448308e9bb1eef5512ea41b8c774cbd044b2cd69c6f1c13fa6ae950e48d14cd05d8c5a97cfe4334f7f -TAG: ed970cb4c8e9493e2b5b16c99aa6932f - -KEY: e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948 -NONCE: e63eabbdd2f357cff8c172e6 -IN: 652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a9871bd6158a17dbba101f840c6638ca0589434c5b842d5dc501c7741142982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d520599 -AD: 5c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d50599a3b2bbea36250ace162989e3c21249115a402c544aa82 -CT: 5fb2516faf226ba7767500f7bb3fbb0750b535b2e4e61f4b1a8f8ac58fd0bfc20d6c83b6d646de135d151ca50d10b7816bc0086e0e45021b3e5ef2560be8a8dd5efad693a7a15192614e2c977d9c7c21792c8226d89171b3020dec505a38162ecd1fb3dbffede31ec80875b5a5c84038fa33895e9f10242885a6a59fe07be083c7d7f904ca636f1d8d812e33d3776fc705d5a658984544a6554176b2cacb0aeca55d3c53cb065769e8bd13096aa7bc86ff923a856d9b6dca7146efc39ab1eb41a3f84bc3240ca7b4882ff937bbb21f3242e98bbc6858a1aaa21f5a603dffaf680d21c9c32e383d4a56c6cbda51dda0db76498c2d3e8dd746662c804f968476f5600c4dc32a2bbd966659b097679a9d604e93b0a0de11935a9945b92821f985a25d065242fa120048d4760d58acf930ad57091bcbca236fcfa1bc6cd5f84dc7d19197a2c349138679a6bb13727a207c46bf733a3a86e52907886cbf6bfccf82fda3dad1b94ae819bdd847f5860b9e9711fb7de0d50868ddf792b3383efb1a2002ac57648af7bcd48b -TAG: 2205942e6c43fcc24e7a8e0e80c3d494 - -KEY: c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd12 -NONCE: 6cc8d0d26816561102778d04 -IN: ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72bb5e6c7b672e7c5d720c2035dfe8d42edaa56f54bd2dab11ce5ebc2f95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea -AD: 51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c85 -CT: d02e8bb096fe307bfb5d5f359e8895f775c126e43289fd30f631559a2edf6d5000974faac0b24b7aec5e6633f862009c0f3e17aeed6fc86154a365a99200d5855a39743f219cccfeaa317b7c9866831e2f61ac7a9553e6b6ab5e5c16ef2711cb0ea9a46a483c057316e4c82b62a895e6d4ed5dd9d3d43576443ffc769630f93b37cef9fe9a79dea94b84ffd991e4429ae6de76fa6d6a9f65479842070271cde06c6e49d21acf98f4ea3e2c28eb67275446e3bcd797bd610cb9aa302430993ef3453c4ae6133f66f766cefbfa5c566bcd43a357fbc502819224352ec68c6da3d596935dfd0dc79655373a588ba08beb1ae21cf222a00e53495946f9ffa7a3edc6dc20559b401c2c5a35ff461bc12bf656b7ab86bb63fd72e7828f3915156a93c4718eb5164e359ae22086f43bb1ac868ab6a3d0631baf4ecb8688a48fa802571606ddc8215af784b04f6823439f0d5cc409c1622ae2a586fe413e4492eae627eee9578e5ef9c891a23341561a9c0f342d824a0347eaae52da91827f55269ffda3ec959613cfe9fbe022f7a8f8f8ba2dd39833ffba261746cca9 -TAG: 7380475e9d2ff3d9df01b6c895d00dbd - -KEY: 7a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6 -NONCE: f584f4ab378a3dc7d6102a17 -IN: 877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c6797b507a2e09cbf5c31f7be6dffc78d883f607f0ec3ddbaaae6b087e8731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96 -AD: bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309b -CT: 7a0f153b5f7976c608206d8791dce0f90cebdc0250b484d7e4669334e8f034165bf4a794dfb989206217c13d4de15e75e7e01a24d2c988212adca2056fa7bdf33a1ff69f6ffff29b78d1560ec21cb4cc96deb9b41437dfe044600724d8ea124f741a5605233143e54d8a58f68d5a7900ed57b734c61d264e71eee4477ffe4d833756c3f65c64ae8fd832296f61a2a7dae5a8cc2c7b3f0cb87900c8c1d885d42420e2a65c414bff138594d00250e8dc451ea319893fdd63f55cad85f9f76ab9806e687fa5e2c1096f13a09ca7febd28cdafc7d0a0592865e568a58b3622876aabdc9a0c0f7924c3173aa0b218e28ad98384ebf5baf7448f316ffd82c5d7b7a51125e65aa78291a342dd30d767e19fb996e961c78d171263e0bc8529c2e3ec6d9430454705a05bd841237a68dc4b7b3039bb3a0a1c22213c9fe6c11d41d39d3cfece07527e0ebacb593add061207c5b1fd221bce69cb5121050f805e2c759423c97a5952962f625c528ff8c11f6550d435d7fbaeffe4155d266f9d0e138ae25cae2030e31fceef9e39666da4fb7e196ab3859532bdcfc10f7ecbcbb8863e7a0c005e9bd7fd9f52dfe03c94 -TAG: d6de820a9b85168257da829272d6271b - -KEY: bcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe -NONCE: 16670d77b089880c962e558f -IN: a573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894f46e56f5394bacb222b30fcb3f5d55476fc37c122d6865751212d4f57651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c -AD: 74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a -CT: e62cb3363816bdbd4153221411b5599b453820d675b5824ea1ef57c2a1bee7563a092976ce33c918a33c67e4628d5661acf2ea7e353bd4cce6a87557593e0ebcece6510b63b9a4a2d2c055e28b464a752b919c593623ee4c2a6bbc2b2a95f884513e446b10e2f0ea6ec98c10d893088084f7519f912afa35a693bd312335cbe2a95e4bb4cff6dfb6c2b632ef01b48d102f244bd0df83d54cda5060a01f3c3c3c8b4dd7077d0f3eeb89cddcddd23ed391697996bfa741dda4462efd006be7bf15c3b2d63aadc3cdcd862e3d09d0ca675e397055307fca30641f62fdba74ccef65682701b9551814139f4ee4eaba2f1739966925b56cbd6c3b16e94980484d32f51a216e17f07deaf70694745829564e486f53bf5cdd38ee660be09a8860be35873f14ce269adc17ce7c2ceb7941810b978a0db7e7d472f23e8ee80c9faef243cafd019d689aafaf0dab91e4b7afd5808f30753b46061057f302b8ca383c6dd7fb35b3282ffcc98487c9616a451386c1204d75337b28390e9968b24800c5a66449831da8ea3bf3aeacf2e6608b96c3291752cd049b168b1ed1f812a6f4901f30363a09b90b4b7f8af22468708c550cf77c30ca4385441d3c74e5f78c -TAG: dfa7cc77acedf8de5a7a0375472f3c07 - -KEY: 3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6a -NONCE: ddae1c3199da88778d920a6c -IN: 79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f4675ade296a8c507fba35f62c82d923051fa718d52a0279ba997149032b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd8 -AD: 23d72dea41a1c1f1611fbab63d339a8dd47a3a31b7790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205c -CT: 44234f12f5df525e7f45d785a5503ef1a78398d9e756eec0b97c426af4661471c57baba5b76a19da18984c8824b0e6573ed324758918543618ece2163e969b07fdb6c1a65164e09f1382653b5cc4823deba6ba403046860421529013e79c703e2b467fc15e4a39b5e9caf9f521a0428b1e68fa51b60492cb6c021bab35107c452c94747b59034da681b1f253d594494983df44e7b394e3c9fa190802fef8fb178a2828ea7ef2aa41cd56779036565da68642da9456079fd3bc8718b218725f657db994a19a0a01ebc51f7bb1dea2c7d476417876a7ccf8b517b968b2243e327eb6288f02858c3d679e599c2d603c80b33fc3603f689b91ce117a8481074f11540f6d75c2bbb5d3c8a3a9d7b5699acef00ce981d6c5fda7a8fcf5ea77a365873d185de9f302be3ccc4567b98b74cb695a323cc6ac162a06556f8c0a9b218407a909d7b173b2f1ad4a497fec9f8ffbb2436a4101f57746cdc24ceeb234fd8dc6f04e488227d4a2a42142bb6122b1b59087dc902e8d11e81852aae897227dbcfe872b537e57849d51968d1aa2dcaa63d6de8faeeb5753cfd8af808c69a2a7e831b34ad8e78c97b6a162401cb85247e9d89bcd593242e8c93f9378c1880a4b3c45aa434a5f6d16182035dea99a4c -TAG: f53384a5ef6edc2cbcfda00cb7456d78 - -KEY: d0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d -NONCE: 5465e4e10e9cedaa39db35fd -IN: d7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726e198729362ba96f79d5e0d89fc404b3836737445756c6060d9e95d1638a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3ed -AD: dd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe8 -CT: 90ccaad48bdd13c3df79d9679465dd0d794b0a0ce4ded4add7f3e2952bf8593c295d17fc43b4c44e56971e0fdb116bae0e7e3203bd02647e8feddbee667ca469ba3b0351a968d746ffe033a60a26b12b525d280353605b71f46cfe3758d9efee4fbb8333945dd794eedca6279fcf5a31003cbce29d748e39ff654bbdf1bed5e7516212dd1ac27e0ac5a121bb5f95c124dc92520b25b8de80874d5d230214c30a8a17196fd23fd91b00e64bb0fb78ea22f15363bc532549252e0f2fc90944ceef75f7c320e3ec75fd148cd130cdf48f88f85cfacde2b6b80ec0f45d0defa941fa89350429da61aea18d25a2d9dd156197dedbc7f736208390274143f63a4f8d2f1dc557c544e364dd3923e54eb79cada64c69c7deffd3ad75f8660b90ea15a2a818d6c5f0d6bd43519eec6cd43618c35b468e10d17b79865e591a0bf1324941a5066c7d1c12dadb77d4993685ac8dcbd2c284f62273888c453808ef40c5d09b054f8459a43c0fbf5c714e8c7b8985ea932ace7a79987b0a9be926335b87d37bc182400a38a847362b3e74b08a952c8c64ca72f1b79d6e0b52cfbe28012c1aa424da95c5a2e8b8c49dc2f305cef00e50b92d320cbec992ca1656848860e0bd790bac5298b7a09b7586c866fed3dcb53afd2f7b313272f1c4b458e1b1bee6 -TAG: 1139d5d9f7e52a51d258d95a9a51b5a3 - -KEY: 5940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37 -NONCE: 597c9a73eb47abcd2aec1b2a -IN: 8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee8716382167ee6f77730766fe8b4ca6c8f0270896bcf14cca5d7c2184dc6eef47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27 -AD: b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38 -CT: af56537eae418deb9f7da2500111c077ca99da5e835705385924845547a592cd3910dd419e6fa4b9b2d7c21d42ce2797873a494a735cfbb4277143dd25592a1f70ad8d29a42b55f697807994a1c0338543bb56543609e052e52e1b7ac473ce717711fd7ce4c269291764c11615637b29bee0a8001ce82003ac91f410153fed863f7aa1071a76b5583852f6e8bb7b565eac8042e0ed76704ddcb2c03504b9c79b1e66c179a9e91d2cd890380421d84e05a70e05c4aae13fa600e57a78d7668e94f87d7bef00b055118480e4944131a39c7b6066161a3815137a3b0e89cc0db03775507b4d3325ee4449946b33892e064954294c6ce83c97fbd7f11f203fd1af49a478cd3eed3cca766ca3b9d3402dcaa4ab9729f209ad46daf17a584d6187659b039176deb9e08a0cc78db16e4122dc5f81ae4f5ee23a7140d2041cc81c8c43568fdd45c9ce4aaefdf7bf2f650f478f7581202b548164c4c160d3e2d5762569341170304e965e09474130e397bda5326b2aa07067a4fc8275a1cbcc43777414185b243ff67f8947b16db687a5b15bd5f685ce250be6ff21355ada2e125b64b57d57b94d6461ed19e77bba9234ba891d8da2008493a07d4f8c76e71973bb9ef87eb048c453cf66bce0e820966d9f62d39deb43c7a2c25335184e0e5ddc1b191138e71b155d39271becbdf097bdfaf1 -TAG: febaae3a1e94e47bf92a1171c91aff8e - -KEY: 888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc -NONCE: 95fc19c449bfc10443c5c163 -IN: 88d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f471b63e84a8114f73f918aba186239947bbbe2973181d9b48e801e3a5597b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b68d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae17 -AD: 0e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72 -CT: fcc54b58b1330cc5e87305ad574eb3ddc760f12a0dbc5075d8b7e825cb52237f48845a1099527fcd5e483f2d99a06a413eaaab04e641bf7ee3e6f08575658da3e48af76b849ca68443b61f260118bf7730d9a4b965c4d55d391c66c87ac9a065f32e784758be031f9f24901737da41fb0b800e61c5d3e75024ce3cbc03c9b0a318b90821623cb50e487fc15ffe6e3b1ba69b98ab10564bb72f868faa2e4f446e5331065f36d30942022038d11dd040d872aecd22163affa37003302cee8da8b02fc1ece3c3b6a29bc515609faaa460032a09adc496bbcc70ae7d35b78c8f97f4b5a55b9fc03a00561bdbdf883edac8761a8c31275c4833ca06a212dcc4fdabaa022c7e7daaaa7435b5c7014fa3866bb77890ef0955afb267417706ccaf3ccd9e633ed9892fb5049600597e9b85f73f7fb065bcc748237f33a0c300298dc4cf37781fe632adac9fdc0f3388d315a1816f315c96b8d75c7143795f56e0e51f09443396dd7e291828cdb0bb70125e90211c68530f33e0b2ef8bceb42905b908fb3f64dcf48ba8ec4abbcfc3da2bc6f04dc8bd993a438cf3e64efafbdad932e01ab3000b6bc819e1c205242220ea72ecd4cb38e54ab7c483a58956f992304512bbeaf7fc0f987098c25797d734cdf74a3bf06a5ec90cbe1e12e59fc47e8ddc4ec0ffcd90e0db824e44bebe661a88a94b335bfd2d957186723d9e0d50544e68547c -TAG: 9c7a7696965ac3b4d1b175a1136fff97 - -KEY: d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e7754de0c -NONCE: e06145d6b247742ab582584c -IN: 3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9cc1ead957027a7303f01622d129eeb87604daa5b792d6d2cc4ba08cab47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe2 -AD: 8b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d -CT: 3fe29eb90fe4d85b070d118e2ee7b5820ba5aa019b5aa64c04485305771ab03b7dbfbf9cefc1f1d4ac7b91e82e460e1e4bff9d6ec7cb61138fd3521a9a13aebaf082907b6bd82fb0cddd4c6d2af72b054c2742ded0241e2db9573ea7cb76b56b14c7bbb2a983b9032bb701a83f7328da550e6fe2c07026a81989d030610afa859b1622c8743e957d3441f044339d5936921104f0d98c427fee9430dc1689261c63f0a02beb9095623480ba798fd13ec536d678550f10f71f2dced90edef6e3db5699a27f20d2382b06adf5df7108d44b5610bd49a7270d1021b93cb167b15cfbafc875c9188211fa31aac4dd9f4abff49cf18c466731d3d343aa04851abf731137c83e8815a04cb48957b7514f5b8d27d1bcfb3f8bb805603062fa4f2a1e50734b2e52ca9e99bf834001dc6f57fca600bc49d0e95c2ca80581a66176f182cbf9602e683b2480492d1e6b0f6119930a85e09f4e56b861c8c287da0b4028c055e3f325802260b7666b38da47960acbf10f9206e68ef247a78b0f9b7b5bc50aa6f5a47684d1e64c79ff28f1bb21bf3e67f7d6ea5c2074b45bfa7d905b989fd262afb2253b172415c16706b9c88a322787a3001460848391863b71aba1d23dda76adb560e7a03c81271330bbf36b6b21d1c8965f8973afa9772b7590b9de18a9c961bac11590825abb5a7fbe78f4d120e6eff290b8b3e4b36222a0fa1de8a5ba2501 -TAG: 0948cf55a922d9ca8061356f5a829236 - -KEY: 09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327dacc20 -NONCE: b8d41590570fd882012b1207 -IN: ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc221262a7e7959ff156f3e69dcf4c3db8ccc256d666d3700475874d600d6e7f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9 -AD: db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212 -CT: d412afdcb77bfba94aa9a2a3a3a016369706fa4ab1efb2bdbf4c657fee4ca85b1c497a4a85e1330854fbff098c2f8450b7a95c4642b970518293a8d6e3f66ea0467cb05b7f2eb5b406e3ba36e153d97c9bf9bf45780e6576840888355f6084adc7ef517ec42e11271d2b72f2675553e21521e4a6b8f92f15fdaee335a4b8141e42a7204e35a96a3bbad2b955e1d9fbf02f735cd1c31f1fbc069b89361a9e0e18c75a587f7f5279a9005f8338412e71eb6e7e644586b9e6aeb6397744cbac0f60b086f7e36b7147c27c077d7038797c6da35bd3812b68dde48917b6695537490992c847a544092c9e16f3715abb930080c10dd8bfc26d51e7fa4b8cbb785d3ca64a2a5e21a10312dc4b55710d7b2dbb727b285b087c542c0e4d9055e16cdbc90954a91dc417ab19eddf8084c765ad1a2636b542411c15f36953f9e6a177089fcb9bc45f0f2256f7b461ff5551a5518c5c33f8fffb282d4698d1ad630cef7bd6c0577624a642eabe3ac0f78386d8dd1429f02a9c206037bdd6ef066ec15fdcf52aaedc1771f3f424e417751b3ee9f8a71ca47a45bb1b8608f68aa1cb29afac84fedb11f579b848e76a5664a8978d5ef26bd087bc28822216454a193a9c4f19126a108cc00b25f9cbe0bfbe704834153bc6dca55f32c4ea87ea6774768c5a36e5e39be927c2e1d4055fd279d99d1b3a8741a4320436791de823c96cba601c0ba9f36f65eec9d3117c6d73bdfecd4a3556f84c -TAG: 8ab0f495275a56e3a0d77f255a615fbf - -KEY: 501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b66d3a -NONCE: 702bcf31e90cd2ff6a350a94 -IN: 689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e5de639113d920e239a0d1581e179f9e90b5bc077c27b08427f0ec327545c1a235b88be7e8451a5bf405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc -AD: 673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0 -CT: d0bace68d76a5be6b31bd038b921b6377f8022e09bfd90a8a94d55c9147b07e9857891b8f4f43ef410378fc0a54966918bae5fde49658e1f6d307908b5346b9d776c1a6dffe52213286fcb298c741d04e9280a4b108419fe9dc938fc5b3810183bb7004a3eb05cd1fa81646e7e64e76e69ddba6d086a020f7c89ceaa7ad53b13b01c5c1addb818eca6d4e060b60e31320267e199af494739f67544542baafb577d2bfc36d7f92b8236dfc6dd5613c9b81681f10ebdc97e49432309d8d46ee1770bfa256b871f9bf76afd426fda88b91fa9a407d6364c181a1f04f17083751944a6925292fb42defb24c215b0128c6f500a642cfd230c89ae2ce117a29adc5c09f7dd4d97a34b9fb4e55802d325a1a13d0f6e664fd5f5a35f22c96c5b567d2297c5832f928ea7041b11f7ee546dfa03bc03385b231c0503657f0119b545faec4010fb67469f2b9bf69f4ab89abd70c339893fd145758b3ae47b44fcd36c20d361e597ca573317b04a5d00997755c97ab20f9b0592aaa8d10a940be50f33c9fab16bb0fbec7d92d21c378a3badc8c2137fb989c9b6111ab8228c427338e0685ccf979afa9e887f06cd840c2795a9e08ed641990f0c29d061c4f93ce6a15836b34dd428d5906714315cd9bd2f636bf9deb8a6371ead07502a46500f987f2ac124428256044948fc4a2cf778012d349ff5f9e3847c8b71793e8acdb96b68eb034d08f6b06db00c72e10bb6574fdccdf39a775628bc387b9ee026866854f52d91cc62659c -TAG: 54c66aab6e2939029293205527852b9f - -KEY: 428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc584 -NONCE: 6f6eb4aa086447f4a7e5e8ee -IN: f4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dabf0f31be89acf8d7fcdb2a063de5a9812a3d6aca502708d448a869bcbbd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f -AD: 9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5b -CT: abc04db39ba31976883d21f55078e5e4f5ead60c56b232124dd035215a124a489249ba560da193cc3152352f241070313d8e8b693bdc7f72e91c34a5713688a6a8ed1d3a3fdd0c5f118fc83df42b8ae307e39b35021b4479fe240be8e161407bd82950dee7d9a13d397cfc10d38ff3736f47a4da0ddf2cba1501c18674a71d1a1c948e038632d65ab51fa41347c583bcf2d13b2d22201957f607e57dab80e8a1bdd2b9cfe95b204976c1fd5f5e9fa304d3f9761b63d0f5dbc7a129bbcfd97c437b7d3bfbaca571a50192cf309a209dc29d51a18cee2ea9790309795ace41ce20c12eebfc6db620c398d3229e773f44048d596bdfacad90e277518ad0b2f8841eba71551f79fd891cd1aa84c6c87224bccac2c95d9ec27d3d0278b274dfa30a3fa8684f7cf50bbb80c49ab4b4ead2943e87a31dcf29df040f1dde7e2bdb097d230bdefa5d541572b9e759edcf498d0db993f5904e838d53230e231cfb57266fe0128c2d8ed81d6be4b0a14c286e9ed109fffd1cd4d5d5b8b280c238e7e276095659da7db5bb400c157901b111036ca13af2c7763fc33fb45f857d4250ac1145678dfa99960c03327cd39f521d71b582a85da13fbf2905faadd0c4b7bdc818761947a5fc42215657959c335d0dd01c8562bcc6338dd183d51e8b3261b90e0642853912da5a19e3c74a6c109e845fb700ca20c5c9c4a185b1060a830c7ddda040de695df1ac085d7a0b0d433a5530e5a5fce1bced424383520ad85c40d709389a4b3e151e4e8b3c68bc5f62bc9acd0885fedf11fe -TAG: d340ff2101c55bc874a152a64dbfbe91 - -KEY: ee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158 -NONCE: 2c9c6974f2442b87c02cb723 -IN: f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcce4ffeb5ff128eb3c798dcdec4c665a4e7b30ac120aace497d03de3d726638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e13 -AD: 15fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d -CT: 829f34b0c9a9dd142c05e45001836bd524075423cd40507819ffc9db5f5149cfd97cb6584c280f936c8fa3c0237673ff858aeab5f678be466c8b0f9356cd48d0a4bf55f5826115100316d5b11dac5cbe21b817f8e5b2587971d4a1f47695f1f917a87fd64356336481b92922244639cb2455c3bd0b338b24727f14c3b68a92ced6a6a58fd2c07aae4b5206f5fe355de532b996e6348d357906ed4736734b62bd27f8e832690b2e63a2fac998b7af27cc98aa64386594eabf12d5989716e8c36169ac8f548433c6cecc114279cef1a62906bb69233a3d74462f4a35528a98651a0325c06c3667ec31f7b66bb9941b843c6faf6ee56a813b03f3bc8775bcaf1efa10cb4ce784c99ea79d49ae57e4a77d7b069f8456b66ddd04a8addfcc441fc3577b5ce2e38eecebe4963e78dd5728e347654403ea249f70817e545528780668c69bd5186cbfa73e9e7cf3813952377f748c6736988a0faf9f06112dad90733847dae8ea272ac49f1290a417f4eb09f6960e0bbd90c098b3d6bd1f49802325e255ad104cd18a90189aa486eedfad8ca999f533ccfc30e63b31809a2f0dd6bacf29e7a4de79813dac86e3b324e7cc89abfe98e91e02a37e3a5d224207958fe4627aa5861cc1d58515e2da73eaa171e29bd436786a8c54c449bf620b0d91a0c001272b5d047a93289e2d6a31ccb14347b019473214c9dc066d867fd3cc9fbec4c1ea887c6e009bbda41f5e888bbb14587c04c406566abe1a7f473f052a17c3604e837d1358255c70098a4993fb0cc25cf89326044f11a7f4e6e320afc5c8ae457425427d5a08 -TAG: ef86f2b8d839c403d817a7a4b73b727e - -KEY: 7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4eb -NONCE: f314fd627004e9a78d133482 -IN: 2040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce4910758ac0726e0bca5d30bf4d0a231fd12420b9b60c3a690e0ce0106c1bcfc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61ff7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde -AD: 1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d -CT: 93ebed6f7254c65c204278a9acae0b123dc19d8e226e41511f349961b1939ca83970b9696f31a7fcac5f5e3d4931b0a592ac27fec71b4e5679a56ad1bc3be37d4bdaa50bfdd0d00545d4b77e757ce7a0c8abfedc9585199ecab1226763a81f9a8c6853462c483f29798a9b28073a57689c5514e356f9fdc3f7bf8ee0688e8cb781af3a365ba940f7ed36ca68f6622fc6b6310a4dd7f8587853f58ef485c82359840e2784460109b4921e4b7ab014b28571938e18b4525bb4d5de35e77cf44573b167883feb3c730945e9ab71a2b755cc315ba99ab96f8d4a8f46589f2e8906b269519da3a2dad2a7075629c82096f028ba47c33e264f55b8898ac5681d396b8e6d23616c1f8db24ece718c2938f88c82da1fa940ecfb402fb300041f9d30e5d47e2d74a4d9822d35aeb6223a4457d621286444f732bed704d529df95627e153246e0688fa97399d96033a06091e77db420c8007ccc33386c28fb76a697dd99ffab76705a7f55797357e563cb607e531938380dfa64800391f06e5cfdd3dad5f91eb7f2138d54cefe9edc0dd3f4d674f5f5aa315f0e1b7922a37821c6cabcc9d81fd002d159d73b0598ddd21b66d3db416b789a40fe886027f1a13d802e54a6bcf691ab029560b67307ecd373f2f9ef2ea2c334fef7d25799088106bbee9fe2b88d06bb23ed0510284c5e1289c1b65a27e4f0fe33f18a0065411ea9e09e65b589a2372f37d0f8f4e07d95f6e8f30fa882726d29f41782b3d5abbd4a9f2dc62419c684a4c8aa92c4adc71c4db805c29b0e561760ea3deadb7d41e7a07a67fed68b8a0f4460e5535e9e0b9f7a754d6f2398fcf399a277 -TAG: 7ec06820957f6a0e0f4a8f7ae0be696b - -KEY: 0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e1062 -NONCE: 86300bfdb282f9e2db0a43c1 -IN: 8132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b7b9f65509a00841930c4087093c0e04945003751c40e59eeb10f62ec33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735 -AD: 565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0c -CT: 84cdf98efa641c2c008e2b2f6a8b59e20e95aab15c276a21569a1ccf8b7494b6c9585220620944517f167e38db24bce3c81fba1743bc6a51abe0ba858d763420ddb06a9a36eb417fdbce903c9528f1db76a70f73e50e22154e8807aff8e05fe6d3d28e3f09135486b33e59ef353e30a294be4870a79664d86ea84dc581ae58ba8aa6355ac8289855e7aca0940669cf5e7b00eeb5a5e9c7ca1dd483c6664def93e76244636eec70296965eca0f6c34f1d9923295e343ff9affdfd51492066cc4d5d762db2864db889441dfaf9c2354acd97c823071098b8b9da9b2a91ea98d6391e40ee4e13b7c5773ad7124c1dc22d4e2dd6142eb665be2e936a20edcba8badec6081a07e54649ed2c371a7f22d4898fcf8cd9916c7033925908c2a03c02000a456ce2beec2b2f94c0f92b9a7885c9231886993600e734948b34fa025b733ccef10a8b66d52dc53b850d2632e1d1573256430661d1aa716fb32dc525e80c96afc19808449391dad1165de6668f9743ae1da522c9a953374fdfe214329c00cf359b40bf9f3edc4144da66e3eb9ded0885a1d3b441cdea692ce0e324686e7b2128bb28f6e4256b4ca1463f93f67743a53509deee18be4f9f0604c3491559612b4052370e4fca33482aa0d2370baad1b7e64a1e6088ba87fda91c83f274ef9501385a96b4df53d0ade464abbc8022498f9df1b2608e42b1905d1dc08c3e4bbc7e3b830145a8ea9d7bbf64cec752ea11195947b587cb5abc811307a66b24df8c95756ca4ec7e7bdce47679a2327f08b94849a7760c702ce07072ad7621e0bbb0fb78e3f6a7739de57c29d49057a7ffece9c013384df796ac954f61590c472eebc27a7adfcebe3ffe -TAG: 18d8a0469f1ba110dbf77ecae36e63c0 - -KEY: ba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8 -NONCE: eb8ff97b4f599c829e412edf -IN: ae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25effb4cba7822382ec3aa42a95221eda5980c488bf7ad0031e1ed987096819cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10 -AD: a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d803 -CT: 5d0cafef15ec06bb165c248fe447bfbdb89207ec1331c65a5d88d419576ad9d423d20d660c95b48bc437fe243a6f860f260894e0230b702af0aaa4260746008ad679676a92003a10ccc12654251de9d2cb09f7294c2fe8c2f4764efbe3984e7265abcffc2cb3e30c5611c3f9eaba13e847fd73fb3aef12c8512b44283935c51d48032865bd6efba3ee4e1f07dea2e26022958f6a966fc4059c81fbec916bf4486429f55732fe3e927bd4109a8bc9ecb820d2c137790b0e296df28f2701ef5cba2c5ef0c7732849c75f59f81460333255f139fcbb30376c21ca317db1f849f79b1826c8f3cc0852e00b0dfb94bf3601afa09c27c130b5088c05619dacf00f36e7c01a9f4a2f24d8be1ae778fef1d367b04313f8cec89c708a57bb332b63e60d15d5b4abb2d5b0bd0dca886e0014051053a5e946750be4a9553549d9102b0d8c08bf9f850a6e06aee7030536ecfba48aa577c7d3614056d790c9130544c172bb4cb386fd3988f149cd77ee8275b0fe434e589b64c13885e9ef4047627dc192a6ad646ac6d62f482eca0183d23f65a29937e9e53a1235f66436897da1213607cd850c32cda9828010e6fc3a93f5f9c709ff259921ce890435b6454c046fb01c76513cc99f66a5c2da8f16525b68e3cc66cd6a7674e674bb0cd8487953ea9048a170ac8e81b616e78d0b8460b729d885f4716b741c04e6236d2171017a5d433754aedba3aa7a39675402337db7081f45ea37374a8f86ce8898ea837583a300c0f74c6292d37e7c6d19c190394dbe777e454c344d7e16bc51c0d93465f05327ff29303d80177b9098b4a4d809fcb103a8c199e3e8f827b237408a242a80ab388d29ea12ee8a0fc313367ad213f7e696f90331c7ab9a5730cfa1 -TAG: 359febfe67037a485d7ccaa4f1b6286e - -KEY: 9a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e9659 -NONCE: 9fe335e06fff534915999ba3 -IN: c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f8004233eba54fe7537d0127b1a062526d33fed44fbd3475daf5c046123befcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a -AD: 9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99d -CT: 28c9024090abbe09b35c4e289dc1b9574ff5172edb28f34e9133539dc98b4557168bcedb11a94c1ea84eb4b803661e405eb007c17cec80afb3121f27f185a197b4ea3f0ba231e538ae3c312e2522218ca2a73402ea7cffd3c1413c0ca2206caa91722cb048e1ec15e63f6c55e563dfcb4c3404a9c380608da0e903bf8037ee1d740275d568a2a3f9ee232d88950b233287b2bdcbace62efd1425c43efbaa8d12f66852cb5f1b665e7f4cb6fb5e3746cd5e8d612bbda8c031fe5ed7f4f3b5741b2aff9bdb150f637fece13ea1f2f5d32718560a49c841f3923d993b1f5f65715aae6b651e7d8f75ff34a9d1737b9e3f9a0375861458faba779ef9f4b72ebf42097e1e0fab5b925fe85f54d40f940f7ace96125273da94c9e394fa9a80680f6567207ee40ffabc8c152bc6956dadba45eff644213178a7a24882ab59ccfec9fc525ea9e37064ff5566e9ef2c56a9d634f59cfbb0b593d3fb19262436b68f57029d83205ed6c466885d7ce9a33046bda7dad9e2ca92691b3d5f1e48348b17aecc311479c4b147f4d61ac14640006a7c0d83b45372073752f9abdb5d1908dc3ec05f85e70324088e360003dc774bb68347c2acd4322fc1733d36e68cadfa95030dfcb9f73165786a30a7e841717ed8b20bcce47ac9b4900fb6d35c917b291a9b5dfc4ec2679846447a1dd140f48699b792a2969384c7e8914522286765a3013e229d3f3e30b130efd498a1cb56cdd493a5fc8bd9726a8784956ee379f907cf2280745379784bf1f177318cac159ce656c4321eac7ae00adea35e209b38c0ce622a1d4451a2dc6e0c3d2679543cdbed19310976d0748db13e341c396089d977546e956c96199828a8cb72ace556a2ece3edd3efec2493a13d61701a1bd525841933e8398ddbe16cd96a2c -TAG: a1cefe9bdf19616e49e6dae07c8a73fa - -KEY: c75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c2 -NONCE: 0da68ee6ee4e0126b67d2a31 -IN: e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124f79000afa6ad2a10b0dbfa4f34e475420437dd10d487f42d2cc40041af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05 -AD: e83596b9ab4cbfae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf0 -CT: 2a59d868291bda6113708e551c89d1d4fd3fbc81017975fc0b99d8dcffd757f19fa4acd4acd47c90100e27eb228ee59ff1910911f8129b8a2cdc59ec38b73cd096271e55fd097329768d102f4398c4f70c52d7b15fcd66a94d0e910a5b6b8bdbb857592ee42871055be1b957013695288e52ad934c6f802677aa89c08654fd932039417bdbe062a5242d5d38b79ac834c7e7fc920bc3981dfb780c9f10f5f761a49a3b95693ee764a97d4de73077838b5ee04ac09e10c72669f7c151446497c9e2c3153938efcc62feeb9b82e605b4bd76ad97b7401ada9bad71718539d47e6edd058c23b5c4f3bdf69d74ee58b7d1c94ef660e4e6b1d43b97cf9e8d191178160bdf0e4fb6db2e9aaa2563322e4413f3b5d57d0f1082d160ae2bb2d3cf6ac17d75f73ca1c80365648a394edcf62f520d2bb648d7c963b1d7deb6eece9583ebd2b2bc2cccc5415c774d9f25c00d221e1f0c2829e288721a9e416df098392f67643d52a9fb0f2f47ca97664aacfa837105e5da4b86774223bbd238a060648f689c59aea623cc688c1aecdffb13d9471fa07352ec02ffaddf080733f07d10ba61eaaa9f8e0d89b6144af9d4a0094bf9fbdfa6b35e9f342a7140ee4c931ffc0126eb8b4cf6e227fc6bfe386e81a32593acafc6d44925f1cf21924720972729e2e9daae0e74f55045d17c25c4c3b8454f912a0f6f6ffd43119ec4f3046d921d20f24662d25d0aa34d95c3a5aeff05ef1a8905ffcdb1b9e55ea22e59a3f5d60106db64b998f0e9683a16c5d82c53b424220690794bdedef384d91bc9a58563fadac76b50e80b64dbf695a38540a9167cf025ee64d28e26fb3dc7e9f33979b33eb887e55d996741d9569642769ddf6332e369674296d510181023a1a3e4ea7327af5838048458ac90a71732fe29e2edc9c477fb6d8827ab4f83ef8626 -TAG: ddeec4a2536869f8f89ac38951bba13d - -KEY: 0c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea3 -NONCE: 2b0a22b260ad3ffa73ff1c5c -IN: 481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b375dacb5173b30a28c99e00eb11181879cbf1fb59bee4e3964b300ce57b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14a -AD: cd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae906 -CT: a56a09a3c7cac593f40fd3af345c1c84d29a7905a05087553640f0727283d1fd270773b6af7537bea2eae40f603567132c199e7f74b7eb98f1d7e73a7b6474d1b0b0eec43dbc33ef6e17e07afbb94848fb78d53729f358c2eefaeae4b92724fe0d6fe97075644ad5b12d1ed93f8c07aeabe373b5bca66b52117018955edf01c238a937c4d5e7993fda05799533a5a15889637628e158604a99b2a21b24dfc2af7ec0013390e6e7259b7ac92f232bdd375fa99a4f6c45f54ab231f6d60fc36809efd3d213813be1f3e1b91ff3091469590f6cc439ff359b0706ec0d0667f58c34ba549e9727d9045adffd0481fdd13c4069160eb871afb2d408e4dfcf6b70a7c2e21e4e54f44b2daa3676ee998515dfc4c8518288b46d92ea835d5e9a0c8c391020aa6efb8b30a580601178e486957918ed9f11fbd2021ed7830c3019c935ce19dfbe95c525c8498803eed097d565b94d047112d494518f7af094705f3fb83b22d9064450701ddbd8cfb209a4c68fbc1667099e605b7cf853d5a78b92df4f6194a7644017434f2658a7529941d3cf71865f8e29238709b373e68fe1e800ee858d8286d80acf4f1d8cdc2668f40338f48dcf5774e5da72644bd9513018688509c444f821c0c648802cefc572c6821005db0fdba6f4eed0f122ac57a213750632ad2eee0018f9f240f2bcd1cdc03d4c8a6585d955dcee93cab5d7041148385a77533a41eb9eb55d7be87432e5508e798aa4e4fd4a06e83bfe355cc698bd16f9b5ebfd17145edb7bfb3c57a0faff18df6075d98ce7a53eb4de7563768e3257ac225de47b8a52ad65699f8c7efa64676a268f9dc97c46bb23dbb335e79be532e0419583e0f8753a38d2de790a3160d0fd63ad5840601a78057708655cde8dfb08060cc0f233688227eeb4a0f20d5e9d58bd858ca3e338ab402011ad975503cd5c86ba3f12a05a26f0b0f79c9a -TAG: ca40f0179157bae889d49b5697a0e26e - -KEY: 1ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd -NONCE: 42bdf685c73f9c31abdf1d28 -IN: 419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a65187b8cd45737c8446b21301be1d5d02ca6af5432cffee125756ae7bbe2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5 -AD: 358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea -CT: 2422ea9d13895921401f84f25a5b011eccf2670b1f12985d4e2c4106829a7ec3c7c75f11e348829a8285b34c745d8892bd1efd02c27a6764311962302524f787866520a562ffc9f0a644c242107a7ff868e20ee2f2da9d41e2e85ef00815e6dc2f242a2fe8986d40e37a59f53c88a168d230745a57714c3e313f8be3f4b780c61c0638c3637add213b1cfd5d07255116d9fe58dad2941f8bd7aa7c37ff7a041419e02b8575b46be6dcb23bd5594c713c93f8415e5da427dccb6f3b6d649ebde09f4f627beff5647bcceb10413f0a58f04d3a03d3a59b4d9f578508a21bdb609a7291bd8863e091907f83eba365e5df61991836fbc8df69fb7d6ecc15c85c8dcf99f771b19c995ea85578ff39ad5e1eeca002dcf843f471198d1d4359845944fdcbeedefd158ba9dfc2045910a911905579a35a4d7749361b8197fd69ee1c988cb7c1a6f5a5db2e926b4b2a0cc8c5a6c01fe1d04ece3bd7d2707c00e001aa097e6fea51bf87654f389fa4caebebd513527c186125fdebb3672316b57d12be3619e125d642719ac96ca97dfb7d2380800e48d8fc29b4e50c81e6238ffed2a3e788182cb6ac51023c587a66b3617734d18f6c2e4c959b84f04609eb81eec83ce7f8589683682c683762355f9a8c72d1423d67da7b654c00fadac8fd2dc4ba22017228acb6b287101719726d0b1d97e9ca2fa67235e768732756cf2662a078c5ca753275d1261011127ba47265e7565422a9da627085f40fe22b680286408004ee5db318b0869f8f8ead0e3d1b4a564e250b6ce61304bdaddd2686041c505b91a8e3dfe411e932549ee9956adabba04add4808a2ebbf0ed92394fbb00c1466ab06f964a325a877bccbc47e0d2ab4e24243164ab4166aee41b9222b8b42ce81668ae8d1ee8ca5a0c2698616183cd4c025b6210a33aa7b72dff37ec40f749fdc0e879a5135967f47ac95bb65c411f0306335afe6d7a2247823decb050578 -TAG: c867f21b1b4c62500ab27499d11eff4a - -KEY: 16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f97214 -NONCE: 8e9a0bc6c897d4fdc82bf439 -IN: bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3ad3ff84d1442224006550f6006be543f7712c5edceaaeb3360ac7ae2e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1 -AD: f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7 -CT: c43a2c260b2421b4f4d0016112a6a90d09f5505f982a66355ba55284f15e24734afdf58bffda6878ed052c5c97c01ef9214e19057b87db04ecb9e8a72dcdd04e6c8194283edbdec0b3182f73a009b5b7ee42edaf82d827bbd49b21f9b33b013fa934d710d38d156f35491004a9f29b7fb11fa60be85179d970a95f6a4321c2250d3300186c186adbc9151f94a916531107237c9f51f1ca4a16067111b3357d26c9caee90656bfd4317c2d52e97b87f7adccd296a295b45a173780db1011d3dc010b8b951a14e0057451cde7984a62b3e29dada4cba1cd5bbdb32acdfdd6160fd41ae42c40a3f294057ba27737f815592ee1ca89a57db35ada5077be4ce805555bfe57293552296a15a9be89473af043f193217ca228afc044e6e9a8ad57fbab59ec12c8358361f38eb9c00b33aa97c90f51a5014fa497c102b7f6dc0e0678e99e7ab7b98cd2521ea98ba31ede92cf621e36addf622adc7b0f77d8df828dd511b9e74f0925c8c7df1ce56cc2e5ad79feb27de705d780c2b77c931aba6a032d99f658f73fd9b9872959cac0137e9af2a565ceb6f73b011ab3aa14132422c14692f7bb3255cc96a3d63dd167028d4221fe4a66f0a010f35ee42d97326f3638fd15cad7d9afa2208efc4e2f0203d1254d93bf532961ab24df78a6a33eedb0d250869244c17074a283ea083c211528e91a13e0c585a85cf5887b09734a5aee9a01a0de3ffaefbf3791d1b1e478ac1c369e9e0e4ba825ac6590aa011cfa0ed15f9fdcb0f386fe1a796dc243862a292844b90d32db05ad0eb8f2839fb386085b7aebe12e7477d5eb5ef9b6603004b3c2ecc6e961059b11495d07ab2a164c64cb0d6f3c94555a5c3fe5cc687601c03861eec326b63b614cfef131a89058d0b320f1076023884882aeda8f28daa0a3dc96ff9ee982925db55fef48586f407f576c5e5b9a723f1f10427304c19aa1d39b70a12a9c9f07ae6b76faeb66f4b26cc00febae63ecfc629968268acceb5aadaca -TAG: 59e3b0e92ae4aa57a2fc4a19b74e06ce - -KEY: d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf83 -NONCE: 6acfa3e2adfcb7f880c53c1a -IN: 8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d439ef8200a13e35000b40e9b0b392c982a4377557abca18c1f3bf774f4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4 -AD: c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17c -CT: 9d4764aa97244b3506582c24cf82947430e6749bbf3a907a941d398b39950dea9c21aa637a6d5030d9b070ff6c810a0f63cbeb107bfe1d91a2b3a71c2683c2d2716759a74f9c022b88afe5f36182153e5378c12f94174e5014743da44601908df428d105362d6299f2989ffbb67d45b65cb2a35e888d823605d2215f325ee59332a066b8139e01ac2ad5165d858fa809343fedaad3ceff19c50b218da9c1ececd713bdd657b02955afa4a90dc2f426cfee4de4b1e097fad3c5183fdc84725db9263bbc207579175ca3171e7cde14b652fa50c2032d59f2832196750731c2268c6f807625e8bce39faed8f85dfe5fe1cfd5d60434a753159b7196cc69c2eed5f50907299a53092d3f3d41bf7c8e4213d9d543bc235e50ec2f569840abb26490f1b0167ac423ee0a680a70797821fbfe7dee33d9ed120a95c6a75596e04eff2263c1c635da44322d18cf720bc90a113790b9e9d5141dfda46fa2c9eeec5afdd43ca5c0ded8a5abae0d3243ab2f81f3ace681a07a59afe8949061e21f8ad0a9d50e3c8d36a6270dfe9eb08451323f71793a5942ee7484cb1eb033037b209bc8c61b38ea28e9f9c2a4cdb629331a1517606feeaa0eb45c69958df6a5e48204489730fa83aeed0b2fa3e555437fe460980e8813e0521d88100088bdf6192257be14eb151d6f4b5c6b0bc9ca6a0ca2e2944d6d51e3bf4fed6cb7722971768da931c1f1e50872f25ca12e72bc984f48010481924fdaf3c744bd098d2153487617e321e665ec9a1346209695ef6b1e0e79f0c4fce7d33f57087512559a8290d8679555ea7f1554ac6374468f3865a2bfec31f27cbbc6adac1d484ca6da48119d88295cacf38b427f792f25f7d3c341a904dd9d3774e355edc0db3748d65506f2a0bef5d8abd37c31daba869dedbf19e3aff557b0466352db1f5820f3b494304604fb6fe42df9dae1c21429ea37258cc087cf72675a15a8159e33855dce7a09a77ba8ff296ccdfbcfacc7adb6b7b020de0bc302a7fbd1e3b8d51c5b1f520d384aba -TAG: c22896658ca6cede859de01b80632d9e - -KEY: b28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea36 -NONCE: 79bb9a78d035bd8ea9e8ad70 -IN: 9f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176abbe5e520c0ee79153c976d71e5c6dd576f4857ba2d63e04d6b69a2d5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb714e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f -AD: 3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a78843256913cad2727f9dbc3a8bd5 -CT: 8cf78ff0f64a19abecbf693d8575602631303858623968c8c4522c5351ac552dd3694b0a04fa270eb9652dbe58c07cacc2bfbc927f22bf561bd4cd2d639a00b240f41d6af836ec3f93dc0610f08d59514c49351e25cfbbe1ad05e8cb21e25f144d926b5752f96ed7dd05c816cc95f5c3a008716c8a18ada661ecc497c6e34540b8924ab0560c57e7190ab567762bc5ece63883ab5522c8e84efa3dbbf71179d6f286127f01e8b909b61a16fb2433798613fae1ba08524d734662bca15dc70a550740d1b741c0cb46528d061c786f129cd49a7f5b9c1f742c906fe7592e70a5185b6b1ab669498bac981f846dfd2401be46c0972f8945adaedbc7c54cd40c8dfa781c0faeb6b2c0150bfef21ecab2995da3426be508f21278a668e81b25938dfe2f8e1f85c8e69468e38ba924ffae71c1e1c990656d42c8069d120c75e840a2df0ddcc88a77fac1a4ee56d3bb00cd53daebc0c981571d0e3f467d2940b4b92c359afdfcecaaa4331ac45f0afd902e8c5815266d195e303eb16960fcc21162f025d5258786963250aad37610c6b191e479bd5ed29b8cfba9df43131feff2571fc87209b69d15b6c380a8623428f01944d6d5e56422fbec4f7720b607901f06f4433fb252ecc251660e6f9160fefff8af8b866c2edb11f6419a6bf91c5fd557851d469c256f511b9acc8e71750587e4ec0482bf4ddb0b73ed82cce239a4d9c6b330527cd8d529675c2c556456b10ebceec05e7971580b553b8a5f720f8ed38123f56869753624f4a6cf9036c3566cb4f6ca8e0f36d914758f07e7f447c67c8b40d703270d035d1cd39b22c291333ac1f628d2ce4697f82ff6c043ede6dba39c03e250efbdab3ed5e73c28e194269d8657862829f7b43192f95766f77a7b9b4c154a787d0050cf11099d372c3f97add6c9cf4a467df0922f7d9e1b17e552b453e80aa050d8a3e4fbf9aaa4c01a463b796cadf65b492f301ef03476bcffdf96a4f5bc933d0d4286bd9e2ac9822957ac9a69fe34b3701d913cabe970dbfa5830e083add43682f261c3aa80fa2beff7942c -TAG: dc5369a6b0814d58060d033aba87a030 - -KEY: 1daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c -NONCE: 7550220b0b5f3c6fa8db7316 -IN: 337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2100c6c8d1e88b842aed09cd16a5d78d4e2d7712e40234292dd1aa27ecbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef -AD: 903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07 -CT: c6610234579809d78c1caa28765c5b05f33a0c5d99660ef94296ba00937522ff4efd86f760d3398a9029877192dee574ee7b882c5ba28d1c388444137c2ac96c6eb4cace7ffe3916bf196afc67b68e4daf0e191450b04284f930f6ebe924cec498e0cf2925bce9d25bb08e872352bbb9aee31a9ca45e41dedd3e931e3ca1ec79aad5390c7f81e8b9473aeb2fc6553bd0ef87a42dd15ae2edeacc148aad6615f3bda730e50f5ae8e44f3639c94242252c2b4b44441f6974652cf783cebfaa2f69e795609a94db16948bb30ab58377c9509ea682a21c408e3b057becf82dc73f1addbdc9b98d659e26092d4f5bc1ef819f9079e0c66bfb684839c0cf1c2e9503afd1ca7de025d4a3a86ac9578bae2d2f6452c2952b57452157d88794a4a872786794a29acb6e4cb511f8cca95cfbd33aebfdd224ba7ace8c12fee32eae1ce60ae0ab6e39766fed2c385ab3888780601cc18a3361468e057d19f97e94ca3bf814bad74f93b8c18364774435a83de1fa867b684a1f2ba8baba24583f8e3808ea7bf238409110959a90c93ae68d8e3fddd8951019e9d6699e868e8f1d156e57eb1d4e8688ef064f18bb8bda91f961d1dca461220f88646bafb0c0bb3e65be33c445f265c0c4e843eb155b5040ddda3a5d104a6d89dd0523e89bf3cc7125774562b5d7a9a386f8e227e6ad71ea9c0361a4e83d9509478a14e9ed8614ce0c39bc9d1ea361cff583ce5bea53cd84083b45ee18e6d4bf3ffec402657c01d54c6db3533ae6ce428317cc3c0a2b2621ca7f82d83cbbbe6571ea87686e20b0d24eaf8489c573353ea3b879b4e7a1f6d87370ff8437c9767d4f99f244d15ee3eab3a1ded233a26c1abf8f010a89d7da628f350cc93529b130ec1085abb62a857bcd8859f738b511f5dde072e723d8fa88fc21dd6d464358df9f972e55a659c5794e7eceda8b780af6ab65ce18814d5c3b38085be841df3b52b8cda8efb8a33fc52d6952fc3c70c42da59aa4eeb61e11ad4b1ba20568da6ddb31a8f1bde37e8c63c440ee90688186b9f222bd4cb369d9e077d0071dd9d6557f5b901829af6a3cb4825c76f05c -TAG: 78ea2271c0bccf96f0d64594820543cc - -KEY: c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c0e2825fa -NONCE: 3a69b798030cadfb168a1f88 -IN: dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b073571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0a646ee4b0e0dd43479849864311c3f743f2a6cf9d0dad34111493f0e55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9 -AD: a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a56 -CT: a6c4079486af388ff129e360fef12e039e54e4900d091be16df1d3712dea1578f11cb12716431f5c6d26a0719012bb89d1a3515e0821258b65157b8e5a8ab7354ad6efe2530337c8974f3f89f674f5dbfd3e8b34d6d425031e4591b37991b5e76acf5c5c13bd47c28c6a55a81bc2f2297fe42e1500f03ac1d97a348cb9c39da8a95b1a5c4b3bd47c56988c19c1d8c6a10a35322acb4338027d2a32cb32f5ce70d4d967fb30052b86f538f1e756bc10492931b40bdb6a579885b94de17cbe917b454db89536a021c4fb230037a4d808ef71159630f48855b47fa90ead1c54903dd925e88516f0cc0968827acd6e57df044c485ed9872e57308e8c5a8992d5d7bba05f7ce949f83dffde903ad093f8fed3ee11a1c6ab031089d77a965e5a89f877b7c4b23c3118ae50e7e21d75e133ac98fba316019b4c2866257d02e6dc8ae5b476517daf7df313093c176a2ca6bd8312bcc96e4fd78fa94313a6ac1b053e72bb622dabc5fa216ebb3a99c4e760737a29d5f452176efd9720197432cf17e8182bf1af60608359195341fb0246baa0087a7af0a5155f32895a06adf69fd01e6f86fb46377e50dc67d5115dda5b0322eeadc8d7b3bc5d0658eaac577725b2656d4cb7803f28df819df0eabfb4d8a7de150887d168f1ab7e5fe0ecd71cb98e35918c8b739059eafdd254f9bc03064d3e27c4b41ae04c2ccb13042a839f82fe9335df59c6991b7e8f6c821026a0d39accd5ca8007aac60ea324eaba577eceea25b4f31504cd64929576513da857f6c9551347457530fca38b173a6e7fbb7219fe861397e0bb50cacf6368929a5a429f1bcc47f6db2517ec62a40bb8310486612d6362870c3980ebf3223216d9df538649b25a704bbf12374442cb489af02020e6886092b0410f922c7680d5fa89effa7780e31f9222348467acdf049ff39ce3df27006406642c01669b819ab61ad05b096270fa75bbad04e8b09b1c4f75b12761b2e2129559625f46bd1005ce39a4b543f34960f0e7c67cae9074b29ba86867a9b35f0a94d716fc7103266b7d14164473b1d4e19a7cb157fe5e04e83dea1bc886947c -TAG: c3bb19a713afccf40080a1923350cf11 - -KEY: 6e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce97d0002 -NONCE: 37e72e6de6176fec75f5baa6 -IN: d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c19c73a26fa433bd4437c1018263e7db4b580a120d1d29775d9d5ced6710ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e074 -AD: 6027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40 -CT: 10327cff240fa05d2aa15a7b299b925a0ad1740957c4fd23ebe24e8a1f36cff5c19007d4fda60dd9d3231258021cf2d11d9ffd32bb221a620d68f2b0077a64a6d575c3802844500b2e6d08ee659006018b6512651a5b903b6d438eaabbd41d0366529788a33dd43a0144637b4a66371a7e58898c4b6d1205a239928c3c3e00907f50a79e2a99f2f675cfffe191f0c584b0e93d72f2a2aa8a400226852fb97ff0cb6d361342185500e3a0db1c9836bb8981d7b4152a399f84a047e5dcbe7c0dde2a85496d4fafd8990f70f28025519dc56ab2fdc150c215bac333af39a981ce5ec484d3cfb06ceeb68471d730e9a6a82d03a4b29dc8ba5ade90c55f6431109bd8c8be337033ca49c4f75fcc2b93a3103638d8516622625749dc4ab0dca45e02abbb2931895f3720bf0d915a6f2802b9a402a5a9c1f47419df6ac9fbe2356cc6c51924bc7c6d9399a92688fc6d75a41f69e4f91fd375df325a75dfdbea2084ee9dbead62754b4b97cd7fa075f6c016678053a8d6cc4de4dddc2c2689efcab3281f1b7f353b3e8710fe396e874784fa54c034aedf078524ecbb18f5bed06a88887797afb0442670224c3bc3e0b347480b7d84268ecd792641b697cc7ed431ff0db957252ee3ce4ab0dbbd47638c15fd0ea8a25d3f3ea75a81dc9986b240ef3189f323a342857ac59900bb8e3bc429435b4c00cce3aa6c516d0c68456a12929359b0bb9b02b349e63c4dc8bf2ed107d94af97af04c14ed454f3920e1f354378c20b3be5c12adaac6d96eed1df0496172a71b585e3f5e39484578475e6c257868b3d0bb45cf229c0752697ab66106a675311318733b02335ce46b1e035a92557d2ddc9536634cbc516800fddfe358d8848198045d746a5b6e00db3d2d0b22f7e4c4d5cde136f62db48968eb360a6d8b645022066ec54f2f2f05b3b8c9af2097986464ab60ad9f05cb63cd194e501507babb6103b96daee90c70efa78c609f95a20e85b26f2d9bb503274dc40aa0aeadc485a2859b3497f4688df1b2eeae81787375dbe3f9fc6ac8b4bfa339b92495d175ad6bc67856b58c1233ee1b0c2b524668750a48c0704e56da23fcb015be58239cdbe228 -TAG: d5bc1db867fb362965c9ec4e686d95e4 - -KEY: fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de874a -NONCE: 859c5637b754a4e7c1ddc3f3 -IN: 4dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f6269b478e1d79f3727831086620e79dd357fea1c84ec4de0bf7d6afa2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496baf4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5 -AD: fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a9 -CT: 29e739b7162cd3504c7a70f3efea5d6c2282bbf1fdd75224729aab622d59b2f680c92de483a46d2e8c45460c8f3efca1fb374ae8a04ab84aeee0c083a09ddae6cbdd1803e19b27fc1bbc4ea58ded24f9f630c16c04b605d107a5fbf640ff1225c919dce7b6f73b1a18aaa37e3d0c757e0062c0de6c516302f246f246051e1a0462db91e5ed5e1d178c3b384ff9d1ab3244b861b4c34e21a7ab194cc3d48d11588f53604609af8029a6ffd166c08a8f669da73f465efa2f0f54dc0e09916fe8903d0ceaab4e55494a043160e6962ca21ec86e1c159532691b34d507024a345aff411b46a1a32f7844ae3e1e250bc17c0c3edf4516231bc574d742b0b2411ceaa3c4cba1d910843534e34e3d405be0f51a304c80a858664142d285e84b8e008fa7247fc0583dc7b8de3dc9015f4d8e24505d1eadf4e7c598e628ca6b5c70dc6fa5c1734cefb418d62cb08b7d5fe81543d3d1b438ecac5359a0f1052e2efea3107b2da554ff669360db0062052917abc854ccae73623175f7e5ad37484609bda0b6ee3cc87667fac9d1d3de9fcd104b190c62e544be71e9badc2440e8b451532781dff81b5a7ec4f80d3686bed8f7747714e994adbb4612406499a6bc3925ab62d566660265ccf2d635c875ac6fec640b515b86ec5a7eeecd34b86d1f2eb6ecc5858cdaedc552175c707d12b677cad0a4b12bb4e717163002607eefddf63ba2581a2b1afca4865b97816e61813bc7ea99f8f69fa5bb8e306d5e6db15293ec2f7a9c4d8ba2d4ff6e258270c9ac7bf4887171434d034875b590fe20b959e0955034687679ddf98a5c777dfc06f11137b52121249ceac90f5eeeb6f1ac59ccc26198388eb8b5deb918cacaccf1e48145486c37bb2a11d371e095a250c86efacb85921129c2e19c9dc09c66173f394f568c47fe4ef0cd3a98a138b1750f3aca91f7677604613b6b0ccc92d6ba8a0c3cae6b7b22be761ce2922ab273debcbe3f68b662038e232430b3e7d3e4142617fea44c0683f0b7eb03950060ced6325409293422d058d88f0b81118183a05a13db7af89429731c8a37aa83328019626a6f2d87ee49f9b4cb39021093e4886d373a292fcf711945f9d572d734f422c92d8fa6e01c4dd778 -TAG: 73f6e44d8a2f3cc357707de856d2ce9f - -KEY: 8e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c303 -NONCE: 77ed6ab683ea82545de480b5 -IN: f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d034047358cdc99ac30e78d6238b5478982a2b4ce58537a34e5ebc37ea72f321f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d43 -AD: 51c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac2570 -CT: 441def04eda7baf0e6edf24863166860ed05c9c3cd0d0c71a383b4dffdd6b5a59a18936779e63c8ce5a3ebcadef82c75d3f241f62d66125b4b4be0b8ae58e42d45421cc68b42ee062d1f6c12a75a80e854a1e44af9813e9be4ee85ea3a9f34534930cb4c51108160e4df6874b900cd293815a1d5bf2b064fef51d0fdce0e077cc26c4d405231b50a1c26ec03a8e956c9605cbb9b4ae68143342f6fa46a651cb39aa783abd0f6359365815aa8084102d856d860f7f6d9344f3d1e65b0af8c7d50f83afd151139808f651e23897331b58dbef7d301dad4ced88feb5db48b6b2e05e1c8cfb58610ac3c58cffcb411dce628c1975d5718631c1c1230ebdd40e6fbb6c2442937f95bd3d6578189fa72cbc963b922d17399439bad035a64f39e78c4aa7f0c4793173131d11c7693aca45c04e0f255daf0b1ab45c3e0d90dbe38ac08782f19325039127454e589953859ef87cb2e4edf1522f946b59b8251a1c154acfb50f0a7b0a349537e17e5de09037e385f51ec4f388517bb1ed1cdf891cf4fb39ecfef69eb553929c82941e078e0f4527614a002a8b8093e1c1ffc8882ece4e7f23951df6347d13b0e4ebdfa76b4fbc6baeda7411883fa74c8e0f567065e4bca86570fe31fc3738fce1469c9539a398a182756d26829b42e7d2f4b48fd35aa2738144a8df7e08678768cfa2e6ddf887558215bb44437939dc911af50cfddd936346155a3e543fbbabdf571cfbf34fe781e5db5b85791ddc465966c001b06efa95e5050f0a422d3026d48604f074f900ec66ae3b8f7b9faa7f438d28e6233428d74dcccebea033f2b57e8a9e77abd8f4fc7f35680062027a20a88c3fe2de501dac972f0296222e6f4ba0943a9d562771d757a8fd002fb032a8bd30f05b6aa0926e4a86c6f7555d3f1816c68db915d71ab2ef9492b97f0741be24e07108fa3e02167b72b5976c83faa4450b52de247f7c54ba7d0e65e44575a5a53bfc37e807983fad7ca5bba4331abb1aa30c1444e131b83af8d72e51dd248feca5e025f6ff0852f929c672c18b47d9e057def886f852ae26d137492d24f8a2c903b84d88b92a3f6679d4039aa4e4292374b66edef378a7410ac091ec61561cbabd788f090d418333794dca3f9744b25b9b8c2b065ec71e9297c0b -TAG: 4a780eb826dde2371feaef229222cd73 - -KEY: 71132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132 -NONCE: 7840ceed28a572c5186f2546 -IN: 2a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c283d86e8371cf7b34cc9988005575c8e98ad34184dac039f04f84e5e8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d89 -AD: 6ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177afcd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036 -CT: 5493a45a3f9edc2fd6c8bf53d3f11be1262ce77f5845c1d47b306e486e6316abbc78fabfdc7ee8da152ded9f36b7ef3ca0ba8e55fcfd865d449fd6d44c99f16ff0280cc8e596889d737d0fcd4211e1e5ea7974698985ead5b8def15a8779674a6cea0715525269d2cae64ecdd8870b9f1ec78d6377edb9c975565eeda60448eb1c871bef0d951514640cbcac4e663942594f0bcf4da56fc56b961464d1777a177b3355ef3b5618f247035761f2cb7dec1fe2bc2ba3f825ce545e51b610613bea6c125a347aea55f8f4f5cd5400e689cba199105170bfecc8f0edce6a9d521cd1707cfb5d12f8f5a9dd2debc5907d05513a949e102e7f29d5ff7ad22eb57d429eaeddcaa2915333f88193f668067a695085853f7be8c0af38d774b3d6cb4ab415d70df8aa02e7461803f597108b27d4838d58b1476c10b570c4f8fd71ed9baef88c140163d5ba69a3c10df451c12a5c5cf66c2ee546c6da004dd5d671946df34987a19650ed8ce9e7ada14f3213d642a9b28d0e376e5e37907b7cceb86d0403b19fdb48b3b732633d498d847c2fd24e0260ab74dce88818941c6f8d9e73daeb7652c55c729c3eee7137a5b80899b036eef89aa02bb730ec277d26bd6498e7d4a2b8208d035498b8e0ff403b2ccd0ce6e9899e984a062b5bed1508f23d485642843ce34b5a8322efb9af3e5c0797c2f519d7ac054304b59461866413b0db05791fa9f16661fcd3d9d86291a48cd61d4696ee685a9aca33b93eef112e2dc772d6e304f150042fb49fa95edee661617d7ffc5624b346a82847249c06ca6174d8a408ad46d3c3073e7815c5e86ce31a82587695b2b6c89ef52c20a0ee8adb24263df1a52b4b3bb68b6bf775ba0029b36edf2406c2509ff633fb4e7b28e0a4d5260d48c364cf99ba662b65e3ac150fb3039f1d267e152f569d708c100121565d72e0f728823abad3a1969a4ca856e9f0f4cb0315f973471a4464ecb348950f95f8efc5700d5f2f0bfa9e4c951a9f37b576695d93a8ae5f2d59f0842f3ea895fb38f0f34f56dc498fc0a5d8816e8346f90215d68e86e69d656b1283d349200ee4935ce5acab7eb08b2e1af57a603a42ba3ce811d8b8c6d6af9796dccf549276ad7183f16a99c61e0208cccc2c80507ece9c3c44419e01a2e23abe2513ec13187d54fd422efbfe17 -TAG: 975dfc03c9b1ef9a854d62ed2a0b628a - -KEY: b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa84 -NONCE: 3473cea023d2c6afdb625b64 -IN: 11ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e6611562d15bc2b910f4edcc981c457c0c20bd2710668b59242f7547d2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e -AD: 86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e33 -CT: 0353acae65a2b86f88795b91e2feb614ab78a508c57854ce78e70667db42d0e8d1288b7e5b55ae50e95a1e3362b0ac3e592ac497791cabcc70f68bde6cb9830323bdb3d7c47d35684ae9a81dcf551698258d0d132eab80cd8926b71dd784f7d87f18158eee49bbc220e57f77c65258a5191ed15d10cf306c4fd22ca91d92f28bb0c602baee0bfe31de77350ad2637d3ea7f7ec04f4708a64c55bf0674dbbb4e9ec7e5ea2db16e3aae57cb3611d46ecc06d4796a109a14a0f714753e979a4b0090c99622c28b62680d437a9f4133dd20ffbbeff73e3a9b47b7c788abf42eaadd7b7284bce8b6ea4cd3bfdb2320f7f3016ebf3f06fe255555c44f95693db7de6470e27165e5ab0640e674c321591d4fbc941b2560a62a42535274d3a7f635c922416f7d9a5b9d22843fe601b296aba676802eb55ece3dc9315d27f56433821c18e760ed64d47b1ad6590abc0d75e7d078aba97d697358112347e39b15c3d21248cb839b23b6fe4957dec22b1e25efb4d537bb0cc8b23894436990583627acf4def3a293a4b9f03a3e8beae184f9d11b79d632797b45e972cb9812b91beb1d861c27728b5cfdf9e370f363a6d85120aa1c21f39e5d52f24430bcb019d328855d7d77082a9a331b788a3bf9dabb65f70c20b64aa3ad3625dcf5cc3153380ac7e61cba17698c387650c8c73db3e9988c10d093bbf5e0695a75772805fd5b2fb8eb7b0aa91b453ca2413e36b285800873339311b63a67bb541d7002d5db39b016c03522023ee6551195aed5154ffbcf126a3618c0431d707104438f2b8964a3e0602a8e22f509e390ecba15c999b14a677e49ca95251d0b5980bdcc7e95714fe28a99023af2c564defd802e1f24e544a040ea295af20e9bbe89df72169265cf183961e78b21020b863f3012c6e4087634bf720884e001ec183711ee6ce14f653fd483c0c1a2719b9dc9b5c64955ba8ff8d5755b0f1dad0d949800b1cca343276efcf6e7633dee3675c8812790fdacecb8ad1e458002ce0396a9d7a4fe030da5582b8ebfe390498407abfa4d1d6fd109ef6811d00f7cf422580f63b8de9dcf66d760bd2c925c82e521c9edfaaa6539e78be6acfcbc6a3183dd29009ea6b51f84528056061b010dc59789cfeff60c15bef4de847e6c3c4cc1e127d6d1176aff9f7e208a1bb70d85ae3a1a581ef08dd6197149abe068fcc5482 -TAG: dc652a0e99481d728e090f5b4c9a70b7 - -KEY: 4b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72f -NONCE: a39926a47e0b75a771783631 -IN: e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e48a7302e5e5e5a3f660bd83aedbf1e2a88ca05db202082d8a59d11b14f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92 -AD: 116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817 -CT: a8afc66ca05ccec231d39098ce3f8982dd55b80226a821f1a97919ff7389b464d8cfff1c65f784eda92bf2cb963e41ff5997ed60d23a80401a2a73a54ce880fd8c56284eacdafbad1ae72c4be9ccb761dba1a0dfb0983656b9749e05dad17c99fe2786fc21d3159f378db39dc227d2379f3851e94183df5c4cb858223a7cb43b68651cb3689b886a4ef24fe879205d0ccfd81872b6dbb0e7c9c5fdc0313130254f86e80d7cb044649051fe74425fe55e7472d396d8e15380386de6f8ccd303a9899fcaa63641f0e6bdba3ca3361566a2f89dac8ac9410032eadcc2d82123eecc677c7b16c100d54d8a297dbf30c6e9479278e513b500e74beba4b4a04038fdd68c96d5939a4041def41a6fb35510b86328cb2b8f6e80d9acfb555631acf856975464b770ded81661558b150b0896ac28f2946c63c9823c4efdf9595e867490e638ef495ffdd3045e0ffabfa669732f6fb3a4869b290006259bb4e19d49c5e88b02440dcac361b7bf6c60b09b5b597e9abde536b4ed29b1b01f386a5e18260d707d6ed9b67be012d0485fc6830c24bf4b384d2eff6de8b38b88603aaff7cb61b0812b4472a63758883bf5efd35680c85e4443b56e6f3097037ac92857ed2ce434cf5f28213539be251b28d3c8c5ee7c04dc6f4a3bf12ca24ce79a022bef0f4de9789c8dfbd8df1c7faf10f8379113bba9a3cc4f48e7d984f37c5626705c5f04c72e85902db3ee40dcdeed4156f68149b8b54722b93a926dd2bd546d1dbfedd4ea34847166fa4b6b325534d88e66e48aad81758dc45e461fe001a6e400b68d2974852950a0fe218933fb601c95ef818a85130c434e559997d5d534105441d0eaa142dad3e4ee686554c83128a1266c68c6186ae2a7935eb5a7dee455fc41025741a539fd84d5acaa60c9151987031f61cb3951c96b646ad3f9027f63768053e7a7fde524dc7bafbcca2819ecfb802cfa9367cfe54a1f0be9f949a471801b81d7b5d72be9d377c97cf452eaeeb243006f9dd1381c0e77f4215a8f4d62f959b83fa9e8012c121906f0bd2b688444da3e2377855976b5c68c888e0a244ccebc9f22f4051d030bc95e256fa95cf1e7a958a88d6fe5ce111b287c24e0e71e4928f7572b34d2f6bfce3a2c6fc89be7d54a1a7c222d5cb8fc3a108c20a1e1e55e6a2f3018c6bb2baae63c3cfbece1fe0959456c1506987fdb5b83acb5e4cd2112a0b18c8d0c0afe438917 -TAG: 21d5eb52605d2ac429b971fe32cc050c - -KEY: fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e -NONCE: 2eebc2343a402e3efdf91f7d -IN: 63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df46642344f4f7c9ef9a5fae05c10b2e7ac41afd55e84c213e1d5f58f4c7aae4f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f6 -AD: 82257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f324879 -CT: 90cc04db6cb6754eb81e088d126829648e5b3ac91b89162b3046635f95d19586eb89646d9412ff3c28321504696d8d8bd7567214345c1e694eeed1ab5e3648300eef27739ba0c286e5f6fe389ac4b05f13e92dcf747aff418c97726e7f0820ea4e93121cc2152d92f2711f64e7a4c66e74c21ad58f80218c292e6d152fe5364fd2b186ddc811f8418d5ee5f7a03ecf98e69dbef146af1fc4d7eda7c261bc1d4d3781ef2ad9a9b316eac55758f97a73c67031886e867d98e1f7c126f19e0aae251d92781ba3ad6c949e677f6f71a0d26e45a8bfbd9c7a8b8fe4d63e687a2a476683f72203f24827a0ebd3162305f4c6e180eb3a7bf5ece592af7831b52479021ab76223e7d0714e0a08d5a621756b84d977ac5a13124e9206caae9c6a2cba1257a81903045414fd6e2403b2d68f07becc2e7a130366c0397a406ba261dd800c647fd087f50702d25177d1cf0097552365cb9a729e27ad9c1e4a61031374d362e309c29f649c7774756c46befc17a7c403a821ed254fe7f16542af8060c5743ce91f6cce0ebc68072c305a1f6d0d97db2541aeb87759804e15308e2955a0e6110c3613495115d1066e3701102531e04c1128ef2dd4434850a6c808cc827c27caf9d2d33ce1646228c26f6d9e7a0d05363694198bddf4f1603dab87e5b01363b3cb4daeb0eecedefe2614bf6d09b01813bb0995615d06efa5172b11d08a46a577fa99aecb30e310e84bc3049205534e836a44fa2de79134e6e7d7fc6e19f841e3f31fd5a8c91c7251b7c14960e2efecb2945dd64926a3d7052574a9f8ffc0f9a6c62025f58275a4ce3a084e73c1094834c65f59e09d4dd16bc75e26810506f0df6e59ac486439ebae613356bc5d8245e15a2c0d8997d80235e7475f6841b6e28cff61d9f5ab11a718b7b60c125118d3f77559aa539c1f15abfb32126ef7a9104c6902b5f872663539f78b002aa11f2224f2b724e346e9fef6b84deec427a05576a51aad885e0fa15e083ff25a1f97b7968dcbbced7b5f3da137e0b48c5bbf783c7125f6a1c7f2e707212bd608bd09d12104ee593838842b127a5b8050a0d411417a5b88ffcbaccd32d1642ff00ba22e42e8827b5be97318bd0a69b06839dce80ef50ca43778a60dcd7193af7ba5da86149f7fc716c22fbcb0b1671b968da755f527dd2ae05ef2b6b8809ce38c9cb8b7095d7b3a9afd16284334da5f0d85b70068646f4ca3c6c39a2ea1d146b84662219827f756b2d1ec641f -TAG: 8c7269eae0df5ed6c8f452fd89c09707 - -KEY: 20261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a -NONCE: 5168b8e6c75f25ac1087b315 -IN: ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0dbc3e4bd36e2de49d855196d82175ac39516571d209cd5a8579b05fbb0bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3feb -AD: e9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c983453 -CT: ac56114a0ed27060f87c7698d659d16b05219d9e013ff22dc90ad469646177feeda9b41531c83ba781c641c740c273a43cac138450eca6c9ff42a2d715de22e0c0e1954842230a0dcc887a42acf1fe75d204ef881af3de7733ebd84a3bed530b34b737a35394097db372f19953b5f9ce288ff8785da5926be93ab67de884d8ace761393c2d3c4d308964a90cc49d9a5a31e55fd20230dd71498d1875476ce257f175135a22e1df34cfec1f31dc788e7c00a483692f1fab826f92ff497253f9e56efc70244346e7fb32180cdb689c6a404c64e391419ccebd9034cab1431be1bb2bd4defe4770d1d9b0cae785592a28ecd3e9dc8993512088186cbea448c8b26ca1c64d623c2535cca60d92a3840a01a9b2b0a7f359d1c597a550b62eb6ffd3d454df319c6c5846c26ccb5ed59e0d3e58aa63615bbcdf4861d85c1635fac7756818a3bd47f5e2bf2b3d14e13ba409379cb62a1b2bb420870879fa522f573eb9b1624d5efbf67f92e50892de2ae454950f97e2b181bae56498585f3b19cd9ea603b6131dfd3995ea29d0bb99f5e6eb6bbb35571d6ac9e52fe02750b97f024b9328ec1dec6aa3a21e391804bf7aba5d3b7bff48760f4fed880259c43ad007208a04a20ca0864c47f9e56b0c969b8a84fb7eabbd58e0d91c44bf8a6ff12225d2c0768c078cb0bf6f0dd67977d801634dd8162500d6440ceee0bfa8750e9411d5a579efb30c34842438105ae2eae6430ae6a98cfba882c974f0f6c870718e4700dd9fe27b98599918896a600b3ee48ec41da20079efff705861c245d31a5d827ad148d0a75cd02b5b7df3484317ff0c2a0a600b22b13bb3b96f2d1c95a5884210e486763cf8d96af48c5bcda8c3ce650d2968981fb003ed3afbd43fbb06502b547f3961e6ec636a12a551a9863b9b89f21dc9485e62a43fc1059d65e1ccab12620ec3a98f2237294567239882c5183c596050b88c38f8be62b364e937ac92ce5f7f8e540af6507f04452ffffb67b51d0e336f57ba71c771c35febbece8e7b0d4eebf2dc0c43df1f42433a3c83a38941d6bbe12e7110f7f266cacbb6fb07d52618e4992a5930e1d416d6e4d1b41a0ddc4ab4a592096bba9437050e2064e0c17d1572c44ea52bd071a8dea305a9d633b0ee963245474fdbb3f274e119e59eb50b63b58fb05ba74242d3ef63cb3e3c98576d2986bcee85d094bd5528d8f43415f627365b08316c11abc433661b83a36129da0550507dd62051a8f5e01c043a04f849899668b3ebd468404811 -TAG: 1dc7ba2dcd3727f14ebee62ecdf66429 - -KEY: 99a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3 -NONCE: e040d46d2429ff2b38d4e35a -IN: 3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f4248364f49aea2a19ccab66841c438df5ff7834ccad859bfdd89fa9af0b99214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376 -AD: b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fdf56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480e -CT: d560de73e9674b561fbb54c6e4267d3101479c2fc269745be89c470109068cb01c6e3a4a7a9ec284606db6e735df2269ea16863673fc35c911fdd6201a1baf9e0b562a847274c2defcc0fb5c165662d0bcbe6b01fe595217d482ddb616ee87138424f5438069abda9dcedd48b29125937e3266cc9d468ca38fec9920ecc81952101c8aff3d3ad2ba4953bdcf26642311ec8c4a880870bc81ac647351a49183e182acd38585cafad3a37a0171c0a0545bb3ee6a67a2da41cdf2397c529064b09dfe0105917e1da7c3df24d2dac6bf06f58efcb38752ffb79e93031cbef73e6c0ad68fb7a192900aa8a23bbb7c6bc15fba8d80058bcf9656323da4c10f19198d9db3b42499621e1d60de8a16046853fa03b783dbd076d0f51fe40e9ce60f4e22aee657246d3ac80913bd495cbcbbaeb778a485bcc6c596af305429afa5f09736e7a78b335f484bbd70a3359a7aa2f4c336f5780f3186fd1753e4673e5234e3f8b803f4199bd859d65267857f8e0391b4e8253fa644a10bf9f68a664bf7573628490b1baa17c23aef5f0414067d2186c08e27eb9d1034aae6361054f2f9bdcb877e72837c70816fabf38e6976c8a5b20ef3a150a5d1ffc997a248ae199d598a01b5bf7da1d6f7a57f982026527e950f33ae33cea9d64e56a3a2d26ed2f2cf0a5d08e6a03db5c483aaa0049514e013b915056c4570c4606e6baefe7c6a74ae301d7b9b6b980d85bb500c8a61c05b38e79db47d2d3b88db098737def0d995267c931a2ef21bfc0d970652a3be8de5f42c20fa43e1f7bbdc34b3b5d2fbe3c396037fa885ec6213748de5a6b64634757aa519573aff1cb78a3191dda039a3c64940b816fd010a584a463cc17789c732d7a099fb423dcc9c20fa1c0f10436bf67f9796c1bab8c85ed76c2cae84ae599f7519991367d69948b757a312cdef01c535f1172ccee7be47fbab14362dc0f3fc89c7a71ec9138b40eec235f585e39b008d1f29a1be9332b2882f6d053acec077ebcb6393ed1dc46d069134d2c37c7f14c0fc9f9e280a6e2598ed8a070edcf9b79a042561dbf3666bc49863c29712d45c41d434172649baca0c2b43e3364cdee11f9da14eaccf8a853998a2a9637b268b6dbbb342575481c37014631180737f970fcb8b8fd5050ebbff873b5bf124b315799c94da41b8b5a4d57210c4edc26ce74738b2fda9c02b3fdac251b2b317d8edd345ce4a3e074255e8c49d8bd02376ee2aa194513963a220529e6c14611288b788b68e74f6dc206ad094e322fa3002d62101dc4d572ef00c1567f0e7a4 -TAG: 799c10bc86be84658d0b03751a29c71b - -KEY: c6e78bc1358c72bbae8fd8dc84038806efbfbca520a9bf9ea1df8ac365a0a95a -NONCE: 9865ab3b3556ad8da691b079 -IN: 26db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfcd12cbb53bab8c9884eb83f1d2dec7faecbb6af3402bf462f965e2c2281c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd -AD: 770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521c -CT: e6ae771db203f1e58b0336c9c655013940053c2a40cc7a6a27e707860b179d7895a16f7a754c2cbf2e0fcf610a3ce97be5e7459cff4684b6b2848f2a39e6c4572c1d7a41f23646eed5909228adf1052adb34b9c44e5ca8b2bfc18a80675e29749e72410851eecaf261868b6b69e7d9dacd5f019de1580549fda721e383b86eb0c51c2eac4600a4a27b5f663a7c89c81401fd452027819b93281b559153c74e5354c320cbad932cab5d261308e241e85c0967a189de09eeced69c834b4c64dadb9447a824bb38d8b8a3fa4128bd8392cd34b0999b4ff0511bfb9fd434a1a0bb3c507c2828d98ecaa9f2dd5a020320f6f31324fd8ba8c175db5284628d1cfc4816054587a6cdd5f9e6d6de2cbce9396e874df36bcc347ef48ee9e6ef7e6cbe976e4361651cf8f92866cc3a54701af59ba03fb8d23024d6be73e1938836c31b303c687c28b1785c5f9b97f3b09b7ec3d83d8e38dcd18c3409db665bf74b85abc540f678bae40157eabb69332abb9c47995f4c412a04f9b99214581f1d18e0662e77a2ef6520a23b5a031153d5586f169923dbcf08d403e37184c5f7977320cb33b8a0d5d7bbb25d7a8477054874a14e3d34b92f7877aed42f595dba8830757f8e92f21d5feab414ecc9e3933f082bf46fcebee2ce5246c2fe839fabd94d4f6bdf875cfa67867f9376281b1e5385d1677a595b018617f44c6113f6178e5446cd28facc9a53bad29cb5b3a3b0cd29186c24339ea008ead440041c6bd0e93b92ab37e3692ed13769d147a1be8335feca11a533156a3e416908d044a5a74454f10d3e59e5f9868c56c517ba1d9642c41c6a764e74540611545ca90219ef4a0db0d25e92196d700f4e57a6778d20b6acf7d1db8060ab534ef409fe35c30c300418641368f0a3ed2407027c126e967406809524860cd88906f046a069a22245d9b2065cc5fc313a7ad79bc7035cb681a39387493b6be51c813748c008269f0681e88616ecec8a01416e4ee8b7a6e4fae2af9648ebb89523434eeae6e5713eb8037bf173e467a6da7d6cd3d357e3962aaca14c03b04046a4f893106e199062360217afe40f40214d28e87eaadc175ccc11d172f6cd42e97c1f331e246f7660fe22717d7f1e24752b1b01398e4c8bead71d8f6aa2d230c6392ae21d43bd88258c1219d491b8de12d53bb9fb917eecb0c254a4e9007f789699de1dc90d35250c6ec4631ced06cef9dc0b0416148835be0be3dc4749d4c2edaff37d7607c9a3e872f723583a1566ee1fa7be77b848fbc4d741ccef311fa5ccb7c18f19295e53cd1da935d663f0b26f776db6d479b4cf3d -TAG: 4fb43763c09a6af54ef7103ea40de1ba - -KEY: ade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa586 -NONCE: 97121394f11a1b1d9caf4e3e -IN: b2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302b243593177cd099dbacd5f8efb412a95132b8ab31815dfb463451fbff63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b3614ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc762d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb -AD: 20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac5 -CT: 0d8f126c444afe37e40d85b6f0c9f02b2232faf975d238cdb227a17ef28e18afa6d88d7d23b99826de9f6e7390f67c2ab722e1be3e5d9f3a2abe41e508abbd22897ec36a70d02fa54db8004fa3dcdfc729d58ee12ec5b1c85346289f2112c059ecfcfeb6e4723904ef1c5e3bd123d302f6e4cc393cf62513cb3e2df3ea822692edd0d8533d6103f22940cc82116c4ff1e5121f0ceb08ee581f40ac68e23c7e9a168661e6d93259e614a3f962fa2ebcfa3a4736f3490d401afc9e6aaa8a8d00ad6926b3a99c6cd2b3b05767cc5b45901d0c4301a68c0783bf1611e2cb95d6859293b615975be7e1d829f13eb4fe601b4d66af3f28171b02d09f820dc77ffdd22537ee2ef0cc291f785c466ea45a0dab45e782e7ec3d4bf0622680791883f89f9926009f6b6bc3fda4276b79d5d9070914e75488c033d47c58defe6b538c58b106fdcc8957619e008f6b508a87d85d4a46364535e76a890716a215fe5f2ecf50d8fc0d8f68d2ee0345497f94525c588eb3d21d66caf1cebec2685020523998cf6e24b5fbc384c32cad31a2345fd88c8b820276d5917d71e69d54b44ff96c8411f1a7b6267e20d67e35cf274cd9031dc157d5638f5fb8faebab2f5fc976fc928bffd8b60ac8d8932b8ac076a000675cc05aeb4d8306d65c6060a46bc200193d56249e605a7b10fa28f7a04a72055cdfc6ced9a220ac50d3c36ceb4ba5405945307f2d332a9a14487d7a74ed0c379623e2fdb04324e515e1d5ede3af27fc5f06baf8d354f6b68621e372347817cd3acb05df1817511c978537722f9a4967db31d24336704d8d7f974afedb487ffc6e877bb948f0c30fd64be7608723eb732a6be38394891e8cb789cc9ec2e09b8cc2ca76b56ee7e1d5e4c0bf76f28d705c61104b508b1c4c7c1a1cfec10f25676ea55f73c95af3fd34bcde939652fa91f5fb9d8b783dcacca1332230e2104cdbb905511e8479da129ad64acbb569809ae2a19e71bf7fd6acc18e7087bd49997e3d57eb19f30afd1a76c42ebadcc7f8d231c0c28c7a0850ae5463d1730def54c24a803bc1e889c0719e364492cb737378f7390e5ae506d36a7f42bd86a6184cd6cf0300331d0f54cd6f5b53200d59eeb8cbec25830eb74b0e1d931073dbd991c8a818d9d7f2b8691fa2b523bf73d9c7f101cb1d83699b9f5e1b3545f8efbb8eea286728045202ec8f81c71bbbb6e888698c69b92563615ee7d07f66c2495cbeeaf15825fdb3a3dbaff7347f5b52f6f886d80464aeca6e35cef31b6909bac29079ee1403f53a6ec45204694e967bcb318f91f4af5e868be46df4082f4e77c627bb34b017c0f9d9889184f8e88d62613335 -TAG: 3350bc1b6fa4c20bc1c0a28bc766778f - -KEY: 32fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fd -NONCE: cacdf99a3852e9ca9516be08 -IN: 987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f05d44b6e557031ed28b60f3a9e73293d03f57c9c636ff9336cee086358c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de0 -AD: 62de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b34 -CT: df417e819076b3a8ae2fa8f0ca968d5be1f31c4c44d02f29f9f1f69c8d2c269835426ea9735aaf95da0cf92b45d512ee8e4b073b40504cfbe9efc62770a0000706f16f7cc350080e52da3501675907b2f657091c1b5980d22bd7dc519203a80c674418500224900d74a11ef87d9f60296ff5074674552263b7b6b249c8adde311b98b4181a3730c101c4ab9bd29c044272751197498e8baff4a8f2558de20d4920ce21f4dbecb64e258d078974dc6c2d574ebc8c8ff32505db2ccd349e82808c44eca7f4ade2ffe9ab1ff2815fd282985a8de28147e547023f0254105d2d35aedc5e2083bad31e05ba905c1b3c53f354aec095add4c5cb40c51adb6a2c290a867ed58b05b14170f8cbaea863ec74a3abb66baf60608721b96c63da4b4d966d1291a3293539ead11167ce4e45f0f62cfef30962d2c979073cd7d0e89899397cc0ecbd858da7de3975fce6ca3bd6759581787c5559bd41dcdc177f6ff4a5cfe5b82236d467f93abf5b2abbd30a90cb25b4ae6723c92621820704542f9d5215258962c67ce9e9e2427c58b5819a709488236f12c1f2a7f5c915a4cf2f8eb3c103a4ab9769f76102a8f8fd73aad7c7b6146768f3a3f53b8e276a8634fc50446d5e0cfaa589a4a7fba9a8095f9567506dd6d2fed0c1e3146dbdb74cd116c13bc5a7ace595a2b42e0e3d46c5232cd92799d6ebfbc06c9d0536db35295cc4f7a7a28bf8ef3c649833d5f330196de4826462dd418f95450cd431454cef7afa6f2f4294ab69bb3e588d3b9300a593ea80890e9d678869e963e75bbf281b61f9f7cb9a3f9a773f2343ea306bea4609b03df78e57d5b9f682e0c0b10b57f360e1b0b9058c12f653b3e1fce60579b7c2ebdbedf0090fac36e72099ccf58d1bd5d7c26701f29f656261e8c2e7d5ae97b224293ac133b2cbee65401f8d256d5106c14da8c837ff48f2479432d5addda274e72ef5810fc3a42ef9b27e75c89bc4d72d6670f855f228609eadf8dda76ade9804c642b140117fce06bc441cf92429d2d3b03bee775c1a52dc409fa4e7a5d3e39f9d9a250a288a29c9de6abfd0303f676a98025a7954fcaf6406d765a260e08ae5948326173f44f2d7cfb5ca9777221f0c984699a9cd1d20c9dedda95b8f066736b372d23116fffd55f7b03d4c7f63a8be3e7806718fa6a961a68db681edbdeb4281c0901c2ecc895f9da0cb04cbb03b5f1323e00c827dafd4d42ff767ffb7531e412d5ce11e0dc469f7bd87549ecab2ed21ee8deb164f67e64bfcd85d858f79c20c8bd4c37d7be76ad6d3c040a3a27c13f70f14b895178ccb02858764e315158ef6cdb827b69dcb24a3f54c2816a75be64496c139d541302b0b71849fdd92e0b83d -TAG: d8f838951f98deb27747a870cf55713f - -KEY: 4a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83130f197a6f35def -NONCE: 3e8e2c6598e6c0a8ee6b0da0 -IN: 1dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2714f39851c1fe09297c8c69dff0e62be3383bb6aceea0cbc71cc7783cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b -AD: 7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a944 -CT: ac837bdf77bb97a1bac4cdde49ef8d6c7024f5f25a7bdcf924fa87b0c77ddd66bdb67c9b8798922f5378c0405be67d5da47f7c245c5f7330accaf74d5bec6a8667c911384d9c77e9d3ca38d88bf87deaca62b58d092bbabe64895b944fa9f6bca0aa17a55031fa19ab0c324948816c57f67adf84077b277e71a7db9a6ac537a95e54d3cd4c9517bcdb7e9e1ccc8e7dc252c27c89b9c20c9876ce7c01b17b80a05c6f75006cdd1e081ade6f9353c66f7113613a5f72d82dd28a65efb74d0d1c92793d652edf23bf7c70f6dcfd5d40b2799b60c2a6fb53beb02571c78001381fc97d4a9292a0eb7a4a0a67cdf20b4810aebe5aa4a6d20fc30e2971924a09f106d0b5b7fcf181321b6f8442f91fb7ff3b5610353500b9d6f8a36301e7cb12d94d1aab6ec0f797fdb57232c02d5fb4b2ffc7d0cd2336ff96a4a811cd1aa02248f4a48c7646591507f9e02f8f441cacee92b5bb3cfcb7a5dbb02993d0fb1818e0ec4cb719a6b43d82e15ce576f95912ebeac7a7aa377a50d1190799b00a6da2fe7cd7231c3fecfd4e6913df0b46887ae8412cd2c9de49ad7a4e8f55e7f53239649b566c4940db50e0ba9a915acbdf0ed97905b0c70930d49c5c31cb398fa4f52222d3cdbd9374ae9d7d979991fa50a2cefeee88b3943578f99b9a46e58900378ef22880c862103ab7e0c2066685571b28c3407cfef5bc0c9b176be8dacf6130bbc44389aac32cd0011aaedcb752e16a1f99838030f7364c17441de87d5ec670a25a2b55a77a57f2304233b3d9d1f4c7b145e7e145eb8607f2d9b6159e954f14b02609830fe54ce1a7dab775b49d77a0ed503773c81e3c53f50e0cb676387dec6e506494ea7843fe533aa7f09dd1d4c960dca585a1590035a9c36cc9f821b4a8aaff6548fddce5250efc4211b0ad0ad4dbc3dc5038218e58851da4848f399f8d7938da211484139000dbf8b6c6314312586311ca1d8639fcdbb20b6a6a608c23027eb46938cd6bb869ea2d3b327728f31012de124a9b57dc96d5d98154b98045943a24e4f788e48bbcf0dc20598fb91627f09495c8fd5bce762b1193fdcf9c45174005d589ba6ad971b5d7ee13e1aab89447a14f9d750621184cdf55ef4ac2f7fedd7b8fe89e0fefb4382ea18cc4feb62e9650e9ba5a12f9366584ec774f5aa09793293b558293991de7fd1793bc44341a5b59cdb45095d5b53a4b847512dd2ea621f9778b4c0f33cb7bdbee1061505f08f1f2919cafc5d6e45206cc35e89e1d366b7abfff3da64f6cfc0d0b855bf5d425a85d93ecb01186697f60a7a47870ee2a6a50cdf134a67a51565d28974dbaa9c62ffc960b70fcdadf79dc489741095ef3052df69c55b99c95a44728d30e267a02922c7a6ef2523ec379239a5148eef6 -TAG: 09a43ea9d67cec2b3f35d401141af9a8 - -KEY: 94f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f -NONCE: 4fe1fd1359a4332402251d90 -IN: b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23a406f8b8ee46d958d10d8724d90bb26e2b38be1c0e8258de3a09541826486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113 -AD: ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43f62ac96f76e13ab5928147c5e63788bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ec -CT: c5311b1a6e3d93da070ee0fc2c1007558db64bfdabdc23c832d151472513482314e7d9385918abe772970c7d8b3ae4eb0d12965e6d7f6d01f6c97d06b51d3be812dfb290592578713ed6342a690ac115c29d471826f37f7f7b46936ab9f431cc0e4029579036bc6311574205810fecd3a17ebccd0f15752152276d5169b48b0a4fa93613fde13997517956f84500edd7eac1082ab6b69bf43f56fb9046cefe8425140db5f6bd3bb201b3345b2138c7f42120a3009ccc19e2d95ddb2b4384205d2aecb47c89cb43fab6c353f781caafae280e93dff5bd213640c41cfcd81b9dfd1be05ce21758c5474c38bd24819e5d085241dd54c8d2cbb5b21a616e47c05d4c64c0f397fc16d52d008fe4e83c040a6304c41a448784fb0c54f8a66fb00b240b9d66e8db234d14534dcdd6b3ba78db0403cf0219406ca858fef6bcb259fb69c53c6f964f450bcd12997955d0190ccbb2d9ae6b3562d85dc7de2bf1bd5a8d49651fe5de73243d7f89ac8796387e0a04c74d5834e47afb6b7444df7d27592fbfdeca72428582703ae52aab48c1b587b12fad6c887e451a54ef81481e3d8b4da1e3fc09404a7c209db8c880c40b3fedc579fdf19f956bfb36d5b2d1affa0a3631681084ae4e41e3a0fed84e056bc72b6c0eb1f5449935f7c2d3de07a2a5fb65af65f91d2c1d730edb80b437cba66fea779449b68c557c5f8bc6a2581b6808a98a1acb9e6de414377f5b08fd5cfeb4806e8699e50236dc8100a88f4f55d887caaa6ae8ca09c23019126b62b5c3186b459c39ee397076c825b6e28ab62d8286743f9d07182cfc634eb4512ec3beb04ba81bc20294b16fb6d42301a74fa95f95510155a15eb953eaa51d82fc363c0c63d1cf401a3ccc0c577474f99f7c4f187316fb85e1db38dac1df4b5e7c710be5b5949dbb1925723d042944eac09dbfd74d7e876f5931f619bfba1ea9580bf4e6c2540fd68d5aa9cd21203ba207f0f62e325c1e054271933563063acb4d932eef201bf3312763dddf6992fbd128cb8fc8b7936acbe8712ad398c5a8719b9efbe0927b9f637f323c4bea80901091608ab76e483b5ef666560937705bff96d430e6e17b0b24c755de19bb88aa81077852c92a96e902d538b4e11b78a4b5d1f5669aacdfe5125d806a21c06ccf4980edee24e41b7e17672fed0ace9b19e4d55415d097f0b5874d60dbe311871abaf47220893c398d5595ee16275eecc6d15f39aa5e2181ad1448345406a4c77a34c3fac77b4c506cf393791d69e113270adf0393cad689a07056e388ea3bbd00ee5878e1120c869531a8b4745ca2debc1e008493d17bb3777992cfcaa165188b4801122af5422acfa0a1807a2a35e793ebdd95aa9e025edc065cf9ae85972a5f42da193cd9b653373a6e15d647b8d26207f3230e50bb49 -TAG: e2df8917d70683fb6e6ea67db55367b0 - -KEY: e22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6 -NONCE: a4c6732e0887f40b5017de54 -IN: e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585ffb8f86b254d0e08d0a0f5a499ef1b2bb0216e486229f5deb16d1e95332b8673652a86a6e3fa0e479987b2bdb1909fb772c6836d15cc57d97f29acf335ec1873c1bc6e714b689db855c8ba59289fe792d93774dd83313e3fdf11bfd6a40d6c8b57a5989e844cdf2fb38c239f6116c1c3aafb9356ad4b07ab37f7fb089cd424a8c1f19e5a13f085ec8cd74c3c9f0aefccd6fe5340eb1e419d15285b6b0d3b57a5545f6e28b75bf4795d995a20dc7a618f0f77a174e3eaafe221f8da0cb071473c507054243a7f9eee7d5c77b071602936fd5bc411e9923fc82016cf5345454285e9c1396696e05d984649a2955d7446a1d3966adda11bddbf3dbc11e093c15b7d4fa2a7a0c33fa28dd3242738d7a77775cbeb8176a6e9a4e4e58e03f631a67c3229d57302fe5967c7e3362ff926fd584edc32905a350b390391f7fc3343f22498bd198ad56cc2827926b0c4700cc352bb990876db7c17e2d32b5b0af617554a1f76c32b94cf7728e89bc208f22e986e7d2faef190f820918afa4e08cc46adf0704aab761cbb9791aa12eb31a7785d7716c3f0a46afbe2a44a52e5d0944fbe207ac78d54c407679814cc03d9c9ea28f1e518a10e0cf034d1ffa27b67c9f027d738e0a96a381571bb52afe2e983b34f9159f05d4ac9973d996c4612b7c60407a66925068fd98ba6b7742a219d8bed4ceb720a8541f4cd9eb990384f8f8698515ed3692 -AD: 8eb26d00d61388ca0f06d45cd697e36f11e25f618eaee0562dbba21d10abfd0bbfe232e6efca4947adfa7fc59de529652d11847d3cca84ad147f8905bfd0743be43cd21a9ece92d2d7397f74b1632ec2b1e398565e3f37039f1e147c061b51d59eb31bd16bf830b7824d1ec5e79441e5c5e5131062171467a037c350fd16f58854e3dfd9c1224d26fd600b006d4bcae123a7a9d4e98c47b9e9e3fdbc22abce09b3c24a5a060e371ee70110227c9a8b6049f194dc4f74cc97d01247d76b460774acf7c5d4a8fb4f01888e29ffc517839c234836cf513951435f226e635ff8b02b18225402b026566e951449023fcf7f6bc2285dac1b7dd83028697dac70927db01c22921f6a7a6304052e58c8e87819bbb75de9cbe6239cb1ae8fd4849eb4f48759aed59d5a0ec3108b3131b0b74a4f860e37d02e04b9501e5e3c306cb25820abc50cdfbb05f8e5e2d2b94c58190c5d950f804786fb2ef97eb013f6f049b38fc57561b9cdfce5ae30516050d13d0ad8c1d750b51a552520785a9dd03c68203d91e72e3bab17cd67989bd103532071676718e889b94ee12856547a6d0a6c88c236d7fc7b0d8f222592d00aad4e813f8c738bc10c0b1fbf23bdb2baa56b1047348ed172a15dffd0bab088e2b406f040ef81d3362d0f86d129fde70ffaf87ef3c4554fa43850d1816407b4d5b0459bc622414a2d9cf2809e60e467fde6ecb7f4d9 -CT: 98763c2423882eb5a1e9075920b2245f2243341f6dd2dceae7780aa738fab65c7d86f41dd4a64283752db5e86cecaed0ac1afe966171e94f2c30d63a93ff11343ce15ff3bf464d88a6912fbba42c08e6225cfaa63c6da17a6354a34362fda3d993920050dfb99c84a235726aa4cbd66260b0e5675bfe89078e33e76ef537d2071d5801758c6cf07557c0e8bfe0a49aa6e212d69617d1a22ff15a26ae28f4d724d6b537ed34af62672cc9d48836f284cbc7eaae8cd15b46b8e233c94bf3036713f2679e23e0bd829dde5b3a5d7a2d65193f55a45def3d52830cfb1ce3f8208c1425d8171a053ab076c2377f7c26b37970bc3c937db75181a47467b9735be331a0f30a7f3ae135a533153ecd0a5e0cc1568e303a6ba6065c0dca8162a33df7c5b69542938c88e2141e2aa697c48e72ec0573065e9d9a9945cfd070d45218f646e5cf0c0ba145ed1fc7b7cf96c64e3a4671eb6b51ac8eb79bf0b4abd56fffa2ad8a93c001e2baf0b65e257782d7b7e3a837cbae16d40183a8b629467f77f2c7f8640da57904ab75a642e99fe4b45ba7ee488f889b07ce7a4e74540c3e0e0e67f88d473509295a66e27d4ebda1d4d3313add2555477aebf7fb84edbfdba18afc6f04c4af6a90730518a8ce28c12ab90921c413bb822e63cae113e5254039cdcad2dbfecfd97c183679c6c4691c99ba771b1389384259b966f358f871343b4bc5f9a92d8f27588202ae1269658ed91bae33deec6a6a35b9fbc523cc11cbc15024f4dd386b8f41c3fc7097d717099e722e6243a13bc475d5f2b1b2569f14cae6710c8650bfd78520caeceb035f58adae811c0fe9857c8cec59a01123e5eb2774190943c2cc7d535af77ea1f79cdce94e23de21004c73fb8469c230e25fe245c8a5a6314736166a7fe4e1bb0f91ee8d60daa0e576b9b7c6b5957d4bd8d8b928d36aa46fbdf742dd602f9cda2ed1608255d6dc962cc6d3f270d6a42f5185b38e6f0085f39dd17260f0580b62d49cdb668e3e5f76d47dd1deaba0db5b315ed6deb62e6e4388a74ff21903d7bed3c3e87585675a608668bc031aa83e7546cee77bacf9d3f5cbcf00ca71d6f6c86751a5db0d7f7065324d33458b7fe66e2b63bf9d8b514006d14da70f0d64f171a7bc11b2fa5955b85090701260a13cb52b930681e10e9daf89bdffacb9c13b9b60319e3be0ed29f7b7d4723ac5af888375c9e23bc97d3b189ec778eaefb3e4649d1b1ea96979c8f004064abefdfb3479e924dd974ff6478beb1034124b1cf27fc739872bd24bf257df2068475f0b144e61411481a48739e2691e535b64066acce2e0fee9c239c4015014dd38570b01646bbe97a389a3604312f06bcf7ae288790b73434288ba0c90d7015bc1bbcd5a0fe84564cd6a692df04d53716bb96d769074d758bf1199f716cfe5c4c542f9852435fc9675a80b4d -TAG: 9f62d794a54433e79c71a5a5cc8d282e - -# Counter wrapping tests -KEY: 0000000000000000000000000000000000000000000000000000000000000000 -NONCE: 000000000000000000000000 -IN: 000000000000000000000000000000004db923dc793ee6497c76dcc03a98e108 -AD: -CT: f3f80f2cf0cb2dd9c5984fcda908456cc537703b5ba70324a6793a7bf218d3ea -TAG: ffffffff000000000000000000000000 - -KEY: 0000000000000000000000000000000000000000000000000000000000000000 -NONCE: 000000000000000000000000 -IN: eb3640277c7ffd1303c7a542d02d3e4c0000000000000000 -AD: -CT: 18ce4f0b8cb4d0cac65fea8f79257b20888e53e72299e56d -TAG: ffffffff000000000000000000000000 diff --git a/crypto/crypto.c b/crypto/crypto.c index 06000a856a..8a3d06675b 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -35,10 +35,4 @@ // initialising it to zero, it becomes a "data symbol", which isn't so // affected. HIDDEN uint32_t GFp_ia32cap_P[4] = {0}; -#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) - -#include - -HIDDEN uint32_t GFp_armcap_P = 0; - #endif diff --git a/crypto/curve25519/curve25519.c b/crypto/curve25519/curve25519.c index b4198996e8..30afff0eda 100644 --- a/crypto/curve25519/curve25519.c +++ b/crypto/curve25519/curve25519.c @@ -159,7 +159,7 @@ static void fe_frombytes_strict(fe *h, const uint8_t s[32]) { static void fe_frombytes(fe *h, const uint8_t s[32]) { uint8_t s_copy[32]; - bytes_copy(s_copy, s, 32); + GFp_memcpy(s_copy, s, 32); s_copy[31] &= 0x7f; fe_frombytes_strict(h, s_copy); } @@ -171,21 +171,21 @@ static void fe_tobytes(uint8_t s[32], const fe *f) { // h = 0 static void fe_0(fe *h) { - fe_limbs_zero(h->v); + GFp_memset(h, 0, sizeof(fe)); } static void fe_loose_0(fe_loose *h) { - fe_limbs_zero(h->v); + GFp_memset(h, 0, sizeof(fe_loose)); } // h = 1 static void fe_1(fe *h) { - fe_0(h); + GFp_memset(h, 0, sizeof(fe)); h->v[0] = 1; } static void fe_loose_1(fe_loose *h) { - fe_loose_0(h); + GFp_memset(h, 0, sizeof(fe_loose)); h->v[0] = 1; } @@ -1782,7 +1782,7 @@ void GFp_x25519_scalar_mult_generic_masked(uint8_t out[32], fe_loose x2l, z2l, x3l, tmp0l, tmp1l; uint8_t e[32]; - bytes_copy(e, scalar_masked, 32); + GFp_memcpy(e, scalar_masked, 32); // The following implementation was transcribed to Coq and proven to // correspond to unary scalar multiplication in affine coordinates given that // x1 != 0 is the x coordinate of some point on the curve. It was also checked @@ -1856,7 +1856,7 @@ void GFp_x25519_scalar_mult_generic_masked(uint8_t out[32], void GFp_x25519_public_from_private_generic_masked(uint8_t out_public_value[32], const uint8_t private_key_masked[32]) { uint8_t e[32]; - bytes_copy(e, private_key_masked, 32); + GFp_memcpy(e, private_key_masked, 32); ge_p3 A; GFp_x25519_ge_scalarmult_base(&A, e); diff --git a/crypto/curve25519/internal.h b/crypto/curve25519/internal.h index 5f87f92003..60f2f615b4 100644 --- a/crypto/curve25519/internal.h +++ b/crypto/curve25519/internal.h @@ -65,12 +65,6 @@ static inline void fe_limbs_copy(fe_limb_t r[], const fe_limb_t a[]) { } } -static inline void fe_limbs_zero(fe_limb_t r[]) { - for (size_t i = 0; i < FE_NUM_LIMBS; ++i) { - r[i] = 0; - } -} - // ge means group element. // // Here the group is the set of pairs (x,y) of field elements (see fe.h) diff --git a/crypto/fipsmodule/.gitattributes b/crypto/fipsmodule/.gitattributes deleted file mode 100644 index 80928d6041..0000000000 --- a/crypto/fipsmodule/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.inl linguist-language=C diff --git a/crypto/fipsmodule/aes/aes_nohw.c b/crypto/fipsmodule/aes/aes_nohw.c index 656f051a6c..19b019e73f 100644 --- a/crypto/fipsmodule/aes/aes_nohw.c +++ b/crypto/fipsmodule/aes/aes_nohw.c @@ -14,13 +14,6 @@ #include -#if !defined(__wasm__) -#include -#else -void *memcpy(void *, const void*, size_t); -void *memset(void *, int, size_t); -#endif - #include "../../internal.h" #if defined(OPENSSL_SSE2) @@ -353,7 +346,7 @@ static inline uint8_t lo(uint32_t a) { static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], const uint8_t in[16]) { - memcpy(out, in, 16); + GFp_memcpy(out, in, 16); #if defined(OPENSSL_SSE2) // No conversions needed. #elif defined(OPENSSL_64_BIT) @@ -381,7 +374,7 @@ static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], static inline void aes_nohw_uncompact_block( uint8_t out[16], const aes_word_t in[AES_NOHW_BLOCK_WORDS]) { #if defined(OPENSSL_SSE2) - memcpy(out, in, 16); // No conversions needed. + GFp_memcpy(out, in, 16); // No conversions needed. #elif defined(OPENSSL_64_BIT) uint64_t a0 = in[0]; uint64_t a1 = in[1]; @@ -389,8 +382,8 @@ static inline void aes_nohw_uncompact_block( aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32)); uint64_t b1 = aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32)); - memcpy(out, &b0, 8); - memcpy(out + 8, &b1, 8); + GFp_memcpy(out, &b0, 8); + GFp_memcpy(out + 8, &b1, 8); #else uint32_t a0 = in[0]; uint32_t a1 = in[1]; @@ -411,10 +404,10 @@ static inline void aes_nohw_uncompact_block( b1 = aes_nohw_uncompact_word(b1); b2 = aes_nohw_uncompact_word(b2); b3 = aes_nohw_uncompact_word(b3); - memcpy(out, &b0, 4); - memcpy(out + 4, &b1, 4); - memcpy(out + 8, &b2, 4); - memcpy(out + 12, &b3, 4); + GFp_memcpy(out, &b0, 4); + GFp_memcpy(out + 4, &b1, 4); + GFp_memcpy(out + 8, &b2, 4); + GFp_memcpy(out + 12, &b3, 4); #endif } @@ -482,7 +475,7 @@ static void aes_nohw_transpose(AES_NOHW_BATCH *batch) { static void aes_nohw_to_batch(AES_NOHW_BATCH *out, const uint8_t *in, size_t num_blocks) { // Don't leave unused blocks uninitialized. - memset(out, 0, sizeof(AES_NOHW_BATCH)); + GFp_memset(out, 0, sizeof(AES_NOHW_BATCH)); debug_assert_nonsecret(num_blocks <= AES_NOHW_BATCH_SIZE); for (size_t i = 0; i < num_blocks; i++) { aes_word_t block[AES_NOHW_BLOCK_WORDS]; @@ -777,7 +770,7 @@ static void aes_nohw_expand_round_keys(AES_NOHW_SCHEDULE *out, // Copy the round key into each block in the batch. for (size_t j = 0; j < AES_NOHW_BATCH_SIZE; j++) { aes_word_t tmp[AES_NOHW_BLOCK_WORDS]; - memcpy(tmp, key->rd_key + 4 * i, 16); + GFp_memcpy(tmp, key->rd_key + 4 * i, 16); aes_nohw_batch_set(&out->keys[i], tmp, j); } aes_nohw_transpose(&out->keys[i]); @@ -801,7 +794,7 @@ static inline aes_word_t aes_nohw_rcon_slice(uint8_t rcon, size_t i) { static void aes_nohw_sub_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], const aes_word_t in[AES_NOHW_BLOCK_WORDS]) { AES_NOHW_BATCH batch; - memset(&batch, 0, sizeof(batch)); + GFp_memset(&batch, 0, sizeof(batch)); aes_nohw_batch_set(&batch, in, 0); aes_nohw_transpose(&batch); aes_nohw_sub_bytes(&batch); @@ -814,7 +807,7 @@ static void aes_nohw_setup_key_128(AES_KEY *key, const uint8_t in[16]) { aes_word_t block[AES_NOHW_BLOCK_WORDS]; aes_nohw_compact_block(block, in); - memcpy(key->rd_key, block, 16); + GFp_memcpy(key->rd_key, block, 16); for (size_t i = 1; i <= 10; i++) { aes_word_t sub[AES_NOHW_BLOCK_WORDS]; @@ -833,7 +826,7 @@ static void aes_nohw_setup_key_128(AES_KEY *key, const uint8_t in[16]) { block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 8)); block[j] = aes_nohw_xor(block[j], aes_nohw_shift_left(v, 12)); } - memcpy(key->rd_key + 4 * i, block, 16); + GFp_memcpy(key->rd_key + 4 * i, block, 16); } } @@ -843,10 +836,10 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) { // Each key schedule iteration produces two round keys. aes_word_t block1[AES_NOHW_BLOCK_WORDS], block2[AES_NOHW_BLOCK_WORDS]; aes_nohw_compact_block(block1, in); - memcpy(key->rd_key, block1, 16); + GFp_memcpy(key->rd_key, block1, 16); aes_nohw_compact_block(block2, in + 16); - memcpy(key->rd_key + 4, block2, 16); + GFp_memcpy(key->rd_key + 4, block2, 16); for (size_t i = 2; i <= 14; i += 2) { aes_word_t sub[AES_NOHW_BLOCK_WORDS]; @@ -864,7 +857,7 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) { block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 8)); block1[j] = aes_nohw_xor(block1[j], aes_nohw_shift_left(v, 12)); } - memcpy(key->rd_key + 4 * i, block1, 16); + GFp_memcpy(key->rd_key + 4 * i, block1, 16); if (i == 14) { break; @@ -880,7 +873,7 @@ static void aes_nohw_setup_key_256(AES_KEY *key, const uint8_t in[32]) { block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 8)); block2[j] = aes_nohw_xor(block2[j], aes_nohw_shift_left(v, 12)); } - memcpy(key->rd_key + 4 * (i + 1), block2, 16); + GFp_memcpy(key->rd_key + 4 * (i + 1), block2, 16); } } @@ -913,10 +906,10 @@ static inline void aes_nohw_xor_block(uint8_t out[16], const uint8_t a[16], const uint8_t b[16]) { for (size_t i = 0; i < 16; i += sizeof(aes_word_t)) { aes_word_t x, y; - memcpy(&x, a + i, sizeof(aes_word_t)); - memcpy(&y, b + i, sizeof(aes_word_t)); + GFp_memcpy(&x, a + i, sizeof(aes_word_t)); + GFp_memcpy(&y, b + i, sizeof(aes_word_t)); x = aes_nohw_xor(x, y); - memcpy(out + i, &x, sizeof(aes_word_t)); + GFp_memcpy(out + i, &x, sizeof(aes_word_t)); } } @@ -936,7 +929,7 @@ void GFp_aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, uint8_t u8[AES_NOHW_BATCH_SIZE * 16]; } ivs, enc_ivs; for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { - memcpy(ivs.u8 + 16 * i, ivec, 16); + GFp_memcpy(ivs.u8 + 16 * i, ivec, 16); } uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]); diff --git a/crypto/fipsmodule/aes/asm/aesv8-armx.pl b/crypto/fipsmodule/aes/asm/aesv8-armx.pl index c1dcde0c4e..804df8181d 100644 --- a/crypto/fipsmodule/aes/asm/aesv8-armx.pl +++ b/crypto/fipsmodule/aes/asm/aesv8-armx.pl @@ -96,6 +96,8 @@ .Lenc_key: ___ $code.=<<___ if ($flavour =~ /64/); + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET stp x29,x30,[sp,#-16]! add x29,sp,#0 ___ @@ -249,6 +251,7 @@ () .type GFp_${prefix}_${dir}crypt,%function .align 5 GFp_${prefix}_${dir}crypt: + AARCH64_VALID_CALL_TARGET ldr $rounds,[$key,#240] vld1.32 {$rndkey0},[$key],#16 vld1.8 {$inout},[$inp] @@ -299,6 +302,8 @@ () GFp_${prefix}_ctr32_encrypt_blocks: ___ $code.=<<___ if ($flavour =~ /64/); + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + AARCH64_VALID_CALL_TARGET stp x29,x30,[sp,#-16]! add x29,sp,#0 ___ @@ -326,20 +331,34 @@ () add $key_,$key,#32 mov $cnt,$rounds cclr $step,lo + + // ARM Cortex-A57 and Cortex-A72 cores running in 32-bit mode are + // affected by silicon errata #1742098 [0] and #1655431 [1], + // respectively, where the second instruction of an aese/aesmc + // instruction pair may execute twice if an interrupt is taken right + // after the first instruction consumes an input register of which a + // single 32-bit lane has been updated the last time it was modified. + // + // This function uses a counter in one 32-bit lane. The vmov.32 lines + // could write to $dat1 and $dat2 directly, but that trips this bugs. + // We write to $ivec and copy to the final register as a workaround. + // + // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice + // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice #ifndef __ARMEB__ rev $ctr, $ctr #endif - vorr $dat1,$dat0,$dat0 add $tctr1, $ctr, #1 - vorr $dat2,$dat0,$dat0 - add $ctr, $ctr, #2 vorr $ivec,$dat0,$dat0 rev $tctr1, $tctr1 - vmov.32 ${dat1}[3],$tctr1 + vmov.32 ${ivec}[3],$tctr1 + add $ctr, $ctr, #2 + vorr $dat1,$ivec,$ivec b.ls .Lctr32_tail rev $tctr2, $ctr + vmov.32 ${ivec}[3],$tctr2 sub $len,$len,#3 // bias - vmov.32 ${dat2}[3],$tctr2 + vorr $dat2,$ivec,$ivec b .Loop3x_ctr32 .align 4 @@ -366,11 +385,11 @@ () aese $dat1,q8 aesmc $tmp1,$dat1 vld1.8 {$in0},[$inp],#16 - vorr $dat0,$ivec,$ivec + add $tctr0,$ctr,#1 aese $dat2,q8 aesmc $dat2,$dat2 vld1.8 {$in1},[$inp],#16 - vorr $dat1,$ivec,$ivec + rev $tctr0,$tctr0 aese $tmp0,q9 aesmc $tmp0,$tmp0 aese $tmp1,q9 @@ -379,8 +398,6 @@ () mov $key_,$key aese $dat2,q9 aesmc $tmp2,$dat2 - vorr $dat2,$ivec,$ivec - add $tctr0,$ctr,#1 aese $tmp0,q12 aesmc $tmp0,$tmp0 aese $tmp1,q12 @@ -395,21 +412,26 @@ () aesmc $tmp0,$tmp0 aese $tmp1,q13 aesmc $tmp1,$tmp1 + // Note the logic to update $dat0, $dat1, and $dat1 is written to work + // around a bug in ARM Cortex-A57 and Cortex-A72 cores running in + // 32-bit mode. See the comment above. veor $in2,$in2,$rndlast - rev $tctr0,$tctr0 + vmov.32 ${ivec}[3], $tctr0 aese $tmp2,q13 aesmc $tmp2,$tmp2 - vmov.32 ${dat0}[3], $tctr0 + vorr $dat0,$ivec,$ivec rev $tctr1,$tctr1 aese $tmp0,q14 aesmc $tmp0,$tmp0 + vmov.32 ${ivec}[3], $tctr1 + rev $tctr2,$ctr aese $tmp1,q14 aesmc $tmp1,$tmp1 - vmov.32 ${dat1}[3], $tctr1 - rev $tctr2,$ctr + vorr $dat1,$ivec,$ivec + vmov.32 ${ivec}[3], $tctr2 aese $tmp2,q14 aesmc $tmp2,$tmp2 - vmov.32 ${dat2}[3], $tctr2 + vorr $dat2,$ivec,$ivec subs $len,$len,#3 aese $tmp0,q15 aese $tmp1,q15 diff --git a/crypto/fipsmodule/aes/asm/vpaes-armv8.pl b/crypto/fipsmodule/aes/asm/vpaes-armv8.pl index 1ab7e0d954..b31bbb81f2 100755 --- a/crypto/fipsmodule/aes/asm/vpaes-armv8.pl +++ b/crypto/fipsmodule/aes/asm/vpaes-armv8.pl @@ -49,6 +49,8 @@ *STDOUT=*OUT; $code.=<<___; +#include + .section .rodata .type _vpaes_consts,%object @@ -237,6 +239,7 @@ .type GFp_vpaes_encrypt,%function .align 4 GFp_vpaes_encrypt: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -246,6 +249,7 @@ st1 {v0.16b}, [$out] ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER ret .size GFp_vpaes_encrypt,.-GFp_vpaes_encrypt @@ -391,6 +395,7 @@ .type _vpaes_schedule_core,%function .align 4 _vpaes_schedule_core: + AARCH64_SIGN_LINK_REGISTER stp x29, x30, [sp,#-16]! add x29,sp,#0 @@ -550,6 +555,7 @@ eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6 eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7 ldp x29, x30, [sp],#16 + AARCH64_VALIDATE_LINK_REGISTER ret .size _vpaes_schedule_core,.-_vpaes_schedule_core @@ -720,6 +726,7 @@ .type GFp_vpaes_set_encrypt_key,%function .align 4 GFp_vpaes_set_encrypt_key: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -735,6 +742,7 @@ ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER ret .size GFp_vpaes_set_encrypt_key,.-GFp_vpaes_set_encrypt_key ___ @@ -750,6 +758,7 @@ .type GFp_vpaes_ctr32_encrypt_blocks,%function .align 4 GFp_vpaes_ctr32_encrypt_blocks: + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-16]! add x29,sp,#0 stp d8,d9,[sp,#-16]! // ABI spec says so @@ -817,6 +826,7 @@ ldp d10,d11,[sp],#16 ldp d8,d9,[sp],#16 ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER ret .size GFp_vpaes_ctr32_encrypt_blocks,.-GFp_vpaes_ctr32_encrypt_blocks ___ diff --git a/crypto/fipsmodule/bn/asm/armv4-mont.pl b/crypto/fipsmodule/bn/asm/armv4-mont.pl index 038006dc6b..dbc28b51d4 100644 --- a/crypto/fipsmodule/bn/asm/armv4-mont.pl +++ b/crypto/fipsmodule/bn/asm/armv4-mont.pl @@ -112,6 +112,8 @@ #endif #if __ARM_MAX_ARCH__>=7 +.extern GFp_armcap_P +.hidden GFp_armcap_P .align 5 .LOPENSSL_armcap: .word GFp_armcap_P-.Lbn_mul_mont @@ -744,11 +746,6 @@ } $code.=<<___; .asciz "Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by " -.align 2 -#if __ARM_MAX_ARCH__>=7 -.comm GFp_armcap_P,4,4 -.hidden GFp_armcap_P -#endif ___ foreach (split("\n",$code)) { diff --git a/crypto/fipsmodule/bn/asm/armv8-mont.pl b/crypto/fipsmodule/bn/asm/armv8-mont.pl index da93f3aa15..717ea68cf1 100644 --- a/crypto/fipsmodule/bn/asm/armv8-mont.pl +++ b/crypto/fipsmodule/bn/asm/armv8-mont.pl @@ -64,12 +64,15 @@ $num="x5"; # size_t num); $code.=<<___; +#include + .text .globl GFp_bn_mul_mont .type GFp_bn_mul_mont,%function .align 5 GFp_bn_mul_mont: + AARCH64_SIGN_LINK_REGISTER tst $num,#7 b.eq __bn_sqr8x_mont tst $num,#3 @@ -267,6 +270,7 @@ mov x0,#1 ldp x23,x24,[x29,#48] ldr x29,[sp],#64 + AARCH64_VALIDATE_LINK_REGISTER ret .size GFp_bn_mul_mont,.-GFp_bn_mul_mont ___ @@ -284,6 +288,8 @@ .type __bn_sqr8x_mont,%function .align 5 __bn_sqr8x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to + // only from bn_mul_mont which has already signed the return address. cmp $ap,$bp b.ne __bn_mul4x_mont .Lsqr8x_mont: @@ -1040,6 +1046,8 @@ ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER ret .size __bn_sqr8x_mont,.-__bn_sqr8x_mont ___ @@ -1063,6 +1071,9 @@ .type __bn_mul4x_mont,%function .align 5 __bn_mul4x_mont: + // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to + // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 stp x19,x20,[sp,#16] @@ -1496,6 +1507,8 @@ ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldr x29,[sp],#128 + // x30 is popped earlier + AARCH64_VALIDATE_LINK_REGISTER ret .size __bn_mul4x_mont,.-__bn_mul4x_mont ___ diff --git a/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl b/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl index e40aaa92d4..f30025e901 100755 --- a/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl +++ b/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl @@ -2136,7 +2136,7 @@ $code.=<<___; ################################################################################ -# void GFp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +# void GFp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, crypto_word index); .globl GFp_nistz256_select_w5 .type GFp_nistz256_select_w5,\@abi-omnipotent .align 32 @@ -2236,7 +2236,7 @@ .size GFp_nistz256_select_w5,.-GFp_nistz256_select_w5 ################################################################################ -# void GFp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +# void GFp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, crypto_word index); .globl GFp_nistz256_select_w7 .type GFp_nistz256_select_w7,\@abi-omnipotent .align 32 @@ -2333,7 +2333,7 @@ $code.=<<___; ################################################################################ -# void GFp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, int index); +# void GFp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, crypto_word index); .type GFp_nistz256_avx2_select_w5,\@abi-omnipotent .align 32 GFp_nistz256_avx2_select_w5: @@ -2440,7 +2440,7 @@ $code.=<<___; ################################################################################ -# void GFp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, int index); +# void GFp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, crypto_word index); .globl GFp_nistz256_avx2_select_w7 .type GFp_nistz256_avx2_select_w7,\@abi-omnipotent .align 32 diff --git a/crypto/fipsmodule/ec/ecp_nistz.h b/crypto/fipsmodule/ec/ecp_nistz.h index 74d31007a8..2bcf4b5d4d 100644 --- a/crypto/fipsmodule/ec/ecp_nistz.h +++ b/crypto/fipsmodule/ec/ecp_nistz.h @@ -246,16 +246,16 @@ // P-384: ...01110011; w = 2, 5, 6, 7 are okay // P-256: ...01010001; w = 5, 7 are okay // P-224: ...00111101; w = 3, 4, 5, 6 are okay -static inline void booth_recode(Limb *is_negative, unsigned *digit, - unsigned in, unsigned w) { +static inline void booth_recode(crypto_word *is_negative, crypto_word *digit, + crypto_word in, crypto_word w) { debug_assert_nonsecret(w >= 2); debug_assert_nonsecret(w <= 7); // Set all bits of `s` to MSB(in), similar to |constant_time_msb_s|, // but 'in' seen as (`w+1`)-bit value. - Limb s = ~((in >> w) - 1); - unsigned d; - d = (1 << (w + 1)) - in - 1; + crypto_word s = ~((in >> w) - 1); + crypto_word d; + d = ((crypto_word)1u << (w + 1)) - in - 1; d = (d & s) | (in & ~s); d = (d >> 1) + (d & 1); diff --git a/crypto/fipsmodule/ec/ecp_nistz256.c b/crypto/fipsmodule/ec/ecp_nistz256.c index 34602956d2..b71100cdad 100644 --- a/crypto/fipsmodule/ec/ecp_nistz256.c +++ b/crypto/fipsmodule/ec/ecp_nistz256.c @@ -193,8 +193,8 @@ void GFp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, const P256_POINT void GFp_nistz256_point_mul(P256_POINT *r, const Limb p_scalar[P256_LIMBS], const Limb p_x[P256_LIMBS], const Limb p_y[P256_LIMBS]) { - static const unsigned kWindowSize = 5; - static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; + static const size_t kWindowSize = 5; + static const crypto_word kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; uint8_t p_str[(P256_LIMBS * sizeof(Limb)) + 1]; gfp_little_endian_bytes_from_scalar(p_str, sizeof(p_str) / sizeof(p_str[0]), @@ -232,23 +232,22 @@ void GFp_nistz256_point_mul(P256_POINT *r, const Limb p_scalar[P256_LIMBS], Limb tmp[P256_LIMBS]; alignas(32) P256_POINT h; - static const unsigned START_INDEX = 256 - 1; - unsigned index = START_INDEX; + static const size_t START_INDEX = 256 - 1; + size_t index = START_INDEX; - unsigned raw_wvalue; - Limb recoded_is_negative; - unsigned recoded; + crypto_word raw_wvalue; + crypto_word recoded_is_negative; + crypto_word recoded; raw_wvalue = p_str[(index - 1) / 8]; raw_wvalue = (raw_wvalue >> ((index - 1) % 8)) & kMask; - booth_recode(&recoded_is_negative, &recoded, raw_wvalue, kWindowSize); dev_assert_secret(!recoded_is_negative); GFp_nistz256_select_w5(r, table, recoded); while (index >= kWindowSize) { if (index != START_INDEX) { - unsigned off = (index - 1) / 8; + size_t off = (index - 1) / 8; raw_wvalue = p_str[off] | p_str[off + 1] << 8; raw_wvalue = (raw_wvalue >> ((index - 1) % 8)) & kMask; @@ -286,12 +285,12 @@ void GFp_nistz256_point_mul(P256_POINT *r, const Limb p_scalar[P256_LIMBS], /* Precomputed tables for the default generator */ #include "ecp_nistz256_table.inl" -static const unsigned kWindowSize = 7; +static const size_t kWindowSize = 7; static inline void select_precomputed(P256_POINT_AFFINE *p, size_t i, - unsigned raw_wvalue) { - Limb recoded_is_negative; - unsigned recoded; + crypto_word raw_wvalue) { + crypto_word recoded_is_negative; + crypto_word recoded; booth_recode(&recoded_is_negative, &recoded, raw_wvalue, kWindowSize); GFp_nistz256_select_w7(p, GFp_nistz256_precomputed[i], recoded); Limb neg_y[P256_LIMBS]; @@ -312,18 +311,18 @@ static Limb is_infinity(const Limb x[P256_LIMBS], void GFp_nistz256_point_mul_base(P256_POINT *r, const Limb g_scalar[P256_LIMBS]) { - static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; + static const crypto_word kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; uint8_t p_str[(P256_LIMBS * sizeof(Limb)) + 1]; gfp_little_endian_bytes_from_scalar(p_str, sizeof(p_str) / sizeof(p_str[0]), g_scalar, P256_LIMBS); /* First window */ - unsigned index = kWindowSize; + size_t index = kWindowSize; alignas(32) P256_POINT_AFFINE t; - unsigned raw_wvalue = (p_str[0] << 1) & kMask; + crypto_word raw_wvalue = (p_str[0] << 1) & kMask; select_precomputed(&t, 0, raw_wvalue); alignas(32) P256_POINT p; @@ -334,7 +333,7 @@ void GFp_nistz256_point_mul_base(P256_POINT *r, copy_conditional(p.Z, p.X, is_infinity(p.X, p.Y)); for (size_t i = 1; i < 37; i++) { - unsigned off = (index - 1) / 8; + size_t off = (index - 1) / 8; raw_wvalue = p_str[off] | p_str[off + 1] << 8; raw_wvalue = (raw_wvalue >> ((index - 1) % 8)) & kMask; index += kWindowSize; diff --git a/crypto/fipsmodule/ec/ecp_nistz256.h b/crypto/fipsmodule/ec/ecp_nistz256.h index 01ad2e148d..561d4155f7 100644 --- a/crypto/fipsmodule/ec/ecp_nistz256.h +++ b/crypto/fipsmodule/ec/ecp_nistz256.h @@ -45,10 +45,10 @@ void GFp_nistz256_sqr_mont(Limb res[P256_LIMBS], const Limb a[P256_LIMBS]); /* Functions that perform constant time access to the precomputed tables */ void GFp_nistz256_select_w5(P256_POINT *out, const P256_POINT table[16], - int index); + crypto_word index); #if defined(GFp_USE_LARGE_TABLE) -void GFp_nistz256_select_w7(P256_POINT_AFFINE *out, const PRECOMP256_ROW table, int index); +void GFp_nistz256_select_w7(P256_POINT_AFFINE *out, const PRECOMP256_ROW table, crypto_word index); #endif #endif /* OPENSSL_HEADER_EC_ECP_NISTZ256_H */ diff --git a/crypto/fipsmodule/ec/ecp_nistz384.inl b/crypto/fipsmodule/ec/ecp_nistz384.inl index 718e4a7915..12fc9d9d35 100644 --- a/crypto/fipsmodule/ec/ecp_nistz384.inl +++ b/crypto/fipsmodule/ec/ecp_nistz384.inl @@ -157,10 +157,10 @@ void GFp_nistz384_point_add(P384_POINT *r, const P384_POINT *a, limbs_copy(r->Z, res_z, P384_LIMBS); } -static void add_precomputed_w5(P384_POINT *r, unsigned wvalue, +static void add_precomputed_w5(P384_POINT *r, crypto_word wvalue, const P384_POINT table[16]) { - BN_ULONG recoded_is_negative; - unsigned int recoded; + crypto_word recoded_is_negative; + crypto_word recoded; booth_recode(&recoded_is_negative, &recoded, wvalue, 5); alignas(64) P384_POINT h; @@ -177,8 +177,8 @@ static void add_precomputed_w5(P384_POINT *r, unsigned wvalue, void GFp_nistz384_point_mul(P384_POINT *r, const BN_ULONG p_scalar[P384_LIMBS], const BN_ULONG p_x[P384_LIMBS], const BN_ULONG p_y[P384_LIMBS]) { - static const unsigned kWindowSize = 5; - static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; + static const size_t kWindowSize = 5; + static const crypto_word kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; uint8_t p_str[(P384_LIMBS * sizeof(Limb)) + 1]; gfp_little_endian_bytes_from_scalar(p_str, sizeof(p_str) / sizeof(p_str[0]), @@ -214,13 +214,13 @@ void GFp_nistz384_point_mul(P384_POINT *r, const BN_ULONG p_scalar[P384_LIMBS], GFp_nistz384_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); GFp_nistz384_point_double(&row[16 - 1], &row[8 - 1]); - static const unsigned START_INDEX = 384 - 4; - unsigned index = START_INDEX; + static const size_t START_INDEX = 384 - 4; + size_t index = START_INDEX; BN_ULONG recoded_is_negative; - unsigned recoded; + crypto_word recoded; - unsigned wvalue = p_str[(index - 1) / 8]; + crypto_word wvalue = p_str[(index - 1) / 8]; wvalue = (wvalue >> ((index - 1) % 8)) & kMask; booth_recode(&recoded_is_negative, &recoded, wvalue, 5); @@ -230,7 +230,7 @@ void GFp_nistz384_point_mul(P384_POINT *r, const BN_ULONG p_scalar[P384_LIMBS], while (index >= kWindowSize) { if (index != START_INDEX) { - unsigned off = (index - 1) / 8; + size_t off = (index - 1) / 8; wvalue = p_str[off] | p_str[off + 1] << 8; wvalue = (wvalue >> ((index - 1) % 8)) & kMask; diff --git a/crypto/fipsmodule/ec/gfp_p256.c b/crypto/fipsmodule/ec/gfp_p256.c index 5e9046a960..60678ec6d9 100644 --- a/crypto/fipsmodule/ec/gfp_p256.c +++ b/crypto/fipsmodule/ec/gfp_p256.c @@ -73,9 +73,8 @@ void GFp_p256_scalar_sqr_rep_mont(ScalarMont r, const ScalarMont a, Limb rep) { /* TODO(perf): Optimize these. */ void GFp_nistz256_select_w5(P256_POINT *out, const P256_POINT table[16], - int index) { + crypto_word index) { dev_assert_secret(index >= 0); - size_t index_s = (size_t)index; /* XXX: constant time? */ alignas(32) Elem x; limbs_zero(x, P256_LIMBS); alignas(32) Elem y; limbs_zero(y, P256_LIMBS); @@ -83,7 +82,7 @@ void GFp_nistz256_select_w5(P256_POINT *out, const P256_POINT table[16], // TODO: Rewrite in terms of |limbs_select|. for (size_t i = 0; i < 16; ++i) { - Limb equal = constant_time_eq_w(index_s, i + 1); + crypto_word equal = constant_time_eq_w(index, (crypto_word)i + 1); for (size_t j = 0; j < P256_LIMBS; ++j) { x[j] = constant_time_select_w(equal, table[i].X[j], x[j]); y[j] = constant_time_select_w(equal, table[i].Y[j], y[j]); @@ -98,12 +97,9 @@ void GFp_nistz256_select_w5(P256_POINT *out, const P256_POINT table[16], #if defined GFp_USE_LARGE_TABLE void GFp_nistz256_select_w7(P256_POINT_AFFINE *out, - const PRECOMP256_ROW table, int index) { - dev_assert_secret(index >= 0); - size_t index_as_s = (size_t)index; /* XXX: constant time? */ - + const PRECOMP256_ROW table, crypto_word index) { alignas(32) Limb xy[P256_LIMBS * 2]; - limbs_select(xy, table, P256_LIMBS * 2, 64, index_as_s - 1); + limbs_select(xy, table, P256_LIMBS * 2, 64, index - 1); limbs_copy(out->X, &xy[0], P256_LIMBS); limbs_copy(out->Y, &xy[P256_LIMBS], P256_LIMBS); } diff --git a/crypto/fipsmodule/ec/gfp_p384.c b/crypto/fipsmodule/ec/gfp_p384.c index 641f4a70cd..820fac4a15 100644 --- a/crypto/fipsmodule/ec/gfp_p384.c +++ b/crypto/fipsmodule/ec/gfp_p384.c @@ -225,7 +225,7 @@ static void gfp_p384_point_select_w5(P384_POINT *out, // TODO: Rewrite in terms of |limbs_select|. for (size_t i = 0; i < 16; ++i) { - Limb equal = constant_time_eq_w(index, i + 1); + crypto_word equal = constant_time_eq_w(index, (crypto_word)i + 1); for (size_t j = 0; j < P384_LIMBS; ++j) { x[j] = constant_time_select_w(equal, table[i].X[j], x[j]); y[j] = constant_time_select_w(equal, table[i].Y[j], y[j]); diff --git a/crypto/fipsmodule/modes/asm/ghash-neon-armv8.pl b/crypto/fipsmodule/modes/asm/ghash-neon-armv8.pl index f90550b06c..7e52ad667f 100644 --- a/crypto/fipsmodule/modes/asm/ghash-neon-armv8.pl +++ b/crypto/fipsmodule/modes/asm/ghash-neon-armv8.pl @@ -157,12 +157,15 @@ sub clmul64x64 { } $code .= <<___; +#include + .text .global GFp_gcm_init_neon .type GFp_gcm_init_neon,%function .align 4 GFp_gcm_init_neon: + AARCH64_VALID_CALL_TARGET // This function is adapted from gcm_init_v8. xC2 is t3. ld1 {$t1.2d}, [x1] // load H movi $t3.16b, #0xe1 @@ -187,6 +190,7 @@ sub clmul64x64 { .type GFp_gcm_gmult_neon,%function .align 4 GFp_gcm_gmult_neon: + AARCH64_VALID_CALL_TARGET ld1 {$INlo.16b}, [$Xi] // load Xi ld1 {$Hlo.1d}, [$Htbl], #8 // load twisted H ld1 {$Hhi.1d}, [$Htbl] @@ -205,6 +209,7 @@ sub clmul64x64 { .type GFp_gcm_ghash_neon,%function .align 4 GFp_gcm_ghash_neon: + AARCH64_VALID_CALL_TARGET ld1 {$Xl.16b}, [$Xi] // load Xi ld1 {$Hlo.1d}, [$Htbl], #8 // load twisted H ld1 {$Hhi.1d}, [$Htbl] diff --git a/crypto/fipsmodule/modes/asm/ghashv8-armx.pl b/crypto/fipsmodule/modes/asm/ghashv8-armx.pl index a477cae8fd..3a551c2901 100644 --- a/crypto/fipsmodule/modes/asm/ghashv8-armx.pl +++ b/crypto/fipsmodule/modes/asm/ghashv8-armx.pl @@ -86,6 +86,7 @@ .type GFp_gcm_init_clmul,%function .align 4 GFp_gcm_init_clmul: + AARCH64_VALID_CALL_TARGET vld1.64 {$t1},[x1] @ load input H vmov.i8 $xC2,#0xe1 vshl.i64 $xC2,$xC2,#57 @ 0xc2.0 @@ -145,6 +146,7 @@ .type GFp_gcm_gmult_clmul,%function .align 4 GFp_gcm_gmult_clmul: + AARCH64_VALID_CALL_TARGET vld1.64 {$t1},[$Xi] @ load Xi vmov.i8 $xC2,#0xe1 vld1.64 {$H-$Hhl},[$Htbl] @ load twisted H, ... @@ -198,6 +200,7 @@ .type GFp_gcm_ghash_clmul,%function .align 4 GFp_gcm_ghash_clmul: + AARCH64_VALID_CALL_TARGET ___ $code.=<<___ if ($flavour !~ /64/); vstmdb sp!,{d8-d15} @ 32-bit ABI says so diff --git a/crypto/fipsmodule/modes/internal.h b/crypto/fipsmodule/modes/internal.h deleted file mode 100644 index efccd24cd6..0000000000 --- a/crypto/fipsmodule/modes/internal.h +++ /dev/null @@ -1,57 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. 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. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED 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 OpenSSL PROJECT OR - * ITS 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 OPENSSL_HEADER_MODES_INTERNAL_H -#define OPENSSL_HEADER_MODES_INTERNAL_H - -#include "../../internal.h" - -// GCM definitions -typedef struct { uint64_t hi,lo; } u128; - -#endif // OPENSSL_HEADER_MODES_INTERNAL_H diff --git a/crypto/fipsmodule/sha/asm/sha256-armv4.pl b/crypto/fipsmodule/sha/asm/sha256-armv4.pl index d71fc82e22..d8661a0911 100644 --- a/crypto/fipsmodule/sha/asm/sha256-armv4.pl +++ b/crypto/fipsmodule/sha/asm/sha256-armv4.pl @@ -218,6 +218,8 @@ sub BODY_16_XX { .size K256,.-K256 .word 0 @ terminator #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.extern GFp_armcap_P +.hidden GFp_armcap_P .LOPENSSL_armcap: .word GFp_armcap_P-.Lsha256_block_data_order #endif @@ -687,11 +689,6 @@ () }}} $code.=<<___; .asciz "SHA256 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by " -.align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm GFp_armcap_P,4,4 -.hidden GFp_armcap_P -#endif ___ open SELF,$0; diff --git a/crypto/fipsmodule/sha/asm/sha512-armv4.pl b/crypto/fipsmodule/sha/asm/sha512-armv4.pl index 4543f4566c..21c7ebddba 100644 --- a/crypto/fipsmodule/sha/asm/sha512-armv4.pl +++ b/crypto/fipsmodule/sha/asm/sha512-armv4.pl @@ -278,6 +278,8 @@ () WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .size K512,.-K512 #if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) +.extern GFp_armcap_P +.hidden GFp_armcap_P .LOPENSSL_armcap: .word GFp_armcap_P-.Lsha512_block_data_order .skip 32-4 @@ -651,11 +653,6 @@ () } $code.=<<___; .asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by " -.align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm GFp_armcap_P,4,4 -.hidden GFp_armcap_P -#endif ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/fipsmodule/sha/asm/sha512-armv8.pl b/crypto/fipsmodule/sha/asm/sha512-armv8.pl index d8667c8db8..bb80b7c96b 100644 --- a/crypto/fipsmodule/sha/asm/sha512-armv8.pl +++ b/crypto/fipsmodule/sha/asm/sha512-armv8.pl @@ -179,12 +179,14 @@ sub BODY_00_xx { .text .extern GFp_armcap_P +.hidden GFp_armcap_P .globl $func .type $func,%function .align 6 $func: ___ $code.=<<___ if ($SZ==4); + AARCH64_VALID_CALL_TARGET #ifndef __KERNEL__ #if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 adrp x16,:pg_hi21_nc:GFp_armcap_P @@ -197,6 +199,7 @@ sub BODY_00_xx { #endif ___ $code.=<<___; + AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -259,6 +262,7 @@ sub BODY_00_xx { ldp x25,x26,[x29,#64] ldp x27,x28,[x29,#80] ldp x29,x30,[sp],#128 + AARCH64_VALIDATE_LINK_REGISTER ret .size $func,.-$func @@ -350,6 +354,7 @@ sub BODY_00_xx { .align 6 sha256_block_armv8: .Lv8_entry: + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. stp x29,x30,[sp,#-16]! add x29,sp,#0 @@ -419,13 +424,6 @@ sub BODY_00_xx { ___ } -$code.=<<___; -#ifndef __KERNEL__ -.comm GFp_armcap_P,4,4 -.hidden GFp_armcap_P -#endif -___ - { my %opcode = ( "sha256h" => 0x5e004000, "sha256h2" => 0x5e005000, "sha256su0" => 0x5e282800, "sha256su1" => 0x5e006000 ); diff --git a/crypto/internal.h b/crypto/internal.h index 57607bfc38..1877bec7f6 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -259,10 +259,39 @@ static inline uint32_t CRYPTO_bswap4(uint32_t x) { } #endif -static inline void bytes_copy(uint8_t out[], const uint8_t in[], size_t len) { - for (size_t i = 0; i < len; ++i) { - out[i] = in[i]; +#if !defined(GFp_NOSTDLIBINC) +#include +#endif + +static inline void *GFp_memcpy(void *dst, const void *src, size_t n) { +#if !defined(GFp_NOSTDLIBINC) + if (n == 0) { + return dst; + } + return memcpy(dst, src, n); +#else + unsigned char *d = dst; + const unsigned char *s = src; + for (size_t i = 0; i < n; ++i) { + d[i] = s[i]; } + return dst; +#endif +} + +static inline void *GFp_memset(void *dst, int c, size_t n) { +#if !defined(GFp_NOSTDLIBINC) + if (n == 0) { + return dst; + } + return memset(dst, c, n); +#else + unsigned char *d = dst; + for (size_t i = 0; i < n; ++i) { + d[i] = (unsigned char)c; + } + return dst; +#endif } #endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/crypto/perlasm/.gitattributes b/crypto/perlasm/.gitattributes deleted file mode 100644 index d77060900d..0000000000 --- a/crypto/perlasm/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.pl linguist-language=Perl - diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl index 9ab8201e94..f69fcda130 100644 --- a/crypto/perlasm/x86asm.pl +++ b/crypto/perlasm/x86asm.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -256,13 +256,13 @@ sub ::asciz sub ::asm_finish { &file_end(); my $comment = "#"; - $comment = ";" if ($win32 || $netware); + $comment = ";" if ($win32); print <<___; $comment This file is generated from a similarly-named Perl script in the BoringSSL $comment source tree. Do not edit by hand. ___ - if ($win32 || $netware) { + if ($win32) { print <<___ unless $masm; %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" @@ -277,7 +277,7 @@ sub ::asm_finish ___ } print @out; - print "#endif\n" unless ($win32 || $netware); + print "#endif\n" unless ($win32); # See https://www.airs.com/blog/archives/518. print ".section\t.note.GNU-stack,\"\",\@progbits\n" if ($elf); } @@ -287,7 +287,7 @@ sub ::asm_init $i386=$cpu; - $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0; + $elf=$cpp=$coff=$aout=$macosx=$win32=$mwerks=$android=0; if (($type eq "elf")) { $elf=1; require "x86gas.pl"; } elsif (($type eq "elf-1")) @@ -298,10 +298,6 @@ sub ::asm_init { $coff=1; require "x86gas.pl"; } elsif (($type eq "win32n")) { $win32=1; require "x86nasm.pl"; } - elsif (($type eq "nw-nasm")) - { $netware=1; require "x86nasm.pl"; } - #elsif (($type eq "nw-mwasm")) - #{ $netware=1; $mwerks=1; require "x86nasm.pl"; } elsif (($type eq "win32")) { $win32=1; $masm=1; require "x86masm.pl"; } elsif (($type eq "macosx")) @@ -315,7 +311,6 @@ sub ::asm_init a.out - DJGPP, elder OpenBSD, etc. coff - GAS/COFF such as Win32 targets win32n - Windows 95/Windows NT NASM format - nw-nasm - NetWare NASM format macosx - Mac OS X EOF exit(1); diff --git a/crypto/perlasm/x86nasm.pl b/crypto/perlasm/x86nasm.pl index aec8949cc9..4dbd85c268 100644 --- a/crypto/perlasm/x86nasm.pl +++ b/crypto/perlasm/x86nasm.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -12,7 +12,7 @@ package x86nasm; *out=\@::out; $::lbdecor="L\$"; # local label decoration -$nmdecor=$::netware?"":"_"; # external name decoration +$nmdecor="_"; # external name decoration $drdecor=$::mwerks?".":""; # directive decoration $initseg=""; @@ -90,15 +90,7 @@ sub ::file %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 -%ifdef __YASM_VERSION_ID__ -%if __YASM_VERSION_ID__ < 01010000h -%error yasm version 1.1.0 or later needed. -%endif -; Yasm automatically includes @feat.00 and complains about redefining it. -; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html -%else \$\@feat.00 equ 1 -%endif section .text code align=64 %else section .text code diff --git a/crypto/poly1305/asm/poly1305-armv4.pl b/crypto/poly1305/asm/poly1305-armv4.pl deleted file mode 100755 index 1265676bbb..0000000000 --- a/crypto/poly1305/asm/poly1305-armv4.pl +++ /dev/null @@ -1,1246 +0,0 @@ -#!/usr/bin/env perl -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# IALU(*)/gcc-4.4 NEON -# -# ARM11xx(ARMv6) 7.78/+100% - -# Cortex-A5 6.35/+130% 3.00 -# Cortex-A8 6.25/+115% 2.36 -# Cortex-A9 5.10/+95% 2.55 -# Cortex-A15 3.85/+85% 1.25(**) -# Snapdragon S4 5.70/+100% 1.48(**) -# -# (*) this is for -march=armv6, i.e. with bunch of ldrb loading data; -# (**) these are trade-off results, they can be improved by ~8% but at -# the cost of 15/12% regression on Cortex-A5/A7, it's even possible -# to improve Cortex-A9 result, but then A5/A7 loose more than 20%; - -$flavour = shift; -if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; } -else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} } - -if ($flavour && $flavour ne "void") { - $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; - ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or - ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or - die "can't locate arm-xlate.pl"; - - open STDOUT,"| \"$^X\" $xlate $flavour $output"; -} else { - open STDOUT,">$output"; -} - -($ctx,$inp,$len,$padbit)=map("r$_",(0..3)); - -$code.=<<___; -#include - -.text -#if defined(__thumb2__) -.syntax unified -.thumb -#else -.code 32 -#endif - -.globl GFp_poly1305_emit -.globl GFp_poly1305_blocks -.globl GFp_poly1305_init_asm - -.type GFp_poly1305_init_asm,%function -.align 5 -GFp_poly1305_init_asm: -.Lpoly1305_init: - stmdb sp!,{r4-r11} - - eor r3,r3,r3 - cmp $inp,#0 - str r3,[$ctx,#0] @ zero hash value - str r3,[$ctx,#4] - str r3,[$ctx,#8] - str r3,[$ctx,#12] - str r3,[$ctx,#16] - str r3,[$ctx,#36] @ is_base2_26 - add $ctx,$ctx,#20 - -#ifdef __thumb2__ - it eq -#endif - moveq r0,#0 - beq .Lno_key - -#if __ARM_MAX_ARCH__>=7 - adr r11,.Lpoly1305_init - ldr r12,.LOPENSSL_armcap -#endif - ldrb r4,[$inp,#0] - mov r10,#0x0fffffff - ldrb r5,[$inp,#1] - and r3,r10,#-4 @ 0x0ffffffc - ldrb r6,[$inp,#2] - ldrb r7,[$inp,#3] - orr r4,r4,r5,lsl#8 - ldrb r5,[$inp,#4] - orr r4,r4,r6,lsl#16 - ldrb r6,[$inp,#5] - orr r4,r4,r7,lsl#24 - ldrb r7,[$inp,#6] - and r4,r4,r10 - -#if __ARM_MAX_ARCH__>=7 - ldr r12,[r11,r12] @ GFp_armcap_P -# ifdef __APPLE__ - ldr r12,[r12] -# endif -#endif - ldrb r8,[$inp,#7] - orr r5,r5,r6,lsl#8 - ldrb r6,[$inp,#8] - orr r5,r5,r7,lsl#16 - ldrb r7,[$inp,#9] - orr r5,r5,r8,lsl#24 - ldrb r8,[$inp,#10] - and r5,r5,r3 - -#if __ARM_MAX_ARCH__>=7 - tst r12,#ARMV7_NEON @ check for NEON -# ifdef __APPLE__ - adr r9,poly1305_blocks_neon - adr r11,GFp_poly1305_blocks -# ifdef __thumb2__ - it ne -# endif - movne r11,r9 - adr r12,GFp_poly1305_emit - adr r10,poly1305_emit_neon -# ifdef __thumb2__ - it ne -# endif - movne r12,r10 -# else -# ifdef __thumb2__ - itete eq -# endif - addeq r12,r11,#(GFp_poly1305_emit-.Lpoly1305_init) - addne r12,r11,#(poly1305_emit_neon-.Lpoly1305_init) - addeq r11,r11,#(GFp_poly1305_blocks-.Lpoly1305_init) - addne r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init) -# endif -# ifdef __thumb2__ - orr r12,r12,#1 @ thumb-ify address - orr r11,r11,#1 -# endif -#endif - ldrb r9,[$inp,#11] - orr r6,r6,r7,lsl#8 - ldrb r7,[$inp,#12] - orr r6,r6,r8,lsl#16 - ldrb r8,[$inp,#13] - orr r6,r6,r9,lsl#24 - ldrb r9,[$inp,#14] - and r6,r6,r3 - - ldrb r10,[$inp,#15] - orr r7,r7,r8,lsl#8 - str r4,[$ctx,#0] - orr r7,r7,r9,lsl#16 - str r5,[$ctx,#4] - orr r7,r7,r10,lsl#24 - str r6,[$ctx,#8] - and r7,r7,r3 - str r7,[$ctx,#12] -#if __ARM_MAX_ARCH__>=7 - stmia r2,{r11,r12} @ fill functions table - mov r0,#1 -#else - mov r0,#0 -#endif -.Lno_key: - ldmia sp!,{r4-r11} -#if __ARM_ARCH__>=5 - ret @ bx lr -#else - tst lr,#1 - moveq pc,lr @ be binary compatible with V4, yet - bx lr @ interoperable with Thumb ISA:-) -#endif -.size GFp_poly1305_init_asm,.-GFp_poly1305_init_asm -___ -{ -my ($h0,$h1,$h2,$h3,$h4,$r0,$r1,$r2,$r3)=map("r$_",(4..12)); -my ($s1,$s2,$s3)=($r1,$r2,$r3); - -$code.=<<___; -.type GFp_poly1305_blocks,%function -.align 5 -GFp_poly1305_blocks: - stmdb sp!,{r3-r11,lr} - - ands $len,$len,#-16 - beq .Lno_data - - cmp $padbit,#0 - add $len,$len,$inp @ end pointer - sub sp,sp,#32 - - ldmia $ctx,{$h0-$r3} @ load context - - str $ctx,[sp,#12] @ offload stuff - mov lr,$inp - str $len,[sp,#16] - str $r1,[sp,#20] - str $r2,[sp,#24] - str $r3,[sp,#28] - b .Loop - -.Loop: -#if __ARM_ARCH__<7 - ldrb r0,[lr],#16 @ load input -# ifdef __thumb2__ - it hi -# endif - addhi $h4,$h4,#1 @ 1<<128 - ldrb r1,[lr,#-15] - ldrb r2,[lr,#-14] - ldrb r3,[lr,#-13] - orr r1,r0,r1,lsl#8 - ldrb r0,[lr,#-12] - orr r2,r1,r2,lsl#16 - ldrb r1,[lr,#-11] - orr r3,r2,r3,lsl#24 - ldrb r2,[lr,#-10] - adds $h0,$h0,r3 @ accumulate input - - ldrb r3,[lr,#-9] - orr r1,r0,r1,lsl#8 - ldrb r0,[lr,#-8] - orr r2,r1,r2,lsl#16 - ldrb r1,[lr,#-7] - orr r3,r2,r3,lsl#24 - ldrb r2,[lr,#-6] - adcs $h1,$h1,r3 - - ldrb r3,[lr,#-5] - orr r1,r0,r1,lsl#8 - ldrb r0,[lr,#-4] - orr r2,r1,r2,lsl#16 - ldrb r1,[lr,#-3] - orr r3,r2,r3,lsl#24 - ldrb r2,[lr,#-2] - adcs $h2,$h2,r3 - - ldrb r3,[lr,#-1] - orr r1,r0,r1,lsl#8 - str lr,[sp,#8] @ offload input pointer - orr r2,r1,r2,lsl#16 - add $s1,$r1,$r1,lsr#2 - orr r3,r2,r3,lsl#24 -#else - ldr r0,[lr],#16 @ load input -# ifdef __thumb2__ - it hi -# endif - addhi $h4,$h4,#1 @ padbit - ldr r1,[lr,#-12] - ldr r2,[lr,#-8] - ldr r3,[lr,#-4] -# ifdef __ARMEB__ - rev r0,r0 - rev r1,r1 - rev r2,r2 - rev r3,r3 -# endif - adds $h0,$h0,r0 @ accumulate input - str lr,[sp,#8] @ offload input pointer - adcs $h1,$h1,r1 - add $s1,$r1,$r1,lsr#2 - adcs $h2,$h2,r2 -#endif - add $s2,$r2,$r2,lsr#2 - adcs $h3,$h3,r3 - add $s3,$r3,$r3,lsr#2 - - umull r2,r3,$h1,$r0 - adc $h4,$h4,#0 - umull r0,r1,$h0,$r0 - umlal r2,r3,$h4,$s1 - umlal r0,r1,$h3,$s1 - ldr $r1,[sp,#20] @ reload $r1 - umlal r2,r3,$h2,$s3 - umlal r0,r1,$h1,$s3 - umlal r2,r3,$h3,$s2 - umlal r0,r1,$h2,$s2 - umlal r2,r3,$h0,$r1 - str r0,[sp,#0] @ future $h0 - mul r0,$s2,$h4 - ldr $r2,[sp,#24] @ reload $r2 - adds r2,r2,r1 @ d1+=d0>>32 - eor r1,r1,r1 - adc lr,r3,#0 @ future $h2 - str r2,[sp,#4] @ future $h1 - - mul r2,$s3,$h4 - eor r3,r3,r3 - umlal r0,r1,$h3,$s3 - ldr $r3,[sp,#28] @ reload $r3 - umlal r2,r3,$h3,$r0 - umlal r0,r1,$h2,$r0 - umlal r2,r3,$h2,$r1 - umlal r0,r1,$h1,$r1 - umlal r2,r3,$h1,$r2 - umlal r0,r1,$h0,$r2 - umlal r2,r3,$h0,$r3 - ldr $h0,[sp,#0] - mul $h4,$r0,$h4 - ldr $h1,[sp,#4] - - adds $h2,lr,r0 @ d2+=d1>>32 - ldr lr,[sp,#8] @ reload input pointer - adc r1,r1,#0 - adds $h3,r2,r1 @ d3+=d2>>32 - ldr r0,[sp,#16] @ reload end pointer - adc r3,r3,#0 - add $h4,$h4,r3 @ h4+=d3>>32 - - and r1,$h4,#-4 - and $h4,$h4,#3 - add r1,r1,r1,lsr#2 @ *=5 - adds $h0,$h0,r1 - adcs $h1,$h1,#0 - adcs $h2,$h2,#0 - adcs $h3,$h3,#0 - adc $h4,$h4,#0 - - cmp r0,lr @ done yet? - bhi .Loop - - ldr $ctx,[sp,#12] - add sp,sp,#32 - stmia $ctx,{$h0-$h4} @ store the result - -.Lno_data: -#if __ARM_ARCH__>=5 - ldmia sp!,{r3-r11,pc} -#else - ldmia sp!,{r3-r11,lr} - tst lr,#1 - moveq pc,lr @ be binary compatible with V4, yet - bx lr @ interoperable with Thumb ISA:-) -#endif -.size GFp_poly1305_blocks,.-GFp_poly1305_blocks -___ -} -{ -my ($ctx,$mac,$nonce)=map("r$_",(0..2)); -my ($h0,$h1,$h2,$h3,$h4,$g0,$g1,$g2,$g3)=map("r$_",(3..11)); -my $g4=$h4; - -$code.=<<___; -.type GFp_poly1305_emit,%function -.align 5 -GFp_poly1305_emit: - stmdb sp!,{r4-r11} -.Lpoly1305_emit_enter: - - ldmia $ctx,{$h0-$h4} - adds $g0,$h0,#5 @ compare to modulus - adcs $g1,$h1,#0 - adcs $g2,$h2,#0 - adcs $g3,$h3,#0 - adc $g4,$h4,#0 - tst $g4,#4 @ did it carry/borrow? - -#ifdef __thumb2__ - it ne -#endif - movne $h0,$g0 - ldr $g0,[$nonce,#0] -#ifdef __thumb2__ - it ne -#endif - movne $h1,$g1 - ldr $g1,[$nonce,#4] -#ifdef __thumb2__ - it ne -#endif - movne $h2,$g2 - ldr $g2,[$nonce,#8] -#ifdef __thumb2__ - it ne -#endif - movne $h3,$g3 - ldr $g3,[$nonce,#12] - - adds $h0,$h0,$g0 - adcs $h1,$h1,$g1 - adcs $h2,$h2,$g2 - adc $h3,$h3,$g3 - -#if __ARM_ARCH__>=7 -# ifdef __ARMEB__ - rev $h0,$h0 - rev $h1,$h1 - rev $h2,$h2 - rev $h3,$h3 -# endif - str $h0,[$mac,#0] - str $h1,[$mac,#4] - str $h2,[$mac,#8] - str $h3,[$mac,#12] -#else - strb $h0,[$mac,#0] - mov $h0,$h0,lsr#8 - strb $h1,[$mac,#4] - mov $h1,$h1,lsr#8 - strb $h2,[$mac,#8] - mov $h2,$h2,lsr#8 - strb $h3,[$mac,#12] - mov $h3,$h3,lsr#8 - - strb $h0,[$mac,#1] - mov $h0,$h0,lsr#8 - strb $h1,[$mac,#5] - mov $h1,$h1,lsr#8 - strb $h2,[$mac,#9] - mov $h2,$h2,lsr#8 - strb $h3,[$mac,#13] - mov $h3,$h3,lsr#8 - - strb $h0,[$mac,#2] - mov $h0,$h0,lsr#8 - strb $h1,[$mac,#6] - mov $h1,$h1,lsr#8 - strb $h2,[$mac,#10] - mov $h2,$h2,lsr#8 - strb $h3,[$mac,#14] - mov $h3,$h3,lsr#8 - - strb $h0,[$mac,#3] - strb $h1,[$mac,#7] - strb $h2,[$mac,#11] - strb $h3,[$mac,#15] -#endif - ldmia sp!,{r4-r11} -#if __ARM_ARCH__>=5 - ret @ bx lr -#else - tst lr,#1 - moveq pc,lr @ be binary compatible with V4, yet - bx lr @ interoperable with Thumb ISA:-) -#endif -.size GFp_poly1305_emit,.-GFp_poly1305_emit -___ -{ -my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("d$_",(0..9)); -my ($D0,$D1,$D2,$D3,$D4, $H0,$H1,$H2,$H3,$H4) = map("q$_",(5..14)); -my ($T0,$T1,$MASK) = map("q$_",(15,4,0)); - -my ($in2,$zeros,$tbl0,$tbl1) = map("r$_",(4..7)); - -$code.=<<___; -#if __ARM_MAX_ARCH__>=7 -.fpu neon - -.type poly1305_init_neon,%function -.align 5 -poly1305_init_neon: - ldr r4,[$ctx,#20] @ load key base 2^32 - ldr r5,[$ctx,#24] - ldr r6,[$ctx,#28] - ldr r7,[$ctx,#32] - - and r2,r4,#0x03ffffff @ base 2^32 -> base 2^26 - mov r3,r4,lsr#26 - mov r4,r5,lsr#20 - orr r3,r3,r5,lsl#6 - mov r5,r6,lsr#14 - orr r4,r4,r6,lsl#12 - mov r6,r7,lsr#8 - orr r5,r5,r7,lsl#18 - and r3,r3,#0x03ffffff - and r4,r4,#0x03ffffff - and r5,r5,#0x03ffffff - - vdup.32 $R0,r2 @ r^1 in both lanes - add r2,r3,r3,lsl#2 @ *5 - vdup.32 $R1,r3 - add r3,r4,r4,lsl#2 - vdup.32 $S1,r2 - vdup.32 $R2,r4 - add r4,r5,r5,lsl#2 - vdup.32 $S2,r3 - vdup.32 $R3,r5 - add r5,r6,r6,lsl#2 - vdup.32 $S3,r4 - vdup.32 $R4,r6 - vdup.32 $S4,r5 - - mov $zeros,#2 @ counter - -.Lsquare_neon: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - @ d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - @ d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - @ d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - @ d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - - vmull.u32 $D0,$R0,${R0}[1] - vmull.u32 $D1,$R1,${R0}[1] - vmull.u32 $D2,$R2,${R0}[1] - vmull.u32 $D3,$R3,${R0}[1] - vmull.u32 $D4,$R4,${R0}[1] - - vmlal.u32 $D0,$R4,${S1}[1] - vmlal.u32 $D1,$R0,${R1}[1] - vmlal.u32 $D2,$R1,${R1}[1] - vmlal.u32 $D3,$R2,${R1}[1] - vmlal.u32 $D4,$R3,${R1}[1] - - vmlal.u32 $D0,$R3,${S2}[1] - vmlal.u32 $D1,$R4,${S2}[1] - vmlal.u32 $D3,$R1,${R2}[1] - vmlal.u32 $D2,$R0,${R2}[1] - vmlal.u32 $D4,$R2,${R2}[1] - - vmlal.u32 $D0,$R2,${S3}[1] - vmlal.u32 $D3,$R0,${R3}[1] - vmlal.u32 $D1,$R3,${S3}[1] - vmlal.u32 $D2,$R4,${S3}[1] - vmlal.u32 $D4,$R1,${R3}[1] - - vmlal.u32 $D3,$R4,${S4}[1] - vmlal.u32 $D0,$R1,${S4}[1] - vmlal.u32 $D1,$R2,${S4}[1] - vmlal.u32 $D2,$R3,${S4}[1] - vmlal.u32 $D4,$R0,${R4}[1] - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ lazy reduction as discussed in "NEON crypto" by D.J. Bernstein - @ and P. Schwabe - @ - @ H0>>+H1>>+H2>>+H3>>+H4 - @ H3>>+H4>>*5+H0>>+H1 - @ - @ Trivia. - @ - @ Result of multiplication of n-bit number by m-bit number is - @ n+m bits wide. However! Even though 2^n is a n+1-bit number, - @ m-bit number multiplied by 2^n is still n+m bits wide. - @ - @ Sum of two n-bit numbers is n+1 bits wide, sum of three - n+2, - @ and so is sum of four. Sum of 2^m n-m-bit numbers and n-bit - @ one is n+1 bits wide. - @ - @ >>+ denotes Hnext += Hn>>26, Hn &= 0x3ffffff. This means that - @ H0, H2, H3 are guaranteed to be 26 bits wide, while H1 and H4 - @ can be 27. However! In cases when their width exceeds 26 bits - @ they are limited by 2^26+2^6. This in turn means that *sum* - @ of the products with these values can still be viewed as sum - @ of 52-bit numbers as long as the amount of addends is not a - @ power of 2. For example, - @ - @ H4 = H4*R0 + H3*R1 + H2*R2 + H1*R3 + H0 * R4, - @ - @ which can't be larger than 5 * (2^26 + 2^6) * (2^26 + 2^6), or - @ 5 * (2^52 + 2*2^32 + 2^12), which in turn is smaller than - @ 8 * (2^52) or 2^55. However, the value is then multiplied by - @ by 5, so we should be looking at 5 * 5 * (2^52 + 2^33 + 2^12), - @ which is less than 32 * (2^52) or 2^57. And when processing - @ data we are looking at triple as many addends... - @ - @ In key setup procedure pre-reduced H0 is limited by 5*4+1 and - @ 5*H4 - by 5*5 52-bit addends, or 57 bits. But when hashing the - @ input H0 is limited by (5*4+1)*3 addends, or 58 bits, while - @ 5*H4 by 5*5*3, or 59[!] bits. How is this relevant? vmlal.u32 - @ instruction accepts 2x32-bit input and writes 2x64-bit result. - @ This means that result of reduction have to be compressed upon - @ loop wrap-around. This can be done in the process of reduction - @ to minimize amount of instructions [as well as amount of - @ 128-bit instructions, which benefits low-end processors], but - @ one has to watch for H2 (which is narrower than H0) and 5*H4 - @ not being wider than 58 bits, so that result of right shift - @ by 26 bits fits in 32 bits. This is also useful on x86, - @ because it allows to use paddd in place for paddq, which - @ benefits Atom, where paddq is ridiculously slow. - - vshr.u64 $T0,$D3,#26 - vmovn.i64 $D3#lo,$D3 - vshr.u64 $T1,$D0,#26 - vmovn.i64 $D0#lo,$D0 - vadd.i64 $D4,$D4,$T0 @ h3 -> h4 - vbic.i32 $D3#lo,#0xfc000000 @ &=0x03ffffff - vadd.i64 $D1,$D1,$T1 @ h0 -> h1 - vbic.i32 $D0#lo,#0xfc000000 - - vshrn.u64 $T0#lo,$D4,#26 - vmovn.i64 $D4#lo,$D4 - vshr.u64 $T1,$D1,#26 - vmovn.i64 $D1#lo,$D1 - vadd.i64 $D2,$D2,$T1 @ h1 -> h2 - vbic.i32 $D4#lo,#0xfc000000 - vbic.i32 $D1#lo,#0xfc000000 - - vadd.i32 $D0#lo,$D0#lo,$T0#lo - vshl.u32 $T0#lo,$T0#lo,#2 - vshrn.u64 $T1#lo,$D2,#26 - vmovn.i64 $D2#lo,$D2 - vadd.i32 $D0#lo,$D0#lo,$T0#lo @ h4 -> h0 - vadd.i32 $D3#lo,$D3#lo,$T1#lo @ h2 -> h3 - vbic.i32 $D2#lo,#0xfc000000 - - vshr.u32 $T0#lo,$D0#lo,#26 - vbic.i32 $D0#lo,#0xfc000000 - vshr.u32 $T1#lo,$D3#lo,#26 - vbic.i32 $D3#lo,#0xfc000000 - vadd.i32 $D1#lo,$D1#lo,$T0#lo @ h0 -> h1 - vadd.i32 $D4#lo,$D4#lo,$T1#lo @ h3 -> h4 - - subs $zeros,$zeros,#1 - beq .Lsquare_break_neon - - add $tbl0,$ctx,#(48+0*9*4) - add $tbl1,$ctx,#(48+1*9*4) - - vtrn.32 $R0,$D0#lo @ r^2:r^1 - vtrn.32 $R2,$D2#lo - vtrn.32 $R3,$D3#lo - vtrn.32 $R1,$D1#lo - vtrn.32 $R4,$D4#lo - - vshl.u32 $S2,$R2,#2 @ *5 - vshl.u32 $S3,$R3,#2 - vshl.u32 $S1,$R1,#2 - vshl.u32 $S4,$R4,#2 - vadd.i32 $S2,$S2,$R2 - vadd.i32 $S1,$S1,$R1 - vadd.i32 $S3,$S3,$R3 - vadd.i32 $S4,$S4,$R4 - - vst4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! - vst4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! - vst4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]! - vst4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]! - vst1.32 {${S4}[0]},[$tbl0,:32] - vst1.32 {${S4}[1]},[$tbl1,:32] - - b .Lsquare_neon - -.align 4 -.Lsquare_break_neon: - add $tbl0,$ctx,#(48+2*4*9) - add $tbl1,$ctx,#(48+3*4*9) - - vmov $R0,$D0#lo @ r^4:r^3 - vshl.u32 $S1,$D1#lo,#2 @ *5 - vmov $R1,$D1#lo - vshl.u32 $S2,$D2#lo,#2 - vmov $R2,$D2#lo - vshl.u32 $S3,$D3#lo,#2 - vmov $R3,$D3#lo - vshl.u32 $S4,$D4#lo,#2 - vmov $R4,$D4#lo - vadd.i32 $S1,$S1,$D1#lo - vadd.i32 $S2,$S2,$D2#lo - vadd.i32 $S3,$S3,$D3#lo - vadd.i32 $S4,$S4,$D4#lo - - vst4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! - vst4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! - vst4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]! - vst4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]! - vst1.32 {${S4}[0]},[$tbl0] - vst1.32 {${S4}[1]},[$tbl1] - - ret @ bx lr -.size poly1305_init_neon,.-poly1305_init_neon - -.type poly1305_blocks_neon,%function -.align 5 -poly1305_blocks_neon: - ldr ip,[$ctx,#36] @ is_base2_26 - ands $len,$len,#-16 - beq .Lno_data_neon - - cmp $len,#64 - bhs .Lenter_neon - tst ip,ip @ is_base2_26? - beq GFp_poly1305_blocks - -.Lenter_neon: - stmdb sp!,{r4-r7} - vstmdb sp!,{d8-d15} @ ABI specification says so - - tst ip,ip @ is_base2_26? - bne .Lbase2_26_neon - - stmdb sp!,{r1-r3,lr} - bl poly1305_init_neon - - ldr r4,[$ctx,#0] @ load hash value base 2^32 - ldr r5,[$ctx,#4] - ldr r6,[$ctx,#8] - ldr r7,[$ctx,#12] - ldr ip,[$ctx,#16] - - and r2,r4,#0x03ffffff @ base 2^32 -> base 2^26 - mov r3,r4,lsr#26 - veor $D0#lo,$D0#lo,$D0#lo - mov r4,r5,lsr#20 - orr r3,r3,r5,lsl#6 - veor $D1#lo,$D1#lo,$D1#lo - mov r5,r6,lsr#14 - orr r4,r4,r6,lsl#12 - veor $D2#lo,$D2#lo,$D2#lo - mov r6,r7,lsr#8 - orr r5,r5,r7,lsl#18 - veor $D3#lo,$D3#lo,$D3#lo - and r3,r3,#0x03ffffff - orr r6,r6,ip,lsl#24 - veor $D4#lo,$D4#lo,$D4#lo - and r4,r4,#0x03ffffff - mov r1,#1 - and r5,r5,#0x03ffffff - str r1,[$ctx,#36] @ is_base2_26 - - vmov.32 $D0#lo[0],r2 - vmov.32 $D1#lo[0],r3 - vmov.32 $D2#lo[0],r4 - vmov.32 $D3#lo[0],r5 - vmov.32 $D4#lo[0],r6 - adr $zeros,.Lzeros - - ldmia sp!,{r1-r3,lr} - b .Lbase2_32_neon - -.align 4 -.Lbase2_26_neon: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ load hash value - - veor $D0#lo,$D0#lo,$D0#lo - veor $D1#lo,$D1#lo,$D1#lo - veor $D2#lo,$D2#lo,$D2#lo - veor $D3#lo,$D3#lo,$D3#lo - veor $D4#lo,$D4#lo,$D4#lo - vld4.32 {$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]! - adr $zeros,.Lzeros - vld1.32 {$D4#lo[0]},[$ctx] - sub $ctx,$ctx,#16 @ rewind - -.Lbase2_32_neon: - add $in2,$inp,#32 - mov $padbit,$padbit,lsl#24 - tst $len,#31 - beq .Leven - - vld4.32 {$H0#lo[0],$H1#lo[0],$H2#lo[0],$H3#lo[0]},[$inp]! - vmov.32 $H4#lo[0],$padbit - sub $len,$len,#16 - add $in2,$inp,#32 - -# ifdef __ARMEB__ - vrev32.8 $H0,$H0 - vrev32.8 $H3,$H3 - vrev32.8 $H1,$H1 - vrev32.8 $H2,$H2 -# endif - vsri.u32 $H4#lo,$H3#lo,#8 @ base 2^32 -> base 2^26 - vshl.u32 $H3#lo,$H3#lo,#18 - - vsri.u32 $H3#lo,$H2#lo,#14 - vshl.u32 $H2#lo,$H2#lo,#12 - vadd.i32 $H4#hi,$H4#lo,$D4#lo @ add hash value and move to #hi - - vbic.i32 $H3#lo,#0xfc000000 - vsri.u32 $H2#lo,$H1#lo,#20 - vshl.u32 $H1#lo,$H1#lo,#6 - - vbic.i32 $H2#lo,#0xfc000000 - vsri.u32 $H1#lo,$H0#lo,#26 - vadd.i32 $H3#hi,$H3#lo,$D3#lo - - vbic.i32 $H0#lo,#0xfc000000 - vbic.i32 $H1#lo,#0xfc000000 - vadd.i32 $H2#hi,$H2#lo,$D2#lo - - vadd.i32 $H0#hi,$H0#lo,$D0#lo - vadd.i32 $H1#hi,$H1#lo,$D1#lo - - mov $tbl1,$zeros - add $tbl0,$ctx,#48 - - cmp $len,$len - b .Long_tail - -.align 4 -.Leven: - subs $len,$len,#64 - it lo - movlo $in2,$zeros - - vmov.i32 $H4,#1<<24 @ padbit, yes, always - vld4.32 {$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp] @ inp[0:1] - add $inp,$inp,#64 - vld4.32 {$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2] @ inp[2:3] (or 0) - add $in2,$in2,#64 - itt hi - addhi $tbl1,$ctx,#(48+1*9*4) - addhi $tbl0,$ctx,#(48+3*9*4) - -# ifdef __ARMEB__ - vrev32.8 $H0,$H0 - vrev32.8 $H3,$H3 - vrev32.8 $H1,$H1 - vrev32.8 $H2,$H2 -# endif - vsri.u32 $H4,$H3,#8 @ base 2^32 -> base 2^26 - vshl.u32 $H3,$H3,#18 - - vsri.u32 $H3,$H2,#14 - vshl.u32 $H2,$H2,#12 - - vbic.i32 $H3,#0xfc000000 - vsri.u32 $H2,$H1,#20 - vshl.u32 $H1,$H1,#6 - - vbic.i32 $H2,#0xfc000000 - vsri.u32 $H1,$H0,#26 - - vbic.i32 $H0,#0xfc000000 - vbic.i32 $H1,#0xfc000000 - - bls .Lskip_loop - - vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^2 - vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^4 - vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]! - vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]! - b .Loop_neon - -.align 5 -.Loop_neon: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 - @ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r - @ \___________________/ - @ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2 - @ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r - @ \___________________/ \____________________/ - @ - @ Note that we start with inp[2:3]*r^2. This is because it - @ doesn't depend on reduction in previous iteration. - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - @ d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - @ d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - @ d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - @ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ inp[2:3]*r^2 - - vadd.i32 $H2#lo,$H2#lo,$D2#lo @ accumulate inp[0:1] - vmull.u32 $D2,$H2#hi,${R0}[1] - vadd.i32 $H0#lo,$H0#lo,$D0#lo - vmull.u32 $D0,$H0#hi,${R0}[1] - vadd.i32 $H3#lo,$H3#lo,$D3#lo - vmull.u32 $D3,$H3#hi,${R0}[1] - vmlal.u32 $D2,$H1#hi,${R1}[1] - vadd.i32 $H1#lo,$H1#lo,$D1#lo - vmull.u32 $D1,$H1#hi,${R0}[1] - - vadd.i32 $H4#lo,$H4#lo,$D4#lo - vmull.u32 $D4,$H4#hi,${R0}[1] - subs $len,$len,#64 - vmlal.u32 $D0,$H4#hi,${S1}[1] - it lo - movlo $in2,$zeros - vmlal.u32 $D3,$H2#hi,${R1}[1] - vld1.32 ${S4}[1],[$tbl1,:32] - vmlal.u32 $D1,$H0#hi,${R1}[1] - vmlal.u32 $D4,$H3#hi,${R1}[1] - - vmlal.u32 $D0,$H3#hi,${S2}[1] - vmlal.u32 $D3,$H1#hi,${R2}[1] - vmlal.u32 $D4,$H2#hi,${R2}[1] - vmlal.u32 $D1,$H4#hi,${S2}[1] - vmlal.u32 $D2,$H0#hi,${R2}[1] - - vmlal.u32 $D3,$H0#hi,${R3}[1] - vmlal.u32 $D0,$H2#hi,${S3}[1] - vmlal.u32 $D4,$H1#hi,${R3}[1] - vmlal.u32 $D1,$H3#hi,${S3}[1] - vmlal.u32 $D2,$H4#hi,${S3}[1] - - vmlal.u32 $D3,$H4#hi,${S4}[1] - vmlal.u32 $D0,$H1#hi,${S4}[1] - vmlal.u32 $D4,$H0#hi,${R4}[1] - vmlal.u32 $D1,$H2#hi,${S4}[1] - vmlal.u32 $D2,$H3#hi,${S4}[1] - - vld4.32 {$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2] @ inp[2:3] (or 0) - add $in2,$in2,#64 - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ (hash+inp[0:1])*r^4 and accumulate - - vmlal.u32 $D3,$H3#lo,${R0}[0] - vmlal.u32 $D0,$H0#lo,${R0}[0] - vmlal.u32 $D4,$H4#lo,${R0}[0] - vmlal.u32 $D1,$H1#lo,${R0}[0] - vmlal.u32 $D2,$H2#lo,${R0}[0] - vld1.32 ${S4}[0],[$tbl0,:32] - - vmlal.u32 $D3,$H2#lo,${R1}[0] - vmlal.u32 $D0,$H4#lo,${S1}[0] - vmlal.u32 $D4,$H3#lo,${R1}[0] - vmlal.u32 $D1,$H0#lo,${R1}[0] - vmlal.u32 $D2,$H1#lo,${R1}[0] - - vmlal.u32 $D3,$H1#lo,${R2}[0] - vmlal.u32 $D0,$H3#lo,${S2}[0] - vmlal.u32 $D4,$H2#lo,${R2}[0] - vmlal.u32 $D1,$H4#lo,${S2}[0] - vmlal.u32 $D2,$H0#lo,${R2}[0] - - vmlal.u32 $D3,$H0#lo,${R3}[0] - vmlal.u32 $D0,$H2#lo,${S3}[0] - vmlal.u32 $D4,$H1#lo,${R3}[0] - vmlal.u32 $D1,$H3#lo,${S3}[0] - vmlal.u32 $D3,$H4#lo,${S4}[0] - - vmlal.u32 $D2,$H4#lo,${S3}[0] - vmlal.u32 $D0,$H1#lo,${S4}[0] - vmlal.u32 $D4,$H0#lo,${R4}[0] - vmov.i32 $H4,#1<<24 @ padbit, yes, always - vmlal.u32 $D1,$H2#lo,${S4}[0] - vmlal.u32 $D2,$H3#lo,${S4}[0] - - vld4.32 {$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp] @ inp[0:1] - add $inp,$inp,#64 -# ifdef __ARMEB__ - vrev32.8 $H0,$H0 - vrev32.8 $H1,$H1 - vrev32.8 $H2,$H2 - vrev32.8 $H3,$H3 -# endif - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ lazy reduction interleaved with base 2^32 -> base 2^26 of - @ inp[0:3] previously loaded to $H0-$H3 and smashed to $H0-$H4. - - vshr.u64 $T0,$D3,#26 - vmovn.i64 $D3#lo,$D3 - vshr.u64 $T1,$D0,#26 - vmovn.i64 $D0#lo,$D0 - vadd.i64 $D4,$D4,$T0 @ h3 -> h4 - vbic.i32 $D3#lo,#0xfc000000 - vsri.u32 $H4,$H3,#8 @ base 2^32 -> base 2^26 - vadd.i64 $D1,$D1,$T1 @ h0 -> h1 - vshl.u32 $H3,$H3,#18 - vbic.i32 $D0#lo,#0xfc000000 - - vshrn.u64 $T0#lo,$D4,#26 - vmovn.i64 $D4#lo,$D4 - vshr.u64 $T1,$D1,#26 - vmovn.i64 $D1#lo,$D1 - vadd.i64 $D2,$D2,$T1 @ h1 -> h2 - vsri.u32 $H3,$H2,#14 - vbic.i32 $D4#lo,#0xfc000000 - vshl.u32 $H2,$H2,#12 - vbic.i32 $D1#lo,#0xfc000000 - - vadd.i32 $D0#lo,$D0#lo,$T0#lo - vshl.u32 $T0#lo,$T0#lo,#2 - vbic.i32 $H3,#0xfc000000 - vshrn.u64 $T1#lo,$D2,#26 - vmovn.i64 $D2#lo,$D2 - vaddl.u32 $D0,$D0#lo,$T0#lo @ h4 -> h0 [widen for a sec] - vsri.u32 $H2,$H1,#20 - vadd.i32 $D3#lo,$D3#lo,$T1#lo @ h2 -> h3 - vshl.u32 $H1,$H1,#6 - vbic.i32 $D2#lo,#0xfc000000 - vbic.i32 $H2,#0xfc000000 - - vshrn.u64 $T0#lo,$D0,#26 @ re-narrow - vmovn.i64 $D0#lo,$D0 - vsri.u32 $H1,$H0,#26 - vbic.i32 $H0,#0xfc000000 - vshr.u32 $T1#lo,$D3#lo,#26 - vbic.i32 $D3#lo,#0xfc000000 - vbic.i32 $D0#lo,#0xfc000000 - vadd.i32 $D1#lo,$D1#lo,$T0#lo @ h0 -> h1 - vadd.i32 $D4#lo,$D4#lo,$T1#lo @ h3 -> h4 - vbic.i32 $H1,#0xfc000000 - - bhi .Loop_neon - -.Lskip_loop: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1 - - add $tbl1,$ctx,#(48+0*9*4) - add $tbl0,$ctx,#(48+1*9*4) - adds $len,$len,#32 - it ne - movne $len,#0 - bne .Long_tail - - vadd.i32 $H2#hi,$H2#lo,$D2#lo @ add hash value and move to #hi - vadd.i32 $H0#hi,$H0#lo,$D0#lo - vadd.i32 $H3#hi,$H3#lo,$D3#lo - vadd.i32 $H1#hi,$H1#lo,$D1#lo - vadd.i32 $H4#hi,$H4#lo,$D4#lo - -.Long_tail: - vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^1 - vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^2 - - vadd.i32 $H2#lo,$H2#lo,$D2#lo @ can be redundant - vmull.u32 $D2,$H2#hi,$R0 - vadd.i32 $H0#lo,$H0#lo,$D0#lo - vmull.u32 $D0,$H0#hi,$R0 - vadd.i32 $H3#lo,$H3#lo,$D3#lo - vmull.u32 $D3,$H3#hi,$R0 - vadd.i32 $H1#lo,$H1#lo,$D1#lo - vmull.u32 $D1,$H1#hi,$R0 - vadd.i32 $H4#lo,$H4#lo,$D4#lo - vmull.u32 $D4,$H4#hi,$R0 - - vmlal.u32 $D0,$H4#hi,$S1 - vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]! - vmlal.u32 $D3,$H2#hi,$R1 - vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]! - vmlal.u32 $D1,$H0#hi,$R1 - vmlal.u32 $D4,$H3#hi,$R1 - vmlal.u32 $D2,$H1#hi,$R1 - - vmlal.u32 $D3,$H1#hi,$R2 - vld1.32 ${S4}[1],[$tbl1,:32] - vmlal.u32 $D0,$H3#hi,$S2 - vld1.32 ${S4}[0],[$tbl0,:32] - vmlal.u32 $D4,$H2#hi,$R2 - vmlal.u32 $D1,$H4#hi,$S2 - vmlal.u32 $D2,$H0#hi,$R2 - - vmlal.u32 $D3,$H0#hi,$R3 - it ne - addne $tbl1,$ctx,#(48+2*9*4) - vmlal.u32 $D0,$H2#hi,$S3 - it ne - addne $tbl0,$ctx,#(48+3*9*4) - vmlal.u32 $D4,$H1#hi,$R3 - vmlal.u32 $D1,$H3#hi,$S3 - vmlal.u32 $D2,$H4#hi,$S3 - - vmlal.u32 $D3,$H4#hi,$S4 - vorn $MASK,$MASK,$MASK @ all-ones, can be redundant - vmlal.u32 $D0,$H1#hi,$S4 - vshr.u64 $MASK,$MASK,#38 - vmlal.u32 $D4,$H0#hi,$R4 - vmlal.u32 $D1,$H2#hi,$S4 - vmlal.u32 $D2,$H3#hi,$S4 - - beq .Lshort_tail - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ (hash+inp[0:1])*r^4:r^3 and accumulate - - vld4.32 {${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]! @ load r^3 - vld4.32 {${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]! @ load r^4 - - vmlal.u32 $D2,$H2#lo,$R0 - vmlal.u32 $D0,$H0#lo,$R0 - vmlal.u32 $D3,$H3#lo,$R0 - vmlal.u32 $D1,$H1#lo,$R0 - vmlal.u32 $D4,$H4#lo,$R0 - - vmlal.u32 $D0,$H4#lo,$S1 - vld4.32 {${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]! - vmlal.u32 $D3,$H2#lo,$R1 - vld4.32 {${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]! - vmlal.u32 $D1,$H0#lo,$R1 - vmlal.u32 $D4,$H3#lo,$R1 - vmlal.u32 $D2,$H1#lo,$R1 - - vmlal.u32 $D3,$H1#lo,$R2 - vld1.32 ${S4}[1],[$tbl1,:32] - vmlal.u32 $D0,$H3#lo,$S2 - vld1.32 ${S4}[0],[$tbl0,:32] - vmlal.u32 $D4,$H2#lo,$R2 - vmlal.u32 $D1,$H4#lo,$S2 - vmlal.u32 $D2,$H0#lo,$R2 - - vmlal.u32 $D3,$H0#lo,$R3 - vmlal.u32 $D0,$H2#lo,$S3 - vmlal.u32 $D4,$H1#lo,$R3 - vmlal.u32 $D1,$H3#lo,$S3 - vmlal.u32 $D2,$H4#lo,$S3 - - vmlal.u32 $D3,$H4#lo,$S4 - vorn $MASK,$MASK,$MASK @ all-ones - vmlal.u32 $D0,$H1#lo,$S4 - vshr.u64 $MASK,$MASK,#38 - vmlal.u32 $D4,$H0#lo,$R4 - vmlal.u32 $D1,$H2#lo,$S4 - vmlal.u32 $D2,$H3#lo,$S4 - -.Lshort_tail: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ horizontal addition - - vadd.i64 $D3#lo,$D3#lo,$D3#hi - vadd.i64 $D0#lo,$D0#lo,$D0#hi - vadd.i64 $D4#lo,$D4#lo,$D4#hi - vadd.i64 $D1#lo,$D1#lo,$D1#hi - vadd.i64 $D2#lo,$D2#lo,$D2#hi - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ lazy reduction, but without narrowing - - vshr.u64 $T0,$D3,#26 - vand.i64 $D3,$D3,$MASK - vshr.u64 $T1,$D0,#26 - vand.i64 $D0,$D0,$MASK - vadd.i64 $D4,$D4,$T0 @ h3 -> h4 - vadd.i64 $D1,$D1,$T1 @ h0 -> h1 - - vshr.u64 $T0,$D4,#26 - vand.i64 $D4,$D4,$MASK - vshr.u64 $T1,$D1,#26 - vand.i64 $D1,$D1,$MASK - vadd.i64 $D2,$D2,$T1 @ h1 -> h2 - - vadd.i64 $D0,$D0,$T0 - vshl.u64 $T0,$T0,#2 - vshr.u64 $T1,$D2,#26 - vand.i64 $D2,$D2,$MASK - vadd.i64 $D0,$D0,$T0 @ h4 -> h0 - vadd.i64 $D3,$D3,$T1 @ h2 -> h3 - - vshr.u64 $T0,$D0,#26 - vand.i64 $D0,$D0,$MASK - vshr.u64 $T1,$D3,#26 - vand.i64 $D3,$D3,$MASK - vadd.i64 $D1,$D1,$T0 @ h0 -> h1 - vadd.i64 $D4,$D4,$T1 @ h3 -> h4 - - cmp $len,#0 - bne .Leven - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ store hash value - - vst4.32 {$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]! - vst1.32 {$D4#lo[0]},[$ctx] - - vldmia sp!,{d8-d15} @ epilogue - ldmia sp!,{r4-r7} -.Lno_data_neon: - ret @ bx lr -.size poly1305_blocks_neon,.-poly1305_blocks_neon - -.type poly1305_emit_neon,%function -.align 5 -poly1305_emit_neon: - ldr ip,[$ctx,#36] @ is_base2_26 - - stmdb sp!,{r4-r11} - - tst ip,ip - beq .Lpoly1305_emit_enter - - ldmia $ctx,{$h0-$h4} - eor $g0,$g0,$g0 - - adds $h0,$h0,$h1,lsl#26 @ base 2^26 -> base 2^32 - mov $h1,$h1,lsr#6 - adcs $h1,$h1,$h2,lsl#20 - mov $h2,$h2,lsr#12 - adcs $h2,$h2,$h3,lsl#14 - mov $h3,$h3,lsr#18 - adcs $h3,$h3,$h4,lsl#8 - adc $h4,$g0,$h4,lsr#24 @ can be partially reduced ... - - and $g0,$h4,#-4 @ ... so reduce - and $h4,$h3,#3 - add $g0,$g0,$g0,lsr#2 @ *= 5 - adds $h0,$h0,$g0 - adcs $h1,$h1,#0 - adcs $h2,$h2,#0 - adcs $h3,$h3,#0 - adc $h4,$h4,#0 - - adds $g0,$h0,#5 @ compare to modulus - adcs $g1,$h1,#0 - adcs $g2,$h2,#0 - adcs $g3,$h3,#0 - adc $g4,$h4,#0 - tst $g4,#4 @ did it carry/borrow? - - it ne - movne $h0,$g0 - ldr $g0,[$nonce,#0] - it ne - movne $h1,$g1 - ldr $g1,[$nonce,#4] - it ne - movne $h2,$g2 - ldr $g2,[$nonce,#8] - it ne - movne $h3,$g3 - ldr $g3,[$nonce,#12] - - adds $h0,$h0,$g0 @ accumulate nonce - adcs $h1,$h1,$g1 - adcs $h2,$h2,$g2 - adc $h3,$h3,$g3 - -# ifdef __ARMEB__ - rev $h0,$h0 - rev $h1,$h1 - rev $h2,$h2 - rev $h3,$h3 -# endif - str $h0,[$mac,#0] @ store the result - str $h1,[$mac,#4] - str $h2,[$mac,#8] - str $h3,[$mac,#12] - - ldmia sp!,{r4-r11} - ret @ bx lr -.size poly1305_emit_neon,.-poly1305_emit_neon - -.align 5 -.Lzeros: -.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.LOPENSSL_armcap: -.word GFp_armcap_P-.Lpoly1305_init -#endif -___ -} } -$code.=<<___; -.asciz "Poly1305 for ARMv4/NEON, CRYPTOGAMS by " -.align 2 -#if __ARM_MAX_ARCH__>=7 -.comm GFp_armcap_P,4,4 -#endif -___ - -foreach (split("\n",$code)) { - s/\`([^\`]*)\`/eval $1/geo; - - s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or - s/\bret\b/bx lr/go or - s/\bbx\s+lr\b/.word\t0xe12fff1e/go; # make it possible to compile with -march=armv4 - - print $_,"\n"; -} -close STDOUT or die "error closing STDOUT"; diff --git a/crypto/poly1305/asm/poly1305-armv8.pl b/crypto/poly1305/asm/poly1305-armv8.pl deleted file mode 100755 index 82aee20c11..0000000000 --- a/crypto/poly1305/asm/poly1305-armv8.pl +++ /dev/null @@ -1,931 +0,0 @@ -#!/usr/bin/env perl -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# This module implements Poly1305 hash for ARMv8. -# -# June 2015 -# -# Numbers are cycles per processed byte with GFp_poly1305_blocks alone. -# -# IALU/gcc-4.9 NEON -# -# Apple A7 1.86/+5% 0.72 -# Cortex-A53 2.69/+58% 1.47 -# Cortex-A57 2.70/+7% 1.14 -# Denver 1.64/+50% 1.18(*) -# X-Gene 2.13/+68% 2.27 -# -# (*) estimate based on resources availability is less than 1.0, -# i.e. measured result is worse than expected, presumably binary -# translator is not almighty; - -$flavour=shift; -$output=shift; - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or -die "can't locate arm-xlate.pl"; - -open OUT,"| \"$^X\" $xlate $flavour $output"; -*STDOUT=*OUT; - -my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3)); -my ($mac,$nonce)=($inp,$len); - -my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14)); - -$code.=<<___; -#include - -.text - -// forward "declarations" are required for Apple -.extern GFp_armcap_P -.globl GFp_poly1305_blocks -.globl GFp_poly1305_emit -.globl GFp_poly1305_init_asm - -.type GFp_poly1305_init_asm,%function -.align 5 -GFp_poly1305_init_asm: - cmp $inp,xzr - stp xzr,xzr,[$ctx] // zero hash value - stp xzr,xzr,[$ctx,#16] // [along with is_base2_26] - - csel x0,xzr,x0,eq - b.eq .Lno_key - -#ifdef __ILP32__ - ldrsw $t1,.LGFp_armcap_P -#else - ldr $t1,.LGFp_armcap_P -#endif - adr $t0,.LGFp_armcap_P - - ldp $r0,$r1,[$inp] // load key - mov $s1,#0xfffffffc0fffffff - movk $s1,#0x0fff,lsl#48 - ldr w17,[$t0,$t1] -#ifdef __ARMEB__ - rev $r0,$r0 // flip bytes - rev $r1,$r1 -#endif - and $r0,$r0,$s1 // &=0ffffffc0fffffff - and $s1,$s1,#-4 - and $r1,$r1,$s1 // &=0ffffffc0ffffffc - stp $r0,$r1,[$ctx,#32] // save key value - - tst w17,#ARMV7_NEON - - adr $d0,GFp_poly1305_blocks - adr $r0,poly1305_blocks_neon - adr $d1,GFp_poly1305_emit - adr $r1,poly1305_emit_neon - - csel $d0,$d0,$r0,eq - csel $d1,$d1,$r1,eq - - stp $d0,$d1,[$len] - - mov x0,#1 -.Lno_key: - ret -.size GFp_poly1305_init_asm,.-GFp_poly1305_init_asm - -.type GFp_poly1305_blocks,%function -.align 5 -GFp_poly1305_blocks: - ands $len,$len,#-16 - b.eq .Lno_data - - ldp $h0,$h1,[$ctx] // load hash value - ldp $r0,$r1,[$ctx,#32] // load key value - ldr $h2,[$ctx,#16] - add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2) - b .Loop - -.align 5 -.Loop: - ldp $t0,$t1,[$inp],#16 // load input - sub $len,$len,#16 -#ifdef __ARMEB__ - rev $t0,$t0 - rev $t1,$t1 -#endif - adds $h0,$h0,$t0 // accumulate input - adcs $h1,$h1,$t1 - - mul $d0,$h0,$r0 // h0*r0 - adc $h2,$h2,$padbit - umulh $d1,$h0,$r0 - - mul $t0,$h1,$s1 // h1*5*r1 - umulh $t1,$h1,$s1 - - adds $d0,$d0,$t0 - mul $t0,$h0,$r1 // h0*r1 - adc $d1,$d1,$t1 - umulh $d2,$h0,$r1 - - adds $d1,$d1,$t0 - mul $t0,$h1,$r0 // h1*r0 - adc $d2,$d2,xzr - umulh $t1,$h1,$r0 - - adds $d1,$d1,$t0 - mul $t0,$h2,$s1 // h2*5*r1 - adc $d2,$d2,$t1 - mul $t1,$h2,$r0 // h2*r0 - - adds $d1,$d1,$t0 - adc $d2,$d2,$t1 - - and $t0,$d2,#-4 // final reduction - and $h2,$d2,#3 - add $t0,$t0,$d2,lsr#2 - adds $h0,$d0,$t0 - adcs $h1,$d1,xzr - adc $h2,$h2,xzr - - cbnz $len,.Loop - - stp $h0,$h1,[$ctx] // store hash value - str $h2,[$ctx,#16] - -.Lno_data: - ret -.size GFp_poly1305_blocks,.-GFp_poly1305_blocks - -.type GFp_poly1305_emit,%function -.align 5 -GFp_poly1305_emit: - ldp $h0,$h1,[$ctx] // load hash base 2^64 - ldr $h2,[$ctx,#16] - ldp $t0,$t1,[$nonce] // load nonce - - adds $d0,$h0,#5 // compare to modulus - adcs $d1,$h1,xzr - adc $d2,$h2,xzr - - tst $d2,#-4 // see if it's carried/borrowed - - csel $h0,$h0,$d0,eq - csel $h1,$h1,$d1,eq - -#ifdef __ARMEB__ - ror $t0,$t0,#32 // flip nonce words - ror $t1,$t1,#32 -#endif - adds $h0,$h0,$t0 // accumulate nonce - adc $h1,$h1,$t1 -#ifdef __ARMEB__ - rev $h0,$h0 // flip output bytes - rev $h1,$h1 -#endif - stp $h0,$h1,[$mac] // write result - - ret -.size GFp_poly1305_emit,.-GFp_poly1305_emit -___ -my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8)); -my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13)); -my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18)); -my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23)); -my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28)); -my ($T0,$T1,$MASK) = map("v$_",(29..31)); - -my ($in2,$zeros)=("x16","x17"); -my $is_base2_26 = $zeros; # borrow - -$code.=<<___; -.type poly1305_mult,%function -.align 5 -poly1305_mult: - mul $d0,$h0,$r0 // h0*r0 - umulh $d1,$h0,$r0 - - mul $t0,$h1,$s1 // h1*5*r1 - umulh $t1,$h1,$s1 - - adds $d0,$d0,$t0 - mul $t0,$h0,$r1 // h0*r1 - adc $d1,$d1,$t1 - umulh $d2,$h0,$r1 - - adds $d1,$d1,$t0 - mul $t0,$h1,$r0 // h1*r0 - adc $d2,$d2,xzr - umulh $t1,$h1,$r0 - - adds $d1,$d1,$t0 - mul $t0,$h2,$s1 // h2*5*r1 - adc $d2,$d2,$t1 - mul $t1,$h2,$r0 // h2*r0 - - adds $d1,$d1,$t0 - adc $d2,$d2,$t1 - - and $t0,$d2,#-4 // final reduction - and $h2,$d2,#3 - add $t0,$t0,$d2,lsr#2 - adds $h0,$d0,$t0 - adcs $h1,$d1,xzr - adc $h2,$h2,xzr - - ret -.size poly1305_mult,.-poly1305_mult - -.type poly1305_splat,%function -.align 5 -poly1305_splat: - and x12,$h0,#0x03ffffff // base 2^64 -> base 2^26 - ubfx x13,$h0,#26,#26 - extr x14,$h1,$h0,#52 - and x14,x14,#0x03ffffff - ubfx x15,$h1,#14,#26 - extr x16,$h2,$h1,#40 - - str w12,[$ctx,#16*0] // r0 - add w12,w13,w13,lsl#2 // r1*5 - str w13,[$ctx,#16*1] // r1 - add w13,w14,w14,lsl#2 // r2*5 - str w12,[$ctx,#16*2] // s1 - str w14,[$ctx,#16*3] // r2 - add w14,w15,w15,lsl#2 // r3*5 - str w13,[$ctx,#16*4] // s2 - str w15,[$ctx,#16*5] // r3 - add w15,w16,w16,lsl#2 // r4*5 - str w14,[$ctx,#16*6] // s3 - str w16,[$ctx,#16*7] // r4 - str w15,[$ctx,#16*8] // s4 - - ret -.size poly1305_splat,.-poly1305_splat - -.type poly1305_blocks_neon,%function -.align 5 -poly1305_blocks_neon: - ldr $is_base2_26,[$ctx,#24] - cmp $len,#128 - b.hs .Lblocks_neon - cbz $is_base2_26,GFp_poly1305_blocks - -.Lblocks_neon: - stp x29,x30,[sp,#-80]! - add x29,sp,#0 - - ands $len,$len,#-16 - b.eq .Lno_data_neon - - cbz $is_base2_26,.Lbase2_64_neon - - ldp w10,w11,[$ctx] // load hash value base 2^26 - ldp w12,w13,[$ctx,#8] - ldr w14,[$ctx,#16] - - tst $len,#31 - b.eq .Leven_neon - - ldp $r0,$r1,[$ctx,#32] // load key value - - add $h0,x10,x11,lsl#26 // base 2^26 -> base 2^64 - lsr $h1,x12,#12 - adds $h0,$h0,x12,lsl#52 - add $h1,$h1,x13,lsl#14 - adc $h1,$h1,xzr - lsr $h2,x14,#24 - adds $h1,$h1,x14,lsl#40 - adc $d2,$h2,xzr // can be partially reduced... - - ldp $d0,$d1,[$inp],#16 // load input - sub $len,$len,#16 - add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2) - - and $t0,$d2,#-4 // ... so reduce - and $h2,$d2,#3 - add $t0,$t0,$d2,lsr#2 - adds $h0,$h0,$t0 - adcs $h1,$h1,xzr - adc $h2,$h2,xzr - -#ifdef __ARMEB__ - rev $d0,$d0 - rev $d1,$d1 -#endif - adds $h0,$h0,$d0 // accumulate input - adcs $h1,$h1,$d1 - adc $h2,$h2,$padbit - - bl poly1305_mult - ldr x30,[sp,#8] - - cbz $padbit,.Lstore_base2_64_neon - - and x10,$h0,#0x03ffffff // base 2^64 -> base 2^26 - ubfx x11,$h0,#26,#26 - extr x12,$h1,$h0,#52 - and x12,x12,#0x03ffffff - ubfx x13,$h1,#14,#26 - extr x14,$h2,$h1,#40 - - cbnz $len,.Leven_neon - - stp w10,w11,[$ctx] // store hash value base 2^26 - stp w12,w13,[$ctx,#8] - str w14,[$ctx,#16] - b .Lno_data_neon - -.align 4 -.Lstore_base2_64_neon: - stp $h0,$h1,[$ctx] // store hash value base 2^64 - stp $h2,xzr,[$ctx,#16] // note that is_base2_26 is zeroed - b .Lno_data_neon - -.align 4 -.Lbase2_64_neon: - ldp $r0,$r1,[$ctx,#32] // load key value - - ldp $h0,$h1,[$ctx] // load hash value base 2^64 - ldr $h2,[$ctx,#16] - - tst $len,#31 - b.eq .Linit_neon - - ldp $d0,$d1,[$inp],#16 // load input - sub $len,$len,#16 - add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2) -#ifdef __ARMEB__ - rev $d0,$d0 - rev $d1,$d1 -#endif - adds $h0,$h0,$d0 // accumulate input - adcs $h1,$h1,$d1 - adc $h2,$h2,$padbit - - bl poly1305_mult - -.Linit_neon: - and x10,$h0,#0x03ffffff // base 2^64 -> base 2^26 - ubfx x11,$h0,#26,#26 - extr x12,$h1,$h0,#52 - and x12,x12,#0x03ffffff - ubfx x13,$h1,#14,#26 - extr x14,$h2,$h1,#40 - - stp d8,d9,[sp,#16] // meet ABI requirements - stp d10,d11,[sp,#32] - stp d12,d13,[sp,#48] - stp d14,d15,[sp,#64] - - fmov ${H0},x10 - fmov ${H1},x11 - fmov ${H2},x12 - fmov ${H3},x13 - fmov ${H4},x14 - - ////////////////////////////////// initialize r^n table - mov $h0,$r0 // r^1 - add $s1,$r1,$r1,lsr#2 // s1 = r1 + (r1 >> 2) - mov $h1,$r1 - mov $h2,xzr - add $ctx,$ctx,#48+12 - bl poly1305_splat - - bl poly1305_mult // r^2 - sub $ctx,$ctx,#4 - bl poly1305_splat - - bl poly1305_mult // r^3 - sub $ctx,$ctx,#4 - bl poly1305_splat - - bl poly1305_mult // r^4 - sub $ctx,$ctx,#4 - bl poly1305_splat - ldr x30,[sp,#8] - - add $in2,$inp,#32 - adr $zeros,.Lzeros - subs $len,$len,#64 - csel $in2,$zeros,$in2,lo - - mov x4,#1 - str x4,[$ctx,#-24] // set is_base2_26 - sub $ctx,$ctx,#48 // restore original $ctx - b .Ldo_neon - -.align 4 -.Leven_neon: - add $in2,$inp,#32 - adr $zeros,.Lzeros - subs $len,$len,#64 - csel $in2,$zeros,$in2,lo - - stp d8,d9,[sp,#16] // meet ABI requirements - stp d10,d11,[sp,#32] - stp d12,d13,[sp,#48] - stp d14,d15,[sp,#64] - - fmov ${H0},x10 - fmov ${H1},x11 - fmov ${H2},x12 - fmov ${H3},x13 - fmov ${H4},x14 - -.Ldo_neon: - ldp x8,x12,[$in2],#16 // inp[2:3] (or zero) - ldp x9,x13,[$in2],#48 - - lsl $padbit,$padbit,#24 - add x15,$ctx,#48 - -#ifdef __ARMEB__ - rev x8,x8 - rev x12,x12 - rev x9,x9 - rev x13,x13 -#endif - and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 - and x5,x9,#0x03ffffff - ubfx x6,x8,#26,#26 - ubfx x7,x9,#26,#26 - add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 - extr x8,x12,x8,#52 - extr x9,x13,x9,#52 - add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 - fmov $IN23_0,x4 - and x8,x8,#0x03ffffff - and x9,x9,#0x03ffffff - ubfx x10,x12,#14,#26 - ubfx x11,x13,#14,#26 - add x12,$padbit,x12,lsr#40 - add x13,$padbit,x13,lsr#40 - add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 - fmov $IN23_1,x6 - add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 - add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 - fmov $IN23_2,x8 - fmov $IN23_3,x10 - fmov $IN23_4,x12 - - ldp x8,x12,[$inp],#16 // inp[0:1] - ldp x9,x13,[$inp],#48 - - ld1 {$R0,$R1,$S1,$R2},[x15],#64 - ld1 {$S2,$R3,$S3,$R4},[x15],#64 - ld1 {$S4},[x15] - -#ifdef __ARMEB__ - rev x8,x8 - rev x12,x12 - rev x9,x9 - rev x13,x13 -#endif - and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 - and x5,x9,#0x03ffffff - ubfx x6,x8,#26,#26 - ubfx x7,x9,#26,#26 - add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 - extr x8,x12,x8,#52 - extr x9,x13,x9,#52 - add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 - fmov $IN01_0,x4 - and x8,x8,#0x03ffffff - and x9,x9,#0x03ffffff - ubfx x10,x12,#14,#26 - ubfx x11,x13,#14,#26 - add x12,$padbit,x12,lsr#40 - add x13,$padbit,x13,lsr#40 - add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 - fmov $IN01_1,x6 - add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 - add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 - movi $MASK.2d,#-1 - fmov $IN01_2,x8 - fmov $IN01_3,x10 - fmov $IN01_4,x12 - ushr $MASK.2d,$MASK.2d,#38 - - b.ls .Lskip_loop - -.align 4 -.Loop_neon: - //////////////////////////////////////////////////////////////// - // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 - // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r - // \___________________/ - // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2 - // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r - // \___________________/ \____________________/ - // - // Note that we start with inp[2:3]*r^2. This is because it - // doesn't depend on reduction in previous iteration. - //////////////////////////////////////////////////////////////// - // d4 = h0*r4 + h1*r3 + h2*r2 + h3*r1 + h4*r0 - // d3 = h0*r3 + h1*r2 + h2*r1 + h3*r0 + h4*5*r4 - // d2 = h0*r2 + h1*r1 + h2*r0 + h3*5*r4 + h4*5*r3 - // d1 = h0*r1 + h1*r0 + h2*5*r4 + h3*5*r3 + h4*5*r2 - // d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1 - - subs $len,$len,#64 - umull $ACC4,$IN23_0,${R4}[2] - csel $in2,$zeros,$in2,lo - umull $ACC3,$IN23_0,${R3}[2] - umull $ACC2,$IN23_0,${R2}[2] - ldp x8,x12,[$in2],#16 // inp[2:3] (or zero) - umull $ACC1,$IN23_0,${R1}[2] - ldp x9,x13,[$in2],#48 - umull $ACC0,$IN23_0,${R0}[2] -#ifdef __ARMEB__ - rev x8,x8 - rev x12,x12 - rev x9,x9 - rev x13,x13 -#endif - - umlal $ACC4,$IN23_1,${R3}[2] - and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 - umlal $ACC3,$IN23_1,${R2}[2] - and x5,x9,#0x03ffffff - umlal $ACC2,$IN23_1,${R1}[2] - ubfx x6,x8,#26,#26 - umlal $ACC1,$IN23_1,${R0}[2] - ubfx x7,x9,#26,#26 - umlal $ACC0,$IN23_1,${S4}[2] - add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 - - umlal $ACC4,$IN23_2,${R2}[2] - extr x8,x12,x8,#52 - umlal $ACC3,$IN23_2,${R1}[2] - extr x9,x13,x9,#52 - umlal $ACC2,$IN23_2,${R0}[2] - add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 - umlal $ACC1,$IN23_2,${S4}[2] - fmov $IN23_0,x4 - umlal $ACC0,$IN23_2,${S3}[2] - and x8,x8,#0x03ffffff - - umlal $ACC4,$IN23_3,${R1}[2] - and x9,x9,#0x03ffffff - umlal $ACC3,$IN23_3,${R0}[2] - ubfx x10,x12,#14,#26 - umlal $ACC2,$IN23_3,${S4}[2] - ubfx x11,x13,#14,#26 - umlal $ACC1,$IN23_3,${S3}[2] - add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 - umlal $ACC0,$IN23_3,${S2}[2] - fmov $IN23_1,x6 - - add $IN01_2,$IN01_2,$H2 - add x12,$padbit,x12,lsr#40 - umlal $ACC4,$IN23_4,${R0}[2] - add x13,$padbit,x13,lsr#40 - umlal $ACC3,$IN23_4,${S4}[2] - add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 - umlal $ACC2,$IN23_4,${S3}[2] - add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 - umlal $ACC1,$IN23_4,${S2}[2] - fmov $IN23_2,x8 - umlal $ACC0,$IN23_4,${S1}[2] - fmov $IN23_3,x10 - - //////////////////////////////////////////////////////////////// - // (hash+inp[0:1])*r^4 and accumulate - - add $IN01_0,$IN01_0,$H0 - fmov $IN23_4,x12 - umlal $ACC3,$IN01_2,${R1}[0] - ldp x8,x12,[$inp],#16 // inp[0:1] - umlal $ACC0,$IN01_2,${S3}[0] - ldp x9,x13,[$inp],#48 - umlal $ACC4,$IN01_2,${R2}[0] - umlal $ACC1,$IN01_2,${S4}[0] - umlal $ACC2,$IN01_2,${R0}[0] -#ifdef __ARMEB__ - rev x8,x8 - rev x12,x12 - rev x9,x9 - rev x13,x13 -#endif - - add $IN01_1,$IN01_1,$H1 - umlal $ACC3,$IN01_0,${R3}[0] - umlal $ACC4,$IN01_0,${R4}[0] - and x4,x8,#0x03ffffff // base 2^64 -> base 2^26 - umlal $ACC2,$IN01_0,${R2}[0] - and x5,x9,#0x03ffffff - umlal $ACC0,$IN01_0,${R0}[0] - ubfx x6,x8,#26,#26 - umlal $ACC1,$IN01_0,${R1}[0] - ubfx x7,x9,#26,#26 - - add $IN01_3,$IN01_3,$H3 - add x4,x4,x5,lsl#32 // bfi x4,x5,#32,#32 - umlal $ACC3,$IN01_1,${R2}[0] - extr x8,x12,x8,#52 - umlal $ACC4,$IN01_1,${R3}[0] - extr x9,x13,x9,#52 - umlal $ACC0,$IN01_1,${S4}[0] - add x6,x6,x7,lsl#32 // bfi x6,x7,#32,#32 - umlal $ACC2,$IN01_1,${R1}[0] - fmov $IN01_0,x4 - umlal $ACC1,$IN01_1,${R0}[0] - and x8,x8,#0x03ffffff - - add $IN01_4,$IN01_4,$H4 - and x9,x9,#0x03ffffff - umlal $ACC3,$IN01_3,${R0}[0] - ubfx x10,x12,#14,#26 - umlal $ACC0,$IN01_3,${S2}[0] - ubfx x11,x13,#14,#26 - umlal $ACC4,$IN01_3,${R1}[0] - add x8,x8,x9,lsl#32 // bfi x8,x9,#32,#32 - umlal $ACC1,$IN01_3,${S3}[0] - fmov $IN01_1,x6 - umlal $ACC2,$IN01_3,${S4}[0] - add x12,$padbit,x12,lsr#40 - - umlal $ACC3,$IN01_4,${S4}[0] - add x13,$padbit,x13,lsr#40 - umlal $ACC0,$IN01_4,${S1}[0] - add x10,x10,x11,lsl#32 // bfi x10,x11,#32,#32 - umlal $ACC4,$IN01_4,${R0}[0] - add x12,x12,x13,lsl#32 // bfi x12,x13,#32,#32 - umlal $ACC1,$IN01_4,${S2}[0] - fmov $IN01_2,x8 - umlal $ACC2,$IN01_4,${S3}[0] - fmov $IN01_3,x10 - fmov $IN01_4,x12 - - ///////////////////////////////////////////////////////////////// - // lazy reduction as discussed in "NEON crypto" by D.J. Bernstein - // and P. Schwabe - // - // [see discussion in poly1305-armv4 module] - - ushr $T0.2d,$ACC3,#26 - xtn $H3,$ACC3 - ushr $T1.2d,$ACC0,#26 - and $ACC0,$ACC0,$MASK.2d - add $ACC4,$ACC4,$T0.2d // h3 -> h4 - bic $H3,#0xfc,lsl#24 // &=0x03ffffff - add $ACC1,$ACC1,$T1.2d // h0 -> h1 - - ushr $T0.2d,$ACC4,#26 - xtn $H4,$ACC4 - ushr $T1.2d,$ACC1,#26 - xtn $H1,$ACC1 - bic $H4,#0xfc,lsl#24 - add $ACC2,$ACC2,$T1.2d // h1 -> h2 - - add $ACC0,$ACC0,$T0.2d - shl $T0.2d,$T0.2d,#2 - shrn $T1.2s,$ACC2,#26 - xtn $H2,$ACC2 - add $ACC0,$ACC0,$T0.2d // h4 -> h0 - bic $H1,#0xfc,lsl#24 - add $H3,$H3,$T1.2s // h2 -> h3 - bic $H2,#0xfc,lsl#24 - - shrn $T0.2s,$ACC0,#26 - xtn $H0,$ACC0 - ushr $T1.2s,$H3,#26 - bic $H3,#0xfc,lsl#24 - bic $H0,#0xfc,lsl#24 - add $H1,$H1,$T0.2s // h0 -> h1 - add $H4,$H4,$T1.2s // h3 -> h4 - - b.hi .Loop_neon - -.Lskip_loop: - dup $IN23_2,${IN23_2}[0] - add $IN01_2,$IN01_2,$H2 - - //////////////////////////////////////////////////////////////// - // multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1 - - adds $len,$len,#32 - b.ne .Long_tail - - dup $IN23_2,${IN01_2}[0] - add $IN23_0,$IN01_0,$H0 - add $IN23_3,$IN01_3,$H3 - add $IN23_1,$IN01_1,$H1 - add $IN23_4,$IN01_4,$H4 - -.Long_tail: - dup $IN23_0,${IN23_0}[0] - umull2 $ACC0,$IN23_2,${S3} - umull2 $ACC3,$IN23_2,${R1} - umull2 $ACC4,$IN23_2,${R2} - umull2 $ACC2,$IN23_2,${R0} - umull2 $ACC1,$IN23_2,${S4} - - dup $IN23_1,${IN23_1}[0] - umlal2 $ACC0,$IN23_0,${R0} - umlal2 $ACC2,$IN23_0,${R2} - umlal2 $ACC3,$IN23_0,${R3} - umlal2 $ACC4,$IN23_0,${R4} - umlal2 $ACC1,$IN23_0,${R1} - - dup $IN23_3,${IN23_3}[0] - umlal2 $ACC0,$IN23_1,${S4} - umlal2 $ACC3,$IN23_1,${R2} - umlal2 $ACC2,$IN23_1,${R1} - umlal2 $ACC4,$IN23_1,${R3} - umlal2 $ACC1,$IN23_1,${R0} - - dup $IN23_4,${IN23_4}[0] - umlal2 $ACC3,$IN23_3,${R0} - umlal2 $ACC4,$IN23_3,${R1} - umlal2 $ACC0,$IN23_3,${S2} - umlal2 $ACC1,$IN23_3,${S3} - umlal2 $ACC2,$IN23_3,${S4} - - umlal2 $ACC3,$IN23_4,${S4} - umlal2 $ACC0,$IN23_4,${S1} - umlal2 $ACC4,$IN23_4,${R0} - umlal2 $ACC1,$IN23_4,${S2} - umlal2 $ACC2,$IN23_4,${S3} - - b.eq .Lshort_tail - - //////////////////////////////////////////////////////////////// - // (hash+inp[0:1])*r^4:r^3 and accumulate - - add $IN01_0,$IN01_0,$H0 - umlal $ACC3,$IN01_2,${R1} - umlal $ACC0,$IN01_2,${S3} - umlal $ACC4,$IN01_2,${R2} - umlal $ACC1,$IN01_2,${S4} - umlal $ACC2,$IN01_2,${R0} - - add $IN01_1,$IN01_1,$H1 - umlal $ACC3,$IN01_0,${R3} - umlal $ACC0,$IN01_0,${R0} - umlal $ACC4,$IN01_0,${R4} - umlal $ACC1,$IN01_0,${R1} - umlal $ACC2,$IN01_0,${R2} - - add $IN01_3,$IN01_3,$H3 - umlal $ACC3,$IN01_1,${R2} - umlal $ACC0,$IN01_1,${S4} - umlal $ACC4,$IN01_1,${R3} - umlal $ACC1,$IN01_1,${R0} - umlal $ACC2,$IN01_1,${R1} - - add $IN01_4,$IN01_4,$H4 - umlal $ACC3,$IN01_3,${R0} - umlal $ACC0,$IN01_3,${S2} - umlal $ACC4,$IN01_3,${R1} - umlal $ACC1,$IN01_3,${S3} - umlal $ACC2,$IN01_3,${S4} - - umlal $ACC3,$IN01_4,${S4} - umlal $ACC0,$IN01_4,${S1} - umlal $ACC4,$IN01_4,${R0} - umlal $ACC1,$IN01_4,${S2} - umlal $ACC2,$IN01_4,${S3} - -.Lshort_tail: - //////////////////////////////////////////////////////////////// - // horizontal add - - addp $ACC3,$ACC3,$ACC3 - ldp d8,d9,[sp,#16] // meet ABI requirements - addp $ACC0,$ACC0,$ACC0 - ldp d10,d11,[sp,#32] - addp $ACC4,$ACC4,$ACC4 - ldp d12,d13,[sp,#48] - addp $ACC1,$ACC1,$ACC1 - ldp d14,d15,[sp,#64] - addp $ACC2,$ACC2,$ACC2 - - //////////////////////////////////////////////////////////////// - // lazy reduction, but without narrowing - - ushr $T0.2d,$ACC3,#26 - and $ACC3,$ACC3,$MASK.2d - ushr $T1.2d,$ACC0,#26 - and $ACC0,$ACC0,$MASK.2d - - add $ACC4,$ACC4,$T0.2d // h3 -> h4 - add $ACC1,$ACC1,$T1.2d // h0 -> h1 - - ushr $T0.2d,$ACC4,#26 - and $ACC4,$ACC4,$MASK.2d - ushr $T1.2d,$ACC1,#26 - and $ACC1,$ACC1,$MASK.2d - add $ACC2,$ACC2,$T1.2d // h1 -> h2 - - add $ACC0,$ACC0,$T0.2d - shl $T0.2d,$T0.2d,#2 - ushr $T1.2d,$ACC2,#26 - and $ACC2,$ACC2,$MASK.2d - add $ACC0,$ACC0,$T0.2d // h4 -> h0 - add $ACC3,$ACC3,$T1.2d // h2 -> h3 - - ushr $T0.2d,$ACC0,#26 - and $ACC0,$ACC0,$MASK.2d - ushr $T1.2d,$ACC3,#26 - and $ACC3,$ACC3,$MASK.2d - add $ACC1,$ACC1,$T0.2d // h0 -> h1 - add $ACC4,$ACC4,$T1.2d // h3 -> h4 - - //////////////////////////////////////////////////////////////// - // write the result, can be partially reduced - - st4 {$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16 - st1 {$ACC4}[0],[$ctx] - -.Lno_data_neon: - ldr x29,[sp],#80 - ret -.size poly1305_blocks_neon,.-poly1305_blocks_neon - -.type poly1305_emit_neon,%function -.align 5 -poly1305_emit_neon: - ldr $is_base2_26,[$ctx,#24] - cbz $is_base2_26,GFp_poly1305_emit - - ldp w10,w11,[$ctx] // load hash value base 2^26 - ldp w12,w13,[$ctx,#8] - ldr w14,[$ctx,#16] - - add $h0,x10,x11,lsl#26 // base 2^26 -> base 2^64 - lsr $h1,x12,#12 - adds $h0,$h0,x12,lsl#52 - add $h1,$h1,x13,lsl#14 - adc $h1,$h1,xzr - lsr $h2,x14,#24 - adds $h1,$h1,x14,lsl#40 - adc $h2,$h2,xzr // can be partially reduced... - - ldp $t0,$t1,[$nonce] // load nonce - - and $d0,$h2,#-4 // ... so reduce - add $d0,$d0,$h2,lsr#2 - and $h2,$h2,#3 - adds $h0,$h0,$d0 - adcs $h1,$h1,xzr - adc $h2,$h2,xzr - - adds $d0,$h0,#5 // compare to modulus - adcs $d1,$h1,xzr - adc $d2,$h2,xzr - - tst $d2,#-4 // see if it's carried/borrowed - - csel $h0,$h0,$d0,eq - csel $h1,$h1,$d1,eq - -#ifdef __ARMEB__ - ror $t0,$t0,#32 // flip nonce words - ror $t1,$t1,#32 -#endif - adds $h0,$h0,$t0 // accumulate nonce - adc $h1,$h1,$t1 -#ifdef __ARMEB__ - rev $h0,$h0 // flip output bytes - rev $h1,$h1 -#endif - stp $h0,$h1,[$mac] // write result - - ret -.size poly1305_emit_neon,.-poly1305_emit_neon - -.align 5 -.Lzeros: -.long 0,0,0,0,0,0,0,0 -.LGFp_armcap_P: -#ifdef __ILP32__ -.long GFp_armcap_P-. -#else -.quad GFp_armcap_P-. -#endif -.asciz "Poly1305 for ARMv8, CRYPTOGAMS by " -.align 2 -___ - -foreach (split("\n",$code)) { - s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/ or - s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/ or - (m/\bdup\b/ and (s/\.[24]s/.2d/g or 1)) or - (m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1)) or - (m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1)) or - (m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1)) or - (m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1)); - - s/\.[124]([sd])\[/.$1\[/; - - print $_,"\n"; -} -close STDOUT or die "error closing STDOUT"; diff --git a/crypto/poly1305/asm/poly1305-x86.pl b/crypto/poly1305/asm/poly1305-x86.pl deleted file mode 100755 index 3f0e4c416b..0000000000 --- a/crypto/poly1305/asm/poly1305-x86.pl +++ /dev/null @@ -1,1223 +0,0 @@ -#!/usr/bin/env perl -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# This module implements Poly1305 hash for x86. -# -# April 2015 -# -# Numbers are cycles per processed byte with poly1305_blocks alone, -# measured with rdtsc at fixed clock frequency. -# -# IALU/gcc-3.4(*) SSE2(**) AVX2 -# Pentium 15.7/+80% - -# PIII 6.21/+90% - -# P4 19.8/+40% 3.24 -# Core 2 4.85/+90% 1.80 -# Westmere 4.58/+100% 1.43 -# Sandy Bridge 3.90/+100% 1.36 -# Haswell 3.88/+70% 1.18 0.72 -# Silvermont 11.0/+40% 4.80 -# VIA Nano 6.71/+90% 2.47 -# Sledgehammer 3.51/+180% 4.27 -# Bulldozer 4.53/+140% 1.31 -# -# (*) gcc 4.8 for some reason generated worse code; -# (**) besides SSE2 there are floating-point and AVX options; FP -# is deemed unnecessary, because pre-SSE2 processor are too -# old to care about, while it's not the fastest option on -# SSE2-capable ones; AVX is omitted, because it doesn't give -# a lot of improvement, 5-10% depending on processor; - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -push(@INC,"${dir}","${dir}../../perlasm"); -require "x86asm.pl"; - -$output=pop; -open STDOUT,">$output"; - -&asm_init($ARGV[0],"poly1305-x86.pl",$ARGV[$#ARGV] eq "386"); - -$sse2=$avx=0; -for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } - -if ($sse2) { - &static_label("const_sse2"); - &static_label("enter_blocks"); - &static_label("enter_emit"); - &external_label("GFp_ia32cap_P"); - - # This may be set to 2, but valgrind can't do AVX2 on 32-bit. Without a - # way to verify test coverage, keep it disabled. - # The AVX2 code was removed. - $avx = 0; -} - -######################################################################## -# Layout of opaque area is following. -# -# unsigned __int32 h[5]; # current hash value base 2^32 -# unsigned __int32 pad; # is_base2_26 in vector context -# unsigned __int32 r[4]; # key value base 2^32 - -&align(64); -&function_begin("GFp_poly1305_init_asm"); - &mov ("edi",&wparam(0)); # context - &mov ("esi",&wparam(1)); # key - &mov ("ebp",&wparam(2)); # function table - - &xor ("eax","eax"); - &mov (&DWP(4*0,"edi"),"eax"); # zero hash value - &mov (&DWP(4*1,"edi"),"eax"); - &mov (&DWP(4*2,"edi"),"eax"); - &mov (&DWP(4*3,"edi"),"eax"); - &mov (&DWP(4*4,"edi"),"eax"); - &mov (&DWP(4*5,"edi"),"eax"); # is_base2_26 - - &cmp ("esi",0); - &je (&label("nokey")); - - if ($sse2) { - &call (&label("pic_point")); - &set_label("pic_point"); - &blindpop("ebx"); - - &lea ("eax",&DWP("GFp_poly1305_blocks-".&label("pic_point"),"ebx")); - &lea ("edx",&DWP("GFp_poly1305_emit-".&label("pic_point"),"ebx")); - - &picmeup("edi","GFp_ia32cap_P","ebx",&label("pic_point")); - &mov ("ecx",&DWP(0,"edi")); - &and ("ecx",1<<26|1<<24); - &cmp ("ecx",1<<26|1<<24); # SSE2 and XMM? - # The non-SSE2 code was removed. - - &lea ("eax",&DWP("_poly1305_blocks_sse2-".&label("pic_point"),"ebx")); - &lea ("edx",&DWP("_poly1305_emit_sse2-".&label("pic_point"),"ebx")); - - # AVX2 code removed. - - # The non-SSE2 code was removed. - - &mov ("edi",&wparam(0)); # reload context - &mov (&DWP(0,"ebp"),"eax"); # fill function table - &mov (&DWP(4,"ebp"),"edx"); - } - - &mov ("eax",&DWP(4*0,"esi")); # load input key - &mov ("ebx",&DWP(4*1,"esi")); - &mov ("ecx",&DWP(4*2,"esi")); - &mov ("edx",&DWP(4*3,"esi")); - &and ("eax",0x0fffffff); - &and ("ebx",0x0ffffffc); - &and ("ecx",0x0ffffffc); - &and ("edx",0x0ffffffc); - &mov (&DWP(4*6,"edi"),"eax"); - &mov (&DWP(4*7,"edi"),"ebx"); - &mov (&DWP(4*8,"edi"),"ecx"); - &mov (&DWP(4*9,"edi"),"edx"); - - &mov ("eax",$sse2); -&set_label("nokey"); -&function_end("GFp_poly1305_init_asm"); - -($h0,$h1,$h2,$h3,$h4, - $d0,$d1,$d2,$d3, - $r0,$r1,$r2,$r3, - $s1,$s2,$s3)=map(4*$_,(0..15)); - -&function_begin("GFp_poly1305_blocks"); - &mov ("edi",&wparam(0)); # ctx - &mov ("esi",&wparam(1)); # inp - &mov ("ecx",&wparam(2)); # len -&set_label("enter_blocks"); - &and ("ecx",-15); - &jz (&label("nodata")); - - &stack_push(16); - &mov ("eax",&DWP(4*6,"edi")); # r0 - &mov ("ebx",&DWP(4*7,"edi")); # r1 - &lea ("ebp",&DWP(0,"esi","ecx")); # end of input - &mov ("ecx",&DWP(4*8,"edi")); # r2 - &mov ("edx",&DWP(4*9,"edi")); # r3 - - &mov (&wparam(2),"ebp"); - &mov ("ebp","esi"); - - &mov (&DWP($r0,"esp"),"eax"); # r0 - &mov ("eax","ebx"); - &shr ("eax",2); - &mov (&DWP($r1,"esp"),"ebx"); # r1 - &add ("eax","ebx"); # s1 - &mov ("ebx","ecx"); - &shr ("ebx",2); - &mov (&DWP($r2,"esp"),"ecx"); # r2 - &add ("ebx","ecx"); # s2 - &mov ("ecx","edx"); - &shr ("ecx",2); - &mov (&DWP($r3,"esp"),"edx"); # r3 - &add ("ecx","edx"); # s3 - &mov (&DWP($s1,"esp"),"eax"); # s1 - &mov (&DWP($s2,"esp"),"ebx"); # s2 - &mov (&DWP($s3,"esp"),"ecx"); # s3 - - &mov ("eax",&DWP(4*0,"edi")); # load hash value - &mov ("ebx",&DWP(4*1,"edi")); - &mov ("ecx",&DWP(4*2,"edi")); - &mov ("esi",&DWP(4*3,"edi")); - &mov ("edi",&DWP(4*4,"edi")); - &jmp (&label("loop")); - -&set_label("loop",32); - &add ("eax",&DWP(4*0,"ebp")); # accumulate input - &adc ("ebx",&DWP(4*1,"ebp")); - &adc ("ecx",&DWP(4*2,"ebp")); - &adc ("esi",&DWP(4*3,"ebp")); - &lea ("ebp",&DWP(4*4,"ebp")); - &adc ("edi",&wparam(3)); # padbit - - &mov (&DWP($h0,"esp"),"eax"); # put aside hash[+inp] - &mov (&DWP($h3,"esp"),"esi"); - - &mul (&DWP($r0,"esp")); # h0*r0 - &mov (&DWP($h4,"esp"),"edi"); - &mov ("edi","eax"); - &mov ("eax","ebx"); # h1 - &mov ("esi","edx"); - &mul (&DWP($s3,"esp")); # h1*s3 - &add ("edi","eax"); - &mov ("eax","ecx"); # h2 - &adc ("esi","edx"); - &mul (&DWP($s2,"esp")); # h2*s2 - &add ("edi","eax"); - &mov ("eax",&DWP($h3,"esp")); - &adc ("esi","edx"); - &mul (&DWP($s1,"esp")); # h3*s1 - &add ("edi","eax"); - &mov ("eax",&DWP($h0,"esp")); - &adc ("esi","edx"); - - &mul (&DWP($r1,"esp")); # h0*r1 - &mov (&DWP($d0,"esp"),"edi"); - &xor ("edi","edi"); - &add ("esi","eax"); - &mov ("eax","ebx"); # h1 - &adc ("edi","edx"); - &mul (&DWP($r0,"esp")); # h1*r0 - &add ("esi","eax"); - &mov ("eax","ecx"); # h2 - &adc ("edi","edx"); - &mul (&DWP($s3,"esp")); # h2*s3 - &add ("esi","eax"); - &mov ("eax",&DWP($h3,"esp")); - &adc ("edi","edx"); - &mul (&DWP($s2,"esp")); # h3*s2 - &add ("esi","eax"); - &mov ("eax",&DWP($h4,"esp")); - &adc ("edi","edx"); - &imul ("eax",&DWP($s1,"esp")); # h4*s1 - &add ("esi","eax"); - &mov ("eax",&DWP($h0,"esp")); - &adc ("edi",0); - - &mul (&DWP($r2,"esp")); # h0*r2 - &mov (&DWP($d1,"esp"),"esi"); - &xor ("esi","esi"); - &add ("edi","eax"); - &mov ("eax","ebx"); # h1 - &adc ("esi","edx"); - &mul (&DWP($r1,"esp")); # h1*r1 - &add ("edi","eax"); - &mov ("eax","ecx"); # h2 - &adc ("esi","edx"); - &mul (&DWP($r0,"esp")); # h2*r0 - &add ("edi","eax"); - &mov ("eax",&DWP($h3,"esp")); - &adc ("esi","edx"); - &mul (&DWP($s3,"esp")); # h3*s3 - &add ("edi","eax"); - &mov ("eax",&DWP($h4,"esp")); - &adc ("esi","edx"); - &imul ("eax",&DWP($s2,"esp")); # h4*s2 - &add ("edi","eax"); - &mov ("eax",&DWP($h0,"esp")); - &adc ("esi",0); - - &mul (&DWP($r3,"esp")); # h0*r3 - &mov (&DWP($d2,"esp"),"edi"); - &xor ("edi","edi"); - &add ("esi","eax"); - &mov ("eax","ebx"); # h1 - &adc ("edi","edx"); - &mul (&DWP($r2,"esp")); # h1*r2 - &add ("esi","eax"); - &mov ("eax","ecx"); # h2 - &adc ("edi","edx"); - &mul (&DWP($r1,"esp")); # h2*r1 - &add ("esi","eax"); - &mov ("eax",&DWP($h3,"esp")); - &adc ("edi","edx"); - &mul (&DWP($r0,"esp")); # h3*r0 - &add ("esi","eax"); - &mov ("ecx",&DWP($h4,"esp")); - &adc ("edi","edx"); - - &mov ("edx","ecx"); - &imul ("ecx",&DWP($s3,"esp")); # h4*s3 - &add ("esi","ecx"); - &mov ("eax",&DWP($d0,"esp")); - &adc ("edi",0); - - &imul ("edx",&DWP($r0,"esp")); # h4*r0 - &add ("edx","edi"); - - &mov ("ebx",&DWP($d1,"esp")); - &mov ("ecx",&DWP($d2,"esp")); - - &mov ("edi","edx"); # last reduction step - &shr ("edx",2); - &and ("edi",3); - &lea ("edx",&DWP(0,"edx","edx",4)); # *5 - &add ("eax","edx"); - &adc ("ebx",0); - &adc ("ecx",0); - &adc ("esi",0); - &adc ("edi",0); - - &cmp ("ebp",&wparam(2)); # done yet? - &jne (&label("loop")); - - &mov ("edx",&wparam(0)); # ctx - &stack_pop(16); - &mov (&DWP(4*0,"edx"),"eax"); # store hash value - &mov (&DWP(4*1,"edx"),"ebx"); - &mov (&DWP(4*2,"edx"),"ecx"); - &mov (&DWP(4*3,"edx"),"esi"); - &mov (&DWP(4*4,"edx"),"edi"); -&set_label("nodata"); -&function_end("GFp_poly1305_blocks"); - -&function_begin("GFp_poly1305_emit"); - &mov ("ebp",&wparam(0)); # context -&set_label("enter_emit"); - &mov ("edi",&wparam(1)); # output - &mov ("eax",&DWP(4*0,"ebp")); # load hash value - &mov ("ebx",&DWP(4*1,"ebp")); - &mov ("ecx",&DWP(4*2,"ebp")); - &mov ("edx",&DWP(4*3,"ebp")); - &mov ("esi",&DWP(4*4,"ebp")); - - &add ("eax",5); # compare to modulus - &adc ("ebx",0); - &adc ("ecx",0); - &adc ("edx",0); - &adc ("esi",0); - &shr ("esi",2); # did it carry/borrow? - &neg ("esi"); # do we choose hash-modulus? - - &and ("eax","esi"); - &and ("ebx","esi"); - &and ("ecx","esi"); - &and ("edx","esi"); - &mov (&DWP(4*0,"edi"),"eax"); - &mov (&DWP(4*1,"edi"),"ebx"); - &mov (&DWP(4*2,"edi"),"ecx"); - &mov (&DWP(4*3,"edi"),"edx"); - - ¬ ("esi"); # or original hash value? - &mov ("eax",&DWP(4*0,"ebp")); - &mov ("ebx",&DWP(4*1,"ebp")); - &mov ("ecx",&DWP(4*2,"ebp")); - &mov ("edx",&DWP(4*3,"ebp")); - &mov ("ebp",&wparam(2)); - &and ("eax","esi"); - &and ("ebx","esi"); - &and ("ecx","esi"); - &and ("edx","esi"); - &or ("eax",&DWP(4*0,"edi")); - &or ("ebx",&DWP(4*1,"edi")); - &or ("ecx",&DWP(4*2,"edi")); - &or ("edx",&DWP(4*3,"edi")); - - &add ("eax",&DWP(4*0,"ebp")); # accumulate key - &adc ("ebx",&DWP(4*1,"ebp")); - &adc ("ecx",&DWP(4*2,"ebp")); - &adc ("edx",&DWP(4*3,"ebp")); - - &mov (&DWP(4*0,"edi"),"eax"); - &mov (&DWP(4*1,"edi"),"ebx"); - &mov (&DWP(4*2,"edi"),"ecx"); - &mov (&DWP(4*3,"edi"),"edx"); -&function_end("GFp_poly1305_emit"); - -if ($sse2) { -######################################################################## -# Layout of opaque area is following. -# -# unsigned __int32 h[5]; # current hash value base 2^26 -# unsigned __int32 is_base2_26; -# unsigned __int32 r[4]; # key value base 2^32 -# unsigned __int32 pad[2]; -# struct { unsigned __int32 r^4, r^3, r^2, r^1; } r[9]; -# -# where r^n are base 2^26 digits of degrees of multiplier key. There are -# 5 digits, but last four are interleaved with multiples of 5, totalling -# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4. - -my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("xmm$_",(0..7)); -my $MASK=$T2; # borrow and keep in mind - -&align (32); -&function_begin_B("_poly1305_init_sse2"); - &movdqu ($D4,&QWP(4*6,"edi")); # key base 2^32 - &lea ("edi",&DWP(16*3,"edi")); # size optimization - &mov ("ebp","esp"); - &sub ("esp",16*(9+5)); - &and ("esp",-16); - - #&pand ($D4,&QWP(96,"ebx")); # magic mask - &movq ($MASK,&QWP(64,"ebx")); - - &movdqa ($D0,$D4); - &movdqa ($D1,$D4); - &movdqa ($D2,$D4); - - &pand ($D0,$MASK); # -> base 2^26 - &psrlq ($D1,26); - &psrldq ($D2,6); - &pand ($D1,$MASK); - &movdqa ($D3,$D2); - &psrlq ($D2,4) - &psrlq ($D3,30); - &pand ($D2,$MASK); - &pand ($D3,$MASK); - &psrldq ($D4,13); - - &lea ("edx",&DWP(16*9,"esp")); # size optimization - &mov ("ecx",2); -&set_label("square"); - &movdqa (&QWP(16*0,"esp"),$D0); - &movdqa (&QWP(16*1,"esp"),$D1); - &movdqa (&QWP(16*2,"esp"),$D2); - &movdqa (&QWP(16*3,"esp"),$D3); - &movdqa (&QWP(16*4,"esp"),$D4); - - &movdqa ($T1,$D1); - &movdqa ($T0,$D2); - &pslld ($T1,2); - &pslld ($T0,2); - &paddd ($T1,$D1); # *5 - &paddd ($T0,$D2); # *5 - &movdqa (&QWP(16*5,"esp"),$T1); - &movdqa (&QWP(16*6,"esp"),$T0); - &movdqa ($T1,$D3); - &movdqa ($T0,$D4); - &pslld ($T1,2); - &pslld ($T0,2); - &paddd ($T1,$D3); # *5 - &paddd ($T0,$D4); # *5 - &movdqa (&QWP(16*7,"esp"),$T1); - &movdqa (&QWP(16*8,"esp"),$T0); - - &pshufd ($T1,$D0,0b01000100); - &movdqa ($T0,$D1); - &pshufd ($D1,$D1,0b01000100); - &pshufd ($D2,$D2,0b01000100); - &pshufd ($D3,$D3,0b01000100); - &pshufd ($D4,$D4,0b01000100); - &movdqa (&QWP(16*0,"edx"),$T1); - &movdqa (&QWP(16*1,"edx"),$D1); - &movdqa (&QWP(16*2,"edx"),$D2); - &movdqa (&QWP(16*3,"edx"),$D3); - &movdqa (&QWP(16*4,"edx"),$D4); - - ################################################################ - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - &pmuludq ($D4,$D0); # h4*r0 - &pmuludq ($D3,$D0); # h3*r0 - &pmuludq ($D2,$D0); # h2*r0 - &pmuludq ($D1,$D0); # h1*r0 - &pmuludq ($D0,$T1); # h0*r0 - -sub pmuladd { -my $load = shift; -my $base = shift; $base = "esp" if (!defined($base)); - - ################################################################ - # As for choice to "rotate" $T0-$T2 in order to move paddq - # past next multiplication. While it makes code harder to read - # and doesn't have significant effect on most processors, it - # makes a lot of difference on Atom, up to 30% improvement. - - &movdqa ($T1,$T0); - &pmuludq ($T0,&QWP(16*3,$base)); # r1*h3 - &movdqa ($T2,$T1); - &pmuludq ($T1,&QWP(16*2,$base)); # r1*h2 - &paddq ($D4,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&QWP(16*1,$base)); # r1*h1 - &paddq ($D3,$T1); - &$load ($T1,5); # s1 - &pmuludq ($T0,&QWP(16*0,$base)); # r1*h0 - &paddq ($D2,$T2); - &pmuludq ($T1,&QWP(16*4,$base)); # s1*h4 - &$load ($T2,2); # r2^n - &paddq ($D1,$T0); - - &movdqa ($T0,$T2); - &pmuludq ($T2,&QWP(16*2,$base)); # r2*h2 - &paddq ($D0,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&QWP(16*1,$base)); # r2*h1 - &paddq ($D4,$T2); - &$load ($T2,6); # s2^n - &pmuludq ($T1,&QWP(16*0,$base)); # r2*h0 - &paddq ($D3,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&QWP(16*4,$base)); # s2*h4 - &paddq ($D2,$T1); - &pmuludq ($T0,&QWP(16*3,$base)); # s2*h3 - &$load ($T1,3); # r3^n - &paddq ($D1,$T2); - - &movdqa ($T2,$T1); - &pmuludq ($T1,&QWP(16*1,$base)); # r3*h1 - &paddq ($D0,$T0); - &$load ($T0,7); # s3^n - &pmuludq ($T2,&QWP(16*0,$base)); # r3*h0 - &paddq ($D4,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&QWP(16*4,$base)); # s3*h4 - &paddq ($D3,$T2); - &movdqa ($T2,$T1); - &pmuludq ($T1,&QWP(16*3,$base)); # s3*h3 - &paddq ($D2,$T0); - &pmuludq ($T2,&QWP(16*2,$base)); # s3*h2 - &$load ($T0,4); # r4^n - &paddq ($D1,$T1); - - &$load ($T1,8); # s4^n - &pmuludq ($T0,&QWP(16*0,$base)); # r4*h0 - &paddq ($D0,$T2); - &movdqa ($T2,$T1); - &pmuludq ($T1,&QWP(16*4,$base)); # s4*h4 - &paddq ($D4,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&QWP(16*1,$base)); # s4*h1 - &paddq ($D3,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&QWP(16*2,$base)); # s4*h2 - &paddq ($D0,$T2); - &pmuludq ($T1,&QWP(16*3,$base)); # s4*h3 - &movdqa ($MASK,&QWP(64,"ebx")); - &paddq ($D1,$T0); - &paddq ($D2,$T1); -} - &pmuladd (sub { my ($reg,$i)=@_; - &movdqa ($reg,&QWP(16*$i,"esp")); - },"edx"); - -sub lazy_reduction { -my $extra = shift; - - ################################################################ - # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein - # and P. Schwabe - # - # [(*) see discussion in poly1305-armv4 module] - - &movdqa ($T0,$D3); - &pand ($D3,$MASK); - &psrlq ($T0,26); - &$extra () if (defined($extra)); - &paddq ($T0,$D4); # h3 -> h4 - &movdqa ($T1,$D0); - &pand ($D0,$MASK); - &psrlq ($T1,26); - &movdqa ($D4,$T0); - &paddq ($T1,$D1); # h0 -> h1 - &psrlq ($T0,26); - &pand ($D4,$MASK); - &movdqa ($D1,$T1); - &psrlq ($T1,26); - &paddd ($D0,$T0); # favour paddd when - # possible, because - # paddq is "broken" - # on Atom - &psllq ($T0,2); - &paddq ($T1,$D2); # h1 -> h2 - &paddq ($T0,$D0); # h4 -> h0 (*) - &pand ($D1,$MASK); - &movdqa ($D2,$T1); - &psrlq ($T1,26); - &pand ($D2,$MASK); - &paddd ($T1,$D3); # h2 -> h3 - &movdqa ($D0,$T0); - &psrlq ($T0,26); - &movdqa ($D3,$T1); - &psrlq ($T1,26); - &pand ($D0,$MASK); - &paddd ($D1,$T0); # h0 -> h1 - &pand ($D3,$MASK); - &paddd ($D4,$T1); # h3 -> h4 -} - &lazy_reduction (); - - &dec ("ecx"); - &jz (&label("square_break")); - - &punpcklqdq ($D0,&QWP(16*0,"esp")); # 0:r^1:0:r^2 - &punpcklqdq ($D1,&QWP(16*1,"esp")); - &punpcklqdq ($D2,&QWP(16*2,"esp")); - &punpcklqdq ($D3,&QWP(16*3,"esp")); - &punpcklqdq ($D4,&QWP(16*4,"esp")); - &jmp (&label("square")); - -&set_label("square_break"); - &psllq ($D0,32); # -> r^3:0:r^4:0 - &psllq ($D1,32); - &psllq ($D2,32); - &psllq ($D3,32); - &psllq ($D4,32); - &por ($D0,&QWP(16*0,"esp")); # r^3:r^1:r^4:r^2 - &por ($D1,&QWP(16*1,"esp")); - &por ($D2,&QWP(16*2,"esp")); - &por ($D3,&QWP(16*3,"esp")); - &por ($D4,&QWP(16*4,"esp")); - - &pshufd ($D0,$D0,0b10001101); # -> r^1:r^2:r^3:r^4 - &pshufd ($D1,$D1,0b10001101); - &pshufd ($D2,$D2,0b10001101); - &pshufd ($D3,$D3,0b10001101); - &pshufd ($D4,$D4,0b10001101); - - &movdqu (&QWP(16*0,"edi"),$D0); # save the table - &movdqu (&QWP(16*1,"edi"),$D1); - &movdqu (&QWP(16*2,"edi"),$D2); - &movdqu (&QWP(16*3,"edi"),$D3); - &movdqu (&QWP(16*4,"edi"),$D4); - - &movdqa ($T1,$D1); - &movdqa ($T0,$D2); - &pslld ($T1,2); - &pslld ($T0,2); - &paddd ($T1,$D1); # *5 - &paddd ($T0,$D2); # *5 - &movdqu (&QWP(16*5,"edi"),$T1); - &movdqu (&QWP(16*6,"edi"),$T0); - &movdqa ($T1,$D3); - &movdqa ($T0,$D4); - &pslld ($T1,2); - &pslld ($T0,2); - &paddd ($T1,$D3); # *5 - &paddd ($T0,$D4); # *5 - &movdqu (&QWP(16*7,"edi"),$T1); - &movdqu (&QWP(16*8,"edi"),$T0); - - &mov ("esp","ebp"); - &lea ("edi",&DWP(-16*3,"edi")); # size de-optimization - &ret (); -&function_end_B("_poly1305_init_sse2"); - -&align (32); -&function_begin("_poly1305_blocks_sse2"); - &mov ("edi",&wparam(0)); # ctx - &mov ("esi",&wparam(1)); # inp - &mov ("ecx",&wparam(2)); # len - - &mov ("eax",&DWP(4*5,"edi")); # is_base2_26 - &and ("ecx",-16); - &jz (&label("nodata")); - &cmp ("ecx",64); - &jae (&label("enter_sse2")); - &test ("eax","eax"); # is_base2_26? - &jz (&label("enter_blocks")); - -&set_label("enter_sse2",16); - &call (&label("pic_point")); -&set_label("pic_point"); - &blindpop("ebx"); - &lea ("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx")); - - &test ("eax","eax"); # is_base2_26? - &jnz (&label("base2_26")); - - &call ("_poly1305_init_sse2"); - - ################################################# base 2^32 -> base 2^26 - &mov ("eax",&DWP(0,"edi")); - &mov ("ecx",&DWP(3,"edi")); - &mov ("edx",&DWP(6,"edi")); - &mov ("esi",&DWP(9,"edi")); - &mov ("ebp",&DWP(13,"edi")); - &mov (&DWP(4*5,"edi"),1); # is_base2_26 - - &shr ("ecx",2); - &and ("eax",0x3ffffff); - &shr ("edx",4); - &and ("ecx",0x3ffffff); - &shr ("esi",6); - &and ("edx",0x3ffffff); - - &movd ($D0,"eax"); - &movd ($D1,"ecx"); - &movd ($D2,"edx"); - &movd ($D3,"esi"); - &movd ($D4,"ebp"); - - &mov ("esi",&wparam(1)); # [reload] inp - &mov ("ecx",&wparam(2)); # [reload] len - &jmp (&label("base2_32")); - -&set_label("base2_26",16); - &movd ($D0,&DWP(4*0,"edi")); # load hash value - &movd ($D1,&DWP(4*1,"edi")); - &movd ($D2,&DWP(4*2,"edi")); - &movd ($D3,&DWP(4*3,"edi")); - &movd ($D4,&DWP(4*4,"edi")); - &movdqa ($MASK,&QWP(64,"ebx")); - -&set_label("base2_32"); - &mov ("eax",&wparam(3)); # padbit - &mov ("ebp","esp"); - - &sub ("esp",16*(5+5+5+9+9)); - &and ("esp",-16); - - &lea ("edi",&DWP(16*3,"edi")); # size optimization - &shl ("eax",24); # padbit - - &test ("ecx",31); - &jz (&label("even")); - - ################################################################ - # process single block, with SSE2, because it's still faster - # even though half of result is discarded - - &movdqu ($T1,&QWP(0,"esi")); # input - &lea ("esi",&DWP(16,"esi")); - - &movdqa ($T0,$T1); # -> base 2^26 ... - &pand ($T1,$MASK); - &paddd ($D0,$T1); # ... and accumuate - - &movdqa ($T1,$T0); - &psrlq ($T0,26); - &psrldq ($T1,6); - &pand ($T0,$MASK); - &paddd ($D1,$T0); - - &movdqa ($T0,$T1); - &psrlq ($T1,4); - &pand ($T1,$MASK); - &paddd ($D2,$T1); - - &movdqa ($T1,$T0); - &psrlq ($T0,30); - &pand ($T0,$MASK); - &psrldq ($T1,7); - &paddd ($D3,$T0); - - &movd ($T0,"eax"); # padbit - &paddd ($D4,$T1); - &movd ($T1,&DWP(16*0+12,"edi")); # r0 - &paddd ($D4,$T0); - - &movdqa (&QWP(16*0,"esp"),$D0); - &movdqa (&QWP(16*1,"esp"),$D1); - &movdqa (&QWP(16*2,"esp"),$D2); - &movdqa (&QWP(16*3,"esp"),$D3); - &movdqa (&QWP(16*4,"esp"),$D4); - - ################################################################ - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - &pmuludq ($D0,$T1); # h4*r0 - &pmuludq ($D1,$T1); # h3*r0 - &pmuludq ($D2,$T1); # h2*r0 - &movd ($T0,&DWP(16*1+12,"edi")); # r1 - &pmuludq ($D3,$T1); # h1*r0 - &pmuludq ($D4,$T1); # h0*r0 - - &pmuladd (sub { my ($reg,$i)=@_; - &movd ($reg,&DWP(16*$i+12,"edi")); - }); - - &lazy_reduction (); - - &sub ("ecx",16); - &jz (&label("done")); - -&set_label("even"); - &lea ("edx",&DWP(16*(5+5+5+9),"esp"));# size optimization - &lea ("eax",&DWP(-16*2,"esi")); - &sub ("ecx",64); - - ################################################################ - # expand and copy pre-calculated table to stack - - &movdqu ($T0,&QWP(16*0,"edi")); # r^1:r^2:r^3:r^4 - &pshufd ($T1,$T0,0b01000100); # duplicate r^3:r^4 - &cmovb ("esi","eax"); - &pshufd ($T0,$T0,0b11101110); # duplicate r^1:r^2 - &movdqa (&QWP(16*0,"edx"),$T1); - &lea ("eax",&DWP(16*10,"esp")); - &movdqu ($T1,&QWP(16*1,"edi")); - &movdqa (&QWP(16*(0-9),"edx"),$T0); - &pshufd ($T0,$T1,0b01000100); - &pshufd ($T1,$T1,0b11101110); - &movdqa (&QWP(16*1,"edx"),$T0); - &movdqu ($T0,&QWP(16*2,"edi")); - &movdqa (&QWP(16*(1-9),"edx"),$T1); - &pshufd ($T1,$T0,0b01000100); - &pshufd ($T0,$T0,0b11101110); - &movdqa (&QWP(16*2,"edx"),$T1); - &movdqu ($T1,&QWP(16*3,"edi")); - &movdqa (&QWP(16*(2-9),"edx"),$T0); - &pshufd ($T0,$T1,0b01000100); - &pshufd ($T1,$T1,0b11101110); - &movdqa (&QWP(16*3,"edx"),$T0); - &movdqu ($T0,&QWP(16*4,"edi")); - &movdqa (&QWP(16*(3-9),"edx"),$T1); - &pshufd ($T1,$T0,0b01000100); - &pshufd ($T0,$T0,0b11101110); - &movdqa (&QWP(16*4,"edx"),$T1); - &movdqu ($T1,&QWP(16*5,"edi")); - &movdqa (&QWP(16*(4-9),"edx"),$T0); - &pshufd ($T0,$T1,0b01000100); - &pshufd ($T1,$T1,0b11101110); - &movdqa (&QWP(16*5,"edx"),$T0); - &movdqu ($T0,&QWP(16*6,"edi")); - &movdqa (&QWP(16*(5-9),"edx"),$T1); - &pshufd ($T1,$T0,0b01000100); - &pshufd ($T0,$T0,0b11101110); - &movdqa (&QWP(16*6,"edx"),$T1); - &movdqu ($T1,&QWP(16*7,"edi")); - &movdqa (&QWP(16*(6-9),"edx"),$T0); - &pshufd ($T0,$T1,0b01000100); - &pshufd ($T1,$T1,0b11101110); - &movdqa (&QWP(16*7,"edx"),$T0); - &movdqu ($T0,&QWP(16*8,"edi")); - &movdqa (&QWP(16*(7-9),"edx"),$T1); - &pshufd ($T1,$T0,0b01000100); - &pshufd ($T0,$T0,0b11101110); - &movdqa (&QWP(16*8,"edx"),$T1); - &movdqa (&QWP(16*(8-9),"edx"),$T0); - -sub load_input { -my ($inpbase,$offbase)=@_; - - &movdqu ($T0,&QWP($inpbase+0,"esi")); # load input - &movdqu ($T1,&QWP($inpbase+16,"esi")); - &lea ("esi",&DWP(16*2,"esi")); - - &movdqa (&QWP($offbase+16*2,"esp"),$D2); - &movdqa (&QWP($offbase+16*3,"esp"),$D3); - &movdqa (&QWP($offbase+16*4,"esp"),$D4); - - &movdqa ($D2,$T0); # splat input - &movdqa ($D3,$T1); - &psrldq ($D2,6); - &psrldq ($D3,6); - &movdqa ($D4,$T0); - &punpcklqdq ($D2,$D3); # 2:3 - &punpckhqdq ($D4,$T1); # 4 - &punpcklqdq ($T0,$T1); # 0:1 - - &movdqa ($D3,$D2); - &psrlq ($D2,4); - &psrlq ($D3,30); - &movdqa ($T1,$T0); - &psrlq ($D4,40); # 4 - &psrlq ($T1,26); - &pand ($T0,$MASK); # 0 - &pand ($T1,$MASK); # 1 - &pand ($D2,$MASK); # 2 - &pand ($D3,$MASK); # 3 - &por ($D4,&QWP(0,"ebx")); # padbit, yes, always - - &movdqa (&QWP($offbase+16*0,"esp"),$D0) if ($offbase); - &movdqa (&QWP($offbase+16*1,"esp"),$D1) if ($offbase); -} - &load_input (16*2,16*5); - - &jbe (&label("skip_loop")); - &jmp (&label("loop")); - -&set_label("loop",32); - ################################################################ - # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 - # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r - # \___________________/ - # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2 - # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r - # \___________________/ \____________________/ - ################################################################ - - &movdqa ($T2,&QWP(16*(0-9),"edx")); # r0^2 - &movdqa (&QWP(16*1,"eax"),$T1); - &movdqa (&QWP(16*2,"eax"),$D2); - &movdqa (&QWP(16*3,"eax"),$D3); - &movdqa (&QWP(16*4,"eax"),$D4); - - ################################################################ - # d4 = h4*r0 + h0*r4 + h1*r3 + h2*r2 + h3*r1 - # d3 = h3*r0 + h0*r3 + h1*r2 + h2*r1 + h4*5*r4 - # d2 = h2*r0 + h0*r2 + h1*r1 + h3*5*r4 + h4*5*r3 - # d1 = h1*r0 + h0*r1 + h2*5*r4 + h3*5*r3 + h4*5*r2 - # d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1 - - &movdqa ($D1,$T0); - &pmuludq ($T0,$T2); # h0*r0 - &movdqa ($D0,$T1); - &pmuludq ($T1,$T2); # h1*r0 - &pmuludq ($D2,$T2); # h2*r0 - &pmuludq ($D3,$T2); # h3*r0 - &pmuludq ($D4,$T2); # h4*r0 - -sub pmuladd_alt { -my $addr = shift; - - &pmuludq ($D0,&$addr(8)); # h1*s4 - &movdqa ($T2,$D1); - &pmuludq ($D1,&$addr(1)); # h0*r1 - &paddq ($D0,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&$addr(2)); # h0*r2 - &paddq ($D1,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&$addr(3)); # h0*r3 - &paddq ($D2,$T2); - &movdqa ($T2,&QWP(16*1,"eax")); # pull h1 - &pmuludq ($T1,&$addr(4)); # h0*r4 - &paddq ($D3,$T0); - - &movdqa ($T0,$T2); - &pmuludq ($T2,&$addr(1)); # h1*r1 - &paddq ($D4,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&$addr(2)); # h1*r2 - &paddq ($D2,$T2); - &movdqa ($T2,&QWP(16*2,"eax")); # pull h2 - &pmuludq ($T1,&$addr(3)); # h1*r3 - &paddq ($D3,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&$addr(7)); # h2*s3 - &paddq ($D4,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&$addr(8)); # h2*s4 - &paddq ($D0,$T2); - - &movdqa ($T2,$T1); - &pmuludq ($T1,&$addr(1)); # h2*r1 - &paddq ($D1,$T0); - &movdqa ($T0,&QWP(16*3,"eax")); # pull h3 - &pmuludq ($T2,&$addr(2)); # h2*r2 - &paddq ($D3,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&$addr(6)); # h3*s2 - &paddq ($D4,$T2); - &movdqa ($T2,$T1); - &pmuludq ($T1,&$addr(7)); # h3*s3 - &paddq ($D0,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&$addr(8)); # h3*s4 - &paddq ($D1,$T1); - - &movdqa ($T1,&QWP(16*4,"eax")); # pull h4 - &pmuludq ($T0,&$addr(1)); # h3*r1 - &paddq ($D2,$T2); - &movdqa ($T2,$T1); - &pmuludq ($T1,&$addr(8)); # h4*s4 - &paddq ($D4,$T0); - &movdqa ($T0,$T2); - &pmuludq ($T2,&$addr(5)); # h4*s1 - &paddq ($D3,$T1); - &movdqa ($T1,$T0); - &pmuludq ($T0,&$addr(6)); # h4*s2 - &paddq ($D0,$T2); - &movdqa ($MASK,&QWP(64,"ebx")); - &pmuludq ($T1,&$addr(7)); # h4*s3 - &paddq ($D1,$T0); - &paddq ($D2,$T1); -} - &pmuladd_alt (sub { my $i=shift; &QWP(16*($i-9),"edx"); }); - - &load_input (-16*2,0); - &lea ("eax",&DWP(-16*2,"esi")); - &sub ("ecx",64); - - &paddd ($T0,&QWP(16*(5+0),"esp")); # add hash value - &paddd ($T1,&QWP(16*(5+1),"esp")); - &paddd ($D2,&QWP(16*(5+2),"esp")); - &paddd ($D3,&QWP(16*(5+3),"esp")); - &paddd ($D4,&QWP(16*(5+4),"esp")); - - &cmovb ("esi","eax"); - &lea ("eax",&DWP(16*10,"esp")); - - &movdqa ($T2,&QWP(16*0,"edx")); # r0^4 - &movdqa (&QWP(16*1,"esp"),$D1); - &movdqa (&QWP(16*1,"eax"),$T1); - &movdqa (&QWP(16*2,"eax"),$D2); - &movdqa (&QWP(16*3,"eax"),$D3); - &movdqa (&QWP(16*4,"eax"),$D4); - - ################################################################ - # d4 += h4*r0 + h0*r4 + h1*r3 + h2*r2 + h3*r1 - # d3 += h3*r0 + h0*r3 + h1*r2 + h2*r1 + h4*5*r4 - # d2 += h2*r0 + h0*r2 + h1*r1 + h3*5*r4 + h4*5*r3 - # d1 += h1*r0 + h0*r1 + h2*5*r4 + h3*5*r3 + h4*5*r2 - # d0 += h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1 - - &movdqa ($D1,$T0); - &pmuludq ($T0,$T2); # h0*r0 - &paddq ($T0,$D0); - &movdqa ($D0,$T1); - &pmuludq ($T1,$T2); # h1*r0 - &pmuludq ($D2,$T2); # h2*r0 - &pmuludq ($D3,$T2); # h3*r0 - &pmuludq ($D4,$T2); # h4*r0 - - &paddq ($T1,&QWP(16*1,"esp")); - &paddq ($D2,&QWP(16*2,"esp")); - &paddq ($D3,&QWP(16*3,"esp")); - &paddq ($D4,&QWP(16*4,"esp")); - - &pmuladd_alt (sub { my $i=shift; &QWP(16*$i,"edx"); }); - - &lazy_reduction (); - - &load_input (16*2,16*5); - - &ja (&label("loop")); - -&set_label("skip_loop"); - ################################################################ - # multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1 - - &pshufd ($T2,&QWP(16*(0-9),"edx"),0x10);# r0^n - &add ("ecx",32); - &jnz (&label("long_tail")); - - &paddd ($T0,$D0); # add hash value - &paddd ($T1,$D1); - &paddd ($D2,&QWP(16*7,"esp")); - &paddd ($D3,&QWP(16*8,"esp")); - &paddd ($D4,&QWP(16*9,"esp")); - -&set_label("long_tail"); - - &movdqa (&QWP(16*0,"eax"),$T0); - &movdqa (&QWP(16*1,"eax"),$T1); - &movdqa (&QWP(16*2,"eax"),$D2); - &movdqa (&QWP(16*3,"eax"),$D3); - &movdqa (&QWP(16*4,"eax"),$D4); - - ################################################################ - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - &pmuludq ($T0,$T2); # h0*r0 - &pmuludq ($T1,$T2); # h1*r0 - &pmuludq ($D2,$T2); # h2*r0 - &movdqa ($D0,$T0); - &pshufd ($T0,&QWP(16*(1-9),"edx"),0x10);# r1^n - &pmuludq ($D3,$T2); # h3*r0 - &movdqa ($D1,$T1); - &pmuludq ($D4,$T2); # h4*r0 - - &pmuladd (sub { my ($reg,$i)=@_; - &pshufd ($reg,&QWP(16*($i-9),"edx"),0x10); - },"eax"); - - &jz (&label("short_tail")); - - &load_input (-16*2,0); - - &pshufd ($T2,&QWP(16*0,"edx"),0x10); # r0^n - &paddd ($T0,&QWP(16*5,"esp")); # add hash value - &paddd ($T1,&QWP(16*6,"esp")); - &paddd ($D2,&QWP(16*7,"esp")); - &paddd ($D3,&QWP(16*8,"esp")); - &paddd ($D4,&QWP(16*9,"esp")); - - ################################################################ - # multiply inp[0:1] by r^4:r^3 and accumulate - - &movdqa (&QWP(16*0,"esp"),$T0); - &pmuludq ($T0,$T2); # h0*r0 - &movdqa (&QWP(16*1,"esp"),$T1); - &pmuludq ($T1,$T2); # h1*r0 - &paddq ($D0,$T0); - &movdqa ($T0,$D2); - &pmuludq ($D2,$T2); # h2*r0 - &paddq ($D1,$T1); - &movdqa ($T1,$D3); - &pmuludq ($D3,$T2); # h3*r0 - &paddq ($D2,&QWP(16*2,"esp")); - &movdqa (&QWP(16*2,"esp"),$T0); - &pshufd ($T0,&QWP(16*1,"edx"),0x10); # r1^n - &paddq ($D3,&QWP(16*3,"esp")); - &movdqa (&QWP(16*3,"esp"),$T1); - &movdqa ($T1,$D4); - &pmuludq ($D4,$T2); # h4*r0 - &paddq ($D4,&QWP(16*4,"esp")); - &movdqa (&QWP(16*4,"esp"),$T1); - - &pmuladd (sub { my ($reg,$i)=@_; - &pshufd ($reg,&QWP(16*$i,"edx"),0x10); - }); - -&set_label("short_tail"); - - ################################################################ - # horizontal addition - - &pshufd ($T1,$D4,0b01001110); - &pshufd ($T0,$D3,0b01001110); - &paddq ($D4,$T1); - &paddq ($D3,$T0); - &pshufd ($T1,$D0,0b01001110); - &pshufd ($T0,$D1,0b01001110); - &paddq ($D0,$T1); - &paddq ($D1,$T0); - &pshufd ($T1,$D2,0b01001110); - #&paddq ($D2,$T1); - - &lazy_reduction (sub { &paddq ($D2,$T1) }); - -&set_label("done"); - &movd (&DWP(-16*3+4*0,"edi"),$D0); # store hash value - &movd (&DWP(-16*3+4*1,"edi"),$D1); - &movd (&DWP(-16*3+4*2,"edi"),$D2); - &movd (&DWP(-16*3+4*3,"edi"),$D3); - &movd (&DWP(-16*3+4*4,"edi"),$D4); - &mov ("esp","ebp"); -&set_label("nodata"); -&function_end("_poly1305_blocks_sse2"); - -&align (32); -&function_begin("_poly1305_emit_sse2"); - &mov ("ebp",&wparam(0)); # context - - &cmp (&DWP(4*5,"ebp"),0); # is_base2_26? - &je (&label("enter_emit")); - - &mov ("eax",&DWP(4*0,"ebp")); # load hash value - &mov ("edi",&DWP(4*1,"ebp")); - &mov ("ecx",&DWP(4*2,"ebp")); - &mov ("edx",&DWP(4*3,"ebp")); - &mov ("esi",&DWP(4*4,"ebp")); - - &mov ("ebx","edi"); # base 2^26 -> base 2^32 - &shl ("edi",26); - &shr ("ebx",6); - &add ("eax","edi"); - &mov ("edi","ecx"); - &adc ("ebx",0); - - &shl ("edi",20); - &shr ("ecx",12); - &add ("ebx","edi"); - &mov ("edi","edx"); - &adc ("ecx",0); - - &shl ("edi",14); - &shr ("edx",18); - &add ("ecx","edi"); - &mov ("edi","esi"); - &adc ("edx",0); - - &shl ("edi",8); - &shr ("esi",24); - &add ("edx","edi"); - &adc ("esi",0); # can be partially reduced - - &mov ("edi","esi"); # final reduction - &and ("esi",3); - &shr ("edi",2); - &lea ("ebp",&DWP(0,"edi","edi",4)); # *5 - &mov ("edi",&wparam(1)); # output - &add ("eax","ebp"); - &mov ("ebp",&wparam(2)); # key - &adc ("ebx",0); - &adc ("ecx",0); - &adc ("edx",0); - &adc ("esi",0); - - &movd ($D0,"eax"); # offload original hash value - &add ("eax",5); # compare to modulus - &movd ($D1,"ebx"); - &adc ("ebx",0); - &movd ($D2,"ecx"); - &adc ("ecx",0); - &movd ($D3,"edx"); - &adc ("edx",0); - &adc ("esi",0); - &shr ("esi",2); # did it carry/borrow? - - &neg ("esi"); # do we choose (hash-modulus) ... - &and ("eax","esi"); - &and ("ebx","esi"); - &and ("ecx","esi"); - &and ("edx","esi"); - &mov (&DWP(4*0,"edi"),"eax"); - &movd ("eax",$D0); - &mov (&DWP(4*1,"edi"),"ebx"); - &movd ("ebx",$D1); - &mov (&DWP(4*2,"edi"),"ecx"); - &movd ("ecx",$D2); - &mov (&DWP(4*3,"edi"),"edx"); - &movd ("edx",$D3); - - ¬ ("esi"); # ... or original hash value? - &and ("eax","esi"); - &and ("ebx","esi"); - &or ("eax",&DWP(4*0,"edi")); - &and ("ecx","esi"); - &or ("ebx",&DWP(4*1,"edi")); - &and ("edx","esi"); - &or ("ecx",&DWP(4*2,"edi")); - &or ("edx",&DWP(4*3,"edi")); - - &add ("eax",&DWP(4*0,"ebp")); # accumulate key - &adc ("ebx",&DWP(4*1,"ebp")); - &mov (&DWP(4*0,"edi"),"eax"); - &adc ("ecx",&DWP(4*2,"ebp")); - &mov (&DWP(4*1,"edi"),"ebx"); - &adc ("edx",&DWP(4*3,"ebp")); - &mov (&DWP(4*2,"edi"),"ecx"); - &mov (&DWP(4*3,"edi"),"edx"); -&function_end("_poly1305_emit_sse2"); - -# The AVX2 code was removed. - -&set_label("const_sse2",64); - &data_word(1<<24,0, 1<<24,0, 1<<24,0, 1<<24,0); - &data_word(0,0, 0,0, 0,0, 0,0); - &data_word(0x03ffffff,0,0x03ffffff,0, 0x03ffffff,0, 0x03ffffff,0); - &data_word(0x0fffffff,0x0ffffffc,0x0ffffffc,0x0ffffffc); -} -&asciz ("Poly1305 for x86, CRYPTOGAMS by "); -&align (4); - -&asm_finish(); - -close STDOUT or die "error closing STDOUT"; diff --git a/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/poly1305/asm/poly1305-x86_64.pl deleted file mode 100755 index d1b547084a..0000000000 --- a/crypto/poly1305/asm/poly1305-x86_64.pl +++ /dev/null @@ -1,2243 +0,0 @@ -#!/usr/bin/env perl -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# This module implements Poly1305 hash for x86_64. -# -# March 2015 -# -# Numbers are cycles per processed byte with poly1305_blocks alone, -# measured with rdtsc at fixed clock frequency. -# -# IALU/gcc-4.8(*) AVX(**) AVX2 -# P4 4.46/+120% - -# Core 2 2.41/+90% - -# Westmere 1.88/+120% - -# Sandy Bridge 1.39/+140% 1.10 -# Haswell 1.14/+175% 1.11 0.65 -# Skylake 1.13/+120% 0.96 0.51 -# Silvermont 2.83/+95% - -# VIA Nano 1.82/+150% - -# Sledgehammer 1.38/+160% - -# Bulldozer 2.30/+130% 0.97 -# -# (*) improvement coefficients relative to clang are more modest and -# are ~50% on most processors, in both cases we are comparing to -# __int128 code; -# (**) SSE2 implementation was attempted, but among non-AVX processors -# it was faster than integer-only code only on older Intel P4 and -# Core processors, 50-30%, less newer processor is, but slower on -# contemporary ones, for example almost 2x slower on Atom, and as -# former are naturally disappearing, SSE2 is deemed unnecessary; - -$flavour = shift; -$output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } - -$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or -die "can't locate x86_64-xlate.pl"; - -$avx = 2; - -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; -*STDOUT=*OUT; - -my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx"); -my ($mac,$nonce)=($inp,$len); # *_emit arguments -my ($d1,$d2,$d3, $r0,$r1,$s1)=map("%r$_",(8..13)); -my ($h0,$h1,$h2)=("%r14","%rbx","%rbp"); - -sub poly1305_iteration { -# input: copy of $r1 in %rax, $h0-$h2, $r0-$r1 -# output: $h0-$h2 *= $r0-$r1 -$code.=<<___; - mulq $h0 # h0*r1 - mov %rax,$d2 - mov $r0,%rax - mov %rdx,$d3 - - mulq $h0 # h0*r0 - mov %rax,$h0 # future $h0 - mov $r0,%rax - mov %rdx,$d1 - - mulq $h1 # h1*r0 - add %rax,$d2 - mov $s1,%rax - adc %rdx,$d3 - - mulq $h1 # h1*s1 - mov $h2,$h1 # borrow $h1 - add %rax,$h0 - adc %rdx,$d1 - - imulq $s1,$h1 # h2*s1 - add $h1,$d2 - mov $d1,$h1 - adc \$0,$d3 - - imulq $r0,$h2 # h2*r0 - add $d2,$h1 - mov \$-4,%rax # mask value - adc $h2,$d3 - - and $d3,%rax # last reduction step - mov $d3,$h2 - shr \$2,$d3 - and \$3,$h2 - add $d3,%rax - add %rax,$h0 - adc \$0,$h1 - adc \$0,$h2 -___ -} - -######################################################################## -# Layout of opaque area is following. -# -# unsigned __int64 h[3]; # current hash value base 2^64 -# unsigned __int64 r[2]; # key value base 2^64 - -$code.=<<___; -.text - -.extern GFp_ia32cap_P - -.globl GFp_poly1305_init_asm -.hidden GFp_poly1305_init_asm -.globl GFp_poly1305_blocks -.hidden GFp_poly1305_blocks -.globl GFp_poly1305_emit -.hidden GFp_poly1305_emit - -.type GFp_poly1305_init_asm,\@function,3 -.align 32 -GFp_poly1305_init_asm: - xor %rax,%rax - mov %rax,0($ctx) # initialize hash value - mov %rax,8($ctx) - mov %rax,16($ctx) - - cmp \$0,$inp - je .Lno_key - - lea GFp_poly1305_blocks(%rip),%r10 - lea GFp_poly1305_emit(%rip),%r11 -___ -$code.=<<___ if ($avx); - mov GFp_ia32cap_P+4(%rip),%r9 - lea poly1305_blocks_avx(%rip),%rax - lea poly1305_emit_avx(%rip),%rcx - bt \$`60-32`,%r9 # AVX? - cmovc %rax,%r10 - cmovc %rcx,%r11 -___ -$code.=<<___ if ($avx>1); - lea poly1305_blocks_avx2(%rip),%rax - bt \$`5+32`,%r9 # AVX2? - cmovc %rax,%r10 -___ -$code.=<<___; - mov \$0x0ffffffc0fffffff,%rax - mov \$0x0ffffffc0ffffffc,%rcx - and 0($inp),%rax - and 8($inp),%rcx - mov %rax,24($ctx) - mov %rcx,32($ctx) -___ -$code.=<<___ if ($flavour !~ /elf32/); - mov %r10,0(%rdx) - mov %r11,8(%rdx) -___ -$code.=<<___ if ($flavour =~ /elf32/); - mov %r10d,0(%rdx) - mov %r11d,4(%rdx) -___ -$code.=<<___; - mov \$1,%eax -.Lno_key: - ret -.size GFp_poly1305_init_asm,.-GFp_poly1305_init_asm - -.type GFp_poly1305_blocks,\@function,4 -.align 32 -GFp_poly1305_blocks: -.Lblocks: - shr \$4,$len - jz .Lno_data # too short - - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.Lblocks_body: - - mov $len,%r15 # reassign $len - - mov 24($ctx),$r0 # load r - mov 32($ctx),$s1 - - mov 0($ctx),$h0 # load hash value - mov 8($ctx),$h1 - mov 16($ctx),$h2 - - mov $s1,$r1 - shr \$2,$s1 - mov $r1,%rax - add $r1,$s1 # s1 = r1 + (r1 >> 2) - jmp .Loop - -.align 32 -.Loop: - add 0($inp),$h0 # accumulate input - adc 8($inp),$h1 - lea 16($inp),$inp - adc $padbit,$h2 -___ - &poly1305_iteration(); -$code.=<<___; - mov $r1,%rax - dec %r15 # len-=16 - jnz .Loop - - mov $h0,0($ctx) # store hash value - mov $h1,8($ctx) - mov $h2,16($ctx) - - mov 0(%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r13 - mov 24(%rsp),%r12 - mov 32(%rsp),%rbp - mov 40(%rsp),%rbx - lea 48(%rsp),%rsp -.Lno_data: -.Lblocks_epilogue: - ret -.size GFp_poly1305_blocks,.-GFp_poly1305_blocks - -.type GFp_poly1305_emit,\@function,3 -.align 32 -GFp_poly1305_emit: -.Lemit: - mov 0($ctx),%r8 # load hash value - mov 8($ctx),%r9 - mov 16($ctx),%r10 - - mov %r8,%rax - add \$5,%r8 # compare to modulus - mov %r9,%rcx - adc \$0,%r9 - adc \$0,%r10 - shr \$2,%r10 # did 130-bit value overfow? - cmovnz %r8,%rax - cmovnz %r9,%rcx - - add 0($nonce),%rax # accumulate nonce - adc 8($nonce),%rcx - mov %rax,0($mac) # write result - mov %rcx,8($mac) - - ret -.size GFp_poly1305_emit,.-GFp_poly1305_emit -___ -if ($avx) { - -######################################################################## -# Layout of opaque area is following. -# -# unsigned __int32 h[5]; # current hash value base 2^26 -# unsigned __int32 is_base2_26; -# unsigned __int64 r[2]; # key value base 2^64 -# unsigned __int64 pad; -# struct { unsigned __int32 r^2, r^1, r^4, r^3; } r[9]; -# -# where r^n are base 2^26 digits of degrees of multiplier key. There are -# 5 digits, but last four are interleaved with multiples of 5, totalling -# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4. - -my ($H0,$H1,$H2,$H3,$H4, $T0,$T1,$T2,$T3,$T4, $D0,$D1,$D2,$D3,$D4, $MASK) = - map("%xmm$_",(0..15)); - -$code.=<<___; -.type __poly1305_block,\@abi-omnipotent -.align 32 -__poly1305_block: -___ - &poly1305_iteration(); -$code.=<<___; - ret -.size __poly1305_block,.-__poly1305_block - -.type __poly1305_init_avx,\@abi-omnipotent -.align 32 -__poly1305_init_avx: - mov $r0,$h0 - mov $r1,$h1 - xor $h2,$h2 - - lea 48+64($ctx),$ctx # size optimization - - mov $r1,%rax - call __poly1305_block # r^2 - - mov \$0x3ffffff,%eax # save interleaved r^2 and r base 2^26 - mov \$0x3ffffff,%edx - mov $h0,$d1 - and $h0#d,%eax - mov $r0,$d2 - and $r0#d,%edx - mov %eax,`16*0+0-64`($ctx) - shr \$26,$d1 - mov %edx,`16*0+4-64`($ctx) - shr \$26,$d2 - - mov \$0x3ffffff,%eax - mov \$0x3ffffff,%edx - and $d1#d,%eax - and $d2#d,%edx - mov %eax,`16*1+0-64`($ctx) - lea (%rax,%rax,4),%eax # *5 - mov %edx,`16*1+4-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - mov %eax,`16*2+0-64`($ctx) - shr \$26,$d1 - mov %edx,`16*2+4-64`($ctx) - shr \$26,$d2 - - mov $h1,%rax - mov $r1,%rdx - shl \$12,%rax - shl \$12,%rdx - or $d1,%rax - or $d2,%rdx - and \$0x3ffffff,%eax - and \$0x3ffffff,%edx - mov %eax,`16*3+0-64`($ctx) - lea (%rax,%rax,4),%eax # *5 - mov %edx,`16*3+4-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - mov %eax,`16*4+0-64`($ctx) - mov $h1,$d1 - mov %edx,`16*4+4-64`($ctx) - mov $r1,$d2 - - mov \$0x3ffffff,%eax - mov \$0x3ffffff,%edx - shr \$14,$d1 - shr \$14,$d2 - and $d1#d,%eax - and $d2#d,%edx - mov %eax,`16*5+0-64`($ctx) - lea (%rax,%rax,4),%eax # *5 - mov %edx,`16*5+4-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - mov %eax,`16*6+0-64`($ctx) - shr \$26,$d1 - mov %edx,`16*6+4-64`($ctx) - shr \$26,$d2 - - mov $h2,%rax - shl \$24,%rax - or %rax,$d1 - mov $d1#d,`16*7+0-64`($ctx) - lea ($d1,$d1,4),$d1 # *5 - mov $d2#d,`16*7+4-64`($ctx) - lea ($d2,$d2,4),$d2 # *5 - mov $d1#d,`16*8+0-64`($ctx) - mov $d2#d,`16*8+4-64`($ctx) - - mov $r1,%rax - call __poly1305_block # r^3 - - mov \$0x3ffffff,%eax # save r^3 base 2^26 - mov $h0,$d1 - and $h0#d,%eax - shr \$26,$d1 - mov %eax,`16*0+12-64`($ctx) - - mov \$0x3ffffff,%edx - and $d1#d,%edx - mov %edx,`16*1+12-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - shr \$26,$d1 - mov %edx,`16*2+12-64`($ctx) - - mov $h1,%rax - shl \$12,%rax - or $d1,%rax - and \$0x3ffffff,%eax - mov %eax,`16*3+12-64`($ctx) - lea (%rax,%rax,4),%eax # *5 - mov $h1,$d1 - mov %eax,`16*4+12-64`($ctx) - - mov \$0x3ffffff,%edx - shr \$14,$d1 - and $d1#d,%edx - mov %edx,`16*5+12-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - shr \$26,$d1 - mov %edx,`16*6+12-64`($ctx) - - mov $h2,%rax - shl \$24,%rax - or %rax,$d1 - mov $d1#d,`16*7+12-64`($ctx) - lea ($d1,$d1,4),$d1 # *5 - mov $d1#d,`16*8+12-64`($ctx) - - mov $r1,%rax - call __poly1305_block # r^4 - - mov \$0x3ffffff,%eax # save r^4 base 2^26 - mov $h0,$d1 - and $h0#d,%eax - shr \$26,$d1 - mov %eax,`16*0+8-64`($ctx) - - mov \$0x3ffffff,%edx - and $d1#d,%edx - mov %edx,`16*1+8-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - shr \$26,$d1 - mov %edx,`16*2+8-64`($ctx) - - mov $h1,%rax - shl \$12,%rax - or $d1,%rax - and \$0x3ffffff,%eax - mov %eax,`16*3+8-64`($ctx) - lea (%rax,%rax,4),%eax # *5 - mov $h1,$d1 - mov %eax,`16*4+8-64`($ctx) - - mov \$0x3ffffff,%edx - shr \$14,$d1 - and $d1#d,%edx - mov %edx,`16*5+8-64`($ctx) - lea (%rdx,%rdx,4),%edx # *5 - shr \$26,$d1 - mov %edx,`16*6+8-64`($ctx) - - mov $h2,%rax - shl \$24,%rax - or %rax,$d1 - mov $d1#d,`16*7+8-64`($ctx) - lea ($d1,$d1,4),$d1 # *5 - mov $d1#d,`16*8+8-64`($ctx) - - lea -48-64($ctx),$ctx # size [de-]optimization - ret -.size __poly1305_init_avx,.-__poly1305_init_avx - -.type poly1305_blocks_avx,\@function,4 -.align 32 -poly1305_blocks_avx: - mov 20($ctx),%r8d # is_base2_26 - cmp \$128,$len - jae .Lblocks_avx - test %r8d,%r8d - jz .Lblocks - -.Lblocks_avx: - and \$-16,$len - jz .Lno_data_avx - - vzeroupper - - test %r8d,%r8d - jz .Lbase2_64_avx - - test \$31,$len - jz .Leven_avx - - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.Lblocks_avx_body: - - mov $len,%r15 # reassign $len - - mov 0($ctx),$d1 # load hash value - mov 8($ctx),$d2 - mov 16($ctx),$h2#d - - mov 24($ctx),$r0 # load r - mov 32($ctx),$s1 - - ################################# base 2^26 -> base 2^64 - mov $d1#d,$h0#d - and \$`-1*(1<<31)`,$d1 - mov $d2,$r1 # borrow $r1 - mov $d2#d,$h1#d - and \$`-1*(1<<31)`,$d2 - - shr \$6,$d1 - shl \$52,$r1 - add $d1,$h0 - shr \$12,$h1 - shr \$18,$d2 - add $r1,$h0 - adc $d2,$h1 - - mov $h2,$d1 - shl \$40,$d1 - shr \$24,$h2 - add $d1,$h1 - adc \$0,$h2 # can be partially reduced... - - mov \$-4,$d2 # ... so reduce - mov $h2,$d1 - and $h2,$d2 - shr \$2,$d1 - and \$3,$h2 - add $d2,$d1 # =*5 - add $d1,$h0 - adc \$0,$h1 - adc \$0,$h2 - - mov $s1,$r1 - mov $s1,%rax - shr \$2,$s1 - add $r1,$s1 # s1 = r1 + (r1 >> 2) - - add 0($inp),$h0 # accumulate input - adc 8($inp),$h1 - lea 16($inp),$inp - adc $padbit,$h2 - - call __poly1305_block - - test $padbit,$padbit # if $padbit is zero, - jz .Lstore_base2_64_avx # store hash in base 2^64 format - - ################################# base 2^64 -> base 2^26 - mov $h0,%rax - mov $h0,%rdx - shr \$52,$h0 - mov $h1,$r0 - mov $h1,$r1 - shr \$26,%rdx - and \$0x3ffffff,%rax # h[0] - shl \$12,$r0 - and \$0x3ffffff,%rdx # h[1] - shr \$14,$h1 - or $r0,$h0 - shl \$24,$h2 - and \$0x3ffffff,$h0 # h[2] - shr \$40,$r1 - and \$0x3ffffff,$h1 # h[3] - or $r1,$h2 # h[4] - - sub \$16,%r15 - jz .Lstore_base2_26_avx - - vmovd %rax#d,$H0 - vmovd %rdx#d,$H1 - vmovd $h0#d,$H2 - vmovd $h1#d,$H3 - vmovd $h2#d,$H4 - jmp .Lproceed_avx - -.align 32 -.Lstore_base2_64_avx: - mov $h0,0($ctx) - mov $h1,8($ctx) - mov $h2,16($ctx) # note that is_base2_26 is zeroed - jmp .Ldone_avx - -.align 16 -.Lstore_base2_26_avx: - mov %rax#d,0($ctx) # store hash value base 2^26 - mov %rdx#d,4($ctx) - mov $h0#d,8($ctx) - mov $h1#d,12($ctx) - mov $h2#d,16($ctx) -.align 16 -.Ldone_avx: - mov 0(%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r13 - mov 24(%rsp),%r12 - mov 32(%rsp),%rbp - mov 40(%rsp),%rbx - lea 48(%rsp),%rsp -.Lno_data_avx: -.Lblocks_avx_epilogue: - ret - -.align 32 -.Lbase2_64_avx: - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.Lbase2_64_avx_body: - - mov $len,%r15 # reassign $len - - mov 24($ctx),$r0 # load r - mov 32($ctx),$s1 - - mov 0($ctx),$h0 # load hash value - mov 8($ctx),$h1 - mov 16($ctx),$h2#d - - mov $s1,$r1 - mov $s1,%rax - shr \$2,$s1 - add $r1,$s1 # s1 = r1 + (r1 >> 2) - - test \$31,$len - jz .Linit_avx - - add 0($inp),$h0 # accumulate input - adc 8($inp),$h1 - lea 16($inp),$inp - adc $padbit,$h2 - sub \$16,%r15 - - call __poly1305_block - -.Linit_avx: - ################################# base 2^64 -> base 2^26 - mov $h0,%rax - mov $h0,%rdx - shr \$52,$h0 - mov $h1,$d1 - mov $h1,$d2 - shr \$26,%rdx - and \$0x3ffffff,%rax # h[0] - shl \$12,$d1 - and \$0x3ffffff,%rdx # h[1] - shr \$14,$h1 - or $d1,$h0 - shl \$24,$h2 - and \$0x3ffffff,$h0 # h[2] - shr \$40,$d2 - and \$0x3ffffff,$h1 # h[3] - or $d2,$h2 # h[4] - - vmovd %rax#d,$H0 - vmovd %rdx#d,$H1 - vmovd $h0#d,$H2 - vmovd $h1#d,$H3 - vmovd $h2#d,$H4 - movl \$1,20($ctx) # set is_base2_26 - - call __poly1305_init_avx - -.Lproceed_avx: - mov %r15,$len - - mov 0(%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r13 - mov 24(%rsp),%r12 - mov 32(%rsp),%rbp - mov 40(%rsp),%rbx - lea 48(%rsp),%rax - lea 48(%rsp),%rsp -.Lbase2_64_avx_epilogue: - jmp .Ldo_avx - -.align 32 -.Leven_avx: - vmovd 4*0($ctx),$H0 # load hash value - vmovd 4*1($ctx),$H1 - vmovd 4*2($ctx),$H2 - vmovd 4*3($ctx),$H3 - vmovd 4*4($ctx),$H4 - -.Ldo_avx: -___ -$code.=<<___ if (!$win64); - lea -0x58(%rsp),%r11 - sub \$0x178,%rsp -___ -$code.=<<___ if ($win64); - lea -0xf8(%rsp),%r11 - sub \$0x218,%rsp - vmovdqa %xmm6,0x50(%r11) - vmovdqa %xmm7,0x60(%r11) - vmovdqa %xmm8,0x70(%r11) - vmovdqa %xmm9,0x80(%r11) - vmovdqa %xmm10,0x90(%r11) - vmovdqa %xmm11,0xa0(%r11) - vmovdqa %xmm12,0xb0(%r11) - vmovdqa %xmm13,0xc0(%r11) - vmovdqa %xmm14,0xd0(%r11) - vmovdqa %xmm15,0xe0(%r11) -.Ldo_avx_body: -___ -$code.=<<___; - sub \$64,$len - lea -32($inp),%rax - cmovc %rax,$inp - - vmovdqu `16*3`($ctx),$D4 # preload r0^2 - lea `16*3+64`($ctx),$ctx # size optimization - lea .Lconst(%rip),%rcx - - ################################################################ - # load input - vmovdqu 16*2($inp),$T0 - vmovdqu 16*3($inp),$T1 - vmovdqa 64(%rcx),$MASK # .Lmask26 - - vpsrldq \$6,$T0,$T2 # splat input - vpsrldq \$6,$T1,$T3 - vpunpckhqdq $T1,$T0,$T4 # 4 - vpunpcklqdq $T1,$T0,$T0 # 0:1 - vpunpcklqdq $T3,$T2,$T3 # 2:3 - - vpsrlq \$40,$T4,$T4 # 4 - vpsrlq \$26,$T0,$T1 - vpand $MASK,$T0,$T0 # 0 - vpsrlq \$4,$T3,$T2 - vpand $MASK,$T1,$T1 # 1 - vpsrlq \$30,$T3,$T3 - vpand $MASK,$T2,$T2 # 2 - vpand $MASK,$T3,$T3 # 3 - vpor 32(%rcx),$T4,$T4 # padbit, yes, always - - jbe .Lskip_loop_avx - - # expand and copy pre-calculated table to stack - vmovdqu `16*1-64`($ctx),$D1 - vmovdqu `16*2-64`($ctx),$D2 - vpshufd \$0xEE,$D4,$D3 # 34xx -> 3434 - vpshufd \$0x44,$D4,$D0 # xx12 -> 1212 - vmovdqa $D3,-0x90(%r11) - vmovdqa $D0,0x00(%rsp) - vpshufd \$0xEE,$D1,$D4 - vmovdqu `16*3-64`($ctx),$D0 - vpshufd \$0x44,$D1,$D1 - vmovdqa $D4,-0x80(%r11) - vmovdqa $D1,0x10(%rsp) - vpshufd \$0xEE,$D2,$D3 - vmovdqu `16*4-64`($ctx),$D1 - vpshufd \$0x44,$D2,$D2 - vmovdqa $D3,-0x70(%r11) - vmovdqa $D2,0x20(%rsp) - vpshufd \$0xEE,$D0,$D4 - vmovdqu `16*5-64`($ctx),$D2 - vpshufd \$0x44,$D0,$D0 - vmovdqa $D4,-0x60(%r11) - vmovdqa $D0,0x30(%rsp) - vpshufd \$0xEE,$D1,$D3 - vmovdqu `16*6-64`($ctx),$D0 - vpshufd \$0x44,$D1,$D1 - vmovdqa $D3,-0x50(%r11) - vmovdqa $D1,0x40(%rsp) - vpshufd \$0xEE,$D2,$D4 - vmovdqu `16*7-64`($ctx),$D1 - vpshufd \$0x44,$D2,$D2 - vmovdqa $D4,-0x40(%r11) - vmovdqa $D2,0x50(%rsp) - vpshufd \$0xEE,$D0,$D3 - vmovdqu `16*8-64`($ctx),$D2 - vpshufd \$0x44,$D0,$D0 - vmovdqa $D3,-0x30(%r11) - vmovdqa $D0,0x60(%rsp) - vpshufd \$0xEE,$D1,$D4 - vpshufd \$0x44,$D1,$D1 - vmovdqa $D4,-0x20(%r11) - vmovdqa $D1,0x70(%rsp) - vpshufd \$0xEE,$D2,$D3 - vmovdqa 0x00(%rsp),$D4 # preload r0^2 - vpshufd \$0x44,$D2,$D2 - vmovdqa $D3,-0x10(%r11) - vmovdqa $D2,0x80(%rsp) - - jmp .Loop_avx - -.align 32 -.Loop_avx: - ################################################################ - # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2 - # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r - # \___________________/ - # ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2 - # ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r - # \___________________/ \____________________/ - # - # Note that we start with inp[2:3]*r^2. This is because it - # doesn't depend on reduction in previous iteration. - ################################################################ - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - # - # though note that $Tx and $Hx are "reversed" in this section, - # and $D4 is preloaded with r0^2... - - vpmuludq $T0,$D4,$D0 # d0 = h0*r0 - vpmuludq $T1,$D4,$D1 # d1 = h1*r0 - vmovdqa $H2,0x20(%r11) # offload hash - vpmuludq $T2,$D4,$D2 # d3 = h2*r0 - vmovdqa 0x10(%rsp),$H2 # r1^2 - vpmuludq $T3,$D4,$D3 # d3 = h3*r0 - vpmuludq $T4,$D4,$D4 # d4 = h4*r0 - - vmovdqa $H0,0x00(%r11) # - vpmuludq 0x20(%rsp),$T4,$H0 # h4*s1 - vmovdqa $H1,0x10(%r11) # - vpmuludq $T3,$H2,$H1 # h3*r1 - vpaddq $H0,$D0,$D0 # d0 += h4*s1 - vpaddq $H1,$D4,$D4 # d4 += h3*r1 - vmovdqa $H3,0x30(%r11) # - vpmuludq $T2,$H2,$H0 # h2*r1 - vpmuludq $T1,$H2,$H1 # h1*r1 - vpaddq $H0,$D3,$D3 # d3 += h2*r1 - vmovdqa 0x30(%rsp),$H3 # r2^2 - vpaddq $H1,$D2,$D2 # d2 += h1*r1 - vmovdqa $H4,0x40(%r11) # - vpmuludq $T0,$H2,$H2 # h0*r1 - vpmuludq $T2,$H3,$H0 # h2*r2 - vpaddq $H2,$D1,$D1 # d1 += h0*r1 - - vmovdqa 0x40(%rsp),$H4 # s2^2 - vpaddq $H0,$D4,$D4 # d4 += h2*r2 - vpmuludq $T1,$H3,$H1 # h1*r2 - vpmuludq $T0,$H3,$H3 # h0*r2 - vpaddq $H1,$D3,$D3 # d3 += h1*r2 - vmovdqa 0x50(%rsp),$H2 # r3^2 - vpaddq $H3,$D2,$D2 # d2 += h0*r2 - vpmuludq $T4,$H4,$H0 # h4*s2 - vpmuludq $T3,$H4,$H4 # h3*s2 - vpaddq $H0,$D1,$D1 # d1 += h4*s2 - vmovdqa 0x60(%rsp),$H3 # s3^2 - vpaddq $H4,$D0,$D0 # d0 += h3*s2 - - vmovdqa 0x80(%rsp),$H4 # s4^2 - vpmuludq $T1,$H2,$H1 # h1*r3 - vpmuludq $T0,$H2,$H2 # h0*r3 - vpaddq $H1,$D4,$D4 # d4 += h1*r3 - vpaddq $H2,$D3,$D3 # d3 += h0*r3 - vpmuludq $T4,$H3,$H0 # h4*s3 - vpmuludq $T3,$H3,$H1 # h3*s3 - vpaddq $H0,$D2,$D2 # d2 += h4*s3 - vmovdqu 16*0($inp),$H0 # load input - vpaddq $H1,$D1,$D1 # d1 += h3*s3 - vpmuludq $T2,$H3,$H3 # h2*s3 - vpmuludq $T2,$H4,$T2 # h2*s4 - vpaddq $H3,$D0,$D0 # d0 += h2*s3 - - vmovdqu 16*1($inp),$H1 # - vpaddq $T2,$D1,$D1 # d1 += h2*s4 - vpmuludq $T3,$H4,$T3 # h3*s4 - vpmuludq $T4,$H4,$T4 # h4*s4 - vpsrldq \$6,$H0,$H2 # splat input - vpaddq $T3,$D2,$D2 # d2 += h3*s4 - vpaddq $T4,$D3,$D3 # d3 += h4*s4 - vpsrldq \$6,$H1,$H3 # - vpmuludq 0x70(%rsp),$T0,$T4 # h0*r4 - vpmuludq $T1,$H4,$T0 # h1*s4 - vpunpckhqdq $H1,$H0,$H4 # 4 - vpaddq $T4,$D4,$D4 # d4 += h0*r4 - vmovdqa -0x90(%r11),$T4 # r0^4 - vpaddq $T0,$D0,$D0 # d0 += h1*s4 - - vpunpcklqdq $H1,$H0,$H0 # 0:1 - vpunpcklqdq $H3,$H2,$H3 # 2:3 - - #vpsrlq \$40,$H4,$H4 # 4 - vpsrldq \$`40/8`,$H4,$H4 # 4 - vpsrlq \$26,$H0,$H1 - vpand $MASK,$H0,$H0 # 0 - vpsrlq \$4,$H3,$H2 - vpand $MASK,$H1,$H1 # 1 - vpand 0(%rcx),$H4,$H4 # .Lmask24 - vpsrlq \$30,$H3,$H3 - vpand $MASK,$H2,$H2 # 2 - vpand $MASK,$H3,$H3 # 3 - vpor 32(%rcx),$H4,$H4 # padbit, yes, always - - vpaddq 0x00(%r11),$H0,$H0 # add hash value - vpaddq 0x10(%r11),$H1,$H1 - vpaddq 0x20(%r11),$H2,$H2 - vpaddq 0x30(%r11),$H3,$H3 - vpaddq 0x40(%r11),$H4,$H4 - - lea 16*2($inp),%rax - lea 16*4($inp),$inp - sub \$64,$len - cmovc %rax,$inp - - ################################################################ - # Now we accumulate (inp[0:1]+hash)*r^4 - ################################################################ - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - vpmuludq $H0,$T4,$T0 # h0*r0 - vpmuludq $H1,$T4,$T1 # h1*r0 - vpaddq $T0,$D0,$D0 - vpaddq $T1,$D1,$D1 - vmovdqa -0x80(%r11),$T2 # r1^4 - vpmuludq $H2,$T4,$T0 # h2*r0 - vpmuludq $H3,$T4,$T1 # h3*r0 - vpaddq $T0,$D2,$D2 - vpaddq $T1,$D3,$D3 - vpmuludq $H4,$T4,$T4 # h4*r0 - vpmuludq -0x70(%r11),$H4,$T0 # h4*s1 - vpaddq $T4,$D4,$D4 - - vpaddq $T0,$D0,$D0 # d0 += h4*s1 - vpmuludq $H2,$T2,$T1 # h2*r1 - vpmuludq $H3,$T2,$T0 # h3*r1 - vpaddq $T1,$D3,$D3 # d3 += h2*r1 - vmovdqa -0x60(%r11),$T3 # r2^4 - vpaddq $T0,$D4,$D4 # d4 += h3*r1 - vpmuludq $H1,$T2,$T1 # h1*r1 - vpmuludq $H0,$T2,$T2 # h0*r1 - vpaddq $T1,$D2,$D2 # d2 += h1*r1 - vpaddq $T2,$D1,$D1 # d1 += h0*r1 - - vmovdqa -0x50(%r11),$T4 # s2^4 - vpmuludq $H2,$T3,$T0 # h2*r2 - vpmuludq $H1,$T3,$T1 # h1*r2 - vpaddq $T0,$D4,$D4 # d4 += h2*r2 - vpaddq $T1,$D3,$D3 # d3 += h1*r2 - vmovdqa -0x40(%r11),$T2 # r3^4 - vpmuludq $H0,$T3,$T3 # h0*r2 - vpmuludq $H4,$T4,$T0 # h4*s2 - vpaddq $T3,$D2,$D2 # d2 += h0*r2 - vpaddq $T0,$D1,$D1 # d1 += h4*s2 - vmovdqa -0x30(%r11),$T3 # s3^4 - vpmuludq $H3,$T4,$T4 # h3*s2 - vpmuludq $H1,$T2,$T1 # h1*r3 - vpaddq $T4,$D0,$D0 # d0 += h3*s2 - - vmovdqa -0x10(%r11),$T4 # s4^4 - vpaddq $T1,$D4,$D4 # d4 += h1*r3 - vpmuludq $H0,$T2,$T2 # h0*r3 - vpmuludq $H4,$T3,$T0 # h4*s3 - vpaddq $T2,$D3,$D3 # d3 += h0*r3 - vpaddq $T0,$D2,$D2 # d2 += h4*s3 - vmovdqu 16*2($inp),$T0 # load input - vpmuludq $H3,$T3,$T2 # h3*s3 - vpmuludq $H2,$T3,$T3 # h2*s3 - vpaddq $T2,$D1,$D1 # d1 += h3*s3 - vmovdqu 16*3($inp),$T1 # - vpaddq $T3,$D0,$D0 # d0 += h2*s3 - - vpmuludq $H2,$T4,$H2 # h2*s4 - vpmuludq $H3,$T4,$H3 # h3*s4 - vpsrldq \$6,$T0,$T2 # splat input - vpaddq $H2,$D1,$D1 # d1 += h2*s4 - vpmuludq $H4,$T4,$H4 # h4*s4 - vpsrldq \$6,$T1,$T3 # - vpaddq $H3,$D2,$H2 # h2 = d2 + h3*s4 - vpaddq $H4,$D3,$H3 # h3 = d3 + h4*s4 - vpmuludq -0x20(%r11),$H0,$H4 # h0*r4 - vpmuludq $H1,$T4,$H0 - vpunpckhqdq $T1,$T0,$T4 # 4 - vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4 - vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4 - - vpunpcklqdq $T1,$T0,$T0 # 0:1 - vpunpcklqdq $T3,$T2,$T3 # 2:3 - - #vpsrlq \$40,$T4,$T4 # 4 - vpsrldq \$`40/8`,$T4,$T4 # 4 - vpsrlq \$26,$T0,$T1 - vmovdqa 0x00(%rsp),$D4 # preload r0^2 - vpand $MASK,$T0,$T0 # 0 - vpsrlq \$4,$T3,$T2 - vpand $MASK,$T1,$T1 # 1 - vpand 0(%rcx),$T4,$T4 # .Lmask24 - vpsrlq \$30,$T3,$T3 - vpand $MASK,$T2,$T2 # 2 - vpand $MASK,$T3,$T3 # 3 - vpor 32(%rcx),$T4,$T4 # padbit, yes, always - - ################################################################ - # lazy reduction as discussed in "NEON crypto" by D.J. Bernstein - # and P. Schwabe - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$D1,$H1 # h0 -> h1 - - vpsrlq \$26,$H4,$D0 - vpand $MASK,$H4,$H4 - - vpsrlq \$26,$H1,$D1 - vpand $MASK,$H1,$H1 - vpaddq $D1,$H2,$H2 # h1 -> h2 - - vpaddq $D0,$H0,$H0 - vpsllq \$2,$D0,$D0 - vpaddq $D0,$H0,$H0 # h4 -> h0 - - vpsrlq \$26,$H2,$D2 - vpand $MASK,$H2,$H2 - vpaddq $D2,$H3,$H3 # h2 -> h3 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$H1,$H1 # h0 -> h1 - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - ja .Loop_avx - -.Lskip_loop_avx: - ################################################################ - # multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1 - - vpshufd \$0x10,$D4,$D4 # r0^n, xx12 -> x1x2 - add \$32,$len - jnz .Long_tail_avx - - vpaddq $H2,$T2,$T2 - vpaddq $H0,$T0,$T0 - vpaddq $H1,$T1,$T1 - vpaddq $H3,$T3,$T3 - vpaddq $H4,$T4,$T4 - -.Long_tail_avx: - vmovdqa $H2,0x20(%r11) - vmovdqa $H0,0x00(%r11) - vmovdqa $H1,0x10(%r11) - vmovdqa $H3,0x30(%r11) - vmovdqa $H4,0x40(%r11) - - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - - vpmuludq $T2,$D4,$D2 # d2 = h2*r0 - vpmuludq $T0,$D4,$D0 # d0 = h0*r0 - vpshufd \$0x10,`16*1-64`($ctx),$H2 # r1^n - vpmuludq $T1,$D4,$D1 # d1 = h1*r0 - vpmuludq $T3,$D4,$D3 # d3 = h3*r0 - vpmuludq $T4,$D4,$D4 # d4 = h4*r0 - - vpmuludq $T3,$H2,$H0 # h3*r1 - vpaddq $H0,$D4,$D4 # d4 += h3*r1 - vpshufd \$0x10,`16*2-64`($ctx),$H3 # s1^n - vpmuludq $T2,$H2,$H1 # h2*r1 - vpaddq $H1,$D3,$D3 # d3 += h2*r1 - vpshufd \$0x10,`16*3-64`($ctx),$H4 # r2^n - vpmuludq $T1,$H2,$H0 # h1*r1 - vpaddq $H0,$D2,$D2 # d2 += h1*r1 - vpmuludq $T0,$H2,$H2 # h0*r1 - vpaddq $H2,$D1,$D1 # d1 += h0*r1 - vpmuludq $T4,$H3,$H3 # h4*s1 - vpaddq $H3,$D0,$D0 # d0 += h4*s1 - - vpshufd \$0x10,`16*4-64`($ctx),$H2 # s2^n - vpmuludq $T2,$H4,$H1 # h2*r2 - vpaddq $H1,$D4,$D4 # d4 += h2*r2 - vpmuludq $T1,$H4,$H0 # h1*r2 - vpaddq $H0,$D3,$D3 # d3 += h1*r2 - vpshufd \$0x10,`16*5-64`($ctx),$H3 # r3^n - vpmuludq $T0,$H4,$H4 # h0*r2 - vpaddq $H4,$D2,$D2 # d2 += h0*r2 - vpmuludq $T4,$H2,$H1 # h4*s2 - vpaddq $H1,$D1,$D1 # d1 += h4*s2 - vpshufd \$0x10,`16*6-64`($ctx),$H4 # s3^n - vpmuludq $T3,$H2,$H2 # h3*s2 - vpaddq $H2,$D0,$D0 # d0 += h3*s2 - - vpmuludq $T1,$H3,$H0 # h1*r3 - vpaddq $H0,$D4,$D4 # d4 += h1*r3 - vpmuludq $T0,$H3,$H3 # h0*r3 - vpaddq $H3,$D3,$D3 # d3 += h0*r3 - vpshufd \$0x10,`16*7-64`($ctx),$H2 # r4^n - vpmuludq $T4,$H4,$H1 # h4*s3 - vpaddq $H1,$D2,$D2 # d2 += h4*s3 - vpshufd \$0x10,`16*8-64`($ctx),$H3 # s4^n - vpmuludq $T3,$H4,$H0 # h3*s3 - vpaddq $H0,$D1,$D1 # d1 += h3*s3 - vpmuludq $T2,$H4,$H4 # h2*s3 - vpaddq $H4,$D0,$D0 # d0 += h2*s3 - - vpmuludq $T0,$H2,$H2 # h0*r4 - vpaddq $H2,$D4,$D4 # h4 = d4 + h0*r4 - vpmuludq $T4,$H3,$H1 # h4*s4 - vpaddq $H1,$D3,$D3 # h3 = d3 + h4*s4 - vpmuludq $T3,$H3,$H0 # h3*s4 - vpaddq $H0,$D2,$D2 # h2 = d2 + h3*s4 - vpmuludq $T2,$H3,$H1 # h2*s4 - vpaddq $H1,$D1,$D1 # h1 = d1 + h2*s4 - vpmuludq $T1,$H3,$H3 # h1*s4 - vpaddq $H3,$D0,$D0 # h0 = d0 + h1*s4 - - jz .Lshort_tail_avx - - vmovdqu 16*0($inp),$H0 # load input - vmovdqu 16*1($inp),$H1 - - vpsrldq \$6,$H0,$H2 # splat input - vpsrldq \$6,$H1,$H3 - vpunpckhqdq $H1,$H0,$H4 # 4 - vpunpcklqdq $H1,$H0,$H0 # 0:1 - vpunpcklqdq $H3,$H2,$H3 # 2:3 - - vpsrlq \$40,$H4,$H4 # 4 - vpsrlq \$26,$H0,$H1 - vpand $MASK,$H0,$H0 # 0 - vpsrlq \$4,$H3,$H2 - vpand $MASK,$H1,$H1 # 1 - vpsrlq \$30,$H3,$H3 - vpand $MASK,$H2,$H2 # 2 - vpand $MASK,$H3,$H3 # 3 - vpor 32(%rcx),$H4,$H4 # padbit, yes, always - - vpshufd \$0x32,`16*0-64`($ctx),$T4 # r0^n, 34xx -> x3x4 - vpaddq 0x00(%r11),$H0,$H0 - vpaddq 0x10(%r11),$H1,$H1 - vpaddq 0x20(%r11),$H2,$H2 - vpaddq 0x30(%r11),$H3,$H3 - vpaddq 0x40(%r11),$H4,$H4 - - ################################################################ - # multiply (inp[0:1]+hash) by r^4:r^3 and accumulate - - vpmuludq $H0,$T4,$T0 # h0*r0 - vpaddq $T0,$D0,$D0 # d0 += h0*r0 - vpmuludq $H1,$T4,$T1 # h1*r0 - vpaddq $T1,$D1,$D1 # d1 += h1*r0 - vpmuludq $H2,$T4,$T0 # h2*r0 - vpaddq $T0,$D2,$D2 # d2 += h2*r0 - vpshufd \$0x32,`16*1-64`($ctx),$T2 # r1^n - vpmuludq $H3,$T4,$T1 # h3*r0 - vpaddq $T1,$D3,$D3 # d3 += h3*r0 - vpmuludq $H4,$T4,$T4 # h4*r0 - vpaddq $T4,$D4,$D4 # d4 += h4*r0 - - vpmuludq $H3,$T2,$T0 # h3*r1 - vpaddq $T0,$D4,$D4 # d4 += h3*r1 - vpshufd \$0x32,`16*2-64`($ctx),$T3 # s1 - vpmuludq $H2,$T2,$T1 # h2*r1 - vpaddq $T1,$D3,$D3 # d3 += h2*r1 - vpshufd \$0x32,`16*3-64`($ctx),$T4 # r2 - vpmuludq $H1,$T2,$T0 # h1*r1 - vpaddq $T0,$D2,$D2 # d2 += h1*r1 - vpmuludq $H0,$T2,$T2 # h0*r1 - vpaddq $T2,$D1,$D1 # d1 += h0*r1 - vpmuludq $H4,$T3,$T3 # h4*s1 - vpaddq $T3,$D0,$D0 # d0 += h4*s1 - - vpshufd \$0x32,`16*4-64`($ctx),$T2 # s2 - vpmuludq $H2,$T4,$T1 # h2*r2 - vpaddq $T1,$D4,$D4 # d4 += h2*r2 - vpmuludq $H1,$T4,$T0 # h1*r2 - vpaddq $T0,$D3,$D3 # d3 += h1*r2 - vpshufd \$0x32,`16*5-64`($ctx),$T3 # r3 - vpmuludq $H0,$T4,$T4 # h0*r2 - vpaddq $T4,$D2,$D2 # d2 += h0*r2 - vpmuludq $H4,$T2,$T1 # h4*s2 - vpaddq $T1,$D1,$D1 # d1 += h4*s2 - vpshufd \$0x32,`16*6-64`($ctx),$T4 # s3 - vpmuludq $H3,$T2,$T2 # h3*s2 - vpaddq $T2,$D0,$D0 # d0 += h3*s2 - - vpmuludq $H1,$T3,$T0 # h1*r3 - vpaddq $T0,$D4,$D4 # d4 += h1*r3 - vpmuludq $H0,$T3,$T3 # h0*r3 - vpaddq $T3,$D3,$D3 # d3 += h0*r3 - vpshufd \$0x32,`16*7-64`($ctx),$T2 # r4 - vpmuludq $H4,$T4,$T1 # h4*s3 - vpaddq $T1,$D2,$D2 # d2 += h4*s3 - vpshufd \$0x32,`16*8-64`($ctx),$T3 # s4 - vpmuludq $H3,$T4,$T0 # h3*s3 - vpaddq $T0,$D1,$D1 # d1 += h3*s3 - vpmuludq $H2,$T4,$T4 # h2*s3 - vpaddq $T4,$D0,$D0 # d0 += h2*s3 - - vpmuludq $H0,$T2,$T2 # h0*r4 - vpaddq $T2,$D4,$D4 # d4 += h0*r4 - vpmuludq $H4,$T3,$T1 # h4*s4 - vpaddq $T1,$D3,$D3 # d3 += h4*s4 - vpmuludq $H3,$T3,$T0 # h3*s4 - vpaddq $T0,$D2,$D2 # d2 += h3*s4 - vpmuludq $H2,$T3,$T1 # h2*s4 - vpaddq $T1,$D1,$D1 # d1 += h2*s4 - vpmuludq $H1,$T3,$T3 # h1*s4 - vpaddq $T3,$D0,$D0 # d0 += h1*s4 - -.Lshort_tail_avx: - ################################################################ - # horizontal addition - - vpsrldq \$8,$D4,$T4 - vpsrldq \$8,$D3,$T3 - vpsrldq \$8,$D1,$T1 - vpsrldq \$8,$D0,$T0 - vpsrldq \$8,$D2,$T2 - vpaddq $T3,$D3,$D3 - vpaddq $T4,$D4,$D4 - vpaddq $T0,$D0,$D0 - vpaddq $T1,$D1,$D1 - vpaddq $T2,$D2,$D2 - - ################################################################ - # lazy reduction - - vpsrlq \$26,$D3,$H3 - vpand $MASK,$D3,$D3 - vpaddq $H3,$D4,$D4 # h3 -> h4 - - vpsrlq \$26,$D0,$H0 - vpand $MASK,$D0,$D0 - vpaddq $H0,$D1,$D1 # h0 -> h1 - - vpsrlq \$26,$D4,$H4 - vpand $MASK,$D4,$D4 - - vpsrlq \$26,$D1,$H1 - vpand $MASK,$D1,$D1 - vpaddq $H1,$D2,$D2 # h1 -> h2 - - vpaddq $H4,$D0,$D0 - vpsllq \$2,$H4,$H4 - vpaddq $H4,$D0,$D0 # h4 -> h0 - - vpsrlq \$26,$D2,$H2 - vpand $MASK,$D2,$D2 - vpaddq $H2,$D3,$D3 # h2 -> h3 - - vpsrlq \$26,$D0,$H0 - vpand $MASK,$D0,$D0 - vpaddq $H0,$D1,$D1 # h0 -> h1 - - vpsrlq \$26,$D3,$H3 - vpand $MASK,$D3,$D3 - vpaddq $H3,$D4,$D4 # h3 -> h4 - - vmovd $D0,`4*0-48-64`($ctx) # save partially reduced - vmovd $D1,`4*1-48-64`($ctx) - vmovd $D2,`4*2-48-64`($ctx) - vmovd $D3,`4*3-48-64`($ctx) - vmovd $D4,`4*4-48-64`($ctx) -___ -$code.=<<___ if ($win64); - vmovdqa 0x50(%r11),%xmm6 - vmovdqa 0x60(%r11),%xmm7 - vmovdqa 0x70(%r11),%xmm8 - vmovdqa 0x80(%r11),%xmm9 - vmovdqa 0x90(%r11),%xmm10 - vmovdqa 0xa0(%r11),%xmm11 - vmovdqa 0xb0(%r11),%xmm12 - vmovdqa 0xc0(%r11),%xmm13 - vmovdqa 0xd0(%r11),%xmm14 - vmovdqa 0xe0(%r11),%xmm15 - lea 0xf8(%r11),%rsp -.Ldo_avx_epilogue: -___ -$code.=<<___ if (!$win64); - lea 0x58(%r11),%rsp -___ -$code.=<<___; - vzeroupper - ret -.size poly1305_blocks_avx,.-poly1305_blocks_avx - -.type poly1305_emit_avx,\@function,3 -.align 32 -poly1305_emit_avx: - cmpl \$0,20($ctx) # is_base2_26? - je .Lemit - - mov 0($ctx),%eax # load hash value base 2^26 - mov 4($ctx),%ecx - mov 8($ctx),%r8d - mov 12($ctx),%r11d - mov 16($ctx),%r10d - - shl \$26,%rcx # base 2^26 -> base 2^64 - mov %r8,%r9 - shl \$52,%r8 - add %rcx,%rax - shr \$12,%r9 - add %rax,%r8 # h0 - adc \$0,%r9 - - shl \$14,%r11 - mov %r10,%rax - shr \$24,%r10 - add %r11,%r9 - shl \$40,%rax - add %rax,%r9 # h1 - adc \$0,%r10 # h2 - - mov %r10,%rax # could be partially reduced, so reduce - mov %r10,%rcx - and \$3,%r10 - shr \$2,%rax - and \$-4,%rcx - add %rcx,%rax - add %rax,%r8 - adc \$0,%r9 - adc \$0,%r10 - - mov %r8,%rax - add \$5,%r8 # compare to modulus - mov %r9,%rcx - adc \$0,%r9 - adc \$0,%r10 - shr \$2,%r10 # did 130-bit value overfow? - cmovnz %r8,%rax - cmovnz %r9,%rcx - - add 0($nonce),%rax # accumulate nonce - adc 8($nonce),%rcx - mov %rax,0($mac) # write result - mov %rcx,8($mac) - - ret -.size poly1305_emit_avx,.-poly1305_emit_avx -___ - -if ($avx>1) { -my ($H0,$H1,$H2,$H3,$H4, $MASK, $T4,$T0,$T1,$T2,$T3, $D0,$D1,$D2,$D3,$D4) = - map("%ymm$_",(0..15)); -my $S4=$MASK; - -$code.=<<___; -.type poly1305_blocks_avx2,\@function,4 -.align 32 -poly1305_blocks_avx2: - mov 20($ctx),%r8d # is_base2_26 - cmp \$128,$len - jae .Lblocks_avx2 - test %r8d,%r8d - jz .Lblocks - -.Lblocks_avx2: - and \$-16,$len - jz .Lno_data_avx2 - - vzeroupper - - test %r8d,%r8d - jz .Lbase2_64_avx2 - - test \$63,$len - jz .Leven_avx2 - - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.Lblocks_avx2_body: - - mov $len,%r15 # reassign $len - - mov 0($ctx),$d1 # load hash value - mov 8($ctx),$d2 - mov 16($ctx),$h2#d - - mov 24($ctx),$r0 # load r - mov 32($ctx),$s1 - - ################################# base 2^26 -> base 2^64 - mov $d1#d,$h0#d - and \$`-1*(1<<31)`,$d1 - mov $d2,$r1 # borrow $r1 - mov $d2#d,$h1#d - and \$`-1*(1<<31)`,$d2 - - shr \$6,$d1 - shl \$52,$r1 - add $d1,$h0 - shr \$12,$h1 - shr \$18,$d2 - add $r1,$h0 - adc $d2,$h1 - - mov $h2,$d1 - shl \$40,$d1 - shr \$24,$h2 - add $d1,$h1 - adc \$0,$h2 # can be partially reduced... - - mov \$-4,$d2 # ... so reduce - mov $h2,$d1 - and $h2,$d2 - shr \$2,$d1 - and \$3,$h2 - add $d2,$d1 # =*5 - add $d1,$h0 - adc \$0,$h1 - adc \$0,$h2 - - mov $s1,$r1 - mov $s1,%rax - shr \$2,$s1 - add $r1,$s1 # s1 = r1 + (r1 >> 2) - -.Lbase2_26_pre_avx2: - add 0($inp),$h0 # accumulate input - adc 8($inp),$h1 - lea 16($inp),$inp - adc $padbit,$h2 - sub \$16,%r15 - - call __poly1305_block - mov $r1,%rax - - test \$63,%r15 - jnz .Lbase2_26_pre_avx2 - - test $padbit,$padbit # if $padbit is zero, - jz .Lstore_base2_64_avx2 # store hash in base 2^64 format - - ################################# base 2^64 -> base 2^26 - mov $h0,%rax - mov $h0,%rdx - shr \$52,$h0 - mov $h1,$r0 - mov $h1,$r1 - shr \$26,%rdx - and \$0x3ffffff,%rax # h[0] - shl \$12,$r0 - and \$0x3ffffff,%rdx # h[1] - shr \$14,$h1 - or $r0,$h0 - shl \$24,$h2 - and \$0x3ffffff,$h0 # h[2] - shr \$40,$r1 - and \$0x3ffffff,$h1 # h[3] - or $r1,$h2 # h[4] - - test %r15,%r15 - jz .Lstore_base2_26_avx2 - - vmovd %rax#d,%x#$H0 - vmovd %rdx#d,%x#$H1 - vmovd $h0#d,%x#$H2 - vmovd $h1#d,%x#$H3 - vmovd $h2#d,%x#$H4 - jmp .Lproceed_avx2 - -.align 32 -.Lstore_base2_64_avx2: - mov $h0,0($ctx) - mov $h1,8($ctx) - mov $h2,16($ctx) # note that is_base2_26 is zeroed - jmp .Ldone_avx2 - -.align 16 -.Lstore_base2_26_avx2: - mov %rax#d,0($ctx) # store hash value base 2^26 - mov %rdx#d,4($ctx) - mov $h0#d,8($ctx) - mov $h1#d,12($ctx) - mov $h2#d,16($ctx) -.align 16 -.Ldone_avx2: - mov 0(%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r13 - mov 24(%rsp),%r12 - mov 32(%rsp),%rbp - mov 40(%rsp),%rbx - lea 48(%rsp),%rsp -.Lno_data_avx2: -.Lblocks_avx2_epilogue: - ret - -.align 32 -.Lbase2_64_avx2: - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 -.Lbase2_64_avx2_body: - - mov $len,%r15 # reassign $len - - mov 24($ctx),$r0 # load r - mov 32($ctx),$s1 - - mov 0($ctx),$h0 # load hash value - mov 8($ctx),$h1 - mov 16($ctx),$h2#d - - mov $s1,$r1 - mov $s1,%rax - shr \$2,$s1 - add $r1,$s1 # s1 = r1 + (r1 >> 2) - - test \$63,$len - jz .Linit_avx2 - -.Lbase2_64_pre_avx2: - add 0($inp),$h0 # accumulate input - adc 8($inp),$h1 - lea 16($inp),$inp - adc $padbit,$h2 - sub \$16,%r15 - - call __poly1305_block - mov $r1,%rax - - test \$63,%r15 - jnz .Lbase2_64_pre_avx2 - -.Linit_avx2: - ################################# base 2^64 -> base 2^26 - mov $h0,%rax - mov $h0,%rdx - shr \$52,$h0 - mov $h1,$d1 - mov $h1,$d2 - shr \$26,%rdx - and \$0x3ffffff,%rax # h[0] - shl \$12,$d1 - and \$0x3ffffff,%rdx # h[1] - shr \$14,$h1 - or $d1,$h0 - shl \$24,$h2 - and \$0x3ffffff,$h0 # h[2] - shr \$40,$d2 - and \$0x3ffffff,$h1 # h[3] - or $d2,$h2 # h[4] - - vmovd %rax#d,%x#$H0 - vmovd %rdx#d,%x#$H1 - vmovd $h0#d,%x#$H2 - vmovd $h1#d,%x#$H3 - vmovd $h2#d,%x#$H4 - movl \$1,20($ctx) # set is_base2_26 - - call __poly1305_init_avx - -.Lproceed_avx2: - mov %r15,$len - - mov 0(%rsp),%r15 - mov 8(%rsp),%r14 - mov 16(%rsp),%r13 - mov 24(%rsp),%r12 - mov 32(%rsp),%rbp - mov 40(%rsp),%rbx - lea 48(%rsp),%rax - lea 48(%rsp),%rsp -.Lbase2_64_avx2_epilogue: - jmp .Ldo_avx2 - -.align 32 -.Leven_avx2: - vmovd 4*0($ctx),%x#$H0 # load hash value base 2^26 - vmovd 4*1($ctx),%x#$H1 - vmovd 4*2($ctx),%x#$H2 - vmovd 4*3($ctx),%x#$H3 - vmovd 4*4($ctx),%x#$H4 - -.Ldo_avx2: -___ -$code.=<<___ if (!$win64); - lea -8(%rsp),%r11 - sub \$0x128,%rsp -___ -$code.=<<___ if ($win64); - lea -0xf8(%rsp),%r11 - sub \$0x1c8,%rsp - vmovdqa %xmm6,0x50(%r11) - vmovdqa %xmm7,0x60(%r11) - vmovdqa %xmm8,0x70(%r11) - vmovdqa %xmm9,0x80(%r11) - vmovdqa %xmm10,0x90(%r11) - vmovdqa %xmm11,0xa0(%r11) - vmovdqa %xmm12,0xb0(%r11) - vmovdqa %xmm13,0xc0(%r11) - vmovdqa %xmm14,0xd0(%r11) - vmovdqa %xmm15,0xe0(%r11) -.Ldo_avx2_body: -___ -$code.=<<___; - lea 48+64($ctx),$ctx # size optimization - lea .Lconst(%rip),%rcx - - # expand and copy pre-calculated table to stack - vmovdqu `16*0-64`($ctx),%x#$T2 - and \$-512,%rsp - vmovdqu `16*1-64`($ctx),%x#$T3 - vmovdqu `16*2-64`($ctx),%x#$T4 - vmovdqu `16*3-64`($ctx),%x#$D0 - vmovdqu `16*4-64`($ctx),%x#$D1 - vmovdqu `16*5-64`($ctx),%x#$D2 - vmovdqu `16*6-64`($ctx),%x#$D3 - vpermq \$0x15,$T2,$T2 # 00003412 -> 12343434 - vmovdqu `16*7-64`($ctx),%x#$D4 - vpermq \$0x15,$T3,$T3 - vpshufd \$0xc8,$T2,$T2 # 12343434 -> 14243444 - vmovdqu `16*8-64`($ctx),%x#$MASK - vpermq \$0x15,$T4,$T4 - vpshufd \$0xc8,$T3,$T3 - vmovdqa $T2,0x00(%rsp) - vpermq \$0x15,$D0,$D0 - vpshufd \$0xc8,$T4,$T4 - vmovdqa $T3,0x20(%rsp) - vpermq \$0x15,$D1,$D1 - vpshufd \$0xc8,$D0,$D0 - vmovdqa $T4,0x40(%rsp) - vpermq \$0x15,$D2,$D2 - vpshufd \$0xc8,$D1,$D1 - vmovdqa $D0,0x60(%rsp) - vpermq \$0x15,$D3,$D3 - vpshufd \$0xc8,$D2,$D2 - vmovdqa $D1,0x80(%rsp) - vpermq \$0x15,$D4,$D4 - vpshufd \$0xc8,$D3,$D3 - vmovdqa $D2,0xa0(%rsp) - vpermq \$0x15,$MASK,$MASK - vpshufd \$0xc8,$D4,$D4 - vmovdqa $D3,0xc0(%rsp) - vpshufd \$0xc8,$MASK,$MASK - vmovdqa $D4,0xe0(%rsp) - vmovdqa $MASK,0x100(%rsp) - vmovdqa 64(%rcx),$MASK # .Lmask26 - - ################################################################ - # load input - vmovdqu 16*0($inp),%x#$T0 - vmovdqu 16*1($inp),%x#$T1 - vinserti128 \$1,16*2($inp),$T0,$T0 - vinserti128 \$1,16*3($inp),$T1,$T1 - lea 16*4($inp),$inp - - vpsrldq \$6,$T0,$T2 # splat input - vpsrldq \$6,$T1,$T3 - vpunpckhqdq $T1,$T0,$T4 # 4 - vpunpcklqdq $T3,$T2,$T2 # 2:3 - vpunpcklqdq $T1,$T0,$T0 # 0:1 - - vpsrlq \$30,$T2,$T3 - vpsrlq \$4,$T2,$T2 - vpsrlq \$26,$T0,$T1 - vpsrlq \$40,$T4,$T4 # 4 - vpand $MASK,$T2,$T2 # 2 - vpand $MASK,$T0,$T0 # 0 - vpand $MASK,$T1,$T1 # 1 - vpand $MASK,$T3,$T3 # 3 - vpor 32(%rcx),$T4,$T4 # padbit, yes, always - - lea 0x90(%rsp),%rax # size optimization - vpaddq $H2,$T2,$H2 # accumulate input - sub \$64,$len - jz .Ltail_avx2 - jmp .Loop_avx2 - -.align 32 -.Loop_avx2: - ################################################################ - # ((inp[0]*r^4+r[4])*r^4+r[8])*r^4 - # ((inp[1]*r^4+r[5])*r^4+r[9])*r^3 - # ((inp[2]*r^4+r[6])*r^4+r[10])*r^2 - # ((inp[3]*r^4+r[7])*r^4+r[11])*r^1 - # \________/\________/ - ################################################################ - #vpaddq $H2,$T2,$H2 # accumulate input - vpaddq $H0,$T0,$H0 - vmovdqa `32*0`(%rsp),$T0 # r0^4 - vpaddq $H1,$T1,$H1 - vmovdqa `32*1`(%rsp),$T1 # r1^4 - vpaddq $H3,$T3,$H3 - vmovdqa `32*3`(%rsp),$T2 # r2^4 - vpaddq $H4,$T4,$H4 - vmovdqa `32*6-0x90`(%rax),$T3 # s3^4 - vmovdqa `32*8-0x90`(%rax),$S4 # s4^4 - - # d4 = h4*r0 + h3*r1 + h2*r2 + h1*r3 + h0*r4 - # d3 = h3*r0 + h2*r1 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 + h2*5*r4 - # d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4 - # - # however, as h2 is "chronologically" first one available pull - # corresponding operations up, so it's - # - # d4 = h2*r2 + h4*r0 + h3*r1 + h1*r3 + h0*r4 - # d3 = h2*r1 + h3*r0 + h1*r2 + h0*r3 + h4*5*r4 - # d2 = h2*r0 + h1*r1 + h0*r2 + h4*5*r3 + h3*5*r4 - # d1 = h2*5*r4 + h1*r0 + h0*r1 + h4*5*r2 + h3*5*r3 - # d0 = h2*5*r3 + h0*r0 + h4*5*r1 + h3*5*r2 + h1*5*r4 - - vpmuludq $H2,$T0,$D2 # d2 = h2*r0 - vpmuludq $H2,$T1,$D3 # d3 = h2*r1 - vpmuludq $H2,$T2,$D4 # d4 = h2*r2 - vpmuludq $H2,$T3,$D0 # d0 = h2*s3 - vpmuludq $H2,$S4,$D1 # d1 = h2*s4 - - vpmuludq $H0,$T1,$T4 # h0*r1 - vpmuludq $H1,$T1,$H2 # h1*r1, borrow $H2 as temp - vpaddq $T4,$D1,$D1 # d1 += h0*r1 - vpaddq $H2,$D2,$D2 # d2 += h1*r1 - vpmuludq $H3,$T1,$T4 # h3*r1 - vpmuludq `32*2`(%rsp),$H4,$H2 # h4*s1 - vpaddq $T4,$D4,$D4 # d4 += h3*r1 - vpaddq $H2,$D0,$D0 # d0 += h4*s1 - vmovdqa `32*4-0x90`(%rax),$T1 # s2 - - vpmuludq $H0,$T0,$T4 # h0*r0 - vpmuludq $H1,$T0,$H2 # h1*r0 - vpaddq $T4,$D0,$D0 # d0 += h0*r0 - vpaddq $H2,$D1,$D1 # d1 += h1*r0 - vpmuludq $H3,$T0,$T4 # h3*r0 - vpmuludq $H4,$T0,$H2 # h4*r0 - vmovdqu 16*0($inp),%x#$T0 # load input - vpaddq $T4,$D3,$D3 # d3 += h3*r0 - vpaddq $H2,$D4,$D4 # d4 += h4*r0 - vinserti128 \$1,16*2($inp),$T0,$T0 - - vpmuludq $H3,$T1,$T4 # h3*s2 - vpmuludq $H4,$T1,$H2 # h4*s2 - vmovdqu 16*1($inp),%x#$T1 - vpaddq $T4,$D0,$D0 # d0 += h3*s2 - vpaddq $H2,$D1,$D1 # d1 += h4*s2 - vmovdqa `32*5-0x90`(%rax),$H2 # r3 - vpmuludq $H1,$T2,$T4 # h1*r2 - vpmuludq $H0,$T2,$T2 # h0*r2 - vpaddq $T4,$D3,$D3 # d3 += h1*r2 - vpaddq $T2,$D2,$D2 # d2 += h0*r2 - vinserti128 \$1,16*3($inp),$T1,$T1 - lea 16*4($inp),$inp - - vpmuludq $H1,$H2,$T4 # h1*r3 - vpmuludq $H0,$H2,$H2 # h0*r3 - vpsrldq \$6,$T0,$T2 # splat input - vpaddq $T4,$D4,$D4 # d4 += h1*r3 - vpaddq $H2,$D3,$D3 # d3 += h0*r3 - vpmuludq $H3,$T3,$T4 # h3*s3 - vpmuludq $H4,$T3,$H2 # h4*s3 - vpsrldq \$6,$T1,$T3 - vpaddq $T4,$D1,$D1 # d1 += h3*s3 - vpaddq $H2,$D2,$D2 # d2 += h4*s3 - vpunpckhqdq $T1,$T0,$T4 # 4 - - vpmuludq $H3,$S4,$H3 # h3*s4 - vpmuludq $H4,$S4,$H4 # h4*s4 - vpunpcklqdq $T1,$T0,$T0 # 0:1 - vpaddq $H3,$D2,$H2 # h2 = d2 + h3*r4 - vpaddq $H4,$D3,$H3 # h3 = d3 + h4*r4 - vpunpcklqdq $T3,$T2,$T3 # 2:3 - vpmuludq `32*7-0x90`(%rax),$H0,$H4 # h0*r4 - vpmuludq $H1,$S4,$H0 # h1*s4 - vmovdqa 64(%rcx),$MASK # .Lmask26 - vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4 - vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4 - - ################################################################ - # lazy reduction (interleaved with tail of input splat) - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$D1,$H1 # h0 -> h1 - - vpsrlq \$26,$H4,$D4 - vpand $MASK,$H4,$H4 - - vpsrlq \$4,$T3,$T2 - - vpsrlq \$26,$H1,$D1 - vpand $MASK,$H1,$H1 - vpaddq $D1,$H2,$H2 # h1 -> h2 - - vpaddq $D4,$H0,$H0 - vpsllq \$2,$D4,$D4 - vpaddq $D4,$H0,$H0 # h4 -> h0 - - vpand $MASK,$T2,$T2 # 2 - vpsrlq \$26,$T0,$T1 - - vpsrlq \$26,$H2,$D2 - vpand $MASK,$H2,$H2 - vpaddq $D2,$H3,$H3 # h2 -> h3 - - vpaddq $T2,$H2,$H2 # modulo-scheduled - vpsrlq \$30,$T3,$T3 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$H1,$H1 # h0 -> h1 - - vpsrlq \$40,$T4,$T4 # 4 - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - vpand $MASK,$T0,$T0 # 0 - vpand $MASK,$T1,$T1 # 1 - vpand $MASK,$T3,$T3 # 3 - vpor 32(%rcx),$T4,$T4 # padbit, yes, always - - sub \$64,$len - jnz .Loop_avx2 - - .byte 0x66,0x90 -.Ltail_avx2: - ################################################################ - # while above multiplications were by r^4 in all lanes, in last - # iteration we multiply least significant lane by r^4 and most - # significant one by r, so copy of above except that references - # to the precomputed table are displaced by 4... - - #vpaddq $H2,$T2,$H2 # accumulate input - vpaddq $H0,$T0,$H0 - vmovdqu `32*0+4`(%rsp),$T0 # r0^4 - vpaddq $H1,$T1,$H1 - vmovdqu `32*1+4`(%rsp),$T1 # r1^4 - vpaddq $H3,$T3,$H3 - vmovdqu `32*3+4`(%rsp),$T2 # r2^4 - vpaddq $H4,$T4,$H4 - vmovdqu `32*6+4-0x90`(%rax),$T3 # s3^4 - vmovdqu `32*8+4-0x90`(%rax),$S4 # s4^4 - - vpmuludq $H2,$T0,$D2 # d2 = h2*r0 - vpmuludq $H2,$T1,$D3 # d3 = h2*r1 - vpmuludq $H2,$T2,$D4 # d4 = h2*r2 - vpmuludq $H2,$T3,$D0 # d0 = h2*s3 - vpmuludq $H2,$S4,$D1 # d1 = h2*s4 - - vpmuludq $H0,$T1,$T4 # h0*r1 - vpmuludq $H1,$T1,$H2 # h1*r1 - vpaddq $T4,$D1,$D1 # d1 += h0*r1 - vpaddq $H2,$D2,$D2 # d2 += h1*r1 - vpmuludq $H3,$T1,$T4 # h3*r1 - vpmuludq `32*2+4`(%rsp),$H4,$H2 # h4*s1 - vpaddq $T4,$D4,$D4 # d4 += h3*r1 - vpaddq $H2,$D0,$D0 # d0 += h4*s1 - - vpmuludq $H0,$T0,$T4 # h0*r0 - vpmuludq $H1,$T0,$H2 # h1*r0 - vpaddq $T4,$D0,$D0 # d0 += h0*r0 - vmovdqu `32*4+4-0x90`(%rax),$T1 # s2 - vpaddq $H2,$D1,$D1 # d1 += h1*r0 - vpmuludq $H3,$T0,$T4 # h3*r0 - vpmuludq $H4,$T0,$H2 # h4*r0 - vpaddq $T4,$D3,$D3 # d3 += h3*r0 - vpaddq $H2,$D4,$D4 # d4 += h4*r0 - - vpmuludq $H3,$T1,$T4 # h3*s2 - vpmuludq $H4,$T1,$H2 # h4*s2 - vpaddq $T4,$D0,$D0 # d0 += h3*s2 - vpaddq $H2,$D1,$D1 # d1 += h4*s2 - vmovdqu `32*5+4-0x90`(%rax),$H2 # r3 - vpmuludq $H1,$T2,$T4 # h1*r2 - vpmuludq $H0,$T2,$T2 # h0*r2 - vpaddq $T4,$D3,$D3 # d3 += h1*r2 - vpaddq $T2,$D2,$D2 # d2 += h0*r2 - - vpmuludq $H1,$H2,$T4 # h1*r3 - vpmuludq $H0,$H2,$H2 # h0*r3 - vpaddq $T4,$D4,$D4 # d4 += h1*r3 - vpaddq $H2,$D3,$D3 # d3 += h0*r3 - vpmuludq $H3,$T3,$T4 # h3*s3 - vpmuludq $H4,$T3,$H2 # h4*s3 - vpaddq $T4,$D1,$D1 # d1 += h3*s3 - vpaddq $H2,$D2,$D2 # d2 += h4*s3 - - vpmuludq $H3,$S4,$H3 # h3*s4 - vpmuludq $H4,$S4,$H4 # h4*s4 - vpaddq $H3,$D2,$H2 # h2 = d2 + h3*r4 - vpaddq $H4,$D3,$H3 # h3 = d3 + h4*r4 - vpmuludq `32*7+4-0x90`(%rax),$H0,$H4 # h0*r4 - vpmuludq $H1,$S4,$H0 # h1*s4 - vmovdqa 64(%rcx),$MASK # .Lmask26 - vpaddq $H4,$D4,$H4 # h4 = d4 + h0*r4 - vpaddq $H0,$D0,$H0 # h0 = d0 + h1*s4 - - ################################################################ - # horizontal addition - - vpsrldq \$8,$D1,$T1 - vpsrldq \$8,$H2,$T2 - vpsrldq \$8,$H3,$T3 - vpsrldq \$8,$H4,$T4 - vpsrldq \$8,$H0,$T0 - vpaddq $T1,$D1,$D1 - vpaddq $T2,$H2,$H2 - vpaddq $T3,$H3,$H3 - vpaddq $T4,$H4,$H4 - vpaddq $T0,$H0,$H0 - - vpermq \$0x2,$H3,$T3 - vpermq \$0x2,$H4,$T4 - vpermq \$0x2,$H0,$T0 - vpermq \$0x2,$D1,$T1 - vpermq \$0x2,$H2,$T2 - vpaddq $T3,$H3,$H3 - vpaddq $T4,$H4,$H4 - vpaddq $T0,$H0,$H0 - vpaddq $T1,$D1,$D1 - vpaddq $T2,$H2,$H2 - - ################################################################ - # lazy reduction - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$D1,$H1 # h0 -> h1 - - vpsrlq \$26,$H4,$D4 - vpand $MASK,$H4,$H4 - - vpsrlq \$26,$H1,$D1 - vpand $MASK,$H1,$H1 - vpaddq $D1,$H2,$H2 # h1 -> h2 - - vpaddq $D4,$H0,$H0 - vpsllq \$2,$D4,$D4 - vpaddq $D4,$H0,$H0 # h4 -> h0 - - vpsrlq \$26,$H2,$D2 - vpand $MASK,$H2,$H2 - vpaddq $D2,$H3,$H3 # h2 -> h3 - - vpsrlq \$26,$H0,$D0 - vpand $MASK,$H0,$H0 - vpaddq $D0,$H1,$H1 # h0 -> h1 - - vpsrlq \$26,$H3,$D3 - vpand $MASK,$H3,$H3 - vpaddq $D3,$H4,$H4 # h3 -> h4 - - vmovd %x#$H0,`4*0-48-64`($ctx)# save partially reduced - vmovd %x#$H1,`4*1-48-64`($ctx) - vmovd %x#$H2,`4*2-48-64`($ctx) - vmovd %x#$H3,`4*3-48-64`($ctx) - vmovd %x#$H4,`4*4-48-64`($ctx) -___ -$code.=<<___ if ($win64); - vmovdqa 0x50(%r11),%xmm6 - vmovdqa 0x60(%r11),%xmm7 - vmovdqa 0x70(%r11),%xmm8 - vmovdqa 0x80(%r11),%xmm9 - vmovdqa 0x90(%r11),%xmm10 - vmovdqa 0xa0(%r11),%xmm11 - vmovdqa 0xb0(%r11),%xmm12 - vmovdqa 0xc0(%r11),%xmm13 - vmovdqa 0xd0(%r11),%xmm14 - vmovdqa 0xe0(%r11),%xmm15 - lea 0xf8(%r11),%rsp -.Ldo_avx2_epilogue: -___ -$code.=<<___ if (!$win64); - lea 8(%r11),%rsp -___ -$code.=<<___; - vzeroupper - ret -.size poly1305_blocks_avx2,.-poly1305_blocks_avx2 -___ -} -$code.=<<___; -.align 64 -.Lconst: -.Lmask24: -.long 0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0 -.L129: -.long `1<<24`,0,`1<<24`,0,`1<<24`,0,`1<<24`,0 -.Lmask26: -.long 0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0 -.Lfive: -.long 5,0,5,0,5,0,5,0 -___ -} - -$code.=<<___; -.asciz "Poly1305 for x86_64, CRYPTOGAMS by " -.align 16 -___ - -# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, -# CONTEXT *context,DISPATCHER_CONTEXT *disp) -if ($win64) { -$rec="%rcx"; -$frame="%rdx"; -$context="%r8"; -$disp="%r9"; - -$code.=<<___; -.extern __imp_RtlVirtualUnwind -.type se_handler,\@abi-omnipotent -.align 16 -se_handler: - push %rsi - push %rdi - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - pushfq - sub \$64,%rsp - - mov 120($context),%rax # pull context->Rax - mov 248($context),%rbx # pull context->Rip - - mov 8($disp),%rsi # disp->ImageBase - mov 56($disp),%r11 # disp->HandlerData - - mov 0(%r11),%r10d # HandlerData[0] - lea (%rsi,%r10),%r10 # prologue label - cmp %r10,%rbx # context->Rip<.Lprologue - jb .Lcommon_seh_tail - - mov 152($context),%rax # pull context->Rsp - - mov 4(%r11),%r10d # HandlerData[1] - lea (%rsi,%r10),%r10 # epilogue label - cmp %r10,%rbx # context->Rip>=.Lepilogue - jae .Lcommon_seh_tail - - lea 48(%rax),%rax - - mov -8(%rax),%rbx - mov -16(%rax),%rbp - mov -24(%rax),%r12 - mov -32(%rax),%r13 - mov -40(%rax),%r14 - mov -48(%rax),%r15 - mov %rbx,144($context) # restore context->Rbx - mov %rbp,160($context) # restore context->Rbp - mov %r12,216($context) # restore context->R12 - mov %r13,224($context) # restore context->R13 - mov %r14,232($context) # restore context->R14 - mov %r15,240($context) # restore context->R14 - - jmp .Lcommon_seh_tail -.size se_handler,.-se_handler - -.type avx_handler,\@abi-omnipotent -.align 16 -avx_handler: - push %rsi - push %rdi - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - pushfq - sub \$64,%rsp - - mov 120($context),%rax # pull context->Rax - mov 248($context),%rbx # pull context->Rip - - mov 8($disp),%rsi # disp->ImageBase - mov 56($disp),%r11 # disp->HandlerData - - mov 0(%r11),%r10d # HandlerData[0] - lea (%rsi,%r10),%r10 # prologue label - cmp %r10,%rbx # context->RipRsp - - mov 4(%r11),%r10d # HandlerData[1] - lea (%rsi,%r10),%r10 # epilogue label - cmp %r10,%rbx # context->Rip>=epilogue label - jae .Lcommon_seh_tail - - mov 208($context),%rax # pull context->R11 - - lea 0x50(%rax),%rsi - lea 0xf8(%rax),%rax - lea 512($context),%rdi # &context.Xmm6 - mov \$20,%ecx - .long 0xa548f3fc # cld; rep movsq - -.Lcommon_seh_tail: - mov 8(%rax),%rdi - mov 16(%rax),%rsi - mov %rax,152($context) # restore context->Rsp - mov %rsi,168($context) # restore context->Rsi - mov %rdi,176($context) # restore context->Rdi - - mov 40($disp),%rdi # disp->ContextRecord - mov $context,%rsi # context - mov \$154,%ecx # sizeof(CONTEXT) - .long 0xa548f3fc # cld; rep movsq - - mov $disp,%rsi - xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER - mov 8(%rsi),%rdx # arg2, disp->ImageBase - mov 0(%rsi),%r8 # arg3, disp->ControlPc - mov 16(%rsi),%r9 # arg4, disp->FunctionEntry - mov 40(%rsi),%r10 # disp->ContextRecord - lea 56(%rsi),%r11 # &disp->HandlerData - lea 24(%rsi),%r12 # &disp->EstablisherFrame - mov %r10,32(%rsp) # arg5 - mov %r11,40(%rsp) # arg6 - mov %r12,48(%rsp) # arg7 - mov %rcx,56(%rsp) # arg8, (NULL) - call *__imp_RtlVirtualUnwind(%rip) - - mov \$1,%eax # ExceptionContinueSearch - add \$64,%rsp - popfq - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - pop %rdi - pop %rsi - ret -.size avx_handler,.-avx_handler - -.section .pdata -.align 4 - .rva .LSEH_begin_GFp_poly1305_init_asm - .rva .LSEH_end_GFp_poly1305_init_asm - .rva .LSEH_info_GFp_poly1305_init_asm - - .rva .LSEH_begin_GFp_poly1305_blocks - .rva .LSEH_end_GFp_poly1305_blocks - .rva .LSEH_info_GFp_poly1305_blocks - - .rva .LSEH_begin_GFp_poly1305_emit - .rva .LSEH_end_GFp_poly1305_emit - .rva .LSEH_info_GFp_poly1305_emit -___ -$code.=<<___ if ($avx); - .rva .LSEH_begin_poly1305_blocks_avx - .rva .Lbase2_64_avx - .rva .LSEH_info_poly1305_blocks_avx_1 - - .rva .Lbase2_64_avx - .rva .Leven_avx - .rva .LSEH_info_poly1305_blocks_avx_2 - - .rva .Leven_avx - .rva .LSEH_end_poly1305_blocks_avx - .rva .LSEH_info_poly1305_blocks_avx_3 - - .rva .LSEH_begin_poly1305_emit_avx - .rva .LSEH_end_poly1305_emit_avx - .rva .LSEH_info_poly1305_emit_avx -___ -$code.=<<___ if ($avx>1); - .rva .LSEH_begin_poly1305_blocks_avx2 - .rva .Lbase2_64_avx2 - .rva .LSEH_info_poly1305_blocks_avx2_1 - - .rva .Lbase2_64_avx2 - .rva .Leven_avx2 - .rva .LSEH_info_poly1305_blocks_avx2_2 - - .rva .Leven_avx2 - .rva .LSEH_end_poly1305_blocks_avx2 - .rva .LSEH_info_poly1305_blocks_avx2_3 -___ -$code.=<<___; -.section .xdata -.align 8 -.LSEH_info_GFp_poly1305_init_asm: - .byte 9,0,0,0 - .rva se_handler - .rva .LSEH_begin_GFp_poly1305_init_asm,.LSEH_begin_GFp_poly1305_init_asm - -.LSEH_info_GFp_poly1305_blocks: - .byte 9,0,0,0 - .rva se_handler - .rva .Lblocks_body,.Lblocks_epilogue - -.LSEH_info_GFp_poly1305_emit: - .byte 9,0,0,0 - .rva se_handler - .rva .LSEH_begin_GFp_poly1305_emit,.LSEH_begin_GFp_poly1305_emit -___ -$code.=<<___ if ($avx); -.LSEH_info_poly1305_blocks_avx_1: - .byte 9,0,0,0 - .rva se_handler - .rva .Lblocks_avx_body,.Lblocks_avx_epilogue # HandlerData[] - -.LSEH_info_poly1305_blocks_avx_2: - .byte 9,0,0,0 - .rva se_handler - .rva .Lbase2_64_avx_body,.Lbase2_64_avx_epilogue # HandlerData[] - -.LSEH_info_poly1305_blocks_avx_3: - .byte 9,0,0,0 - .rva avx_handler - .rva .Ldo_avx_body,.Ldo_avx_epilogue # HandlerData[] - -.LSEH_info_poly1305_emit_avx: - .byte 9,0,0,0 - .rva se_handler - .rva .LSEH_begin_poly1305_emit_avx,.LSEH_begin_poly1305_emit_avx -___ -$code.=<<___ if ($avx>1); -.LSEH_info_poly1305_blocks_avx2_1: - .byte 9,0,0,0 - .rva se_handler - .rva .Lblocks_avx2_body,.Lblocks_avx2_epilogue # HandlerData[] - -.LSEH_info_poly1305_blocks_avx2_2: - .byte 9,0,0,0 - .rva se_handler - .rva .Lbase2_64_avx2_body,.Lbase2_64_avx2_epilogue # HandlerData[] - -.LSEH_info_poly1305_blocks_avx2_3: - .byte 9,0,0,0 - .rva avx_handler - .rva .Ldo_avx2_body,.Ldo_avx2_epilogue # HandlerData[] -___ -} - -foreach (split('\n',$code)) { - s/\`([^\`]*)\`/eval($1)/ge; - s/%r([a-z]+)#d/%e$1/g; - s/%r([0-9]+)#d/%r$1d/g; - s/%x#%y/%x/g; - - print $_,"\n"; -} -close STDOUT or die "error closing STDOUT"; diff --git a/crypto/poly1305/internal.h b/crypto/poly1305/internal.h new file mode 100644 index 0000000000..98e7a482d1 --- /dev/null +++ b/crypto/poly1305/internal.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, Google Inc. + * + * 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. */ + +#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H +#define OPENSSL_HEADER_POLY1305_INTERNAL_H + +#include +#include + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define OPENSSL_POLY1305_NEON +#endif + +#endif // OPENSSL_HEADER_POLY1305_INTERNAL_H diff --git a/crypto/poly1305/poly1305.c b/crypto/poly1305/poly1305.c new file mode 100644 index 0000000000..66620580ae --- /dev/null +++ b/crypto/poly1305/poly1305.c @@ -0,0 +1,301 @@ +/* Copyright (c) 2014, Google Inc. + * + * 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. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. + +#include + +#include "internal.h" +#include "../internal.h" + + +#if !defined(BORINGSSL_HAS_UINT128) || !defined(OPENSSL_X86_64) + +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +// We can assume little-endian. +static uint32_t U8TO32_LE(const uint8_t *m) { + uint32_t r; + GFp_memcpy(&r, m, sizeof(r)); + return r; +} + +static void U32TO8_LE(uint8_t *m, uint32_t v) { + GFp_memcpy(m, &v, sizeof(v)); +} + +static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; } + +struct poly1305_state_st { + uint32_t r0, r1, r2, r3, r4; + uint32_t s1, s2, s3, s4; + uint32_t h0, h1, h2, h3, h4; + uint8_t buf[16]; + size_t buf_used; + uint8_t key[16]; +}; + +OPENSSL_STATIC_ASSERT(sizeof(struct poly1305_state_st) <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_st"); + +static inline struct poly1305_state_st *poly1305_aligned_state( + poly1305_state *state) { + dev_assert_secret(((uintptr_t)state & 63) == 0); + return (struct poly1305_state_st *)(((uintptr_t)state + 63) & ~63); +} + +// poly1305_blocks updates |state| given some amount of input data. This +// function may only be called with a |len| that is not a multiple of 16 at the +// end of the data. Otherwise the input must be buffered into 16 byte blocks. +static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in, + size_t len) { + uint32_t t0, t1, t2, t3; + uint64_t t[5]; + uint32_t b; + uint64_t c; + size_t j; + uint8_t mp[16]; + + if (len < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_16bytes: + t0 = U8TO32_LE(in); + t1 = U8TO32_LE(in + 4); + t2 = U8TO32_LE(in + 8); + t3 = U8TO32_LE(in + 12); + + in += 16; + len -= 16; + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8) | (1 << 24); + +poly1305_donna_mul: + t[0] = mul32x32_64(state->h0, state->r0) + mul32x32_64(state->h1, state->s4) + + mul32x32_64(state->h2, state->s3) + mul32x32_64(state->h3, state->s2) + + mul32x32_64(state->h4, state->s1); + t[1] = mul32x32_64(state->h0, state->r1) + mul32x32_64(state->h1, state->r0) + + mul32x32_64(state->h2, state->s4) + mul32x32_64(state->h3, state->s3) + + mul32x32_64(state->h4, state->s2); + t[2] = mul32x32_64(state->h0, state->r2) + mul32x32_64(state->h1, state->r1) + + mul32x32_64(state->h2, state->r0) + mul32x32_64(state->h3, state->s4) + + mul32x32_64(state->h4, state->s3); + t[3] = mul32x32_64(state->h0, state->r3) + mul32x32_64(state->h1, state->r2) + + mul32x32_64(state->h2, state->r1) + mul32x32_64(state->h3, state->r0) + + mul32x32_64(state->h4, state->s4); + t[4] = mul32x32_64(state->h0, state->r4) + mul32x32_64(state->h1, state->r3) + + mul32x32_64(state->h2, state->r2) + mul32x32_64(state->h3, state->r1) + + mul32x32_64(state->h4, state->r0); + + state->h0 = (uint32_t)t[0] & 0x3ffffff; + c = (t[0] >> 26); + t[1] += c; + state->h1 = (uint32_t)t[1] & 0x3ffffff; + b = (uint32_t)(t[1] >> 26); + t[2] += b; + state->h2 = (uint32_t)t[2] & 0x3ffffff; + b = (uint32_t)(t[2] >> 26); + t[3] += b; + state->h3 = (uint32_t)t[3] & 0x3ffffff; + b = (uint32_t)(t[3] >> 26); + t[4] += b; + state->h4 = (uint32_t)t[4] & 0x3ffffff; + b = (uint32_t)(t[4] >> 26); + state->h0 += b * 5; + + if (len >= 16) { + goto poly1305_donna_16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!len) { + return; + } + + for (j = 0; j < len; j++) { + mp[j] = in[j]; + } + mp[j++] = 1; + for (; j < 16; j++) { + mp[j] = 0; + } + len = 0; + + t0 = U8TO32_LE(mp + 0); + t1 = U8TO32_LE(mp + 4); + t2 = U8TO32_LE(mp + 8); + t3 = U8TO32_LE(mp + 12); + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8); + + goto poly1305_donna_mul; +} + +void GFp_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint32_t t0, t1, t2, t3; + + t0 = U8TO32_LE(key + 0); + t1 = U8TO32_LE(key + 4); + t2 = U8TO32_LE(key + 8); + t3 = U8TO32_LE(key + 12); + + // precompute multipliers + state->r0 = t0 & 0x3ffffff; + t0 >>= 26; + t0 |= t1 << 6; + state->r1 = t0 & 0x3ffff03; + t1 >>= 20; + t1 |= t2 << 12; + state->r2 = t1 & 0x3ffc0ff; + t2 >>= 14; + t2 |= t3 << 18; + state->r3 = t2 & 0x3f03fff; + t3 >>= 8; + state->r4 = t3 & 0x00fffff; + + state->s1 = state->r1 * 5; + state->s2 = state->r2 * 5; + state->s3 = state->r3 * 5; + state->s4 = state->r4 * 5; + + // init state + state->h0 = 0; + state->h1 = 0; + state->h2 = 0; + state->h3 = 0; + state->h4 = 0; + + state->buf_used = 0; + GFp_memcpy(state->key, key + 16, sizeof(state->key)); +} + +void GFp_poly1305_update(poly1305_state *statep, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + + if (state->buf_used) { + size_t todo = 16 - state->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (size_t i = 0; i < todo; i++) { + state->buf[state->buf_used + i] = in[i]; + } + state->buf_used += todo; + in_len -= todo; + in += todo; + + if (state->buf_used == 16) { + poly1305_update(state, state->buf, 16); + state->buf_used = 0; + } + } + + if (in_len >= 16) { + size_t todo = in_len & ~0xf; + poly1305_update(state, in, todo); + in += todo; + in_len &= 0xf; + } + + if (in_len) { + for (size_t i = 0; i < in_len; i++) { + state->buf[i] = in[i]; + } + state->buf_used = in_len; + } +} + +void GFp_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint64_t f0, f1, f2, f3; + uint32_t g0, g1, g2, g3, g4; + uint32_t b, nb; + + if (state->buf_used) { + poly1305_update(state, state->buf, state->buf_used); + } + + b = state->h0 >> 26; + state->h0 = state->h0 & 0x3ffffff; + state->h1 += b; + b = state->h1 >> 26; + state->h1 = state->h1 & 0x3ffffff; + state->h2 += b; + b = state->h2 >> 26; + state->h2 = state->h2 & 0x3ffffff; + state->h3 += b; + b = state->h3 >> 26; + state->h3 = state->h3 & 0x3ffffff; + state->h4 += b; + b = state->h4 >> 26; + state->h4 = state->h4 & 0x3ffffff; + state->h0 += b * 5; + + g0 = state->h0 + 5; + b = g0 >> 26; + g0 &= 0x3ffffff; + g1 = state->h1 + b; + b = g1 >> 26; + g1 &= 0x3ffffff; + g2 = state->h2 + b; + b = g2 >> 26; + g2 &= 0x3ffffff; + g3 = state->h3 + b; + b = g3 >> 26; + g3 &= 0x3ffffff; + g4 = state->h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + state->h0 = (state->h0 & nb) | (g0 & b); + state->h1 = (state->h1 & nb) | (g1 & b); + state->h2 = (state->h2 & nb) | (g2 & b); + state->h3 = (state->h3 & nb) | (g3 & b); + state->h4 = (state->h4 & nb) | (g4 & b); + + f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]); + f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)U8TO32_LE(&state->key[4]); + f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)U8TO32_LE(&state->key[8]); + f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)U8TO32_LE(&state->key[12]); + + U32TO8_LE(&mac[0], (uint32_t)f0); + f1 += (f0 >> 32); + U32TO8_LE(&mac[4], (uint32_t)f1); + f2 += (f1 >> 32); + U32TO8_LE(&mac[8], (uint32_t)f2); + f3 += (f2 >> 32); + U32TO8_LE(&mac[12], (uint32_t)f3); +} + +#endif // !BORINGSSL_HAS_UINT128 || !OPENSSL_X86_64 diff --git a/crypto/poly1305/poly1305_arm.c b/crypto/poly1305/poly1305_arm.c new file mode 100644 index 0000000000..3b00a9f2f3 --- /dev/null +++ b/crypto/poly1305/poly1305_arm.c @@ -0,0 +1,307 @@ +/* Copyright (c) 2014, Google Inc. + * + * 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. */ + +// This implementation was taken from the public domain, neon2 version in +// SUPERCOP by D. J. Bernstein and Peter Schwabe. + +#include + +#include "internal.h" +#include "../internal.h" + + +#if defined(OPENSSL_POLY1305_NEON) + +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wcast-align" + +typedef struct { + uint32_t v[12]; // for alignment; only using 10 +} fe1305x2; + +#define addmulmod GFp_poly1305_neon2_addmulmod +#define blocks GFp_poly1305_neon2_blocks + +extern void addmulmod(fe1305x2 *r, const fe1305x2 *x, const fe1305x2 *y, + const fe1305x2 *c); + +extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in, + size_t inlen); + +static void freeze(fe1305x2 *r) { + int i; + + uint32_t x0 = r->v[0]; + uint32_t x1 = r->v[2]; + uint32_t x2 = r->v[4]; + uint32_t x3 = r->v[6]; + uint32_t x4 = r->v[8]; + uint32_t y0; + uint32_t y1; + uint32_t y2; + uint32_t y3; + uint32_t y4; + uint32_t swap; + + for (i = 0; i < 3; ++i) { + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + x0 += 5 * (x4 >> 26); + x4 &= 0x3ffffff; + } + + y0 = x0 + 5; + y1 = x1 + (y0 >> 26); + y0 &= 0x3ffffff; + y2 = x2 + (y1 >> 26); + y1 &= 0x3ffffff; + y3 = x3 + (y2 >> 26); + y2 &= 0x3ffffff; + y4 = x4 + (y3 >> 26); + y3 &= 0x3ffffff; + swap = -(y4 >> 26); + y4 &= 0x3ffffff; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + y0 &= swap; + y1 &= swap; + y2 &= swap; + y3 &= swap; + y4 &= swap; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + r->v[0] = y0; + r->v[2] = y1; + r->v[4] = y2; + r->v[6] = y3; + r->v[8] = y4; +} + +static void store32(uint8_t out[4], uint32_t v) { GFp_memcpy(out, &v, 4); } + +// load32 exists to avoid breaking strict aliasing rules in +// fe1305x2_frombytearray. +static uint32_t load32(const uint8_t t[4]) { + uint32_t tmp; + GFp_memcpy(&tmp, t, sizeof(tmp)); + return tmp; +} + +static void fe1305x2_tobytearray(uint8_t r[16], fe1305x2 *x) { + uint32_t x0 = x->v[0]; + uint32_t x1 = x->v[2]; + uint32_t x2 = x->v[4]; + uint32_t x3 = x->v[6]; + uint32_t x4 = x->v[8]; + + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + + store32(r, x0 + (x1 << 26)); + store32(r + 4, (x1 >> 6) + (x2 << 20)); + store32(r + 8, (x2 >> 12) + (x3 << 14)); + store32(r + 12, (x3 >> 18) + (x4 << 8)); +} + +static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x, size_t xlen) { + size_t i; + uint8_t t[17]; + + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + xlen -= i; + x += i; + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[0] = 0x3ffffff & load32(t); + r->v[2] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[4] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[6] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[8] = load32(t + 13); + + if (xlen) { + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[1] = 0x3ffffff & load32(t); + r->v[3] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[5] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[7] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[9] = load32(t + 13); + } else { + r->v[1] = r->v[3] = r->v[5] = r->v[7] = r->v[9] = 0; + } +} + +static const alignas(16) fe1305x2 zero; + +struct poly1305_state_st { + uint8_t data[sizeof(fe1305x2[5]) + 128]; + uint8_t buf[32]; + size_t buf_used; + uint8_t key[16]; +}; + +OPENSSL_STATIC_ASSERT(sizeof(struct poly1305_state_st) <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_st"); + +void GFp_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + r->v[1] = r->v[0] = 0x3ffffff & load32(key); + r->v[3] = r->v[2] = 0x3ffff03 & (load32(key + 3) >> 2); + r->v[5] = r->v[4] = 0x3ffc0ff & (load32(key + 6) >> 4); + r->v[7] = r->v[6] = 0x3f03fff & (load32(key + 9) >> 6); + r->v[9] = r->v[8] = 0x00fffff & (load32(key + 12) >> 8); + + for (size_t j = 0; j < 10; j++) { + h->v[j] = 0; // XXX: should fast-forward a bit + } + + addmulmod(precomp, r, r, &zero); // precompute r^2 + addmulmod(precomp + 1, precomp, precomp, &zero); // precompute r^4 + + GFp_memcpy(st->key, key + 16, 16); + st->buf_used = 0; +} + +void GFp_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + if (st->buf_used) { + size_t todo = 32 - st->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (size_t i = 0; i < todo; i++) { + st->buf[st->buf_used + i] = in[i]; + } + st->buf_used += todo; + in_len -= todo; + in += todo; + + if (st->buf_used == sizeof(st->buf) && in_len) { + addmulmod(h, h, precomp, &zero); + fe1305x2_frombytearray(c, st->buf, sizeof(st->buf)); + for (size_t i = 0; i < 10; i++) { + h->v[i] += c->v[i]; + } + st->buf_used = 0; + } + } + + while (in_len > 32) { + size_t tlen = 1048576; + if (in_len < tlen) { + tlen = in_len; + } + tlen -= blocks(h, precomp, in, tlen); + in_len -= tlen; + in += tlen; + } + + if (in_len) { + for (size_t i = 0; i < in_len; i++) { + st->buf[i] = in[i]; + } + st->buf_used = in_len; + } +} + +void GFp_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + addmulmod(h, h, precomp, &zero); + + if (st->buf_used > 16) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + precomp->v[1] = r->v[1]; + precomp->v[3] = r->v[3]; + precomp->v[5] = r->v[5]; + precomp->v[7] = r->v[7]; + precomp->v[9] = r->v[9]; + addmulmod(h, h, precomp, c); + } else if (st->buf_used > 0) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + r->v[1] = 1; + r->v[3] = 0; + r->v[5] = 0; + r->v[7] = 0; + r->v[9] = 0; + addmulmod(h, h, r, c); + } + + h->v[0] += h->v[1]; + h->v[2] += h->v[3]; + h->v[4] += h->v[5]; + h->v[6] += h->v[7]; + h->v[8] += h->v[9]; + freeze(h); + + fe1305x2_frombytearray(c, st->key, 16); + c->v[8] ^= (1 << 24); + + h->v[0] += c->v[0]; + h->v[2] += c->v[2]; + h->v[4] += c->v[4]; + h->v[6] += c->v[6]; + h->v[8] += c->v[8]; + fe1305x2_tobytearray(mac, h); +} + +#endif // OPENSSL_POLY1305_NEON diff --git a/crypto/poly1305/poly1305_arm_asm.S b/crypto/poly1305/poly1305_arm_asm.S new file mode 100644 index 0000000000..24ae435fdd --- /dev/null +++ b/crypto/poly1305/poly1305_arm_asm.S @@ -0,0 +1,2031 @@ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if defined(__arm__) && !defined(OPENSSL_NO_ASM) && !defined(__APPLE__) + +#pragma GCC diagnostic ignored "-Wlanguage-extension-token" + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +# This implementation was taken from the public domain, neon2 version in +# SUPERCOP by D. J. Bernstein and Peter Schwabe. + +# qhasm: int32 input_0 + +# qhasm: int32 input_1 + +# qhasm: int32 input_2 + +# qhasm: int32 input_3 + +# qhasm: stack32 input_4 + +# qhasm: stack32 input_5 + +# qhasm: stack32 input_6 + +# qhasm: stack32 input_7 + +# qhasm: int32 caller_r4 + +# qhasm: int32 caller_r5 + +# qhasm: int32 caller_r6 + +# qhasm: int32 caller_r7 + +# qhasm: int32 caller_r8 + +# qhasm: int32 caller_r9 + +# qhasm: int32 caller_r10 + +# qhasm: int32 caller_r11 + +# qhasm: int32 caller_r12 + +# qhasm: int32 caller_r14 + +# qhasm: reg128 caller_q4 + +# qhasm: reg128 caller_q5 + +# qhasm: reg128 caller_q6 + +# qhasm: reg128 caller_q7 + +# qhasm: startcode +.fpu neon +.text + +# qhasm: reg128 r0 + +# qhasm: reg128 r1 + +# qhasm: reg128 r2 + +# qhasm: reg128 r3 + +# qhasm: reg128 r4 + +# qhasm: reg128 x01 + +# qhasm: reg128 x23 + +# qhasm: reg128 x4 + +# qhasm: reg128 y0 + +# qhasm: reg128 y12 + +# qhasm: reg128 y34 + +# qhasm: reg128 5y12 + +# qhasm: reg128 5y34 + +# qhasm: stack128 y0_stack + +# qhasm: stack128 y12_stack + +# qhasm: stack128 y34_stack + +# qhasm: stack128 5y12_stack + +# qhasm: stack128 5y34_stack + +# qhasm: reg128 z0 + +# qhasm: reg128 z12 + +# qhasm: reg128 z34 + +# qhasm: reg128 5z12 + +# qhasm: reg128 5z34 + +# qhasm: stack128 z0_stack + +# qhasm: stack128 z12_stack + +# qhasm: stack128 z34_stack + +# qhasm: stack128 5z12_stack + +# qhasm: stack128 5z34_stack + +# qhasm: stack128 two24 + +# qhasm: int32 ptr + +# qhasm: reg128 c01 + +# qhasm: reg128 c23 + +# qhasm: reg128 d01 + +# qhasm: reg128 d23 + +# qhasm: reg128 t0 + +# qhasm: reg128 t1 + +# qhasm: reg128 t2 + +# qhasm: reg128 t3 + +# qhasm: reg128 t4 + +# qhasm: reg128 mask + +# qhasm: reg128 u0 + +# qhasm: reg128 u1 + +# qhasm: reg128 u2 + +# qhasm: reg128 u3 + +# qhasm: reg128 u4 + +# qhasm: reg128 v01 + +# qhasm: reg128 mid + +# qhasm: reg128 v23 + +# qhasm: reg128 v4 + +# qhasm: int32 len + +# qhasm: qpushenter crypto_onetimeauth_poly1305_neon2_blocks +.align 4 +.global GFp_poly1305_neon2_blocks +.hidden GFp_poly1305_neon2_blocks +.type GFp_poly1305_neon2_blocks STT_FUNC +GFp_poly1305_neon2_blocks: +vpush {q4,q5,q6,q7} +mov r12,sp +sub sp,sp,#192 +bic sp,sp,#31 + +# qhasm: len = input_3 +# asm 1: mov >len=int32#4,len=r3,y12=reg128#2%bot->y12=reg128#2%top},[y12=d2->y12=d3},[y34=reg128#3%bot->y34=reg128#3%top},[y34=d4->y34=d5},[input_1=int32#2,input_1=r1,z12=reg128#5%bot->z12=reg128#5%top},[z12=d8->z12=d9},[z34=reg128#6%bot->z34=reg128#6%top},[z34=d10->z34=d11},[mask=reg128#7,#0xffffffff +# asm 2: vmov.i64 >mask=q6,#0xffffffff +vmov.i64 q6,#0xffffffff + +# qhasm: 2x u4 = 0xff +# asm 1: vmov.i64 >u4=reg128#8,#0xff +# asm 2: vmov.i64 >u4=q7,#0xff +vmov.i64 q7,#0xff + +# qhasm: x01 aligned= mem128[input_0];input_0+=16 +# asm 1: vld1.8 {>x01=reg128#9%bot->x01=reg128#9%top},[x01=d16->x01=d17},[x23=reg128#10%bot->x23=reg128#10%top},[x23=d18->x23=d19},[input_0=int32#1,input_0=r0,>=6 +# asm 1: vshr.u64 >mask=reg128#7,mask=q6,>= 7 +# asm 1: vshr.u64 >u4=reg128#8,u4=q7,5y12=reg128#12,5y12=q11,5y34=reg128#13,5y34=q12,5y12=reg128#12,<5y12=reg128#12,5y12=q11,<5y12=q11,5y34=reg128#13,<5y34=reg128#13,5y34=q12,<5y34=q12,u4=reg128#8,u4=q7,5z12=reg128#14,5z12=q13,5z34=reg128#15,5z34=q14,5z12=reg128#14,<5z12=reg128#14,5z12=q13,<5z12=q13,5z34=reg128#15,<5z34=reg128#15,5z34=q14,<5z34=q14,ptr=int32#2,ptr=r1,r4=reg128#16,r4=q15,r0=reg128#8,r0=q7,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,ptr=r1,ptr=int32#2,<5y12_stack=stack128#5 +# asm 2: lea >ptr=r1,<5y12_stack=[sp,#64] +add r1,sp,#64 + +# qhasm: mem128[ptr] aligned= 5y12 +# asm 1: vst1.8 {<5y12=reg128#12%bot-<5y12=reg128#12%top},[ptr=int32#2,<5y34_stack=stack128#6 +# asm 2: lea >ptr=r1,<5y34_stack=[sp,#80] +add r1,sp,#80 + +# qhasm: mem128[ptr] aligned= 5y34 +# asm 1: vst1.8 {<5y34=reg128#13%bot-<5y34=reg128#13%top},[ptr=int32#2,<5z12_stack=stack128#10 +# asm 2: lea >ptr=r1,<5z12_stack=[sp,#144] +add r1,sp,#144 + +# qhasm: mem128[ptr] aligned= 5z12 +# asm 1: vst1.8 {<5z12=reg128#14%bot-<5z12=reg128#14%top},[ptr=int32#2,<5z34_stack=stack128#11 +# asm 2: lea >ptr=r1,<5z34_stack=[sp,#160] +add r1,sp,#160 + +# qhasm: mem128[ptr] aligned= 5z34 +# asm 1: vst1.8 {<5z34=reg128#15%bot-<5z34=reg128#15%top},[? len - 64 +# asm 1: cmp +bls ._below64bytes + +# qhasm: input_2 += 32 +# asm 1: add >input_2=int32#2,input_2=r1,c01=reg128#1%bot->c01=reg128#1%top},[c01=d0->c01=d1},[c23=reg128#2%bot->c23=reg128#2%top},[c23=d2->c23=d3},[ptr=int32#3,ptr=r2,z12=reg128#3%bot->z12=reg128#3%top},[z12=d4->z12=d5},[ptr=int32#3,ptr=r2,z0=reg128#4%bot->z0=reg128#4%top},[z0=d6->z0=d7},[r3=reg128#5,r3=q4,input_2=int32#2,input_2=r1,ptr=int32#3,<5z34_stack=stack128#11 +# asm 2: lea >ptr=r2,<5z34_stack=[sp,#160] +add r2,sp,#160 + +# qhasm: 5z34 aligned= mem128[ptr] +# asm 1: vld1.8 {>5z34=reg128#6%bot->5z34=reg128#6%top},[5z34=d10->5z34=d11},[r0=reg128#8,r0=q7,r2=reg128#14,r2=q13,d01=reg128#12%bot->d01=reg128#12%top},[d01=d22->d01=d23},[r1=reg128#15,r1=q14,ptr=int32#3,<5z12_stack=stack128#10 +# asm 2: lea >ptr=r2,<5z12_stack=[sp,#144] +add r2,sp,#144 + +# qhasm: 5z12 aligned= mem128[ptr] +# asm 1: vld1.8 {>5z12=reg128#1%bot->5z12=reg128#1%top},[5z12=d0->5z12=d1},[d23=reg128#2%bot->d23=reg128#2%top},[d23=d2->d23=d3},[input_2=int32#2,input_2=r1,> 40 +# asm 1: vshr.u64 >v4=reg128#4,v4=q3,> 14; v23[3] = d23[2,3] unsigned>> 14 +# asm 1: vshrn.u64 > 26; v01[3] = d01[2,3] unsigned>> 26 +# asm 1: vshrn.u64 > 20; v23[1] = mid[2,3] unsigned>> 20 +# asm 1: vshrn.u64 ptr=int32#3,ptr=r2,y34=reg128#3%bot->y34=reg128#3%top},[y34=d4->y34=d5},[ptr=int32#3,ptr=r2,y12=reg128#2%bot->y12=reg128#2%top},[y12=d2->y12=d3},[ptr=int32#3,ptr=r2,y0=reg128#1%bot->y0=reg128#1%top},[y0=d0->y0=d1},[ptr=int32#3,<5y34_stack=stack128#6 +# asm 2: lea >ptr=r2,<5y34_stack=[sp,#80] +add r2,sp,#80 + +# qhasm: 5y34 aligned= mem128[ptr] +# asm 1: vld1.8 {>5y34=reg128#13%bot->5y34=reg128#13%top},[5y34=d24->5y34=d25},[ptr=int32#3,<5y12_stack=stack128#5 +# asm 2: lea >ptr=r2,<5y12_stack=[sp,#64] +add r2,sp,#64 + +# qhasm: 5y12 aligned= mem128[ptr] +# asm 1: vld1.8 {>5y12=reg128#12%bot->5y12=reg128#12%top},[5y12=d22->5y12=d23},[ptr=int32#3,ptr=r2,> 26 +# asm 1: vshr.u64 >t1=reg128#4,t1=q3,len=int32#4,len=r3,r0=reg128#6,r0=q5,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#8,t4=q7,r3=reg128#5,r3=q4,x4=reg128#8,x4=q7,r4=reg128#16%bot->r4=reg128#16%top},[r4=d30->r4=d31},[> 26 +# asm 1: vshr.u64 >t2=reg128#9,t2=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t0=reg128#10,t0=q9,r2=reg128#9,r2=q8,x4=reg128#11,x4=q10,x01=reg128#6,x01=q5,r0=reg128#8%bot->r0=reg128#8%top},[r0=d14->r0=d15},[ptr=int32#3,ptr=r2,t0=reg128#10,t0=q9,> 26 +# asm 1: vshr.u64 >t3=reg128#14,t3=q13,x01=reg128#15,x01=q14,z34=reg128#6%bot->z34=reg128#6%top},[z34=d10->z34=d11},[x23=reg128#10,x23=q9,r3=reg128#5,r3=q4,input_2=int32#2,input_2=r1,> 26 +# asm 1: vshr.u64 >t1=reg128#14,t1=q13,x01=reg128#9,x01=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#14,t4=q13,r3=reg128#5,r3=q4,x4=reg128#11,x4=q10,? len - 64 +# asm 1: cmp +bhi ._mainloop2 + +# qhasm: input_2 -= 32 +# asm 1: sub >input_2=int32#3,input_2=r2,? len - 32 +# asm 1: cmp +bls ._end + +# qhasm: mainloop: +._mainloop: + +# qhasm: new r0 + +# qhasm: ptr = &two24 +# asm 1: lea >ptr=int32#2,ptr=r1,r4=reg128#5%bot->r4=reg128#5%top},[r4=d8->r4=d9},[u4=reg128#6%bot->u4=reg128#6%top},[u4=d10->u4=d11},[c01=reg128#8%bot->c01=reg128#8%top},[c01=d14->c01=d15},[c23=reg128#14%bot->c23=reg128#14%top},[c23=d26->c23=d27},[r0=reg128#4,r0=q3,r3=reg128#6,r3=q5,r1=reg128#14,r1=q13,r2=reg128#8,r2=q7,> 26 +# asm 1: vshr.u64 >t1=reg128#9,t1=q8,r0=reg128#4,r0=q3,r1=reg128#9,r1=q8,> 26 +# asm 1: vshr.u64 >t4=reg128#10,t4=q9,r3=reg128#6,r3=q5,r4=reg128#5,r4=q4,> 26 +# asm 1: vshr.u64 >t2=reg128#10,t2=q9,r1=reg128#11,r1=q10,> 26 +# asm 1: vshr.u64 >t0=reg128#9,t0=q8,r2=reg128#8,r2=q7,r4=reg128#5,r4=q4,r0=reg128#4,r0=q3,t0=reg128#9,t0=q8,> 26 +# asm 1: vshr.u64 >t3=reg128#14,t3=q13,r0=reg128#4,r0=q3,x23=reg128#10,x23=q9,r3=reg128#6,r3=q5,> 26 +# asm 1: vshr.u64 >t1=reg128#8,t1=q7,x01=reg128#9,x01=q8,r1=reg128#4,r1=q3,> 26 +# asm 1: vshr.u64 >t4=reg128#8,t4=q7,r3=reg128#6,r3=q5,x4=reg128#11,x4=q10,len=int32#4,len=r3,? len - 32 +# asm 1: cmp +bhi ._mainloop + +# qhasm: end: +._end: + +# qhasm: mem128[input_0] = x01;input_0+=16 +# asm 1: vst1.8 {len=int32#1,len=r0,mask=reg128#1,#0xffffffff +# asm 2: vmov.i64 >mask=q0,#0xffffffff +vmov.i64 q0,#0xffffffff + +# qhasm: y01 aligned= mem128[input_2];input_2+=16 +# asm 1: vld1.8 {>y01=reg128#2%bot->y01=reg128#2%top},[y01=d2->y01=d3},[_5y01=reg128#3,_5y01=q2,y23=reg128#4%bot->y23=reg128#4%top},[y23=d6->y23=d7},[_5y23=reg128#9,_5y23=q8,_5y4=reg128#11,_5y4=q10,x01=reg128#12%bot->x01=reg128#12%top},[x01=d22->x01=d23},[_5y01=reg128#3,<_5y01=reg128#3,_5y01=q2,<_5y01=q2,x23=reg128#13%bot->x23=reg128#13%top},[x23=d24->x23=d25},[_5y23=reg128#9,<_5y23=reg128#9,_5y23=q8,<_5y23=q8,_5y4=reg128#11,<_5y4=reg128#11,_5y4=q10,<_5y4=q10,c01=reg128#14%bot->c01=reg128#14%top},[c01=d26->c01=d27},[x01=reg128#12,x01=q11,c23=reg128#14%bot->c23=reg128#14%top},[c23=d26->c23=d27},[x23=reg128#13,x23=q12,>=6 +# asm 1: vshr.u64 >mask=reg128#1,mask=q0,x4=reg128#14,x4=q13,r0=reg128#15,r0=q14,r1=reg128#3,r1=q2,r2=reg128#16,r2=q15,r3=reg128#9,r3=q8,r4=reg128#10,r4=q9,> 26 +# asm 1: vshr.u64 >t1=reg128#2,t1=q1,r0=reg128#4,r0=q3,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t4=reg128#3,t4=q2,r3=reg128#9,r3=q8,r4=reg128#3,r4=q2,> 26 +# asm 1: vshr.u64 >t2=reg128#10,t2=q9,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t0=reg128#11,t0=q10,r2=reg128#10,r2=q9,r4=reg128#3,r4=q2,r0=reg128#4,r0=q3,t0=reg128#11,t0=q10,> 26 +# asm 1: vshr.u64 >t3=reg128#12,t3=q11,r0=reg128#4,r0=q3,x23=reg128#10,x23=q9,r3=reg128#9,r3=q8,> 26 +# asm 1: vshr.u64 >t1=reg128#11,t1=q10,x01=reg128#4,x01=q3,r1=reg128#2,r1=q1,> 26 +# asm 1: vshr.u64 >t4=reg128#11,t4=q10,r3=reg128#1,r3=q0,x4=reg128#3,x4=q2, + +#include "internal.h" +#include "../internal.h" + + +#if defined(BORINGSSL_HAS_UINT128) && defined(OPENSSL_X86_64) + +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wsign-conversion" + +#include + +static uint32_t load_u32_le(const uint8_t in[4]) { + uint32_t ret; + GFp_memcpy(&ret, in, 4); + return ret; +} + +static uint64_t load_u64_le(const uint8_t in[8]) { + uint64_t ret; + GFp_memcpy(&ret, in, 8); + return ret; +} + +static void store_u64_le(uint8_t out[8], uint64_t v) { + GFp_memcpy(out, &v, 8); +} + +typedef __m128i xmmi; + +static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = { + (1 << 26) - 1, 0, (1 << 26) - 1, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = { + (1 << 24), 0, (1 << 24), 0}; + +static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; } + +static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; } + +static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) { + return (uint128_t)a * b; +} + +static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; } + +static inline uint64_t shr128(uint128_t v, const int shift) { + return (uint64_t)(v >> shift); +} + +static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) { + return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift); +} + +typedef struct poly1305_power_t { + union { + xmmi v; + uint64_t u[2]; + uint32_t d[4]; + } R20, R21, R22, R23, R24, S21, S22, S23, S24; +} poly1305_power; + +typedef struct poly1305_state_internal_t { + poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 + bytes of free storage */ + union { + xmmi H[5]; // 80 bytes + uint64_t HH[10]; + }; + // uint64_t r0,r1,r2; [24 bytes] + // uint64_t pad0,pad1; [16 bytes] + uint64_t started; // 8 bytes + uint64_t leftover; // 8 bytes + uint8_t buffer[64]; // 64 bytes +} poly1305_state_internal; /* 448 bytes total + 63 bytes for + alignment = 511 bytes raw */ + +OPENSSL_STATIC_ASSERT(sizeof(poly1305_state_internal) <= sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned poly1305_state_internal"); + +static inline poly1305_state_internal *poly1305_aligned_state( + poly1305_state *state) { + dev_assert_secret(((uintptr_t)state & 63) == 0); + return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63); +} + +static inline size_t poly1305_min(size_t a, size_t b) { + return (a < b) ? a : b; +} + +void GFp_poly1305_init(poly1305_state *state, const uint8_t key[32]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + poly1305_power *p; + uint64_t r0, r1, r2; + uint64_t t0, t1; + + // clamp key + t0 = load_u64_le(key + 0); + t1 = load_u64_le(key + 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + // store r in un-used space of st->P[1] + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + + // store pad + p->R23.d[1] = load_u32_le(key + 16); + p->R23.d[3] = load_u32_le(key + 20); + p->R24.d[1] = load_u32_le(key + 24); + p->R24.d[3] = load_u32_le(key + 28); + + // H = 0 + st->H[0] = _mm_setzero_si128(); + st->H[1] = _mm_setzero_si128(); + st->H[2] = _mm_setzero_si128(); + st->H[3] = _mm_setzero_si128(); + st->H[4] = _mm_setzero_si128(); + + st->started = 0; + st->leftover = 0; +} + +static void poly1305_first_block(poly1305_state_internal *st, + const uint8_t *m) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + xmmi T5, T6; + poly1305_power *p; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t r20, r21, r22, s22; + uint64_t pad0, pad1; + uint64_t c; + uint64_t i; + + // pull out stored info + p = &st->P[1]; + + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + + // compute powers r^2,r^4 + r20 = r0; + r21 = r1; + r22 = r2; + for (i = 0; i < 2; i++) { + s22 = r22 * (5 << 2); + + d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22)); + d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21)); + d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20)); + + r20 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + r21 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + r22 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + r20 += c * 5; + c = (r20 >> 44); + r20 = r20 & 0xfffffffffff; + r21 += c; + + p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R21.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R22.v = + _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R23.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), + _MM_SHUFFLE(1, 0, 1, 0)); + p->S21.v = _mm_mul_epu32(p->R21.v, FIVE); + p->S22.v = _mm_mul_epu32(p->R22.v, FIVE); + p->S23.v = _mm_mul_epu32(p->R23.v, FIVE); + p->S24.v = _mm_mul_epu32(p->R24.v, FIVE); + p--; + } + + // put saved info back + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + p->R23.d[1] = (uint32_t)(pad0); + p->R23.d[3] = (uint32_t)(pad0 >> 32); + p->R24.d[1] = (uint32_t)(pad1); + p->R24.d[3] = (uint32_t)(pad1 >> 32); + + // H = [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + st->H[0] = _mm_and_si128(MMASK, T5); + st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + st->H[2] = _mm_and_si128(MMASK, T5); + st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); +} + +static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi M0, M1, M2, M3, M4; + xmmi C1, C2; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + while (bytes >= 64) { + // H *= [r^4,r^4] + p = &st->P[0]; + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My]*[r^2,r^2] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + p = &st->P[1]; + T5 = _mm_mul_epu32(M0, p->R20.v); + T6 = _mm_mul_epu32(M0, p->R21.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M1, p->S24.v); + T6 = _mm_mul_epu32(M1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M2, p->S23.v); + T6 = _mm_mul_epu32(M2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M3, p->S22.v); + T6 = _mm_mul_epu32(M3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M4, p->S21.v); + T6 = _mm_mul_epu32(M4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M0, p->R22.v); + T6 = _mm_mul_epu32(M0, p->R23.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M1, p->R21.v); + T6 = _mm_mul_epu32(M1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M2, p->R20.v); + T6 = _mm_mul_epu32(M2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M3, p->S24.v); + T6 = _mm_mul_epu32(M3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M4, p->S23.v); + T6 = _mm_mul_epu32(M4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M0, p->R24.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)), + _mm_loadl_epi64((const xmmi *)(m + 48))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)), + _mm_loadl_epi64((const xmmi *)(m + 56))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + 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, M4); + + // 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^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; + } + + st->H[0] = H0; + st->H[1] = H1; + st->H[2] = H2; + st->H[3] = H3; + st->H[4] = H4; +} + +static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi M0, M1, M2, M3, M4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi C1, C2; + + uint64_t r0, r1, r2; + uint64_t t0, t1, t2, t3, t4; + uint64_t c; + size_t consumed = 0; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + // p = [r^2,r^2] + p = &st->P[1]; + + if (bytes >= 32) { + // H *= [r^2,r^2] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + 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, M4); + + // 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; + + consumed = 32; + } + + // finalize, H *= [r^2,r] + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + + p->R20.d[2] = (uint32_t)(r0)&0x3ffffff; + p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + p->R24.d[2] = (uint32_t)((r2 >> 16)); + p->S21.d[2] = p->R21.d[2] * 5; + p->S22.d[2] = p->R22.d[2] * 5; + p->S23.d[2] = p->R23.d[2] * 5; + p->S24.d[2] = p->R24.d[2] * 5; + + // H *= [r^2,r] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + 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[0]+H[1] + H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(H0); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(H1) + c; + c = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(H2) + c; + c = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(H3) + c; + c = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(H4) + c; + c = (t4 >> 26); + t4 &= 0x3ffffff; + t0 = t0 + (c * 5); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = t1 + c; + + st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff); + st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff); + st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff); + + return consumed; +} + +void GFp_poly1305_update(poly1305_state *state, const uint8_t *m, + size_t bytes) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t want; + + // Work around a C language bug. See https://crbug.com/1019588. + if (bytes == 0) { + return; + } + + // need at least 32 initial bytes to start the accelerated branch + if (!st->started) { + if ((st->leftover == 0) && (bytes > 32)) { + poly1305_first_block(st, m); + m += 32; + bytes -= 32; + } else { + want = poly1305_min(32 - st->leftover, bytes); + GFp_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if ((st->leftover < 32) || (bytes == 0)) { + return; + } + poly1305_first_block(st, st->buffer); + st->leftover = 0; + } + st->started = 1; + } + + // handle leftover + if (st->leftover) { + want = poly1305_min(64 - st->leftover, bytes); + GFp_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < 64) { + return; + } + poly1305_blocks(st, st->buffer, 64); + st->leftover = 0; + } + + // process 64 byte blocks + if (bytes >= 64) { + want = (bytes & ~63); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + if (bytes) { + GFp_memcpy(st->buffer + st->leftover, m, bytes); + st->leftover += bytes; + } +} + +void GFp_poly1305_finish(poly1305_state *state, uint8_t mac[16]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t leftover = st->leftover; + uint8_t *m = st->buffer; + uint128_t d[3]; + uint64_t h0, h1, h2; + uint64_t t0, t1; + uint64_t g0, g1, g2, c, nc; + uint64_t r0, r1, r2, s1, s2; + poly1305_power *p; + + if (st->started) { + size_t consumed = poly1305_combine(st, m, leftover); + leftover -= consumed; + m += consumed; + } + + // st->HH will either be 0 or have the combined result + h0 = st->HH[0]; + h1 = st->HH[1]; + h2 = st->HH[2]; + + p = &st->P[1]; + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + if (leftover < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_atleast16bytes: + t0 = load_u64_le(m + 0); + t1 = load_u64_le(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24) | ((uint64_t)1 << 40); + +poly1305_donna_mul: + d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), + mul64x64_128(h2, s1)); + d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), + mul64x64_128(h2, s2)); + d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), + mul64x64_128(h2, r0)); + h0 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + h1 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + h2 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + h0 += c * 5; + + m += 16; + leftover -= 16; + if (leftover >= 16) { + goto poly1305_donna_atleast16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!leftover) { + goto poly1305_donna_finish; + } + + m[leftover++] = 1; + GFp_memset(m + leftover, 0, 16 - leftover); + leftover = 16; + + t0 = load_u64_le(m + 0); + t1 = load_u64_le(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + + 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); + + // pad + t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + h0 += (t0 & 0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += (t0 & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + t1 = (t1 >> 24); + h2 += (t1)+c; + + store_u64_le(mac + 0, ((h0) | (h1 << 44))); + store_u64_le(mac + 8, ((h1 >> 20) | (h2 << 24))); +} + +#endif // BORINGSSL_HAS_UINT128 && OPENSSL_X86_64 diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000000..dcfb03439f --- /dev/null +++ b/deny.toml @@ -0,0 +1,30 @@ +[advisories] +unmaintained = "deny" +yanked = "deny" +notice = "deny" + +[licenses] +allow = [ + "Apache-2.0", + "ISC", + "LicenseRef-ring", + "MIT", +] +confidence-threshold = 1.0 + +[[licenses.clarify]] +name = "ring" +expression = "LicenseRef-ring" +license-files = [ + { path = "LICENSE", hash = 0xbd0eed23 }, +] + +[bans] +# We don't maintain a fixed Cargo.lock so enforcing +# `multiple-versions = "deny"` is impractical. +multiple-versions = "allow" +wildcards = "deny" + +[sources] +unknown-registry = "deny" +unknown-git = "deny" diff --git a/include/GFp/.gitattributes b/include/GFp/.gitattributes deleted file mode 100644 index 15a5c58091..0000000000 --- a/include/GFp/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.h linguist-language=C diff --git a/include/GFp/arm_arch.h b/include/GFp/arm_arch.h index ee5e32c8f3..2e64aa9e5e 100644 --- a/include/GFp/arm_arch.h +++ b/include/GFp/arm_arch.h @@ -110,4 +110,68 @@ // ARMV8_SHA256 indicates support for hardware SHA-256 instructions. #define ARMV8_SHA256 (1 << 4) +#if defined(__ASSEMBLER__) + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" +#endif + +// Support macros for +// - Armv8.3-A Pointer Authentication and +// - Armv8.5-A Branch Target Identification +// features which require emitting a .note.gnu.property section with the +// appropriate architecture-dependent feature bits set. +// Read more: "ELF for the Arm® 64-bit Architecture" + +#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 +#define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has Branch Target Identification +#define AARCH64_VALID_CALL_TARGET hint #34 // BTI 'c' +#else +#define GNU_PROPERTY_AARCH64_BTI 0 // No Branch Target Identification +#define AARCH64_VALID_CALL_TARGET +#endif + +#if defined(__ARM_FEATURE_PAC_DEFAULT) && \ + (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 // Signed with A-key +#define GNU_PROPERTY_AARCH64_POINTER_AUTH \ + (1 << 1) // Has Pointer Authentication +#define AARCH64_SIGN_LINK_REGISTER hint #25 // PACIASP +#define AARCH64_VALIDATE_LINK_REGISTER hint #29 // AUTIASP +#elif defined(__ARM_FEATURE_PAC_DEFAULT) && \ + (__ARM_FEATURE_PAC_DEFAULT & 2) == 2 // Signed with B-key +#define GNU_PROPERTY_AARCH64_POINTER_AUTH \ + (1 << 1) // Has Pointer Authentication +#define AARCH64_SIGN_LINK_REGISTER hint #27 // PACIBSP +#define AARCH64_VALIDATE_LINK_REGISTER hint #31 // AUTIBSP +#else +#define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 // No Pointer Authentication +#if GNU_PROPERTY_AARCH64_BTI != 0 +#define AARCH64_SIGN_LINK_REGISTER AARCH64_VALID_CALL_TARGET +#else +#define AARCH64_SIGN_LINK_REGISTER +#endif +#define AARCH64_VALIDATE_LINK_REGISTER +#endif + +#if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0 +.pushsection .note.gnu.property, "a"; +.balign 8; +.long 4; +.long 0x10; +.long 0x5; +.asciz "GNU"; +.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ +.long 4; +.long (GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI); +.long 0; +.popsection; +#endif + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#endif /* defined __ASSEMBLER__ */ + #endif // OPENSSL_HEADER_ARM_ARCH_H diff --git a/include/GFp/base.h b/include/GFp/base.h index 737d297947..e18ee44ed7 100644 --- a/include/GFp/base.h +++ b/include/GFp/base.h @@ -75,16 +75,16 @@ #elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86) #define OPENSSL_32_BIT #define OPENSSL_X86 -#elif defined(__aarch64__) +#elif defined(__AARCH64EL__) || defined(_M_ARM64) #define OPENSSL_64_BIT #define OPENSSL_AARCH64 -#elif defined(__arm) || defined(__arm__) || defined(_M_ARM) +#elif defined(__ARMEL__) || defined(_M_ARM) #define OPENSSL_32_BIT #define OPENSSL_ARM -#elif defined(__mips__) && !defined(__LP64__) +#elif defined(__MIPSEL__) && !defined(__LP64__) #define OPENSSL_32_BIT #define OPENSSL_MIPS -#elif defined(__mips__) && defined(__LP64__) +#elif defined(__MIPSEL__) && defined(__LP64__) #define OPENSSL_64_BIT #define OPENSSL_MIPS64 #elif defined(__wasm__) diff --git a/include/GFp/check.h b/include/GFp/check.h index cf44db834d..4bd257ca35 100644 --- a/include/GFp/check.h +++ b/include/GFp/check.h @@ -17,12 +17,13 @@ // |debug_assert_nonsecret| is like |assert| and should be used (only) when the // assertion does not have any potential to leak a secret. |NDEBUG| controls this -// exactly like |assert|. It is emulated for WebAssembly so that is -// not required for it. +// exactly like |assert|. It is emulated when there is no assert.h to make +// cross-building easier. // // When reviewing uses of |debug_assert_nonsecret|, verify that the check // really does not have potential to leak a secret. -#if !defined(__wasm__) + +#if !defined(GFp_NOSTDLIBINC) # include # define debug_assert_nonsecret(x) assert(x) #else diff --git a/include/GFp/poly1305.h b/include/GFp/poly1305.h new file mode 100644 index 0000000000..53c4036c86 --- /dev/null +++ b/include/GFp/poly1305.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2014, Google Inc. + * + * 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. */ + +#ifndef OPENSSL_HEADER_POLY1305_H +#define OPENSSL_HEADER_POLY1305_H + +#include + +// Keep in sync with `poly1305_state` in poly1305.rs. +typedef uint8_t poly1305_state[512]; + +#endif // OPENSSL_HEADER_POLY1305_H diff --git a/mk/appveyor.bat b/mk/appveyor.bat deleted file mode 100644 index ac7c2b713f..0000000000 --- a/mk/appveyor.bat +++ /dev/null @@ -1,60 +0,0 @@ -echo on -SetLocal EnableDelayedExpansion - -set VCVARSALL="C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN_VERSION%\VC\vcvarsall.bat" - -if [%Platform%] NEQ [x64] goto win32 -set TARGET_ARCH=x86_64 -goto download - -:win32 -echo on -if [%Platform%] NEQ [Win32] exit 1 -set TARGET_ARCH=i686 -goto download - -:download -REM vcvarsall turns echo off -echo on - -mkdir windows_build_tools -mkdir windows_build_tools\ -echo Downloading Yasm... -powershell -Command "(New-Object Net.WebClient).DownloadFile('https://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe', 'windows_build_tools\yasm.exe')" -if %ERRORLEVEL% NEQ 0 ( - echo ...downloading Yasm failed. - exit 1 -) - -mkdir build -set RUSTUP_URL=https://win.rustup.rs/%TARGET_ARCH% -set RUSTUP_EXE=build\rustup-init-%TARGET_ARCH%.exe -echo Downloading %RUSTUP_URL%... -powershell -Command "(New-Object Net.WebClient).DownloadFile('%RUSTUP_URL%', '%RUSTUP_EXE%')" -if %ERRORLEVEL% NEQ 0 ( - echo ...downloading rustup failed. - exit 1 -) - -set TARGET=%TARGET_ARCH%-pc-windows-msvc -%RUSTUP_EXE% -y --default-host %TARGET% --default-toolchain %RUST% -if %ERRORLEVEL% NEQ 0 exit 1 - -set PATH=%USERPROFILE%\.cargo\bin;%cd%\windows_build_tools;%PATH% - -if [%Configuration%] == [Release] set CARGO_MODE=--release - -set - -link /? -cl /? -rustc --version -cargo --version - -cargo test -vv %CARGO_MODE% -if %ERRORLEVEL% NEQ 0 exit 1 - -REM Verify that `cargo build`, independent from `cargo test`, works; i.e. -REM verify that non-test builds aren't trying to use test-only features. -cargo build -vv %CARGO_MODE% -if %ERRORLEVEL% NEQ 0 exit 1 diff --git a/mk/cargo.sh b/mk/cargo.sh new file mode 100755 index 0000000000..a7b8154baf --- /dev/null +++ b/mk/cargo.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash +# +# Copyright 2020 Brian Smith. +# +# 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 AUTHORS DISCLAIM ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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. + +set -eux -o pipefail +IFS=$'\n\t' + +rustflags_self_contained="-Clink-self-contained=yes -Clinker=rust-lld" +qemu_aarch64="qemu-aarch64 -L /usr/aarch64-linux-gnu" +qemu_arm="qemu-arm -L /usr/arm-linux-gnueabihf" + +# Avoid putting the Android tools in `$PATH` because there are tools in this +# directory like `clang` that would conflict with the same-named tools that may +# be needed to compile the build script, or to compile for other targets. +if [ -n "${ANDROID_SDK_ROOT-}" ]; then + android_tools=$ANDROID_SDK_ROOT/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin +fi + +for arg in $*; do + case $arg in + --target=*) + target=${arg#*=} + ;; + *) + ;; + esac +done + +# See comments in install-build-tools.sh. +llvm_version=10 +if [ -n "${RING_COVERAGE-}" ]; then + llvm_version=11 +fi + +case $target in + aarch64-linux-android) + export CC_aarch64_linux_android=$android_tools/aarch64-linux-android21-clang + export AR_aarch64_linux_android=$android_tools/aarch64-linux-android-ar + export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$android_tools/aarch64-linux-android21-clang + ;; + aarch64-unknown-linux-gnu) + export CC_aarch64_unknown_linux_gnu=clang-$llvm_version + export AR_aarch64_unknown_linux_gnu=llvm-ar-$llvm_version + export CFLAGS_aarch64_unknown_linux_gnu="--sysroot=/usr/aarch64-linux-gnu" + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="$qemu_aarch64" + ;; + aarch64-unknown-linux-musl) + export CC_aarch64_unknown_linux_musl=clang-$llvm_version + export AR_aarch64_unknown_linux_musl=llvm-ar-$llvm_version + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained" + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER="$qemu_aarch64" + ;; + arm-unknown-linux-gnueabihf) + export CC_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc + export AR_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc-ar + export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc + export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER="$qemu_arm" + ;; + armv7-linux-androideabi) + export CC_armv7_linux_androideabi=$android_tools/armv7a-linux-androideabi18-clang + export AR_armv7_linux_androideabi=$android_tools/arm-linux-androideabi-ar + export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$android_tools/armv7a-linux-androideabi18-clang + ;; + armv7-unknown-linux-musleabihf) + export CC_armv7_unknown_linux_musleabihf=clang-$llvm_version + export AR_armv7_unknown_linux_musleabihf=llvm-ar-$llvm_version + export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUSTFLAGS="$rustflags_self_contained" + export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="$qemu_arm" + ;; + i686-unknown-linux-gnu) + export CC_i686_unknown_linux_gnu=clang-$llvm_version + export AR_i686_unknown_linux_gnu=llvm-ar-$llvm_version + export CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang-$llvm_version + ;; + i686-unknown-linux-musl) + export CC_i686_unknown_linux_musl=clang-$llvm_version + export AR_i686_unknown_linux_musl=llvm-ar-$llvm_version + export CARGO_TARGET_I686_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained" + ;; + x86_64-unknown-linux-musl) + export CC_x86_64_unknown_linux_musl=clang-$llvm_version + export AR_x86_64_unknown_linux_musl=llvm-ar-$llvm_version + # XXX: Work around https://github.com/rust-lang/rust/issues/79555. + if [ -n "${RING_COVERAGE-}" ]; then + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=clang-$llvm_version + else + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained" + fi + ;; + wasm32-unknown-unknown) + # The first two are only needed for when the "wasm_c" feature is enabled. + export CC_wasm32_unknown_unknown=clang-$llvm_version + export AR_wasm32_unknown_unknown=llvm-ar-$llvm_version + export CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner + ;; + *) + ;; +esac + +if [ -n "${RING_COVERAGE-}" ]; then + # XXX: Collides between release and debug. + coverage_dir=$PWD/target/$target/debug/coverage + mkdir -p "$coverage_dir" + rm -f "$coverage_dir/*.profraw" + + export RING_BUILD_EXECUTABLE_LIST="$coverage_dir/executables" + truncate --size=0 "$RING_BUILD_EXECUTABLE_LIST" + + # This doesn't work when profiling under QEMU. Instead mk/runner does + # something similar but different. + # export LLVM_PROFILE_FILE="$coverage_dir/%m.profraw" + + # ${target} with hyphens replaced by underscores, lowercase and uppercase. + target_lower=${target//-/_} + target_upper=${target_lower^^} + + cflags_var=CFLAGS_${target_lower} + declare -x "${cflags_var}=-fprofile-instr-generate -fcoverage-mapping ${!cflags_var-}" + + runner_var=CARGO_TARGET_${target_upper}_RUNNER + declare -x "${runner_var}=mk/runner ${!runner_var-}" + + rustflags_var=CARGO_TARGET_${target_upper}_RUSTFLAGS + declare -x "${rustflags_var}=-Zinstrument-coverage ${!rustflags_var-}" +fi + +cargo "$@" + +if [ -n "${RING_COVERAGE-}" ]; then + while read executable; do + basename=$(basename "$executable") + llvm-profdata-$llvm_version merge -sparse ""$coverage_dir"/$basename.profraw" -o "$coverage_dir"/$basename.profdata + mkdir -p "$coverage_dir"/reports + llvm-cov-$llvm_version export \ + --instr-profile "$coverage_dir"/$basename.profdata \ + --format lcov \ + "$executable" \ + > "$coverage_dir"/reports/coverage-$basename.txt + done < "$RING_BUILD_EXECUTABLE_LIST" +fi diff --git a/mk/install-build-tools.ps1 b/mk/install-build-tools.ps1 new file mode 100644 index 0000000000..f1d51b981a --- /dev/null +++ b/mk/install-build-tools.ps1 @@ -0,0 +1,67 @@ +function Verify-Or-Delete-File { + param ( + [Parameter(Mandatory)] + [string]$File, + [Parameter(Mandatory)] + [string]$ExpectedDigest + ) + $ActualDigest = ( Get-FileHash -Algorithm SHA256 $File ).Hash + if ( $ActualDigest -eq $ExpectedDigest ) + { + return + } + rm $File + echo "Digest verification failed for $Url; actual $ActualDigest, expected $ExpectedDigest" + exit 1 +} + +function Download-Zip-and-Extract-File { + param ( + [Parameter(Mandatory)] + [string]$Uri, + [Parameter(Mandatory)] + [string]$ZipExpectedDigest, + [Parameter(Mandatory)] + [string]$PathWithinZip, + [Parameter(Mandatory)] + [string]$FileExpectedDigest, + [Parameter(Mandatory)] + [string]$OutFile + ) + $TmpZip = New-TemporaryFile + Invoke-WebRequest -Uri $Uri -OutFile $TmpZip.FullName + echo $TmpZip + Verify-Or-Delete-File -File $TmpZip.FullName -ExpectedDigest $ZipExpectedDigest + + Add-Type -AssemblyName System.IO.Compression.FileSystem + $zip = [System.IO.Compression.ZipFile]::OpenRead($TmpZip) + $zip.Entries | + Where-Object { $_.FullName -eq $PathWithinZip } | + ForEach-Object { + $TmpFile = New-TemporaryFile + # extract the selected items from the ZIP archive + # and copy them to the out folder + $FileName = $_.Name + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$TmpFile", $true) + Verify-Or-Delete-File -File $TmpFile -ExpectedDigest $FileExpectedDigest + Move-Item -Force $TmpFile $OutFile + } + $zip.Dispose() +} + +$tools_dir = "target/tools" +mkdir -Force $tools_dir + +# This is the file BoringSSL refers to in +# https://boringssl.googlesource.com/boringssl/+/26f8297177ad8033cc39de84afe9c2000430a66d. +$nasm_version = "nasm-2.13.03" +$nasm_zip = "$nasm_version-win64.zip" +$nasm_zip_sha256 = "B3A1F896B53D07854884C2E0D6BE7DEFBA7EBD09B864BBB9E6D69ADA1C3E989F" +$nasm_exe = "nasm.exe" +$nasm_exe_sha256 = "D8A933BF5CC3597C56193135CB78B225AB225E1F611D2FDB51EF6E3F555B21E3" +Download-Zip-and-Extract-File ` + -Uri "https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win64/$nasm_zip" ` + -ZipExpectedDigest "$nasm_zip_sha256" ` + -PathWithinZip "$nasm_version/$nasm_exe" ` + -FileExpectedDigest "$nasm_exe_sha256" ` + -OutFile "$tools_dir/$nasm_exe" diff --git a/mk/install-build-tools.sh b/mk/install-build-tools.sh new file mode 100755 index 0000000000..e997bbb40e --- /dev/null +++ b/mk/install-build-tools.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# +# Copyright 2020 Brian Smith. +# +# 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 AUTHORS DISCLAIM ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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. + +set -eux -o pipefail +IFS=$'\n\t' + +target=$1 +features=${2-} + +function install_packages { + sudo apt-get -yq --no-install-suggests --no-install-recommends install "$@" +} + +use_clang= +case $target in +--target*android*) + mkdir -p "${ANDROID_SDK_ROOT}/licenses" + android_license_file="${ANDROID_SDK_ROOT}/licenses/android-sdk-license" + accept_android_license=24333f8a63b6825ea9c5514f83c2829b004d1fee + grep --quiet --no-messages "$accept_android_license" "$android_license_file" \ + || echo $accept_android_license >> "$android_license_file" + sudo "${ANDROID_SDK_ROOT}/tools/bin/sdkmanager" ndk-bundle + ;; +esac + +case $target in +--target=aarch64-unknown-linux-gnu) + # Clang is needed for code coverage. + use_clang=1 + install_packages \ + qemu-user \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross + ;; +--target=aarch64-unknown-linux-musl|--target=armv7-unknown-linux-musleabihf) + use_clang=1 + install_packages \ + qemu-user + ;; +--target=arm-unknown-linux-gnueabihf) + install_packages \ + qemu-user \ + gcc-arm-linux-gnueabihf \ + libc6-dev-armhf-cross + ;; +--target=i686-unknown-linux-gnu) + use_clang=1 + install_packages \ + gcc-multilib \ + libc6-dev-i386 + ;; +--target=i686-unknown-linux-musl|--target=x86_64-unknown-linux-musl) + use_clang=1 + ;; +--target=wasm32-unknown-unknown) + # The version of wasm-bindgen-cli must match the wasm-bindgen version. + wasm_bindgen_version=$(cargo metadata --format-version 1 | jq -r '.packages | map(select( .name == "wasm-bindgen")) | map(.version) | .[0]') + cargo install wasm-bindgen-cli --vers "$wasm_bindgen_version" --bin wasm-bindgen-test-runner + case ${features-} in + *wasm32_c*) + use_clang=1 + ;; + *) + ;; + esac + ;; +--target=*) + ;; +esac + +if [ -n "$use_clang" ]; then + llvm_version=10 + if [ -n "${RING_COVERAGE-}" ]; then + # https://github.com/rust-lang/rust/pull/79365 upgraded the coverage file + # format to one that only LLVM 11+ can use + llvm_version=11 + sudo apt-key add mk/llvm-snapshot.gpg.key + sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-$llvm_version main" + sudo apt-get update + fi + install_packages clang-$llvm_version llvm-$llvm_version +fi diff --git a/mk/llvm-snapshot.gpg.key b/mk/llvm-snapshot.gpg.key new file mode 100644 index 0000000000..87a01ff889 --- /dev/null +++ b/mk/llvm-snapshot.gpg.key @@ -0,0 +1,54 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.12 (GNU/Linux) +Comment: See https://apt.llvm.org/. +Comment: Fingerprint: 6084 F3CF 814B 57C1 CF12 EFD5 15CF 4D18 AF4F 7421 + +mQINBFE9lCwBEADi0WUAApM/mgHJRU8lVkkw0CHsZNpqaQDNaHefD6Rw3S4LxNmM +EZaOTkhP200XZM8lVdbfUW9xSjA3oPldc1HG26NjbqqCmWpdo2fb+r7VmU2dq3NM +R18ZlKixiLDE6OUfaXWKamZsXb6ITTYmgTO6orQWYrnW6ckYHSeaAkW0wkDAryl2 +B5v8aoFnQ1rFiVEMo4NGzw4UX+MelF7rxaaregmKVTPiqCOSPJ1McC1dHFN533FY +Wh/RVLKWo6npu+owtwYFQW+zyQhKzSIMvNujFRzhIxzxR9Gn87MoLAyfgKEzrbbT +DhqqNXTxS4UMUKCQaO93TzetX/EBrRpJj+vP640yio80h4Dr5pAd7+LnKwgpTDk1 +G88bBXJAcPZnTSKu9I2c6KY4iRNbvRz4i+ZdwwZtdW4nSdl2792L7Sl7Nc44uLL/ +ZqkKDXEBF6lsX5XpABwyK89S/SbHOytXv9o4puv+65Ac5/UShspQTMSKGZgvDauU +cs8kE1U9dPOqVNCYq9Nfwinkf6RxV1k1+gwtclxQuY7UpKXP0hNAXjAiA5KS5Crq +7aaJg9q2F4bub0mNU6n7UI6vXguF2n4SEtzPRk6RP+4TiT3bZUsmr+1ktogyOJCc +Ha8G5VdL+NBIYQthOcieYCBnTeIH7D3Sp6FYQTYtVbKFzmMK+36ERreL/wARAQAB +tD1TeWx2ZXN0cmUgTGVkcnUgLSBEZWJpYW4gTExWTSBwYWNrYWdlcyA8c3lsdmVz +dHJlQGRlYmlhbi5vcmc+iQI4BBMBAgAiBQJRPZQsAhsDBgsJCAcDAgYVCAIJCgsE +FgIDAQIeAQIXgAAKCRAVz00Yr090Ibx+EADArS/hvkDF8juWMXxh17CgR0WZlHCC +9CTBWkg5a0bNN/3bb97cPQt/vIKWjQtkQpav6/5JTVCSx2riL4FHYhH0iuo4iAPR +udC7Cvg8g7bSPrKO6tenQZNvQm+tUmBHgFiMBJi92AjZ/Qn1Shg7p9ITivFxpLyX +wpmnF1OKyI2Kof2rm4BFwfSWuf8Fvh7kDMRLHv+MlnK/7j/BNpKdozXxLcwoFBmn +l0WjpAH3OFF7Pvm1LJdf1DjWKH0Dc3sc6zxtmBR/KHHg6kK4BGQNnFKujcP7TVdv +gMYv84kun14pnwjZcqOtN3UJtcx22880DOQzinoMs3Q4w4o05oIF+sSgHViFpc3W +R0v+RllnH05vKZo+LDzc83DQVrdwliV12eHxrMQ8UYg88zCbF/cHHnlzZWAJgftg +hB08v1BKPgYRUzwJ6VdVqXYcZWEaUJmQAPuAALyZESw94hSo28FAn0/gzEc5uOYx +K+xG/lFwgAGYNb3uGM5m0P6LVTfdg6vDwwOeTNIExVk3KVFXeSQef2ZMkhwA7wya +KJptkb62wBHFE+o9TUdtMCY6qONxMMdwioRE5BYNwAsS1PnRD2+jtlI0DzvKHt7B +MWd8hnoUKhMeZ9TNmo+8CpsAtXZcBho0zPGz/R8NlJhAWpdAZ1CmcPo83EW86Yq7 +BxQUKnNHcwj2ebkCDQRRPZQsARAA4jxYmbTHwmMjqSizlMJYNuGOpIidEdx9zQ5g +zOr431/VfWq4S+VhMDhs15j9lyml0y4ok215VRFwrAREDg6UPMr7ajLmBQGau0Fc +bvZJ90l4NjXp5p0NEE/qOb9UEHT7EGkEhaZ1ekkWFTWCgsy7rRXfZLxB6sk7pzLC +DshyW3zjIakWAnpQ5j5obiDy708pReAuGB94NSyb1HoW/xGsGgvvCw4r0w3xPStw +F1PhmScE6NTBIfLliea3pl8vhKPlCh54Hk7I8QGjo1ETlRP4Qll1ZxHJ8u25f/ta +RES2Aw8Hi7j0EVcZ6MT9JWTI83yUcnUlZPZS2HyeWcUj+8nUC8W4N8An+aNps9l/ +21inIl2TbGo3Yn1JQLnA1YCoGwC34g8QZTJhElEQBN0X29ayWW6OdFx8MDvllbBV +ymmKq2lK1U55mQTfDli7S3vfGz9Gp/oQwZ8bQpOeUkc5hbZszYwP4RX+68xDPfn+ +M9udl+qW9wu+LyePbW6HX90LmkhNkkY2ZzUPRPDHZANU5btaPXc2H7edX4y4maQa +xenqD0lGh9LGz/mps4HEZtCI5CY8o0uCMF3lT0XfXhuLksr7Pxv57yue8LLTItOJ +d9Hmzp9G97SRYYeqU+8lyNXtU2PdrLLq7QHkzrsloG78lCpQcalHGACJzrlUWVP/ +fN3Ht3kAEQEAAYkCHwQYAQIACQUCUT2ULAIbDAAKCRAVz00Yr090IbhWEADbr50X +OEXMIMGRLe+YMjeMX9NG4jxs0jZaWHc/WrGR+CCSUb9r6aPXeLo+45949uEfdSsB +pbaEdNWxF5Vr1CSjuO5siIlgDjmT655voXo67xVpEN4HhMrxugDJfCa6z97P0+ML +PdDxim57uNqkam9XIq9hKQaurxMAECDPmlEXI4QT3eu5qw5/knMzDMZj4Vi6hovL +wvvAeLHO/jsyfIdNmhBGU2RWCEZ9uo/MeerPHtRPfg74g+9PPfP6nyHD2Wes6yGd +oVQwtPNAQD6Cj7EaA2xdZYLJ7/jW6yiPu98FFWP74FN2dlyEA2uVziLsfBrgpS4l +tVOlrO2YzkkqUGrybzbLpj6eeHx+Cd7wcjI8CalsqtL6cG8cUEjtWQUHyTbQWAgG +5VPEgIAVhJ6RTZ26i/G+4J8neKyRs4vz+57UGwY6zI4AB1ZcWGEE3Bf+CDEDgmnP +LSwbnHefK9IljT9XU98PelSryUO/5UPw7leE0akXKB4DtekToO226px1VnGp3Bov +1GBGvpHvL2WizEwdk+nfk8LtrLzej+9FtIcq3uIrYnsac47Pf7p0otcFeTJTjSq3 +krCaoG4Hx0zGQG2ZFpHrSrZTVy6lxvIdfi0beMgY6h78p6M9eYZHQHc02DjFkQXN +bXb5c6gCHESH5PXwPU4jQEE7Ib9J6sbk7ZT2Mw== +=j+4q +-----END PGP PUBLIC KEY BLOCK----- diff --git a/mk/package.sh b/mk/package.sh index 43b9851272..7def4b623e 100644 --- a/mk/package.sh +++ b/mk/package.sh @@ -1,4 +1,3 @@ - # This only works on Windows, using MinGW. set -eux -o pipefail IFS=$'\n\t' diff --git a/mk/runner b/mk/runner new file mode 100755 index 0000000000..ffa1441084 --- /dev/null +++ b/mk/runner @@ -0,0 +1,21 @@ +#!/bin/bash +set -eux -o pipefail +IFS=$'\n\t' + +for arg in $*; do + # There can be some arguments prefixed in front of the executable, e.g. + # when qemu-user is used. There can be arguments after the executable, + # e.g. `cargo test` arguments like `TESTNAME`. + if [[ $arg = */deps/* ]]; then + executable=$arg + break + fi +done + +export LLVM_PROFILE_FILE=$(dirname "$RING_BUILD_EXECUTABLE_LIST")/$(basename "$executable").profraw + +if [ -n "$RING_BUILD_EXECUTABLE_LIST" ]; then + echo "$executable" >> "$RING_BUILD_EXECUTABLE_LIST" +fi + +$* diff --git a/mk/travis-install-kcov.sh b/mk/travis-install-kcov.sh deleted file mode 100755 index af1dcbf5e5..0000000000 --- a/mk/travis-install-kcov.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2016 Pietro Monteiro -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -set -ex - - -# kcov 26 or newer is needed when getting coverage information for Rust. -# kcov 31 is needed so `kcov --version` doesn't exit with status 1. -KCOV_VERSION=${KCOV_VERSION:-36} - -KCOV_INSTALL_PREFIX="${HOME}/kcov-${TARGET_X}" - -# Check if kcov has been cached on travis. -if [[ -f "$KCOV_INSTALL_PREFIX/bin/kcov" ]]; then - KCOV_INSTALLED_VERSION=`$KCOV_INSTALL_PREFIX/bin/kcov --version` - # Exit if we don't need to upgrade kcov. - if [[ "$KCOV_INSTALLED_VERSION" == "kcov $KCOV_VERSION" ]]; then - echo "Using cached kcov version: ${KCOV_VERSION}" - exit 0 - else - rm -rf "$KCOV_INSTALL_PREFIX" - fi -fi - -curl -L https://github.com/SimonKagstrom/kcov/archive/v$KCOV_VERSION.tar.gz | tar -zxf - - -pushd kcov-$KCOV_VERSION - -mkdir build - -pushd build - -if [[ "$TARGET_X" == "i686-unknown-linux-gnu" ]]; then - # set PKG_CONFIG_PATH so the kcov build system uses the 32 bit libraries we installed. - # otherwise kcov will be linked with 64 bit libraries and won't work with 32 bit executables. - PKG_CONFIG_PATH="/usr/lib/i386-linux-gnu/pkgconfig" CFLAGS="-m32" \ - CXXFLAGS="-m32" TARGET=$TARGET_X \ - cmake -DCMAKE_INSTALL_PREFIX:PATH="${KCOV_INSTALL_PREFIX}" .. -else - TARGET=$TARGET_X cmake -DCMAKE_INSTALL_PREFIX:PATH="${KCOV_INSTALL_PREFIX}" .. -fi - -make -make install - -$KCOV_INSTALL_PREFIX/bin/kcov --version - -popd -popd diff --git a/mk/travis.sh b/mk/travis.sh deleted file mode 100755 index 6938114c46..0000000000 --- a/mk/travis.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright 2015 Brian Smith. -# -# 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 AUTHORS DISCLAIM ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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. - -set -eux -o pipefail -IFS=$'\n\t' - -printenv - -case $TARGET_X in -aarch64-unknown-linux-gnu) - export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu - ;; -arm-unknown-linux-gnueabihf) - export QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf - ;; -aarch64-linux-android) - # XXX: Tests are built but not run because we couldn't get the emulator to work; see - # https://github.com/briansmith/ring/issues/838 - export ANDROID_ABI=aarch64 - ;; -armv7-linux-androideabi) - # XXX: Tests are built but not run because we couldn't get the emulator to work; see - # https://github.com/briansmith/ring/issues/838 - # export ANDROID_SYSTEM_IMAGE="system-images;android-18;default;armeabi-v7a" - export ANDROID_ABI=armeabi-v7a - ;; -esac - -if [[ ! -z "${ANDROID_ABI-}" ]]; then - # install the android sdk/ndk - mkdir "$ANDROID_HOME/licenses" || true - echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_HOME/licenses/android-sdk-license" - sdkmanager ndk-bundle - curl -sSf https://build.travis-ci.org/files/rustup-init.sh | sh -s -- --default-toolchain=$RUST_X -y - export PATH=$HOME/.cargo/bin:$ANDROID_HOME/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH - rustup default -fi - -if [[ "$TARGET_X" =~ ^(arm|aarch64) && ! "$TARGET_X" =~ android ]]; then - # We need a newer QEMU than Travis has. - # sudo is needed until the PPA and its packages are whitelisted. - # See https://github.com/travis-ci/apt-source-whitelist/issues/271 - sudo add-apt-repository ppa:pietro-monteiro/qemu-backport -y - sudo apt-get update -qq - sudo apt-get install --no-install-recommends binfmt-support qemu-user-binfmt -y -fi - -if [[ ! "$TARGET_X" =~ "x86_64-" ]]; then - rustup target add "$TARGET_X" - - # By default cargo/rustc seems to use cc for linking, We installed the - # multilib support that corresponds to $CC_X but unless cc happens to match - # $CC_X, that's not the right version. The symptom is a linker error - # where it fails to find -lgcc_s. - if [[ ! -z "${CC_X-}" ]]; then - mkdir .cargo - echo "[target.$TARGET_X]" > .cargo/config - echo "linker= \"$CC_X\"" >> .cargo/config - cat .cargo/config - fi -fi - -if [[ ! -z "${CC_X-}" ]]; then - export CC=$CC_X - $CC --version -else - cc --version -fi - -# KCOV needs a C++ compiler. -if [[ "$KCOV" == "1" ]]; then - if [[ ! -z "${CC_X-}" ]]; then - CXX="${CC_X/clang/clang++}" - CXX="${CC_X/gcc/g++}" - export CXX=$CXX - $CXX --version - else - c++ --version - fi -fi - -cargo version -rustc --version - -if [[ "$MODE_X" == "RELWITHDEBINFO" ]]; then - mode=--release - target_dir=target/$TARGET_X/release -else - target_dir=target/$TARGET_X/debug -fi - -if [[ -z "${ANDROID_ABI-}" ]]; then - cargo test -vv -j2 ${mode-} ${FEATURES_X-} --target=$TARGET_X -else - cargo test -vv -j2 --no-run ${mode-} ${FEATURES_X-} --target=$TARGET_X - - if [[ ! -z "${ANDROID_SYSTEM_IMAGE-}" ]]; then - # Building the AVD is slow. Do it here, after we build the code so that any - # build breakage is reported sooner, instead of being delayed by this. - sdkmanager tools - echo no | avdmanager create avd --force --name $ANDROID_ABI -k $ANDROID_SYSTEM_IMAGE --abi $ANDROID_ABI - avdmanager list avd - - $ANDROID_HOME/emulator/emulator @$ANDROID_ABI -memory 2048 -no-skin -no-boot-anim -no-window & - adb wait-for-device - - # Run the unit tests first. The file named ring- in $target_dir is - # the test executable. - - find $target_dir -maxdepth 1 -name ring-* ! -name "*.*" \ - -exec adb push {} /data/ring-test \; - adb shell "cd /data && ./ring-test" 2>&1 | tee /tmp/ring-test-log - grep "test result: ok" /tmp/ring-test-log - - for test_exe in `find $target_dir -maxdepth 1 -name "*test*" -type f ! -name "*.*" `; do - adb push $test_exe /data/`basename $test_exe` - adb shell "cd /data && ./`basename $test_exe`" 2>&1 | \ - tee /tmp/`basename $test_exe`-log - grep "test result: ok" /tmp/`basename $test_exe`-log - done - - adb emu kill - fi -fi - -if [[ "$KCOV" == "1" ]]; then - # kcov reports coverage as a percentage of code *linked into the executable* - # (more accurately, code that has debug info linked into the executable), not - # as a percentage of source code. Thus, any code that gets discarded by the - # linker due to lack of usage isn't counted at all. Thus, we have to re-link - # with "-C link-dead-code" to get accurate code coverage reports. - # Alternatively, we could link pass "-C link-dead-code" in the "cargo test" - # step above, but then "cargo test" we wouldn't be testing the configuration - # we expect people to use in production. - # - # panic=abort is used to get accurate coverage. See - # https://github.com/rust-lang/rust/issues/43410 and - # https://github.com/mozilla/grcov/issues/427#issuecomment-623995594 and - # https://github.com/rust-lang/rust/issues/55352. - cargo clean - CARGO_INCREMENTAL=0 \ - RUSTDOCFLAGS="-Cpanic=abort" \ - RUSTFLAGS="-Ccodegen-units=1 -Clink-dead-code -Coverflow-checks=on -Cpanic=abort -Zpanic_abort_tests -Zprofile" \ - cargo test -vv --no-run -j2 ${mode-} ${FEATURES_X-} --target=$TARGET_X - mk/travis-install-kcov.sh - for test_exe in `find target/$TARGET_X/debug -maxdepth 1 -executable -type f`; do - ${HOME}/kcov-${TARGET_X}/bin/kcov \ - --verify \ - --coveralls-id=$TRAVIS_JOB_ID \ - --exclude-path=/usr/include \ - --include-pattern="ring/crypto,ring/src,ring/tests" \ - target/kcov \ - $test_exe - done -fi - -echo end of mk/travis.sh diff --git a/mk/update-travis-yml.py b/mk/update-travis-yml.py deleted file mode 100755 index 4468484111..0000000000 --- a/mk/update-travis-yml.py +++ /dev/null @@ -1,285 +0,0 @@ -# Run this as "python mk/update-travis-yml.py" - -# Copyright 2015 Brian Smith. -# -# 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 BRIAN SMITH AND THE AUTHORS DISCLAIM -# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL BRIAN SMITH OR THE AUTHORS -# 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. - -import re -import shutil - -rusts = [ - "stable", - "nightly", - "beta", -] - -gcc = "gcc-7" -#Clang 5.0 is the default compiler on Travis CI for Ubuntu 14.04. -clang = "clang" - -linux_compilers = [ - # Assume the default compiler is GCC. - # GCC 4.8 is the default compiler on Travis CI for Ubuntu 14.04. - "", - - clang, - - gcc, -] - -osx_compilers = [ - "", # Don't set CC.' -] - -compilers = { - "aarch64-unknown-linux-gnu" : [ "aarch64-linux-gnu-gcc" ], - "aarch64-linux-android" : [ "aarch64-linux-android21-clang" ], - "armv7-linux-androideabi" : [ "armv7a-linux-androideabi18-clang" ], - "arm-unknown-linux-gnueabihf" : [ "arm-linux-gnueabihf-gcc" ], - "i686-unknown-linux-gnu" : linux_compilers, - "x86_64-unknown-linux-gnu" : linux_compilers, - "x86_64-apple-darwin" : osx_compilers, -} - -feature_sets = [ - "", -] - -modes = [ - "DEBUG", - "RELWITHDEBINFO" -] - -# Mac OS X is first because we don't want to have to wait until all the Linux -# configurations have been built to find out that there is a failure on Mac. -oss = [ - "osx", - "linux", -] - -targets = { - "osx" : [ - "x86_64-apple-darwin", - ], - "linux" : [ - "aarch64-linux-android", - "armv7-linux-androideabi", - "x86_64-unknown-linux-gnu", - "aarch64-unknown-linux-gnu", - "i686-unknown-linux-gnu", - "arm-unknown-linux-gnueabihf", - ], -} - -def format_entries(): - return "\n".join([format_entry(os, target, compiler, rust, mode, features) - for rust in rusts - for os in oss - for target in targets[os] - for compiler in compilers[target] - for mode in modes - for features in feature_sets]) - -# We use alternative names (the "_X" suffix) so that, in mk/travis.sh, we can -# ensure that we set the specific variables we want and that no relevant -# variables are unintentially inherited into the build process. Also, we have -# to set |CC_X| instead of |CC| since Travis sets |CC| to its Travis CI default -# value *after* processing the |env:| directive here. -entry_template = """ - - env: TARGET_X=%(target)s %(compilers)s FEATURES_X=%(features)s MODE_X=%(mode)s KCOV=%(kcov)s RUST_X=%(rust)s - rust: %(rust)s - os: %(os)s""" - -entry_indent = " " - -entry_packages_template = """ - addons: - apt: - packages: - %(packages)s""" - -entry_sources_template = """ - sources: - %(sources)s""" - -def format_entry(os, target, compiler, rust, mode, features): - target_words = target.split("-") - arch = target_words[0] - vendor = target_words[1] - sys = target_words[2] - - # Currently kcov only runs on Linux. - # - # GCC 7 was picked arbitrarily to restrict coverage report to one build for - # efficiency reasons. - # - # DEBUG mode is needed because debug symbols are needed for coverage - # tracking. - kcov = (os == "linux" and compiler == gcc and rust == "nightly" and - mode == "DEBUG") - - template = entry_template - - if sys == "darwin": - abi = sys - sys = "macos" - elif sys == "androideabi": - abi = sys - sys = "linux" - template += """ - language: android - android: - components: - - android-18 - - build-tools-26.0.2 - - sys-img-armeabi-v7a-android-18""" - elif sys == "android": - abi = sys - sys = "linux" - template += """ - language: android - android: - components: - - android-21 - - build-tools-26.0.2""" - else: - abi = target_words[3] - - def prefix_all(prefix, xs): - return [prefix + x for x in xs] - - if sys == "linux": - packages = sorted(get_linux_packages_to_install(target, compiler, arch, kcov)) - sources_with_dups = sum([get_sources_for_package(p) for p in packages],[]) - sources = sorted(list(set(sources_with_dups))) - template += """ - dist: trusty""" - - if sys == "linux": - if packages: - template += entry_packages_template - if sources: - template += entry_sources_template - else: - packages = [] - sources = [] - - cc = compiler - - if os == "osx": - os += "\n" + entry_indent + "osx_image: xcode10.1" - - compilers = [] - if cc != "": - compilers += ["CC_X=" + cc] - compilers += "" - - return template % { - "compilers": " ".join(compilers), - "features" : features, - "mode" : mode, - "kcov": "1" if kcov == True else "0", - "packages" : "\n ".join(prefix_all("- ", packages)), - "rust" : rust, - "sources" : "\n ".join(prefix_all("- ", sources)), - "target" : target, - "os" : os, - } - -def get_linux_packages_to_install(target, compiler, arch, kcov): - if compiler.startswith("clang-") or compiler.startswith("gcc-"): - packages = [compiler] - else: - packages = [] - - if kcov: - packages += [replace_cc_with_cxx(compiler)] - - if target == "aarch64-unknown-linux-gnu": - packages += ["gcc-aarch64-linux-gnu", - "libc6-dev-arm64-cross"] - if target == "arm-unknown-linux-gnueabihf": - packages += ["gcc-arm-linux-gnueabihf", - "libc6-dev-armhf-cross"] - - if arch == "i686": - if kcov == True: - packages += [replace_cc_with_cxx(compiler) + "-multilib", - "libcurl3:i386", - "libcurl4-openssl-dev:i386", - "libdw-dev:i386", - "libelf-dev:i386", - "libiberty-dev:i386", - "libkrb5-dev:i386", - "libssl-dev:i386"] - - if compiler.startswith("clang") or compiler == "": - packages += ["libc6-dev-i386", - "gcc-multilib"] - elif compiler.startswith("gcc-"): - packages += [compiler + "-multilib", - "linux-libc-dev:i386"] - else: - raise ValueError("unexpected compiler: %s" % compiler) - elif arch == "x86_64": - if kcov == True: - packages += ["libcurl4-openssl-dev", - "libelf-dev", - "libdw-dev", - "binutils-dev", - "libiberty-dev"] - elif arch not in ["aarch64", "arm", "armv7"]: - raise ValueError("unexpected arch: %s" % arch) - - return packages - -def get_sources_for_package(package): - ubuntu_toolchain = "ubuntu-toolchain-r-test" - if package.startswith("clang-"): - _, version = package.split("-") - llvm_toolchain = "llvm-toolchain-trusty-%s" % version - - # Stuff in llvm-toolchain-trusty depends on stuff in the toolchain - # packages. - return [llvm_toolchain, ubuntu_toolchain] - elif package.startswith("gcc-"): - return [ubuntu_toolchain] - else: - return [] - -def replace_cc_with_cxx(compiler): - return compiler \ - .replace("gcc", "g++") \ - .replace("clang", "clang++") - -def main(): - # Make a backup of the file we are about to update. - shutil.copyfile(".travis.yml", ".travis.yml~") - with open(".travis.yml", "r+b") as file: - begin = " # BEGIN GENERATED\n" - end = " # END GENERATED\n" - old_contents = file.read() - new_contents = re.sub("%s(.*?)\n[ ]*%s" % (begin, end), - "".join([begin, format_entries(), "\n\n", end]), - old_contents, flags=re.S) - if old_contents == new_contents: - print "No changes" - return - - file.seek(0) - file.write(new_contents) - file.truncate() - print new_contents - -if __name__ == '__main__': - main() diff --git a/pregenerate_asm/Cargo.toml b/pregenerate_asm/Cargo.toml index a200e0a4c2..8a64273f8a 100644 --- a/pregenerate_asm/Cargo.toml +++ b/pregenerate_asm/Cargo.toml @@ -9,4 +9,4 @@ path = "../build.rs" # Keep this in sync with `[build-dependencies]` in ../Cargo.toml. [dependencies] -cc = "1.0.26" +cc = { version = "1.0.62", default-features = false } diff --git a/src/aead.rs b/src/aead.rs index 989b0b9479..4d6bdb7904 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -398,7 +398,7 @@ impl core::fmt::Debug for UnboundKey { } } -#[allow(variant_size_differences)] +#[allow(clippy::large_enum_variant, variant_size_differences)] enum KeyInner { AesGcm(aes_gcm::Key), ChaCha20Poly1305(chacha20_poly1305::Key), diff --git a/src/aead/aes.rs b/src/aead/aes.rs index 5f474c6698..5028e242c2 100644 --- a/src/aead/aes.rs +++ b/src/aead/aes.rs @@ -300,6 +300,10 @@ impl Key { out } + // TODO: use `matches!` when MSRV increases to 1.42.0 and remove this + // `#[allow(...)]` + #[allow(clippy::unknown_clippy_lints)] + #[allow(clippy::match_like_matches_macro)] #[cfg(target_arch = "x86_64")] #[must_use] pub fn is_aes_hw(&self) -> bool { diff --git a/src/aead/block.rs b/src/aead/block.rs index 658ac22d44..157f8ad842 100644 --- a/src/aead/block.rs +++ b/src/aead/block.rs @@ -87,6 +87,7 @@ impl From<&'_ [u8; BLOCK_LEN]> for Block { } impl AsRef<[u8; BLOCK_LEN]> for Block { + #[allow(clippy::transmute_ptr_to_ptr)] #[inline] fn as_ref(&self) -> &[u8; BLOCK_LEN] { unsafe { core::mem::transmute(self) } diff --git a/src/aead/chacha.rs b/src/aead/chacha.rs index cb43fb00e3..668c41d854 100644 --- a/src/aead/chacha.rs +++ b/src/aead/chacha.rs @@ -16,13 +16,13 @@ use super::{counter, iv::Iv, quic::Sample, BLOCK_LEN}; use crate::{c, endian::*}; -#[repr(C)] -pub struct Key([u8; KEY_LEN]); +#[repr(transparent)] +pub struct Key([LittleEndian; KEY_LEN / 4]); impl From<[u8; KEY_LEN]> for Key { #[inline] fn from(value: [u8; KEY_LEN]) -> Self { - Self(value) + Self(FromByteArray::from_byte_array(&value)) } } @@ -121,6 +121,12 @@ impl Key { GFp_ChaCha20_ctr32(output, input, in_out_len, self, &iv); } + + #[cfg(target_arch = "x86_64")] + #[inline] + pub(super) fn words_less_safe(&self) -> &[LittleEndian; KEY_LEN / 4] { + &self.0 + } } pub type Counter = counter::Counter>; diff --git a/src/aead/chacha20_poly1305.rs b/src/aead/chacha20_poly1305.rs index 26d3315b27..497d760032 100644 --- a/src/aead/chacha20_poly1305.rs +++ b/src/aead/chacha20_poly1305.rs @@ -50,6 +50,68 @@ fn chacha20_poly1305_seal( in_out: &mut [u8], cpu_features: cpu::Features, ) -> Tag { + let key = match key { + aead::KeyInner::ChaCha20Poly1305(key) => key, + _ => unreachable!(), + }; + + #[cfg(target_arch = "x86_64")] + { + if cpu::intel::SSE41.available(cpu_features) { + // XXX: BoringSSL uses `alignas(16)` on `key` instead of on the + // structure, but Rust can't do that yet; see + // https://github.com/rust-lang/rust/issues/73557. + // + // Keep in sync with the anonymous struct of BoringSSL's + // `chacha20_poly1305_seal_data`. + #[repr(align(16), C)] + #[derive(Clone, Copy)] + struct seal_data_in { + key: [u8; chacha::KEY_LEN], + counter: u32, + nonce: [u8; super::NONCE_LEN], + extra_ciphertext: *const u8, + extra_ciphertext_len: usize, + } + + let mut data = InOut { + input: seal_data_in { + key: *key.words_less_safe().as_byte_array(), + counter: 0, + nonce: *nonce.as_ref(), + extra_ciphertext: core::ptr::null(), + extra_ciphertext_len: 0, + }, + }; + + // Encrypts `plaintext_len` bytes from `plaintext` and writes them to `out_ciphertext`. + extern "C" { + fn GFp_chacha20_poly1305_seal( + out_ciphertext: *mut u8, + plaintext: *const u8, + plaintext_len: usize, + ad: *const u8, + ad_len: usize, + data: &mut InOut, + ); + } + + let out = unsafe { + GFp_chacha20_poly1305_seal( + in_out.as_mut_ptr(), + in_out.as_ptr(), + in_out.len(), + aad.as_ref().as_ptr(), + aad.as_ref().len(), + &mut data, + ); + &data.out + }; + + return Tag(out.tag); + } + } + aead(key, nonce, aad, in_out, Direction::Sealing, cpu_features) } @@ -61,6 +123,64 @@ fn chacha20_poly1305_open( in_out: &mut [u8], cpu_features: cpu::Features, ) -> Tag { + let key = match key { + aead::KeyInner::ChaCha20Poly1305(key) => key, + _ => unreachable!(), + }; + + #[cfg(target_arch = "x86_64")] + { + if cpu::intel::SSE41.available(cpu_features) { + // XXX: BoringSSL uses `alignas(16)` on `key` instead of on the + // structure, but Rust can't do that yet; see + // https://github.com/rust-lang/rust/issues/73557. + // + // Keep in sync with the anonymous struct of BoringSSL's + // `chacha20_poly1305_open_data`. + #[derive(Copy, Clone)] + #[repr(align(16), C)] + struct open_data_in { + key: [u8; chacha::KEY_LEN], + counter: u32, + nonce: [u8; super::NONCE_LEN], + } + + let mut data = InOut { + input: open_data_in { + key: *key.words_less_safe().as_byte_array(), + counter: 0, + nonce: *nonce.as_ref(), + }, + }; + + // Decrypts `plaintext_len` bytes from `ciphertext` and writes them to `out_plaintext`. + extern "C" { + fn GFp_chacha20_poly1305_open( + out_plaintext: *mut u8, + ciphertext: *const u8, + plaintext_len: usize, + ad: *const u8, + ad_len: usize, + data: &mut InOut, + ); + } + + let out = unsafe { + GFp_chacha20_poly1305_open( + in_out.as_mut_ptr(), + in_out.as_ptr().add(in_prefix_len), + in_out.len() - in_prefix_len, + aad.as_ref().as_ptr(), + aad.as_ref().len(), + &mut data, + ); + &data.out + }; + + return Tag(out.tag); + } + } + aead( key, nonce, @@ -73,23 +193,41 @@ fn chacha20_poly1305_open( pub type Key = chacha::Key; +// Keep in sync with BoringSSL's `chacha20_poly1305_open_data` and +// `chacha20_poly1305_seal_data`. +#[repr(C)] +#[cfg(target_arch = "x86_64")] +union InOut +where + T: Copy, +{ + input: T, + out: Out, +} + +// It isn't obvious whether the assembly code works for tags that aren't +// 16-byte aligned. In practice it will always be 16-byte aligned because it +// is embedded in a union where the other member of the union is 16-byte +// aligned. +#[cfg(target_arch = "x86_64")] +#[derive(Clone, Copy)] +#[repr(align(16), C)] +struct Out { + tag: [u8; super::TAG_LEN], +} + #[inline(always)] // Statically eliminate branches on `direction`. fn aead( - key: &aead::KeyInner, + chacha20_key: &Key, nonce: Nonce, Aad(aad): Aad<&[u8]>, in_out: &mut [u8], direction: Direction, - _todo: cpu::Features, + cpu_features: cpu::Features, ) -> Tag { - let chacha20_key = match key { - aead::KeyInner::ChaCha20Poly1305(key) => key, - _ => unreachable!(), - }; - let mut counter = Counter::zero(nonce); let mut ctx = { - let key = derive_poly1305_key(chacha20_key, counter.increment()); + let key = derive_poly1305_key(chacha20_key, counter.increment(), cpu_features); poly1305::Context::from_key(key) }; @@ -108,12 +246,12 @@ fn aead( } }; - ctx.update_block( + ctx.update( Block::from_u64_le( LittleEndian::from(polyfill::u64_from_usize(aad.len())), LittleEndian::from(polyfill::u64_from_usize(in_out_len)), - ), - poly1305::Pad::Pad, + ) + .as_ref(), ); ctx.finish() } @@ -123,20 +261,24 @@ fn poly1305_update_padded_16(ctx: &mut poly1305::Context, input: &[u8]) { let remainder_len = input.len() % BLOCK_LEN; let whole_len = input.len() - remainder_len; if whole_len > 0 { - ctx.update_blocks(&input[..whole_len]); + ctx.update(&input[..whole_len]); } if remainder_len > 0 { let mut block = Block::zero(); block.overwrite_part_at(0, &input[whole_len..]); - ctx.update_block(block, poly1305::Pad::Pad) + ctx.update(block.as_ref()) } } // Also used by chacha20_poly1305_openssh. -pub(super) fn derive_poly1305_key(chacha_key: &chacha::Key, iv: Iv) -> poly1305::Key { +pub(super) fn derive_poly1305_key( + chacha_key: &chacha::Key, + iv: Iv, + cpu_features: cpu::Features, +) -> poly1305::Key { let mut key_bytes = [0u8; 2 * BLOCK_LEN]; chacha_key.encrypt_iv_xor_blocks_in_place(iv, &mut key_bytes); - poly1305::Key::from(key_bytes) + poly1305::Key::new(key_bytes, cpu_features) } #[cfg(test)] diff --git a/src/aead/chacha20_poly1305_openssh.rs b/src/aead/chacha20_poly1305_openssh.rs index 656ca3bf4d..cb6f6913e4 100644 --- a/src/aead/chacha20_poly1305_openssh.rs +++ b/src/aead/chacha20_poly1305_openssh.rs @@ -32,7 +32,7 @@ use super::{ chacha::{self, *}, chacha20_poly1305::derive_poly1305_key, - poly1305, Nonce, Tag, + cpu, poly1305, Nonce, Tag, }; use crate::{constant_time, endian::*, error}; use core::convert::TryInto; @@ -46,7 +46,7 @@ impl SealingKey { /// Constructs a new `SealingKey`. pub fn new(key_material: &[u8; KEY_LEN]) -> SealingKey { SealingKey { - key: Key::new(key_material), + key: Key::new(key_material, cpu::features()), } } @@ -64,7 +64,8 @@ impl SealingKey { tag_out: &mut [u8; TAG_LEN], ) { let mut counter = make_counter(sequence_number); - let poly_key = derive_poly1305_key(&self.key.k_2, counter.increment()); + let poly_key = + derive_poly1305_key(&self.key.k_2, counter.increment(), self.key.cpu_features); { let (len_in_out, data_and_padding_in_out) = @@ -92,7 +93,7 @@ impl OpeningKey { /// Constructs a new `OpeningKey`. pub fn new(key_material: &[u8; KEY_LEN]) -> OpeningKey { OpeningKey { - key: Key::new(key_material), + key: Key::new(key_material, cpu::features()), } } @@ -131,7 +132,8 @@ impl OpeningKey { // We must verify the tag before decrypting so that // `ciphertext_in_plaintext_out` is unmodified if verification fails. // This is beyond what we guarantee. - let poly_key = derive_poly1305_key(&self.key.k_2, counter.increment()); + let poly_key = + derive_poly1305_key(&self.key.k_2, counter.increment(), self.key.cpu_features); verify(poly_key, ciphertext_in_plaintext_out, tag)?; let plaintext_in_ciphertext_out = &mut ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..]; @@ -146,10 +148,11 @@ impl OpeningKey { struct Key { k_1: chacha::Key, k_2: chacha::Key, + cpu_features: cpu::Features, } impl Key { - fn new(key_material: &[u8; KEY_LEN]) -> Key { + fn new(key_material: &[u8; KEY_LEN], cpu_features: cpu::Features) -> Key { // The first half becomes K_2 and the second half becomes K_1. let (k_2, k_1) = key_material.split_at(chacha::KEY_LEN); let k_1: [u8; chacha::KEY_LEN] = k_1.try_into().unwrap(); @@ -157,6 +160,7 @@ impl Key { Key { k_1: chacha::Key::from(k_1), k_2: chacha::Key::from(k_2), + cpu_features, } } } diff --git a/src/aead/gcm.rs b/src/aead/gcm.rs index 0873e0e0f4..6696f776dd 100644 --- a/src/aead/gcm.rs +++ b/src/aead/gcm.rs @@ -336,5 +336,5 @@ fn detect_implementation(cpu_features: cpu::Features) -> Implementation { #[cfg(target_arch = "x86_64")] fn has_avx_movbe(cpu_features: cpu::Features) -> bool { - return cpu::intel::AVX.available(cpu_features) && cpu::intel::MOVBE.available(cpu_features); + cpu::intel::AVX.available(cpu_features) && cpu::intel::MOVBE.available(cpu_features) } diff --git a/src/aead/poly1305.rs b/src/aead/poly1305.rs index b903a6af12..a87f709a4d 100644 --- a/src/aead/poly1305.rs +++ b/src/aead/poly1305.rs @@ -15,155 +15,105 @@ // TODO: enforce maximum input length. -use super::{ - block::{Block, BLOCK_LEN}, - Tag, TAG_LEN, -}; -use crate::{bssl, c, error}; -use core::convert::TryInto; +use super::{block::BLOCK_LEN, Tag, TAG_LEN}; +use crate::{c, cpu}; /// A Poly1305 key. -pub struct Key([u8; KEY_LEN]); +pub(super) struct Key { + key_and_nonce: [u8; KEY_LEN], + cpu_features: cpu::Features, +} const KEY_LEN: usize = 2 * BLOCK_LEN; -impl From<[u8; KEY_LEN]> for Key { +impl Key { #[inline] - fn from(value: [u8; KEY_LEN]) -> Self { - Self(value) + pub(super) fn new(key_and_nonce: [u8; KEY_LEN], cpu_features: cpu::Features) -> Self { + Self { + key_and_nonce, + cpu_features, + } } } pub struct Context { - opaque: Opaque, - nonce: Nonce, - func: Funcs, + state: poly1305_state, + #[allow(dead_code)] + cpu_features: cpu::Features, } -/// The memory manipulated by the assembly. -#[repr(C, align(8))] -struct Opaque([u8; OPAQUE_LEN]); -const OPAQUE_LEN: usize = 192; +// Keep in sync with `poly1305_state` in GFp/poly1305.h. +// +// The C code, in particular the way the `poly1305_aligned_state` functions +// are used, is only correct when the state buffer is 64-byte aligned. +#[repr(C, align(64))] +struct poly1305_state([u8; OPAQUE_LEN]); +const OPAQUE_LEN: usize = 512; + +// Abstracts the dispatching logic that chooses the NEON implementation if and +// only if it would work. +macro_rules! dispatch { + ( $features:expr => + ( $f:ident | $neon_f:ident ) + ( $( $p:ident : $t:ty ),+ ) + ( $( $a:expr ),+ ) ) => { + match () { + // Apple's 32-bit ARM ABI is incompatible with the assembly code. + #[cfg(all(target_arch = "arm", not(target_vendor = "apple")))] + () if cpu::arm::NEON.available($features) => { + extern "C" { + fn $neon_f( $( $p : $t ),+ ); + } + unsafe { $neon_f( $( $a ),+ ) } + } + () => { + extern "C" { + fn $f( $( $p : $t ),+ ); + } + unsafe { $f( $( $a ),+ ) } + } + } + } +} impl Context { #[inline] - pub fn from_key(Key(key_and_nonce): Key) -> Self { - extern "C" { - fn GFp_poly1305_blocks( - state: &mut Opaque, - input: *const u8, - len: c::size_t, - should_pad: Pad, - ); - fn GFp_poly1305_emit(state: &mut Opaque, tag: &mut Tag, nonce: &Nonce); - } - - let (key, nonce) = key_and_nonce.split_at(BLOCK_LEN); - let key: [u8; BLOCK_LEN] = key.try_into().unwrap(); - let nonce: [u8; BLOCK_LEN] = nonce.try_into().unwrap(); - - let key = DerivedKey(key); - let nonce = Nonce(nonce); - + pub(super) fn from_key( + Key { + key_and_nonce, + cpu_features, + }: Key, + ) -> Self { let mut ctx = Self { - opaque: Opaque([0u8; OPAQUE_LEN]), - nonce, - func: Funcs { - blocks_fn: GFp_poly1305_blocks, - emit_fn: GFp_poly1305_emit, - }, + state: poly1305_state([0u8; OPAQUE_LEN]), + cpu_features, }; - // On some platforms `init()` doesn't initialize `funcs`. The - // return value of `init()` indicates whether it did or not. Since - // we already gave `func` a default value above, we can ignore the - // return value assuming `init()` doesn't change `func` if it chose - // not to initialize it. Note that this is different than what - // BoringSSL does. - let _ = init(&mut ctx.opaque, key, &mut ctx.func); + dispatch!( + cpu_features => + (GFp_poly1305_init | GFp_poly1305_init_neon) + (statep: &mut poly1305_state, key: &[u8; KEY_LEN]) + (&mut ctx.state, &key_and_nonce)); ctx } - pub fn update_block(&mut self, block: Block, pad: Pad) { - self.func.blocks(&mut self.opaque, block.as_ref(), pad); - } - - pub fn update_blocks(&mut self, input: &[u8]) { - debug_assert_eq!(input.len() % BLOCK_LEN, 0); - self.func.blocks(&mut self.opaque, input, Pad::Pad); + #[inline(always)] + pub fn update(&mut self, input: &[u8]) { + dispatch!( + self.cpu_features => + (GFp_poly1305_update | GFp_poly1305_update_neon) + (statep: &mut poly1305_state, input: *const u8, in_len: c::size_t) + (&mut self.state, input.as_ptr(), input.len())); } pub(super) fn finish(mut self) -> Tag { - self.func.emit(&mut self.opaque, &self.nonce) - } -} - -#[cfg(test)] -pub fn check_state_layout() { - let required_state_size = if cfg!(target_arch = "x86") { - // See comment above `_poly1305_init_sse2` in poly1305-x86.pl. - Some(4 * (5 + 1 + 4 + 2 + 4 * 9)) - } else if cfg!(target_arch = "x86_64") { - // See comment above `__poly1305_block` in poly1305-x86_64.pl. - Some(4 * (5 + 1 + 2 * 2 + 2 + 4 * 9)) - } else { - // TODO(davidben): Figure out the layout of the struct. For now, - // `OPAQUE_LEN` is taken from OpenSSL. - None - }; - - if let Some(required_state_size) = required_state_size { - assert!(core::mem::size_of::() >= required_state_size); - } -} - -#[repr(C)] -struct DerivedKey([u8; BLOCK_LEN]); - -/// This is *not* an "AEAD nonce"; it's a Poly1305-specific nonce. -#[repr(C)] -struct Nonce([u8; BLOCK_LEN]); - -#[repr(C)] -struct Funcs { - blocks_fn: - unsafe extern "C" fn(&mut Opaque, input: *const u8, input_len: c::size_t, should_pad: Pad), - emit_fn: unsafe extern "C" fn(&mut Opaque, &mut Tag, nonce: &Nonce), -} - -#[inline] -fn init(state: &mut Opaque, key: DerivedKey, func: &mut Funcs) -> Result<(), error::Unspecified> { - extern "C" { - fn GFp_poly1305_init_asm( - state: &mut Opaque, - key: &DerivedKey, - out_func: &mut Funcs, - ) -> bssl::Result; - } - Result::from(unsafe { GFp_poly1305_init_asm(state, &key, func) }) -} - -#[repr(u32)] -pub enum Pad { - AlreadyPadded = 0, - Pad = 1, -} - -impl Funcs { - #[inline] - fn blocks(&self, state: &mut Opaque, data: &[u8], should_pad: Pad) { - unsafe { - (self.blocks_fn)(state, data.as_ptr(), data.len(), should_pad); - } - } - - #[inline] - fn emit(&self, state: &mut Opaque, nonce: &Nonce) -> Tag { let mut tag = Tag([0u8; TAG_LEN]); - unsafe { - (self.emit_fn)(state, &mut tag, nonce); - } + dispatch!( + self.cpu_features => + (GFp_poly1305_finish | GFp_poly1305_finish_neon) + (statep: &mut poly1305_state, mac: &mut [u8; TAG_LEN]) + (&mut self.state, &mut tag.0)); tag } } @@ -174,16 +124,7 @@ impl Funcs { /// poly1305 test vectors. pub(super) fn sign(key: Key, input: &[u8]) -> Tag { let mut ctx = Context::from_key(key); - let remainder_len = input.len() % BLOCK_LEN; - let full_blocks_len = input.len() - remainder_len; - let (full_blocks, remainder) = input.split_at(full_blocks_len); - ctx.update_blocks(full_blocks); - if remainder_len > 0 { - let mut bytes = [0; BLOCK_LEN]; - bytes[..remainder_len].copy_from_slice(remainder); - bytes[remainder_len] = 1; - ctx.update_block(Block::from(&bytes), Pad::AlreadyPadded); - } + ctx.update(input); ctx.finish() } @@ -193,21 +134,17 @@ mod tests { use crate::test; use core::convert::TryInto; - #[test] - pub fn test_state_layout() { - check_state_layout(); - } - // Adapted from BoringSSL's crypto/poly1305/poly1305_test.cc. #[test] pub fn test_poly1305() { + let cpu_features = cpu::features(); test::run(test_file!("poly1305_test.txt"), |section, test_case| { assert_eq!(section, ""); let key = test_case.consume_bytes("Key"); let key: &[u8; BLOCK_LEN * 2] = key.as_slice().try_into().unwrap(); let input = test_case.consume_bytes("Input"); let expected_mac = test_case.consume_bytes("MAC"); - let key = Key::from(*key); + let key = Key::new(*key, cpu_features); let Tag(actual_mac) = sign(key, &input); assert_eq!(expected_mac, actual_mac.as_ref()); diff --git a/src/aead/quic.rs b/src/aead/quic.rs index e83e076c77..ac667aeda1 100644 --- a/src/aead/quic.rs +++ b/src/aead/quic.rs @@ -28,7 +28,7 @@ pub struct HeaderProtectionKey { algorithm: &'static Algorithm, } -#[allow(variant_size_differences)] +#[allow(clippy::large_enum_variant, variant_size_differences)] enum KeyInner { Aes(aes::Key), ChaCha20(chacha::Key), diff --git a/src/agreement.rs b/src/agreement.rs index 4c1e803430..d116c8faab 100644 --- a/src/agreement.rs +++ b/src/agreement.rs @@ -63,7 +63,6 @@ // Model." use crate::{cpu, debug, ec, error, rand}; -use untrusted; pub use crate::ec::{ curve25519::x25519::X25519, diff --git a/src/arithmetic/bigint.rs b/src/arithmetic/bigint.rs index f563b66c51..620595effd 100644 --- a/src/arithmetic/bigint.rs +++ b/src/arithmetic/bigint.rs @@ -46,7 +46,6 @@ use core::{ marker::PhantomData, ops::{Deref, DerefMut}, }; -use untrusted; pub unsafe trait Prime {} @@ -86,7 +85,7 @@ impl Clone for BoxedLimbs { fn clone(&self) -> Self { Self { limbs: self.limbs.clone(), - m: self.m.clone(), + m: self.m, } } } @@ -137,7 +136,7 @@ impl BoxedLimbs { fn zero(width: Width) -> Self { Self { - limbs: vec![0; width.num_limbs].to_owned().into_boxed_slice(), + limbs: vec![0; width.num_limbs].into_boxed_slice(), m: PhantomData, } } @@ -264,6 +263,7 @@ impl Modulus { // n_mod_r = n % r. As explained in the documentation for `n0`, this is // done by taking the lowest `N0_LIMBS_USED` limbs of `n`. + #[allow(clippy::useless_conversion)] let n0 = { extern "C" { fn GFp_bn_neg_inv_mod_r_u64(n: u64) -> u64; @@ -389,7 +389,7 @@ impl Clone for Elem { fn clone(&self) -> Self { Self { limbs: self.limbs.clone(), - encoding: self.encoding.clone(), + encoding: self.encoding, } } } @@ -1169,7 +1169,7 @@ impl Nonnegative { return Err(error::Unspecified); } } - return Ok(()); + Ok(()) } } @@ -1397,7 +1397,6 @@ mod tests { use super::*; use crate::test; use alloc::format; - use untrusted; // Type-level representation of an arbitrary modulus. struct M {} @@ -1530,7 +1529,7 @@ mod tests { #[test] fn test_modulus_debug() { let (modulus, _) = Modulus::::from_be_bytes_with_bit_length(untrusted::Input::from( - &vec![0xff; LIMB_BYTES * MODULUS_MIN_LIMBS], + &[0xff; LIMB_BYTES * MODULUS_MIN_LIMBS], )) .unwrap(); assert_eq!("Modulus", format!("{:?}", modulus)); diff --git a/src/cpu.rs b/src/cpu.rs index d5e09af459..e0895ae809 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -24,16 +24,15 @@ pub(crate) struct Features(()); #[inline(always)] pub(crate) fn features() -> Features { - // We don't do runtime feature detection on iOS. instead some features are - // assumed to be present; see `arm::Feature`. - #[cfg(all( - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86", - target_arch = "x86_64" - ), - not(target_os = "ios") + // We don't do runtime feature detection on aarch64-apple-* as all AAarch64 + // features we use are available on every device since the first devices. + #[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + all( + any(target_arch = "aarch64", target_arch = "arm"), + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ) ))] { static INIT: spin::Once<()> = spin::Once::new(); @@ -49,16 +48,11 @@ pub(crate) fn features() -> Features { } #[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_arch = "aarch64", target_arch = "arm") + any(target_arch = "aarch64", target_arch = "arm"), + any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] { - arm::linux_setup(); - } - - #[cfg(all(target_os = "fuchsia", any(target_arch = "aarch64")))] - { - arm::fuchsia_setup(); + arm::setup(); } }); } @@ -71,7 +65,7 @@ pub(crate) mod arm { any(target_os = "android", target_os = "linux"), any(target_arch = "aarch64", target_arch = "arm") ))] - pub fn linux_setup() { + pub fn setup() { use libc::c_ulong; // XXX: The `libc` crate doesn't provide `libc::getauxval` consistently @@ -123,15 +117,15 @@ pub(crate) mod arm { features |= PMULL.mask; } if caps & HWCAP_SHA2 == HWCAP_SHA2 { - features |= 1 << 4; + features |= SHA256.mask; } unsafe { GFp_armcap_P = features }; } } - #[cfg(all(target_os = "fuchsia", any(target_arch = "aarch64")))] - pub fn fuchsia_setup() { + #[cfg(all(target_os = "fuchsia", target_arch = "aarch64"))] + pub fn setup() { type zx_status_t = i32; #[link(name = "zircon")] @@ -168,82 +162,139 @@ pub(crate) mod arm { } } - #[cfg(not(target_arch = "wasm32"))] + macro_rules! features { + { + $( + $name:ident { + mask: $mask:expr, + + /// Should we assume that the feature is always available + /// for aarch64-apple-* targets? The first AArch64 iOS + /// device used the Apple A7 chip. + // TODO: When we can use `if` in const expressions: + // ``` + // aarch64_apple: $aarch64_apple, + // ``` + aarch64_apple: true, + } + ),+ + , // trailing comma is required. + } => { + $( + #[allow(dead_code)] + pub(crate) const $name: Feature = Feature { + mask: $mask, + }; + )+ + + // TODO: When we can use `if` in const expressions, do this: + // ``` + // const ARMCAP_STATIC: u32 = 0 + // $( + // | ( if $aarch64_apple && + // cfg!(all(target_arch = "aarch64", + // target_vendor = "apple")) { + // $name.mask + // } else { + // 0 + // } + // ) + // )+; + // ``` + // + // TODO: Add static feature detection to other targets. + // TODO: Combine static feature detection with runtime feature + // detection. + #[cfg(all(target_arch = "aarch64", target_vendor = "apple"))] + const ARMCAP_STATIC: u32 = 0 + $( | $name.mask + )+; + #[cfg(not(all(target_arch = "aarch64", target_vendor = "apple")))] + const ARMCAP_STATIC: u32 = 0; + + #[cfg(all(target_arch = "aarch64", target_vendor = "apple"))] + #[test] + fn test_armcap_static_available() { + let features = crate::cpu::features(); + $( + assert!($name.available(features)); + )+ + } + } + } + + #[allow(dead_code)] pub(crate) struct Feature { - #[cfg_attr( - any( - target_os = "ios", - not(any(target_arch = "arm", target_arch = "aarch64")) - ), - allow(dead_code) - )] mask: u32, - - #[cfg_attr(not(target_os = "ios"), allow(dead_code))] - ios: bool, } - #[cfg(not(target_arch = "wasm32"))] impl Feature { + #[allow(dead_code)] #[inline(always)] pub fn available(&self, _: super::Features) -> bool { - #[cfg(all(target_os = "ios", any(target_arch = "arm", target_arch = "aarch64")))] - { - return self.ios; + if self.mask == self.mask & ARMCAP_STATIC { + return true; } #[cfg(all( - any(target_os = "android", target_os = "linux", target_os = "fuchsia", target_os = "switch"), + any(target_os = "android", target_os = "fuchsia", target_os = "linux"), any(target_arch = "arm", target_arch = "aarch64") ))] { - return self.mask == self.mask & unsafe { GFp_armcap_P }; + if self.mask == self.mask & unsafe { GFp_armcap_P } { + return true; + } } - #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] - { - return false; - } + false } } - // Keep in sync with `ARMV7_NEON`. - #[cfg(all(any(target_arch = "aarch64", target_arch = "arm"), not(target_os = "switch")))] - pub(crate) const NEON: Feature = Feature { - mask: 1 << 0, - ios: true, - }; + features! { + // Keep in sync with `ARMV7_NEON`. + NEON { + mask: 1 << 0, + aarch64_apple: true, + }, + + // Keep in sync with `ARMV8_AES`. + AES { + mask: 1 << 2, + aarch64_apple: true, + }, + + // Keep in sync with `ARMV8_SHA256`. + SHA256 { + mask: 1 << 4, + aarch64_apple: true, + }, + + // Keep in sync with `ARMV8_PMULL`. + PMULL { + mask: 1 << 5, + aarch64_apple: true, + }, + } - // Keep in sync with `ARMV8_AES`. - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86", - target_arch = "x86_64" - ))] - pub(crate) const AES: Feature = Feature { - mask: 1 << 2, - ios: true, - }; - - // Keep in sync with `ARMV8_PMULL`. - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86", - target_arch = "x86_64" - ))] - pub(crate) const PMULL: Feature = Feature { - mask: 1 << 5, - ios: true, - }; + // Some non-Rust code still checks this even when it is statically known + // the given feature is available, so we have to ensure that this is + // initialized properly. Keep this in sync with the initialization in + // BoringSSL's crypto.c. + // + // TODO: This should have "hidden" visibility but we don't have a way of + // controlling that yet: https://github.com/rust-lang/rust/issues/73958. + #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] + #[no_mangle] + static mut GFp_armcap_P: u32 = ARMCAP_STATIC; #[cfg(all( - any(target_os = "android", target_os = "linux", target_os = "fuchsia", target_os = "switch"), - any(target_arch = "arm", target_arch = "aarch64") + any(target_arch = "arm", target_arch = "aarch64"), + target_vendor = "apple" ))] - extern "C" { - static mut GFp_armcap_P: u32; + #[test] + fn test_armcap_static_matches_armcap_dynamic() { + assert_eq!(ARMCAP_STATIC, 1 | 4 | 16 | 32); + assert_eq!(ARMCAP_STATIC, unsafe { GFp_armcap_P }); } } @@ -258,6 +309,7 @@ pub(crate) mod intel { } impl Feature { + #[allow(clippy::needless_return)] #[inline(always)] pub fn available(&self, _: super::Features) -> bool { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] @@ -290,6 +342,12 @@ pub(crate) mod intel { mask: 1 << 9, }; + #[cfg(target_arch = "x86_64")] + pub(crate) const SSE41: Feature = Feature { + word: 1, + mask: 1 << 19, + }; + #[cfg(target_arch = "x86_64")] pub(crate) const MOVBE: Feature = Feature { word: 1, diff --git a/src/ec/curve25519/ed25519/signing.rs b/src/ec/curve25519/ed25519/signing.rs index b89e0db66a..3b522e8191 100644 --- a/src/ec/curve25519/ed25519/signing.rs +++ b/src/ec/curve25519/ed25519/signing.rs @@ -22,7 +22,6 @@ use crate::{ signature::{self, KeyPair as SigningKeyPair}, }; use core::convert::TryInto; -use untrusted; /// An Ed25519 key pair, for signing. pub struct Ed25519KeyPair { @@ -43,10 +42,11 @@ impl Ed25519KeyPair { /// PKCS#8 document. /// /// The PKCS#8 document will be a v2 `OneAsymmetricKey` with the public key, - /// as described in [RFC 5958 Section 2]. See also - /// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04. + /// as described in [RFC 5958 Section 2]; see [RFC 8410 Section 10.3] for an + /// example. /// /// [RFC 5958 Section 2]: https://tools.ietf.org/html/rfc5958#section-2 + /// [RFC 8410 Section 10.3]: https://tools.ietf.org/html/rfc8410#section-10.3 pub fn generate_pkcs8( rng: &dyn rand::SecureRandom, ) -> Result { diff --git a/src/ec/curve25519/ed25519/verification.rs b/src/ec/curve25519/ed25519/verification.rs index 6d082e093f..e0c1b652fa 100644 --- a/src/ec/curve25519/ed25519/verification.rs +++ b/src/ec/curve25519/ed25519/verification.rs @@ -17,7 +17,6 @@ use super::{super::ops::*, eddsa_digest}; use crate::{error, sealed, signature}; use core::convert::TryInto; -use untrusted; /// Parameters for EdDSA signing and verification. pub struct EdDSAParameters; diff --git a/src/ec/curve25519/x25519.rs b/src/ec/curve25519/x25519.rs index 44ee17f4a9..53a2a5cf84 100644 --- a/src/ec/curve25519/x25519.rs +++ b/src/ec/curve25519/x25519.rs @@ -17,7 +17,6 @@ use super::{ops, scalar::SCALAR_LEN}; use crate::{agreement, constant_time, cpu, ec, error, rand}; use core::convert::TryInto; -use untrusted; static CURVE25519: ec::Curve = ec::Curve { public_key_len: PUBLIC_KEY_LEN, diff --git a/src/ec/suite_b.rs b/src/ec/suite_b.rs index caa5b3f1df..9e363563b8 100644 --- a/src/ec/suite_b.rs +++ b/src/ec/suite_b.rs @@ -16,7 +16,6 @@ use self::ops::*; use crate::{arithmetic::montgomery::*, cpu, ec, error, io::der, limb::LimbMask, pkcs8}; -use untrusted; // NIST SP 800-56A Step 3: "If q is an odd prime p, verify that // yQ**2 = xQ**3 + axQ + b in GF(p), where the arithmetic is performed modulo diff --git a/src/ec/suite_b/curve.rs b/src/ec/suite_b/curve.rs index 0788e10712..e0ff4f4617 100644 --- a/src/ec/suite_b/curve.rs +++ b/src/ec/suite_b/curve.rs @@ -31,7 +31,7 @@ macro_rules! suite_b_curve { /// [NIST Special Publication 800-56A, revision 2]: /// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf /// [Suite B Implementer's Guide to NIST SP 800-56A]: - /// https://github.com/briansmith/ring/blob/master/doc/ecdh.pdf + /// https://github.com/briansmith/ring/blob/main/doc/ecdh.pdf pub static $NAME: ec::Curve = ec::Curve { public_key_len: 1 + (2 * (($bits + 7) / 8)), elem_scalar_seed_len: ($bits + 7) / 8, diff --git a/src/ec/suite_b/ecdh.rs b/src/ec/suite_b/ecdh.rs index f8680ccad6..aae31d2369 100644 --- a/src/ec/suite_b/ecdh.rs +++ b/src/ec/suite_b/ecdh.rs @@ -16,7 +16,6 @@ use super::{ops::*, private_key::*, public_key::*}; use crate::{agreement, ec, error}; -use untrusted; /// A key agreement algorithm. macro_rules! ecdh { @@ -38,7 +37,7 @@ macro_rules! ecdh { /// [NIST Special Publication 800-56A, revision 2]: /// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf /// [Suite B Implementer's Guide to NIST SP 800-56A]: - /// https://github.com/briansmith/ring/blob/master/doc/ecdh.pdf + /// https://github.com/briansmith/ring/blob/main/doc/ecdh.pdf pub static $NAME: agreement::Algorithm = agreement::Algorithm { curve: $curve, ecdh: $ecdh, diff --git a/src/ec/suite_b/ecdsa/digest_scalar.rs b/src/ec/suite_b/ecdsa/digest_scalar.rs index 1f885c1a92..133e7da5df 100644 --- a/src/ec/suite_b/ecdsa/digest_scalar.rs +++ b/src/ec/suite_b/ecdsa/digest_scalar.rs @@ -19,7 +19,6 @@ use crate::{ ec::suite_b::ops::*, limb::{self, LIMB_BYTES}, }; -use untrusted; /// Calculate the digest of `msg` using the digest algorithm `digest_alg`. Then /// convert the digest to a scalar in the range [0, n) as described in @@ -84,7 +83,6 @@ mod tests { limb::{self, LIMB_BYTES}, test, }; - use untrusted; #[test] fn test() { diff --git a/src/ec/suite_b/ecdsa/signing.rs b/src/ec/suite_b/ecdsa/signing.rs index ca2bb39b05..5422e06b16 100644 --- a/src/ec/suite_b/ecdsa/signing.rs +++ b/src/ec/suite_b/ecdsa/signing.rs @@ -26,8 +26,6 @@ use crate::{ io::der, limb, pkcs8, rand, sealed, signature, }; -use untrusted; - /// An ECDSA signing algorithm. pub struct EcdsaSigningAlgorithm { curve: &'static ec::Curve, diff --git a/src/ec/suite_b/ecdsa/verification.rs b/src/ec/suite_b/ecdsa/verification.rs index 2b4ccbed69..be551e695d 100644 --- a/src/ec/suite_b/ecdsa/verification.rs +++ b/src/ec/suite_b/ecdsa/verification.rs @@ -23,7 +23,6 @@ use crate::{ io::der, limb, sealed, signature, }; -use untrusted; /// An ECDSA verification algorithm. pub struct EcdsaVerificationAlgorithm { diff --git a/src/ec/suite_b/ops.rs b/src/ec/suite_b/ops.rs index 6bcb8a4bb5..13d80c0d2e 100644 --- a/src/ec/suite_b/ops.rs +++ b/src/ec/suite_b/ops.rs @@ -14,7 +14,6 @@ use crate::{arithmetic::montgomery::*, c, error, limb::*}; use core::marker::PhantomData; -use untrusted; pub use self::elem::*; @@ -441,7 +440,6 @@ mod tests { use super::*; use crate::test; use alloc::{format, vec, vec::Vec}; - use untrusted; const ZERO_SCALAR: Scalar = Scalar { limbs: [0; MAX_LIMBS], @@ -491,11 +489,11 @@ mod tests { let b = consume_elem(cops, test_case, "b"); let expected_sum = consume_elem(cops, test_case, "r"); - let mut actual_sum = a.clone(); + let mut actual_sum = a; ops.public_key_ops.common.elem_add(&mut actual_sum, &b); assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs); - let mut actual_sum = b.clone(); + let mut actual_sum = b; ops.public_key_ops.common.elem_add(&mut actual_sum, &a); assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs); @@ -692,10 +690,10 @@ mod tests { test::run(test_file, |section, test_case| { assert_eq!(section, ""); let cops = ops.common; - let mut a = consume_scalar(cops, test_case, "a"); + let a = consume_scalar(cops, test_case, "a"); let b = consume_scalar_mont(cops, test_case, "b"); let expected_result = consume_scalar(cops, test_case, "r"); - let actual_result = ops.scalar_product(&mut a, &b); + let actual_result = ops.scalar_product(&a, &b); assert_limbs_are_equal(cops, &actual_result.limbs, &expected_result.limbs); Ok(()) @@ -1072,7 +1070,7 @@ mod tests { p } - fn consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &Vec<&str>, i: usize) { + fn consume_point_elem(ops: &CommonOps, limbs_out: &mut [Limb], elems: &[&str], i: usize) { let bytes = test::from_hex(elems[i]).unwrap(); let bytes = untrusted::Input::from(&bytes); let r: Elem = elem_parse_big_endian_fixed_consttime(ops, bytes).unwrap(); @@ -1087,7 +1085,7 @@ mod tests { } fn consume_point(ops: &PrivateKeyOps, test_case: &mut test::TestCase, name: &str) -> TestPoint { - fn consume_point_elem(ops: &CommonOps, elems: &Vec<&str>, i: usize) -> Elem { + fn consume_point_elem(ops: &CommonOps, elems: &[&str], i: usize) -> Elem { let bytes = test::from_hex(elems[i]).unwrap(); let bytes = untrusted::Input::from(&bytes); let unencoded: Elem = @@ -1178,84 +1176,6 @@ mod tests { } } -#[cfg(feature = "internal_benches")] -mod internal_benches { - use super::{Limb, MAX_LIMBS}; - - pub const LIMBS_1: [Limb; MAX_LIMBS] = limbs![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - - pub const LIMBS_ALTERNATING_10: [Limb; MAX_LIMBS] = limbs![ - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010, - 0b10101010_10101010_10101010_10101010 - ]; -} - -#[cfg(feature = "internal_benches")] -macro_rules! bench_curve { - ( $vectors:expr ) => { - use super::super::{Elem, Scalar}; - extern crate test; - - #[bench] - fn elem_inverse_squared_bench(bench: &mut test::Bencher) { - // This benchmark assumes that `elem_inverse_squared()` is - // constant-time so inverting 1 mod q is as good of a choice as - // anything. - let mut a = Elem::zero(); - a.limbs[0] = 1; - bench.iter(|| { - let _ = PRIVATE_KEY_OPS.elem_inverse_squared(&a); - }); - } - - #[bench] - fn elem_product_bench(bench: &mut test::Bencher) { - // This benchmark assumes that the multiplication is constant-time - // so 0 * 0 is as good of a choice as anything. - let a: Elem = Elem::zero(); - let b: Elem = Elem::zero(); - bench.iter(|| { - let _ = COMMON_OPS.elem_product(&a, &b); - }); - } - - #[bench] - fn elem_squared_bench(bench: &mut test::Bencher) { - // This benchmark assumes that the squaring is constant-time so - // 0**2 * 0 is as good of a choice as anything. - let a = Elem::zero(); - bench.iter(|| { - let _ = COMMON_OPS.elem_squared(&a); - }); - } - - #[bench] - fn scalar_inv_to_mont_bench(bench: &mut test::Bencher) { - const VECTORS: &[Scalar] = $vectors; - let vectors_len = VECTORS.len(); - let mut i = 0; - bench.iter(|| { - let _ = SCALAR_OPS.scalar_inv_to_mont(&VECTORS[i]); - - i += 1; - if i == vectors_len { - i = 0; - } - }); - } - }; -} - mod elem; pub mod p256; pub mod p384; diff --git a/src/ec/suite_b/ops/p256.rs b/src/ec/suite_b/ops/p256.rs index 69c89eb893..4c54f5c00e 100644 --- a/src/ec/suite_b/ops/p256.rs +++ b/src/ec/suite_b/ops/p256.rs @@ -380,36 +380,3 @@ extern "C" { rep: Limb, ); } - -#[cfg(feature = "internal_benches")] -mod internal_benches { - use super::{super::internal_benches::*, *}; - - bench_curve!(&[ - Scalar { - limbs: LIMBS_1, - m: PhantomData, - encoding: PhantomData, - }, - Scalar { - limbs: LIMBS_ALTERNATING_10, - m: PhantomData, - encoding: PhantomData, - }, - Scalar { - // n - 1 - limbs: p256_limbs![ - 0xfc632551 - 1, - 0xf3b9cac2, - 0xa7179e84, - 0xbce6faad, - 0xffffffff, - 0xffffffff, - 0x00000000, - 0xffffffff - ], - m: PhantomData, - encoding: PhantomData, - }, - ]); -} diff --git a/src/ec/suite_b/ops/p384.rs b/src/ec/suite_b/ops/p384.rs index 4b2ecb8300..7ecba1f18f 100644 --- a/src/ec/suite_b/ops/p384.rs +++ b/src/ec/suite_b/ops/p384.rs @@ -368,40 +368,3 @@ extern "C" { b: *const Limb, // [COMMON_OPS.num_limbs] ); } - -#[cfg(feature = "internal_benches")] -mod internal_benches { - use super::{super::internal_benches::*, *}; - - bench_curve!(&[ - Scalar { - limbs: LIMBS_1, - encoding: PhantomData, - m: PhantomData - }, - Scalar { - limbs: LIMBS_ALTERNATING_10, - encoding: PhantomData, - m: PhantomData - }, - Scalar { - // n - 1 - limbs: p384_limbs![ - 0xccc52973 - 1, - 0xecec196a, - 0x48b0a77a, - 0x581a0db2, - 0xf4372ddf, - 0xc7634d81, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff - ], - encoding: PhantomData, - m: PhantomData, - }, - ]); -} diff --git a/src/ec/suite_b/private_key.rs b/src/ec/suite_b/private_key.rs index fb16b245e9..31c35664f6 100644 --- a/src/ec/suite_b/private_key.rs +++ b/src/ec/suite_b/private_key.rs @@ -22,7 +22,6 @@ use crate::{ limb::{self, LIMB_BYTES}, rand, }; -use untrusted; /// Generates a random scalar in the range [1, n). pub fn random_scalar( diff --git a/src/ec/suite_b/public_key.rs b/src/ec/suite_b/public_key.rs index 4521af339e..5bafa36039 100644 --- a/src/ec/suite_b/public_key.rs +++ b/src/ec/suite_b/public_key.rs @@ -17,7 +17,6 @@ use super::{ops::*, verify_affine_point_is_on_the_curve}; use crate::{arithmetic::montgomery::*, error}; -use untrusted; /// Parses a public key encoded in uncompressed form. The key is validated /// using the ECC Partial Public-Key Validation Routine from @@ -69,7 +68,6 @@ pub fn parse_uncompressed_point( mod tests { use super::{super::ops, *}; use crate::test; - use untrusted; #[test] fn parse_uncompressed_point_test() { diff --git a/src/endian.rs b/src/endian.rs index 77ecd91e2d..94979e1b23 100644 --- a/src/endian.rs +++ b/src/endian.rs @@ -1,8 +1,13 @@ -use core::{convert::TryInto, num::Wrapping}; +use core::num::Wrapping; /// An `Encoding` of a type `T` can be converted to/from its byte /// representation without any byte swapping or other computation. -pub trait Encoding: From + Into { +/// +/// The `Self: Copy` constraint addresses `clippy::declare_interior_mutable_const`. +pub trait Encoding: From + Into +where + Self: Copy, +{ const ZERO: Self; } @@ -19,6 +24,12 @@ pub trait ArrayEncoding { fn as_byte_array(&self) -> &T; } +/// Work around the inability to implement `from` for arrays of `Encoding`s +/// due to the coherence rules. +pub trait FromByteArray { + fn from_byte_array(a: &T) -> Self; +} + macro_rules! define_endian { ($endian:ident) => { #[repr(transparent)] @@ -44,15 +55,34 @@ macro_rules! define_endian { }; } -macro_rules! impl_as_ref { +macro_rules! impl_from_byte_array { + ($endian:ident, $base:ident, $elems:expr) => { + impl FromByteArray<[u8; $elems * core::mem::size_of::<$base>()]> + for [$endian<$base>; $elems] + { + fn from_byte_array(a: &[u8; $elems * core::mem::size_of::<$base>()]) -> Self { + unsafe { core::mem::transmute_copy(a) } + } + } + }; +} + +macro_rules! impl_array_encoding { ($endian:ident, $base:ident, $elems:expr) => { impl ArrayEncoding<[u8; $elems * core::mem::size_of::<$base>()]> for [$endian<$base>; $elems] { - fn as_byte_array<'a>(&'a self) -> &'a [u8; $elems * core::mem::size_of::<$base>()] { - as_byte_slice(self).try_into().unwrap() + fn as_byte_array(&self) -> &[u8; $elems * core::mem::size_of::<$base>()] { + // TODO: When we can require Rust 1.47.0 or later we could avoid + // `as` and `unsafe` here using + // `as_byte_slice(self).try_into().unwrap()`. + let as_bytes_ptr = + self.as_ptr() as *const [u8; $elems * core::mem::size_of::<$base>()]; + unsafe { &*as_bytes_ptr } } } + + impl_from_byte_array!($endian, $base, $elems); }; } @@ -97,10 +127,11 @@ macro_rules! impl_endian { } } - impl_as_ref!($endian, $base, 1); - impl_as_ref!($endian, $base, 2); - impl_as_ref!($endian, $base, 3); - impl_as_ref!($endian, $base, 4); + impl_array_encoding!($endian, $base, 1); + impl_array_encoding!($endian, $base, 2); + impl_array_encoding!($endian, $base, 3); + impl_array_encoding!($endian, $base, 4); + impl_array_encoding!($endian, $base, 8); }; } diff --git a/src/error.rs b/src/error.rs index 65d3df0489..23e2ab32a9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,8 +14,6 @@ //! Error reporting. -use untrusted; - #[cfg(feature = "std")] extern crate std; @@ -78,15 +76,30 @@ extern crate std; #[derive(Clone, Copy, Debug, PartialEq)] pub struct Unspecified; +impl Unspecified { + fn description_() -> &'static str { + "ring::error::Unspecified" + } +} + // This is required for the implementation of `std::error::Error`. impl core::fmt::Display for Unspecified { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.write_str("ring::error::Unspecified") + f.write_str(Self::description_()) } } #[cfg(feature = "std")] -impl std::error::Error for Unspecified {} +impl std::error::Error for Unspecified { + #[inline] + fn cause(&self) -> Option<&dyn std::error::Error> { + None + } + + fn description(&self) -> &str { + Self::description_() + } +} impl From for Unspecified { fn from(_: untrusted::EndOfInput) -> Self { @@ -102,10 +115,10 @@ impl From for Unspecified { /// An error parsing or validating a key. /// -/// The `Display` implementation will return a string that will help you better -/// understand why a key was rejected change which errors are reported in which -/// situations while minimizing the likelihood that any applications will be -/// broken. +/// The `Display` implementation and `::description()` +/// will return a string that will help you better understand why a key was +/// rejected change which errors are reported in which situations while +/// minimizing the likelihood that any applications will be broken. /// /// Here is an incomplete list of reasons a key may be unsupported: /// @@ -134,6 +147,11 @@ impl From for Unspecified { pub struct KeyRejected(&'static str); impl KeyRejected { + /// The value returned from ::description() + pub fn description_(&self) -> &'static str { + self.0 + } + pub(crate) fn inconsistent_components() -> Self { KeyRejected("InconsistentComponents") } @@ -185,11 +203,19 @@ impl KeyRejected { } #[cfg(feature = "std")] -impl std::error::Error for KeyRejected {} +impl std::error::Error for KeyRejected { + fn cause(&self) -> Option<&dyn std::error::Error> { + None + } + + fn description(&self) -> &str { + self.description_() + } +} impl core::fmt::Display for KeyRejected { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.write_str(self.0) + f.write_str(self.description_()) } } diff --git a/src/hmac.rs b/src/hmac.rs index 1329058f66..3e2d7e7b0f 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -105,9 +105,9 @@ //! //! [RFC 2104]: https://tools.ietf.org/html/rfc2104 //! [code for `ring::pbkdf2`]: -//! https://github.com/briansmith/ring/blob/master/src/pbkdf2.rs +//! https://github.com/briansmith/ring/blob/main/src/pbkdf2.rs //! [code for `ring::hkdf`]: -//! https://github.com/briansmith/ring/blob/master/src/hkdf.rs +//! https://github.com/briansmith/ring/blob/main/src/hkdf.rs use crate::{constant_time, digest, error, hkdf, rand}; @@ -182,7 +182,9 @@ impl Key { /// random value generated from `rng`. /// /// The key will be `digest_alg.output_len` bytes long, based on the - /// recommendation in https://tools.ietf.org/html/rfc2104#section-3. + /// recommendation in [RFC 2104 Section 3]. + /// + /// [RFC 2104 Section 3]: https://tools.ietf.org/html/rfc2104#section-3 pub fn generate( algorithm: Algorithm, rng: &dyn rand::SecureRandom, @@ -363,7 +365,7 @@ mod tests { // completely wacky. #[test] pub fn hmac_signing_key_coverage() { - let mut rng = rand::SystemRandom::new(); + let rng = rand::SystemRandom::new(); const HELLO_WORLD_GOOD: &[u8] = b"hello, world"; const HELLO_WORLD_BAD: &[u8] = b"hello, worle"; @@ -374,7 +376,7 @@ mod tests { hmac::HMAC_SHA384, hmac::HMAC_SHA512, ] { - let key = hmac::Key::generate(*algorithm, &mut rng).unwrap(); + let key = hmac::Key::generate(*algorithm, &rng).unwrap(); let tag = hmac::sign(&key, HELLO_WORLD_GOOD); assert!(hmac::verify(&key, HELLO_WORLD_GOOD, tag.as_ref()).is_ok()); assert!(hmac::verify(&key, HELLO_WORLD_BAD, tag.as_ref()).is_err()) diff --git a/src/io/der.rs b/src/io/der.rs index 325d6f0d8b..1a00d85999 100644 --- a/src/io/der.rs +++ b/src/io/der.rs @@ -18,7 +18,6 @@ use super::Positive; use crate::error; -use untrusted; pub const CONSTRUCTED: u8 = 1 << 5; pub const CONTEXT_SPECIFIC: u8 = 2 << 6; @@ -212,7 +211,6 @@ pub fn positive_integer<'a>( mod tests { use super::*; use crate::error; - use untrusted; fn with_good_i(value: &[u8], f: F) where diff --git a/src/lib.rs b/src/lib.rs index b54c5f11a3..cc66d73c3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,8 +15,6 @@ //! Safe, fast, small crypto using Rust with BoringSSL's cryptography //! primitives. //! -//! git clone https://github.com/briansmith/ring -//! //! # Feature Flags //! //! @@ -33,22 +31,36 @@ //! fallbacks will not occur. See the documentation for //! rand::SystemRandom for more details. //!
std -//! Enable features that use libstd, in particular `std::error::Error` -//! integration. +//! Enable features that use libstd, in particular +//! std::error::Error integration. Implies `alloc`. //!
wasm32_c //! Enables features that require a C compiler on wasm32 targets, such as //! the constant_time module, HMAC verification, and PBKDF2 //! verification. Without this feature, only a subset of functionality //! is provided to wasm32 targets so that a C compiler isn't needed. A //! typical invocation would be: -//! TARGET_AR=llvm-ar cargo test --target=wasm32-unknown-unknown --features=wasm32_c -//! with llvm-ar and clang in $PATH. +//! TARGET_CC=clang-10 TARGET_AR=llvm-ar-10 cargo test --target=wasm32-unknown-unknown --features=wasm32_c +//! with llvm-ar-10 and clang-10 in $PATH. //! (Going forward more functionality should be enabled by default, without //! requiring these hacks, and without requiring a C compiler.) //!
#![doc(html_root_url = "https://briansmith.org/rustdoc/")] #![allow( + clippy::collapsible_if, + clippy::identity_op, + clippy::len_without_is_empty, + clippy::len_zero, + clippy::let_unit_value, + clippy::many_single_char_names, + clippy::needless_range_loop, + clippy::new_without_default, + clippy::neg_cmp_op_on_partial_ord, + clippy::range_plus_one, + clippy::too_many_arguments, + clippy::trivially_copy_pass_by_ref, + clippy::type_complexity, + clippy::unreadable_literal, missing_copy_implementations, missing_debug_implementations, non_camel_case_types, @@ -57,23 +69,9 @@ )] // `#[derive(...)]` uses `trivial_numeric_casts` and `unused_qualifications` // internally. -#![deny( - missing_docs, - unstable_features, // Used by `internal_benches` - unused_qualifications, - variant_size_differences, -)] -#![forbid( - anonymous_parameters, - trivial_casts, - trivial_numeric_casts, - unused_extern_crates, - unused_import_braces, - unused_results, - warnings -)] +#![deny(missing_docs, unused_qualifications, variant_size_differences)] +#![forbid(unused_results)] #![no_std] -#![cfg_attr(feature = "internal_benches", allow(unstable_features), feature(test))] #[cfg(feature = "alloc")] extern crate alloc; diff --git a/src/limb.rs b/src/limb.rs index 65fdae5ca7..eb5aed5fa4 100644 --- a/src/limb.rs +++ b/src/limb.rs @@ -19,7 +19,6 @@ //! limbs use the native endianness. use crate::{c, error}; -use untrusted; #[cfg(feature = "alloc")] use crate::bits; @@ -350,7 +349,6 @@ extern "C" { #[cfg(test)] mod tests { use super::*; - use untrusted; const MAX: Limb = LimbMask::True as Limb; @@ -541,10 +539,10 @@ mod tests { #[cfg(target_pointer_width = "64")] let limbs = [ - 0x89900aab_bccddeef, - 0x01122334_45566778, - 0x99aabbcc_ddeeff00, - 0x11223344_55667788, + 0x8990_0aab_bccd_deef, + 0x0112_2334_4556_6778, + 0x99aa_bbcc_ddee_ff00, + 0x1122_3344_5566_7788, ]; let expected = [ @@ -570,9 +568,9 @@ mod tests { // One fewer limb. #[cfg(target_pointer_width = "64")] let limbs = [ - 0x89900aab_bccddeef, - 0x01122334_45566778, - 0x99aabbcc_ddeeff00, + 0x8990_0aab_bccd_deef, + 0x0112_2334_4556_6778, + 0x99aa_bbcc_ddee_ff00, ]; let mut out = [0xabu8; 32]; diff --git a/src/pkcs8.rs b/src/pkcs8.rs index 53bec5ae81..c3ca49918a 100644 --- a/src/pkcs8.rs +++ b/src/pkcs8.rs @@ -17,7 +17,6 @@ //! [RFC 5958]: https://tools.ietf.org/html/rfc5958. use crate::{ec, error, io::der}; -use untrusted; pub(crate) enum Version { V1Only, diff --git a/src/rand.rs b/src/rand.rs index ca97733b2c..467f822e2f 100644 --- a/src/rand.rs +++ b/src/rand.rs @@ -180,10 +180,12 @@ use self::sysrand::fill as fill_impl; use self::sysrand_or_urandom::fill as fill_impl; #[cfg(any( + target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris" + target_os = "solaris", ))] use self::urandom::fill as fill_impl; @@ -193,9 +195,6 @@ use self::darwin::fill as fill_impl; #[cfg(any(target_os = "fuchsia"))] use self::fuchsia::fill as fill_impl; -#[cfg(target_os = "switch")] -use self::switch::fill as fill_impl; - #[cfg(any(target_os = "android", target_os = "linux"))] mod sysrand_chunk { use crate::{c, error}; @@ -354,10 +353,12 @@ mod sysrand_or_urandom { any(target_os = "android", target_os = "linux"), feature = "dev_urandom_fallback" ), + target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris" + target_os = "solaris", + target_os = "illumos" ))] mod urandom { use crate::error; @@ -431,6 +432,9 @@ mod fuchsia { } } +#[cfg(target_os = "switch")] +use self::switch::fill as fill_impl; + #[cfg(target_os = "switch")] mod switch { use crate::error; diff --git a/src/rsa.rs b/src/rsa.rs index 04a3bf87bd..9adb3285dd 100644 --- a/src/rsa.rs +++ b/src/rsa.rs @@ -24,7 +24,6 @@ use crate::{ io::{self, der}, limb, }; -use untrusted; mod padding; diff --git a/src/rsa/padding.rs b/src/rsa/padding.rs index 3ba00e10f0..f6b4cf6c74 100644 --- a/src/rsa/padding.rs +++ b/src/rsa/padding.rs @@ -14,7 +14,6 @@ use super::PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN; use crate::{bits, digest, error, io::der}; -use untrusted; #[cfg(feature = "alloc")] use crate::rand; @@ -100,7 +99,7 @@ impl Verification for PKCS1 { let mut calculated = [0u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN]; let calculated = &mut calculated[..mod_bits.as_usize_bytes_rounded_up()]; pkcs1_encode(&self, m_hash, calculated); - if m.read_bytes_to_end() != *calculated.as_ref() { + if m.read_bytes_to_end() != *calculated { return Err(error::Unspecified); } Ok(()) @@ -279,7 +278,7 @@ impl RsaEncoding for PSS { { // Steps 7. - let masked_db = masked_db.into_iter(); + let masked_db = masked_db.iter_mut(); // `PS` is all zero bytes, so skipping `ps_len` bytes is equivalent // to XORing `PS` onto `db`. let mut masked_db = masked_db.skip(metrics.ps_len); @@ -522,7 +521,6 @@ mod test { use super::*; use crate::{digest, error, test}; use alloc::vec; - use untrusted; #[test] fn test_pss_padding_verify() { diff --git a/src/rsa/signing.rs b/src/rsa/signing.rs index 9ae904e4b2..52d857d302 100644 --- a/src/rsa/signing.rs +++ b/src/rsa/signing.rs @@ -25,7 +25,6 @@ use crate::{ pkcs8, rand, signature, }; use alloc::boxed::Box; -use untrusted; /// An RSA key pair, used for signing. pub struct RsaKeyPair { @@ -621,8 +620,7 @@ mod tests { const MESSAGE: &[u8] = b"hello, world"; let rng = rand::SystemRandom::new(); - const PRIVATE_KEY_DER: &'static [u8] = - include_bytes!("signature_rsa_example_private_key.der"); + const PRIVATE_KEY_DER: &[u8] = include_bytes!("signature_rsa_example_private_key.der"); let key_pair = signature::RsaKeyPair::from_der(PRIVATE_KEY_DER).unwrap(); // The output buffer is one byte too short. diff --git a/src/rsa/verification.rs b/src/rsa/verification.rs index cedf64f783..f898f211a6 100644 --- a/src/rsa/verification.rs +++ b/src/rsa/verification.rs @@ -22,8 +22,6 @@ use crate::{ sealed, signature, }; -use untrusted; - #[derive(Debug)] pub struct Key { pub n: bigint::Modulus, diff --git a/src/signature.rs b/src/signature.rs index e325dc0a7a..bef92dc4b8 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -111,7 +111,7 @@ //! [NIST Special Publication 800-56A, revision 2]: //! http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf //! [Suite B implementer's guide to FIPS 186-3]: -//! https://github.com/briansmith/ring/blob/master/doc/ecdsa.pdf +//! https://github.com/briansmith/ring/blob/main/doc/ecdsa.pdf //! [RFC 3279 Section 2.2.3]: //! https://tools.ietf.org/html/rfc3279#section-2.2.3 //! [RFC 3447 Section 8.2]: @@ -132,7 +132,7 @@ //! signature::{self, KeyPair}, //! }; //! -//! # fn sign_and_verify_ed25519() -> Result<(), ring::error::Unspecified> { +//! # fn main() -> Result<(), ring::error::Unspecified> { //! // Generate a key pair in PKCS#8 (v2) format. //! let rng = rand::SystemRandom::new(); //! let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)?; @@ -160,8 +160,6 @@ //! //! # Ok(()) //! # } -//! -//! # fn main() { sign_and_verify_ed25519().unwrap() } //! ``` //! //! ## Signing and verifying with RSA (PKCS#1 1.5 padding) @@ -257,7 +255,6 @@ //! ``` use crate::{cpu, ec, error, sealed}; -use untrusted; pub use crate::ec::{ curve25519::ed25519::{ diff --git a/src/test.rs b/src/test.rs index 69d0e8fc82..304968840c 100644 --- a/src/test.rs +++ b/src/test.rs @@ -380,15 +380,16 @@ pub fn from_hex(hex_str: &str) -> Result, String> { #[cfg(feature = "alloc")] fn from_hex_digit(d: u8) -> Result { - if d >= b'0' && d <= b'9' { - Ok(d - b'0') - } else if d >= b'a' && d <= b'f' { - Ok(d - b'a' + 10u8) - } else if d >= b'A' && d <= b'F' { - Ok(d - b'A' + 10u8) - } else { - Err(format!("Invalid hex digit '{}'", d as char)) + use core::ops::RangeInclusive; + const DECIMAL: (u8, RangeInclusive) = (0, b'0'..=b'9'); + const HEX_LOWER: (u8, RangeInclusive) = (10, b'a'..=b'f'); + const HEX_UPPER: (u8, RangeInclusive) = (10, b'A'..=b'F'); + for (offset, range) in &[DECIMAL, HEX_LOWER, HEX_UPPER] { + if range.contains(&d) { + return Ok(d - range.start() + offset); + } } + Err(format!("Invalid hex digit '{}'", d as char)) } #[cfg(feature = "alloc")] diff --git a/tests/aead_tests.rs b/tests/aead_tests.rs index 0fc7ff18e8..75e0e9e92d 100644 --- a/tests/aead_tests.rs +++ b/tests/aead_tests.rs @@ -13,23 +13,6 @@ // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #![cfg(any(not(target_arch = "wasm32"), feature = "wasm32_c"))] -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; @@ -208,22 +191,20 @@ fn test_aead( ]; let mut more_comprehensive_in_prefix_lengths = [0; 4096]; - let in_prefix_lengths; - if cfg!(debug_assertions) { - in_prefix_lengths = &MINIMAL_IN_PREFIX_LENS[..]; + let in_prefix_lengths = if cfg!(debug_assertions) { + &MINIMAL_IN_PREFIX_LENS[..] } else { + #[allow(clippy::needless_range_loop)] for b in 0..more_comprehensive_in_prefix_lengths.len() { more_comprehensive_in_prefix_lengths[b] = b; } - in_prefix_lengths = &more_comprehensive_in_prefix_lengths[..]; - } + &more_comprehensive_in_prefix_lengths[..] + }; let mut o_in_out = vec![123u8; 4096]; - for in_prefix_len in in_prefix_lengths.iter() { + for &in_prefix_len in in_prefix_lengths.iter() { o_in_out.truncate(0); - for _ in 0..*in_prefix_len { - o_in_out.push(123); - } + o_in_out.resize(in_prefix_len, 123); o_in_out.extend_from_slice(&ct[..]); let nonce = aead::Nonce::try_assume_unique_for_key(&nonce_bytes).unwrap(); @@ -233,7 +214,7 @@ fn test_aead( nonce, aead::Aad::from(&aad[..]), &mut o_in_out, - *in_prefix_len.., + in_prefix_len.., ); match error { None => { @@ -300,6 +281,7 @@ fn open_with_less_safe_key<'a>( key.open_within(nonce, aad, in_out, ciphertext_and_tag) } +#[allow(clippy::range_plus_one)] fn test_aead_key_sizes(aead_alg: &'static aead::Algorithm) { let key_len = aead_alg.key_len(); let key_data = vec![0u8; key_len * 2]; @@ -327,6 +309,7 @@ fn test_aead_key_sizes(aead_alg: &'static aead::Algorithm) { } // Test that we reject non-standard nonce sizes. +#[allow(clippy::range_plus_one)] #[test] fn test_aead_nonce_sizes() -> Result<(), error::Unspecified> { let nonce_len = aead::NONCE_LEN; @@ -350,6 +333,7 @@ fn test_aead_nonce_sizes() -> Result<(), error::Unspecified> { target_arch = "x86_64", target_arch = "x86" ))] +#[allow(clippy::range_plus_one)] #[test] fn aead_chacha20_poly1305_openssh() { // TODO: test_aead_key_sizes(...); @@ -380,7 +364,7 @@ fn aead_chacha20_poly1305_openssh() { let mut tag = [0u8; aead::chacha20_poly1305_openssh::TAG_LEN]; let mut s_in_out = plaintext.clone(); let s_key = aead::chacha20_poly1305_openssh::SealingKey::new(&key_bytes); - let () = s_key.seal_in_place(sequence_num, &mut s_in_out[..], &mut tag); + s_key.seal_in_place(sequence_num, &mut s_in_out[..], &mut tag); assert_eq!(&ct, &s_in_out); assert_eq!(&expected_tag, &tag); let o_key = aead::chacha20_poly1305_openssh::OpeningKey::new(&key_bytes); diff --git a/tests/agreement_tests.rs b/tests/agreement_tests.rs index 7e4152d139..4162015378 100644 --- a/tests/agreement_tests.rs +++ b/tests/agreement_tests.rs @@ -12,30 +12,12 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - extern crate alloc; use ring::{agreement, error, rand, test, test_file}; #[test] -fn agreement_traits<'a>() { +fn agreement_traits() { use alloc::vec::Vec; let rng = rand::SystemRandom::new(); @@ -61,9 +43,9 @@ fn agreement_traits<'a>() { // TODO: Test the actual output. let _: &dyn core::fmt::Debug = &public_key; - test::compile_time_assert_clone::>(); - test::compile_time_assert_copy::>(); - test::compile_time_assert_sync::>(); + test::compile_time_assert_clone::>(); + test::compile_time_assert_copy::>(); + test::compile_time_assert_sync::>(); test::compile_time_assert_clone::>>(); test::compile_time_assert_sync::>>(); @@ -105,13 +87,12 @@ fn agreement_agree_ephemeral() { assert_eq!(my_private.algorithm(), alg); - assert!( + let result = agreement::agree_ephemeral(my_private, &peer_public, (), |key_material| { assert_eq!(key_material, &output[..]); Ok(()) - }) - .is_ok() - ); + }); + assert_eq!(result, Ok(())); } Some(_) => { @@ -134,7 +115,7 @@ fn agreement_agree_ephemeral() { } } - return Ok(()); + Ok(()) }); } diff --git a/tests/constant_time_tests.rs b/tests/constant_time_tests.rs index 37bcebd93b..422ab2c8b9 100644 --- a/tests/constant_time_tests.rs +++ b/tests/constant_time_tests.rs @@ -28,7 +28,7 @@ fn test_verify_slices_are_equal() { let initial: [u8; 256] = rand::generate(&rand::SystemRandom::new()).unwrap().expose(); { - let copy = initial.clone(); + let copy = initial; for len in 0..copy.len() { // Not equal because the lengths do not match. assert_eq!( @@ -50,7 +50,7 @@ fn test_verify_slices_are_equal() { for i in 0..initial.len() { for bit in 0..8 { - let mut copy = initial.clone(); + let mut copy = initial; copy[i] ^= 1u8 << bit; for len in 0..=initial.len() { @@ -67,7 +67,7 @@ fn test_verify_slices_are_equal() { // The flipped bit is outside of `b` so `a` and `b` are equal. Ok(()) }; - assert_eq!((&a == &b), expected_result.is_ok()); // Sanity check. + assert_eq!(a == b, expected_result.is_ok()); // Sanity check. assert_eq!( constant_time::verify_slices_are_equal(&a, &b), expected_result diff --git a/tests/digest_tests.rs b/tests/digest_tests.rs index 1b16bb66e0..c275de7054 100644 --- a/tests/digest_tests.rs +++ b/tests/digest_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use ring::{digest, test, test_file}; #[cfg(target_arch = "wasm32")] diff --git a/tests/ecdsa_tests.rs b/tests/ecdsa_tests.rs index d0d728d043..317fdbc938 100644 --- a/tests/ecdsa_tests.rs +++ b/tests/ecdsa_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use ring::{ rand, signature::{self, KeyPair}, @@ -86,7 +68,7 @@ fn ecdsa_from_pkcs8_test() { match ( signature::EcdsaKeyPair::from_pkcs8(this_asn1, &input), - error.clone(), + error, ) { (Ok(_), None) => (), (Err(e), None) => panic!("Failed with error \"{}\", but expected to succeed", e), @@ -209,9 +191,11 @@ fn ecdsa_test_public_key_coverage() { assert_eq!(key_pair.public_key().as_ref(), PUBLIC_KEY); // Test `Clone`. - { - let _ = key_pair.public_key().clone(); - } + #[allow(clippy::clone_on_copy, clippy::redundant_clone)] + let _: ::PublicKey = key_pair.public_key().clone(); + + // Test `Copy`. + let _: ::PublicKey = *key_pair.public_key(); // Test `Debug`. assert_eq!(PUBLIC_KEY_DEBUG, format!("{:?}", key_pair.public_key())); diff --git a/tests/ed25519_tests.rs b/tests/ed25519_tests.rs index 0289362162..d800112c90 100644 --- a/tests/ed25519_tests.rs +++ b/tests/ed25519_tests.rs @@ -12,25 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use ring::{ + error, signature::{self, Ed25519KeyPair, KeyPair}, test, test_file, }; @@ -67,26 +50,51 @@ fn test_signature_ed25519() { assert_eq!(&expected_sig[..], actual_sig.as_ref()); // Test Signature verification. - - assert!( - signature::UnparsedPublicKey::new(&signature::ED25519, &public_key) - .verify(&msg, &expected_sig) - .is_ok() - ); + test_signature_verification(&public_key, &msg, &expected_sig, Ok(())); let mut tampered_sig = expected_sig; tampered_sig[0] ^= 1; - assert!( - signature::UnparsedPublicKey::new(&signature::ED25519, &public_key) - .verify(&msg, &tampered_sig) - .is_err() - ); + test_signature_verification(&public_key, &msg, &tampered_sig, Err(error::Unspecified)); Ok(()) }); } +/// Test vectors from BoringSSL. +#[test] +fn test_signature_ed25519_verify() { + test::run( + test_file!("ed25519_verify_tests.txt"), + |section, test_case| { + assert_eq!(section, ""); + + let public_key = test_case.consume_bytes("PUB"); + let msg = test_case.consume_bytes("MESSAGE"); + let sig = test_case.consume_bytes("SIG"); + let expected_result = match test_case.consume_string("Result").as_str() { + "P" => Ok(()), + "F" => Err(error::Unspecified), + s => panic!("{:?} is not a valid result", s), + }; + test_signature_verification(&public_key, &msg, &sig, expected_result); + Ok(()) + }, + ); +} + +fn test_signature_verification( + public_key: &[u8], + msg: &[u8], + sig: &[u8], + expected_result: Result<(), error::Unspecified>, +) { + assert_eq!( + expected_result, + signature::UnparsedPublicKey::new(&signature::ED25519, public_key).verify(msg, sig) + ); +} + #[test] fn test_ed25519_from_seed_and_public_key_misuse() { const PRIVATE_KEY: &[u8] = include_bytes!("ed25519_test_private_key.bin"); @@ -114,14 +122,11 @@ fn test_ed25519_from_pkcs8_unchecked() { let input = test_case.consume_bytes("Input"); let error = test_case.consume_optional_string("Error"); - match ( - Ed25519KeyPair::from_pkcs8_maybe_unchecked(&input), - error.clone(), - ) { + match (Ed25519KeyPair::from_pkcs8_maybe_unchecked(&input), error) { (Ok(_), None) => (), (Err(e), None) => panic!("Failed with error \"{}\", but expected to succeed", e), (Ok(_), Some(e)) => panic!("Succeeded, but expected error \"{}\"", e), - (Err(actual), Some(expected)) => assert_eq!(format!("{}", actual), expected), + (Err(actual), Some(expected)) => assert_eq!(actual.description_(), expected), }; Ok(()) @@ -139,11 +144,11 @@ fn test_ed25519_from_pkcs8() { let input = test_case.consume_bytes("Input"); let error = test_case.consume_optional_string("Error"); - match (Ed25519KeyPair::from_pkcs8(&input), error.clone()) { + match (Ed25519KeyPair::from_pkcs8(&input), error) { (Ok(_), None) => (), (Err(e), None) => panic!("Failed with error \"{}\", but expected to succeed", e), (Ok(_), Some(e)) => panic!("Succeeded, but expected error \"{}\"", e), - (Err(actual), Some(expected)) => assert_eq!(format!("{}", actual), expected), + (Err(actual), Some(expected)) => assert_eq!(actual.description_(), expected), }; Ok(()) @@ -155,7 +160,7 @@ fn test_ed25519_from_pkcs8() { fn ed25519_test_public_key_coverage() { const PRIVATE_KEY: &[u8] = include_bytes!("ed25519_test_private_key.p8"); const PUBLIC_KEY: &[u8] = include_bytes!("ed25519_test_public_key.der"); - const PUBLIC_KEY_DEBUG: &'static str = + const PUBLIC_KEY_DEBUG: &str = "PublicKey(\"5809e9fef6dcec58f0f2e3b0d67e9880a11957e083ace85835c3b6c8fbaf6b7d\")"; let key_pair = signature::Ed25519KeyPair::from_pkcs8(PRIVATE_KEY).unwrap(); @@ -164,7 +169,11 @@ fn ed25519_test_public_key_coverage() { assert_eq!(key_pair.public_key().as_ref(), PUBLIC_KEY); // Test `Clone`. - let _ = key_pair.public_key().clone(); + #[allow(clippy::clone_on_copy)] + let _: ::PublicKey = key_pair.public_key().clone(); + + // Test `Copy`. + let _: ::PublicKey = *key_pair.public_key(); // Test `Debug`. assert_eq!(PUBLIC_KEY_DEBUG, format!("{:?}", key_pair.public_key())); diff --git a/tests/ed25519_verify_tests.txt b/tests/ed25519_verify_tests.txt new file mode 100644 index 0000000000..74c94b36b6 --- /dev/null +++ b/tests/ed25519_verify_tests.txt @@ -0,0 +1,34 @@ +# BoringSSL TEST(Ed25519Test Malleability) + +# Control; S is in range. +MESSAGE = 54657374 +SIG = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d +PUB = 7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa +Result = P + +# Same as above, but with the order L added to S so it is out of range. +# BoringSSL commit 472ba2c2dd52d06a657a63b7fbf02732a6649d21 +MESSAGE = 54657374 +SIG = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab067654bce3832c2d76f8f6f5dafc08d9339d4eef676573336a5c51eb6f946b31d +PUB = 7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa +Result = F + + +# BoringSSL commit 3094902fcdc2db2cc832fa854b9a6a8be383926c +MESSAGE = 124e583f8b8eca58bb29c271b41d36986bbc45541f8e51f9cb0133eca447601e +SIG = dac119d6ca87fc59ae611c157048f4d4fc932a149dbe20ec6effd1436abf83ea05c7df0fef06147241259113909bc71bd3c53ba4464ffcad3c0968f2ffffff0f +PUB = 100fdf47fb94f1536a4f7c3fda27383fa03375a8f527c537e6f1703c47f94f86 +Result = P + +# Control. Same key as above; same message and signature as below, except S is in range. +PUB = 100fdf47fb94f1536a4f7c3fda27383fa03375a8f527c537e6f1703c47f94f86 +MESSAGE = 6a0bc2b0057cedfc0fa2e3f7f7d39279b30f454a69dfd1117c758d86b19d85e0 +SIG = 0971f86d2c9c78582524a103cb9cf949522ae528f8054dc20107d999be673ff4f58ac9d20ec563133cabc6230b1db8625f8446639ede46ad4df4053000000000 +Result = P + +# Same key as above, but S is out of range. +# BoringSSL commit 472ba2c2dd52d06a657a63b7fbf02732a6649d21 +PUB = 100fdf47fb94f1536a4f7c3fda27383fa03375a8f527c537e6f1703c47f94f86 +MESSAGE = 6a0bc2b0057cedfc0fa2e3f7f7d39279b30f454a69dfd1117c758d86b19d85e0 +SIG = 0971f86d2c9c78582524a103cb9cf949522ae528f8054dc20107d999be673ff4e25ebf2f2928766b1248bec6e91697775f8446639ede46ad4df4053000000010 +Result = F diff --git a/tests/hkdf_tests.rs b/tests/hkdf_tests.rs index e17968c456..88435a845e 100644 --- a/tests/hkdf_tests.rs +++ b/tests/hkdf_tests.rs @@ -12,23 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_results, - variant_size_differences, - warnings -)] - use ring::{digest, error, hkdf, test, test_file}; #[cfg(target_arch = "wasm32")] diff --git a/tests/hmac_tests.rs b/tests/hmac_tests.rs index 9e01714eb6..486a90a530 100644 --- a/tests/hmac_tests.rs +++ b/tests/hmac_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use ring::{digest, error, hmac, test, test_file}; #[cfg(target_arch = "wasm32")] diff --git a/tests/pbkdf2_tests.rs b/tests/pbkdf2_tests.rs index 0b0cf94b3b..13300fa46e 100644 --- a/tests/pbkdf2_tests.rs +++ b/tests/pbkdf2_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use core::num::NonZeroU32; use ring::{digest, error, pbkdf2, test, test_file}; diff --git a/tests/quic_tests.rs b/tests/quic_tests.rs index 472938f87d..545d7a76fb 100644 --- a/tests/quic_tests.rs +++ b/tests/quic_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - use ring::{aead::quic, test, test_file}; #[test] @@ -64,6 +46,7 @@ fn test_quic(alg: &'static quic::Algorithm, test_file: test::File) { }); } +#[allow(clippy::range_plus_one)] fn test_sample_len(alg: &'static quic::Algorithm) { let key_len = alg.key_len(); let key_data = vec![0u8; key_len]; diff --git a/tests/rsa_tests.rs b/tests/rsa_tests.rs index 03e062e29f..2b29b26150 100644 --- a/tests/rsa_tests.rs +++ b/tests/rsa_tests.rs @@ -12,24 +12,6 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#![forbid( - anonymous_parameters, - box_pointers, - missing_copy_implementations, - missing_debug_implementations, - missing_docs, - trivial_casts, - trivial_numeric_casts, - unsafe_code, - unstable_features, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - unused_results, - variant_size_differences, - warnings -)] - #[cfg(feature = "alloc")] use ring::{ error, diff --git a/util/ar/ar.go b/util/ar/ar.go deleted file mode 100644 index 756caf53d8..0000000000 --- a/util/ar/ar.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2017, Google Inc. -// -// 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. */ - -// ar.go contains functions for parsing .a archive files. - -package ar - -import ( - "bytes" - "errors" - "fmt" - "io" - "strconv" - "strings" -) - -// ParseAR parses an archive file from r and returns a map from filename to -// contents, or else an error. -func ParseAR(r io.Reader) (map[string][]byte, error) { - // See https://en.wikipedia.org/wiki/Ar_(Unix)#File_format_details - const expectedMagic = "!\n" - var magic [len(expectedMagic)]byte - if _, err := io.ReadFull(r, magic[:]); err != nil { - return nil, err - } - if string(magic[:]) != expectedMagic { - return nil, errors.New("ar: not an archive file") - } - - const filenameTableName = "//" - const symbolTableName = "/" - var longFilenameTable []byte - ret := make(map[string][]byte) - - for { - var header [60]byte - if _, err := io.ReadFull(r, header[:]); err != nil { - if err == io.EOF { - break - } - return nil, errors.New("ar: error reading file header: " + err.Error()) - } - - name := strings.TrimRight(string(header[:16]), " ") - sizeStr := strings.TrimRight(string(header[48:58]), "\x00 ") - size, err := strconv.ParseUint(sizeStr, 10, 64) - if err != nil { - return nil, errors.New("ar: failed to parse file size: " + err.Error()) - } - - // File contents are padded to a multiple of two bytes - storedSize := size - if storedSize%2 == 1 { - storedSize++ - } - - contents := make([]byte, storedSize) - if _, err := io.ReadFull(r, contents); err != nil { - return nil, errors.New("ar: error reading file contents: " + err.Error()) - } - contents = contents[:size] - - switch { - case name == filenameTableName: - if longFilenameTable != nil { - return nil, errors.New("ar: two filename tables found") - } - longFilenameTable = contents - continue - - case name == symbolTableName: - continue - - case len(name) > 1 && name[0] == '/': - if longFilenameTable == nil { - return nil, errors.New("ar: long filename reference found before filename table") - } - - // A long filename is stored as "/" followed by a - // base-10 offset in the filename table. - offset, err := strconv.ParseUint(name[1:], 10, 64) - if err != nil { - return nil, errors.New("ar: failed to parse filename offset: " + err.Error()) - } - if offset > uint64((^uint(0))>>1) { - return nil, errors.New("ar: filename offset overflow") - } - - if int(offset) > len(longFilenameTable) { - return nil, errors.New("ar: filename offset out of bounds") - } - - filename := longFilenameTable[offset:] - // Windows terminates filenames with NUL characters, - // while sysv/GNU uses /. - if i := bytes.IndexAny(filename, "/\x00"); i < 0 { - return nil, errors.New("ar: unterminated filename in table") - } else { - filename = filename[:i] - } - - name = string(filename) - - default: - name = strings.TrimRight(name, "/") - } - - // Post-processing for BSD: - // https://en.wikipedia.org/wiki/Ar_(Unix)#BSD_variant - // - // If the name is of the form #1/XXX, XXX identifies the length of the - // name, and the name itself is stored as a prefix of the data, possibly - // null-padded. - - var namelen uint - n, err := fmt.Sscanf(name, "#1/%d", &namelen) - if err == nil && n == 1 && len(contents) >= int(namelen) { - name = string(contents[:namelen]) - contents = contents[namelen:] - - // Names can be null padded; find the first null (if any). Note that - // this also handles the case of a null followed by non-null - // characters. It's not clear whether those can ever show up in - // practice, but we might as well handle them in case they can show - // up. - var null int - for ; null < len(name); null++ { - if name[null] == 0 { - break - } - } - name = name[:null] - } - - if name == "__.SYMDEF" || name == "__.SYMDEF SORTED" { - continue - } - - ret[name] = contents - } - - return ret, nil -} diff --git a/util/ar/ar_test.go b/util/ar/ar_test.go deleted file mode 100644 index ef37d795d2..0000000000 --- a/util/ar/ar_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2018, Google Inc. -// -// 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. */ - -package ar - -import ( - "bytes" - "flag" - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -var testDataDir = flag.String("testdata", "testdata", "The path to the test data directory.") - -type arTest struct { - name string - in string - out map[string]string - // allowPadding is true if the contents may have trailing newlines at end. - // On macOS, ar calls ranlib which pads all inputs up to eight bytes with - // newlines. Unlike ar's native padding up to two bytes, this padding is - // included in the size field, so it is not removed when decoding. - allowPadding bool -} - -func (test *arTest) Path(file string) string { - return filepath.Join(*testDataDir, test.name, file) -} - -func removeTrailingNewlines(in []byte) []byte { - for len(in) > 0 && in[len(in)-1] == '\n' { - in = in[:len(in)-1] - } - return in -} - -var arTests = []arTest{ - { - "linux", - "libsample.a", - map[string]string{ - "foo.c.o": "foo.c.o", - "bar.cc.o": "bar.cc.o", - }, - false, - }, - { - "mac", - "libsample.a", - map[string]string{ - "foo.c.o": "foo.c.o", - "bar.cc.o": "bar.cc.o", - }, - true, - }, - { - "windows", - "sample.lib", - map[string]string{ - "CMakeFiles\\sample.dir\\foo.c.obj": "foo.c.obj", - "CMakeFiles\\sample.dir\\bar.cc.obj": "bar.cc.obj", - }, - false, - }, -} - -func TestAR(t *testing.T) { - for _, test := range arTests { - t.Run(test.name, func(t *testing.T) { - in, err := os.Open(test.Path(test.in)) - if err != nil { - t.Fatalf("opening input failed: %s", err) - } - defer in.Close() - - ret, err := ParseAR(in) - if err != nil { - t.Fatalf("reading input failed: %s", err) - } - - for file, contentsPath := range test.out { - expected, err := ioutil.ReadFile(test.Path(contentsPath)) - if err != nil { - t.Fatalf("error reading %s: %s", contentsPath, err) - } - got, ok := ret[file] - if test.allowPadding { - got = removeTrailingNewlines(got) - expected = removeTrailingNewlines(got) - } - if !ok { - t.Errorf("file %s missing from output", file) - } else if !bytes.Equal(got, expected) { - t.Errorf("contents for file %s did not match", file) - } - } - - for file, _ := range ret { - if _, ok := test.out[file]; !ok { - t.Errorf("output contained unexpected file %q", file) - } - } - }) - } -} diff --git a/util/ar/testdata/linux/bar.cc.o b/util/ar/testdata/linux/bar.cc.o deleted file mode 100644 index 92e83a9a11..0000000000 Binary files a/util/ar/testdata/linux/bar.cc.o and /dev/null differ diff --git a/util/ar/testdata/linux/foo.c.o b/util/ar/testdata/linux/foo.c.o deleted file mode 100644 index 6423c1d49b..0000000000 Binary files a/util/ar/testdata/linux/foo.c.o and /dev/null differ diff --git a/util/ar/testdata/linux/libsample.a b/util/ar/testdata/linux/libsample.a deleted file mode 100644 index cae6ae70c9..0000000000 Binary files a/util/ar/testdata/linux/libsample.a and /dev/null differ diff --git a/util/ar/testdata/mac/bar.cc.o b/util/ar/testdata/mac/bar.cc.o deleted file mode 100644 index 9c60798532..0000000000 Binary files a/util/ar/testdata/mac/bar.cc.o and /dev/null differ diff --git a/util/ar/testdata/mac/foo.c.o b/util/ar/testdata/mac/foo.c.o deleted file mode 100644 index 0f96a0a018..0000000000 Binary files a/util/ar/testdata/mac/foo.c.o and /dev/null differ diff --git a/util/ar/testdata/mac/libsample.a b/util/ar/testdata/mac/libsample.a deleted file mode 100644 index b7d8eb5ce0..0000000000 Binary files a/util/ar/testdata/mac/libsample.a and /dev/null differ diff --git a/util/ar/testdata/sample/CMakeLists.txt b/util/ar/testdata/sample/CMakeLists.txt deleted file mode 100644 index 9ea2fe8ee1..0000000000 --- a/util/ar/testdata/sample/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 3.0) -project(Sample) -add_library(sample STATIC foo.c bar.cc) diff --git a/util/ar/testdata/sample/bar.cc b/util/ar/testdata/sample/bar.cc deleted file mode 100644 index a0ac7e14ab..0000000000 --- a/util/ar/testdata/sample/bar.cc +++ /dev/null @@ -1,15 +0,0 @@ -extern "C" { -void foo(); -void bar() {} -} - -namespace bar_namespace { - -void SomeExternalFunction(); - -void SomeFunction() { - foo(); - SomeExternalFunction(); -} - -} // namespace bar_namespace diff --git a/util/ar/testdata/sample/foo.c b/util/ar/testdata/sample/foo.c deleted file mode 100644 index fed596cbe2..0000000000 --- a/util/ar/testdata/sample/foo.c +++ /dev/null @@ -1,7 +0,0 @@ -extern void external_symbol(void); -extern void bar(void); - -void foo(void) { - external_symbol(); - bar(); -} diff --git a/util/ar/testdata/windows/bar.cc.obj b/util/ar/testdata/windows/bar.cc.obj deleted file mode 100644 index 4a315cdd6b..0000000000 Binary files a/util/ar/testdata/windows/bar.cc.obj and /dev/null differ diff --git a/util/ar/testdata/windows/foo.c.obj b/util/ar/testdata/windows/foo.c.obj deleted file mode 100644 index 9b4aad7a42..0000000000 Binary files a/util/ar/testdata/windows/foo.c.obj and /dev/null differ diff --git a/util/ar/testdata/windows/sample.lib b/util/ar/testdata/windows/sample.lib deleted file mode 100644 index efeebb24e5..0000000000 Binary files a/util/ar/testdata/windows/sample.lib and /dev/null differ diff --git a/util/generate-asm-lcov.py b/util/generate-asm-lcov.py deleted file mode 100755 index 257ae841c3..0000000000 --- a/util/generate-asm-lcov.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2016, Google Inc. -# -# 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. -import os -import os.path -import subprocess -import sys - -# The LCOV output format for each source file is: -# -# SF: -# DA:, -# ... -# end_of_record -# -# The can either be 0 for an unexecuted instruction or a -# value representing the number of executions. The DA line should be omitted -# for lines not representing an instruction. - -SECTION_SEPERATOR = '-' * 80 - -def is_asm(l): - """Returns whether a line should be considered to be an instruction.""" - l = l.strip() - # Empty lines - if l == '': - return False - # Comments - if l.startswith('#'): - return False - # Assembly Macros - if l.startswith('.'): - return False - # Label - if l.endswith(':'): - return False - return True - -def merge(callgrind_files, srcs): - """Calls callgrind_annotate over the set of callgrind output - |callgrind_files| using the sources |srcs| and merges the results - together.""" - out = '' - for file in callgrind_files: - data = subprocess.check_output(['callgrind_annotate', file] + srcs) - out += '%s\n%s\n' % (data, SECTION_SEPERATOR) - return out - -def parse(filename, data, current): - """Parses an annotated execution flow |data| from callgrind_annotate for - source |filename| and updates the current execution counts from |current|.""" - with open(filename) as f: - source = f.read().split('\n') - - out = current - if out == None: - out = [0 if is_asm(l) else None for l in source] - - # Lines are of the following formats: - # -- line: Indicates that analysis continues from a different place. - # Ir : Indicates the start of a file. - # => : Indicates a call/jump in the control flow. - # : Indicates that the line has been executed that many times. - line = None - for l in data: - l = l.strip() + ' ' - if l.startswith('-- line'): - line = int(l.split(' ')[2]) - 1 - elif l.strip() == 'Ir': - line = 0 - elif line != None and l.strip() and '=>' not in l and 'unidentified lines' not in l: - count = l.split(' ')[0].replace(',', '').replace('.', '0') - instruction = l.split(' ', 1)[1].strip() - if count != '0' or is_asm(instruction): - if out[line] == None: - out[line] = 0 - out[line] += int(count) - line += 1 - - return out - - -def generate(data): - """Parses the merged callgrind_annotate output |data| and generates execution - counts for all annotated files.""" - out = {} - data = [p.strip() for p in data.split(SECTION_SEPERATOR)] - - - # Most sections are ignored, but a section with: - # User-annotated source: - # precedes a listing of execution count for that . - for i in range(len(data)): - if 'User-annotated source' in data[i] and i < len(data) - 1: - filename = data[i].split(':', 1)[1].strip() - res = data[i + 1] - if filename not in out: - out[filename] = None - if 'No information' in res: - res = [] - else: - res = res.split('\n') - out[filename] = parse(filename, res, out[filename]) - return out - -def output(data): - """Takes a dictionary |data| of filenames and execution counts and generates - a LCOV coverage output.""" - out = '' - for filename, counts in data.iteritems(): - out += 'SF:%s\n' % (os.path.abspath(filename)) - for line, count in enumerate(counts): - if count != None: - out += 'DA:%d,%s\n' % (line + 1, count) - out += 'end_of_record\n' - return out - -if __name__ == '__main__': - if len(sys.argv) != 3: - print '%s ' % (__file__) - sys.exit() - - cg_folder = sys.argv[1] - build_folder = sys.argv[2] - - cg_files = [] - for (cwd, _, files) in os.walk(cg_folder): - for f in files: - if f.startswith('callgrind.out'): - cg_files.append(os.path.abspath(os.path.join(cwd, f))) - - srcs = [] - for (cwd, _, files) in os.walk(build_folder): - for f in files: - fn = os.path.join(cwd, f) - if fn.endswith('.S'): - srcs.append(fn) - - annotated = merge(cg_files, srcs) - lcov = generate(annotated) - print output(lcov) diff --git a/util/generate-coverage.sh b/util/generate-coverage.sh deleted file mode 100755 index 2fbe6b8378..0000000000 --- a/util/generate-coverage.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# Copyright (c) 2016, Google Inc. -# -# 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. - -set -xe - -SRC=$PWD - -BUILD=$(mktemp -d '/tmp/boringssl.XXXXXX') -BUILD_SRC=$(mktemp -d '/tmp/boringssl-src.XXXXXX') -LCOV=$(mktemp -d '/tmp/boringssl-lcov.XXXXXX') - -if [ -n "$1" ]; then - LCOV=$(readlink -f "$1") - mkdir -p "$LCOV" -fi - -cd "$BUILD" -cmake "$SRC" -GNinja -DCMAKE_C_FLAGS='-fprofile-arcs -ftest-coverage' \ - -DCMAKE_CXX_FLAGS='-fprofile-arcs -ftest-coverage' -DCMAKE_ASM_FLAGS='-Wa,-g' -ninja - -cp -r "$SRC/crypto" "$SRC/decrepit" "$SRC/include" "$SRC/ssl" "$SRC/tool" \ - "$BUILD_SRC" -cp -r "$BUILD"/* "$BUILD_SRC" -mkdir "$BUILD/callgrind/" - -cd "$SRC" -go run "$SRC/util/all_tests.go" -build-dir "$BUILD" -callgrind -num-workers 16 -util/generate-asm-lcov.py "$BUILD/callgrind" "$BUILD" > "$BUILD/asm.info" - -go run "util/all_tests.go" -build-dir "$BUILD" - -cd "$SRC/ssl/test/runner" -go test -shim-path "$BUILD/ssl/test/bssl_shim" -num-workers 1 - -cd "$LCOV" -lcov -c -d "$BUILD" -b "$BUILD" -o "$BUILD/lcov.info" -lcov -r "$BUILD/lcov.info" "*_test.c" -o "$BUILD/lcov-1.info" -lcov -r "$BUILD/lcov-1.info" "*_test.cc" -o "$BUILD/lcov-2.info" -cat "$BUILD/lcov-2.info" "$BUILD/asm.info" > "$BUILD/final.info" -sed -i "s;$BUILD;$BUILD_SRC;g" "$BUILD/final.info" -sed -i "s;$SRC;$BUILD_SRC;g" "$BUILD/final.info" -genhtml -p "$BUILD_SRC" "$BUILD/final.info" - -rm -rf "$BUILD" -rm -rf "$BUILD_SRC" - -xdg-open index.html diff --git a/util/make_prefix_headers.go b/util/make_prefix_headers.go deleted file mode 100644 index b536f14cea..0000000000 --- a/util/make_prefix_headers.go +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2018, Google Inc. -// -// 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. - -// This program takes a file containing newline-separated symbols, and generates -// boringssl_prefix_symbols.h, boringssl_prefix_symbols_asm.h, and -// boringssl_prefix_symbols_nasm.inc. These header files can be used to build -// BoringSSL with a prefix for all symbols in order to avoid symbol name -// conflicts when linking a project with multiple copies of BoringSSL; see -// BUILDING.md for more details. - -// TODO(joshlf): For platforms which support it, use '#pragma redefine_extname' -// instead of a custom macro. This avoids the need for a custom macro, but also -// ensures that our renaming won't conflict with symbols defined and used by our -// consumers (the "HMAC" problem). An example of this approach can be seen in -// IllumOS' fork of OpenSSL: -// https://github.com/joyent/illumos-extra/blob/master/openssl1x/sunw_prefix.h - -package main - -import ( - "bufio" - "flag" - "fmt" - "os" - "path/filepath" - "strings" -) - -var out = flag.String("out", ".", "Path to a directory where the outputs will be written") - -// Read newline-separated symbols from a file, ignoring any comments started -// with '#'. -func readSymbols(path string) ([]string, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - scanner := bufio.NewScanner(f) - var ret []string - for scanner.Scan() { - line := scanner.Text() - if idx := strings.IndexByte(line, '#'); idx >= 0 { - line = line[:idx] - } - line = strings.TrimSpace(line) - if len(line) == 0 { - continue - } - ret = append(ret, line) - } - if err := scanner.Err(); err != nil { - return nil, err - } - return ret, nil -} - -func writeCHeader(symbols []string, path string) error { - f, err := os.Create(path) - if err != nil { - return err - } - defer f.Close() - - if _, err := f.WriteString(`// Copyright (c) 2018, Google Inc. -// -// 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. - -// BORINGSSL_ADD_PREFIX pastes two identifiers into one. It performs one -// iteration of macro expansion on its arguments before pasting. -#define BORINGSSL_ADD_PREFIX(a, b) BORINGSSL_ADD_PREFIX_INNER(a, b) -#define BORINGSSL_ADD_PREFIX_INNER(a, b) a ## _ ## b - -`); err != nil { - return err - } - - for _, symbol := range symbols { - if _, err := fmt.Fprintf(f, "#define %s BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, %s)\n", symbol, symbol); err != nil { - return err - } - } - - return nil -} - -func writeASMHeader(symbols []string, path string) error { - f, err := os.Create(path) - if err != nil { - return err - } - defer f.Close() - - if _, err := f.WriteString(`// Copyright (c) 2018, Google Inc. -// -// 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. - -#if !defined(__APPLE__) -#include -#else -// On iOS and macOS, we need to treat assembly symbols differently from other -// symbols. The linker expects symbols to be prefixed with an underscore. -// Perlasm thus generates symbol with this underscore applied. Our macros must, -// in turn, incorporate it. -#define BORINGSSL_ADD_PREFIX_MAC_ASM(a, b) BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b) -#define BORINGSSL_ADD_PREFIX_INNER_MAC_ASM(a, b) _ ## a ## _ ## b - -`); err != nil { - return err - } - - for _, symbol := range symbols { - if _, err := fmt.Fprintf(f, "#define _%s BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, %s)\n", symbol, symbol); err != nil { - return err - } - } - - _, err = fmt.Fprintf(f, "#endif\n") - return nil -} - -func writeNASMHeader(symbols []string, path string) error { - f, err := os.Create(path) - if err != nil { - return err - } - defer f.Close() - - // NASM uses a different syntax from the C preprocessor. - if _, err := f.WriteString(`; Copyright (c) 2018, Google Inc. -; -; 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. - -; 32-bit Windows adds underscores to C functions, while 64-bit Windows does not. -%ifidn __OUTPUT_FORMAT__, win32 -`); err != nil { - return err - } - - for _, symbol := range symbols { - if _, err := fmt.Fprintf(f, "%%xdefine _%s _ %%+ BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil { - return err - } - } - - if _, err := fmt.Fprintf(f, "%%else\n"); err != nil { - return err - } - - for _, symbol := range symbols { - if _, err := fmt.Fprintf(f, "%%xdefine %s BORINGSSL_PREFIX %%+ _%s\n", symbol, symbol); err != nil { - return err - } - } - - if _, err := fmt.Fprintf(f, "%%endif\n"); err != nil { - return err - } - - return nil -} - -func main() { - flag.Parse() - if flag.NArg() != 1 { - fmt.Fprintf(os.Stderr, "Usage: %s [-out OUT] SYMBOLS\n", os.Args[0]) - os.Exit(1) - } - - symbols, err := readSymbols(flag.Arg(0)) - if err != nil { - fmt.Fprintf(os.Stderr, "Error reading symbols: %s\n", err) - os.Exit(1) - } - - if err := writeCHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols.h")); err != nil { - fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols.h: %s\n", err) - os.Exit(1) - } - - if err := writeASMHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols_asm.h")); err != nil { - fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols_asm.h: %s\n", err) - os.Exit(1) - } - - if err := writeNASMHeader(symbols, filepath.Join(*out, "boringssl_prefix_symbols_nasm.inc")); err != nil { - fmt.Fprintf(os.Stderr, "Error writing boringssl_prefix_symbols_nasm.inc: %s\n", err) - os.Exit(1) - } - -} diff --git a/util/read_symbols.go b/util/read_symbols.go deleted file mode 100644 index 791ea5d126..0000000000 --- a/util/read_symbols.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) 2018, Google Inc. -// -// 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. - -// read_symbols scans one or more .a files and, for each object contained in -// the .a files, reads the list of symbols in that object file. -package main - -import ( - "bytes" - "debug/elf" - "debug/macho" - "debug/pe" - "flag" - "fmt" - "os" - "runtime" - "sort" - "strings" - - "boringssl.googlesource.com/boringssl/util/ar" -) - -const ( - ObjFileFormatELF = "elf" - ObjFileFormatMachO = "macho" - ObjFileFormatPE = "pe" -) - -var ( - outFlag = flag.String("out", "-", "File to write output symbols") - objFileFormat = flag.String("obj-file-format", defaultObjFileFormat(runtime.GOOS), "Object file format to expect (options are elf, macho, pe)") -) - -func defaultObjFileFormat(goos string) string { - switch goos { - case "linux": - return ObjFileFormatELF - case "darwin": - return ObjFileFormatMachO - case "windows": - return ObjFileFormatPE - default: - // By returning a value here rather than panicking, the user can still - // cross-compile from an unsupported platform to a supported platform by - // overriding this default with a flag. If the user doesn't provide the - // flag, we will panic during flag parsing. - return "unsupported" - } -} - -func printAndExit(format string, args ...interface{}) { - s := fmt.Sprintf(format, args...) - fmt.Fprintln(os.Stderr, s) - os.Exit(1) -} - -func main() { - flag.Parse() - if flag.NArg() < 1 { - printAndExit("Usage: %s [-out OUT] [-obj-file-format FORMAT] ARCHIVE_FILE [ARCHIVE_FILE [...]]", os.Args[0]) - } - archiveFiles := flag.Args() - - out := os.Stdout - if *outFlag != "-" { - var err error - out, err = os.Create(*outFlag) - if err != nil { - printAndExit("Error opening %q: %s", *outFlag, err) - } - defer out.Close() - } - - var symbols []string - // Only add first instance of any symbol; keep track of them in this map. - added := make(map[string]struct{}) - for _, archive := range archiveFiles { - f, err := os.Open(archive) - if err != nil { - printAndExit("Error opening %s: %s", archive, err) - } - objectFiles, err := ar.ParseAR(f) - f.Close() - if err != nil { - printAndExit("Error parsing %s: %s", archive, err) - } - - for name, contents := range objectFiles { - syms, err := listSymbols(contents) - if err != nil { - printAndExit("Error listing symbols from %q in %q: %s", name, archive, err) - } - for _, s := range syms { - if _, ok := added[s]; !ok { - added[s] = struct{}{} - symbols = append(symbols, s) - } - } - } - } - - sort.Strings(symbols) - for _, s := range symbols { - var skipSymbols = []string{ - // Inline functions, etc., from the compiler or language - // runtime will naturally end up in the library, to be - // deduplicated against other object files. Such symbols - // should not be prefixed. It is a limitation of this - // symbol-prefixing strategy that we cannot distinguish - // our own inline symbols (which should be prefixed) - // from the system's (which should not), so we blacklist - // known system symbols. - "__local_stdio_printf_options", - "__local_stdio_scanf_options", - "_vscprintf", - "_vscprintf_l", - "_vsscanf_l", - "_xmm", - "sscanf", - "vsnprintf", - // sdallocx is a weak symbol and intended to merge with - // the real one, if present. - "sdallocx", - } - var skip bool - for _, sym := range skipSymbols { - if sym == s { - skip = true - break - } - } - if skip || isCXXSymbol(s) || strings.HasPrefix(s, "__real@") || strings.HasPrefix(s, "__x86.get_pc_thunk.") { - continue - } - if _, err := fmt.Fprintln(out, s); err != nil { - printAndExit("Error writing to %s: %s", *outFlag, err) - } - } -} - -func isCXXSymbol(s string) bool { - if *objFileFormat == ObjFileFormatPE { - return strings.HasPrefix(s, "?") - } - return strings.HasPrefix(s, "_Z") -} - -// listSymbols lists the exported symbols from an object file. -func listSymbols(contents []byte) ([]string, error) { - switch *objFileFormat { - case ObjFileFormatELF: - return listSymbolsELF(contents) - case ObjFileFormatMachO: - return listSymbolsMachO(contents) - case ObjFileFormatPE: - return listSymbolsPE(contents) - default: - return nil, fmt.Errorf("unsupported object file format %q", *objFileFormat) - } -} - -func listSymbolsELF(contents []byte) ([]string, error) { - f, err := elf.NewFile(bytes.NewReader(contents)) - if err != nil { - return nil, err - } - syms, err := f.Symbols() - if err != nil { - return nil, err - } - - var names []string - for _, sym := range syms { - // Only include exported, defined symbols - if elf.ST_BIND(sym.Info) != elf.STB_LOCAL && sym.Section != elf.SHN_UNDEF { - names = append(names, sym.Name) - } - } - return names, nil -} - -func listSymbolsMachO(contents []byte) ([]string, error) { - f, err := macho.NewFile(bytes.NewReader(contents)) - if err != nil { - return nil, err - } - if f.Symtab == nil { - return nil, nil - } - var names []string - for _, sym := range f.Symtab.Syms { - // Source: https://opensource.apple.com/source/xnu/xnu-3789.51.2/EXTERNAL_HEADERS/mach-o/nlist.h.auto.html - const ( - N_PEXT uint8 = 0x10 // Private external symbol bit - N_EXT uint8 = 0x01 // External symbol bit, set for external symbols - N_TYPE uint8 = 0x0e // mask for the type bits - - N_UNDF uint8 = 0x0 // undefined, n_sect == NO_SECT - N_ABS uint8 = 0x2 // absolute, n_sect == NO_SECT - N_SECT uint8 = 0xe // defined in section number n_sect - N_PBUD uint8 = 0xc // prebound undefined (defined in a dylib) - N_INDR uint8 = 0xa // indirect - ) - - // Only include exported, defined symbols. - if sym.Type&N_EXT != 0 && sym.Type&N_TYPE != N_UNDF { - if len(sym.Name) == 0 || sym.Name[0] != '_' { - return nil, fmt.Errorf("unexpected symbol without underscore prefix: %q", sym.Name) - } - names = append(names, sym.Name[1:]) - } - } - return names, nil -} - -func listSymbolsPE(contents []byte) ([]string, error) { - f, err := pe.NewFile(bytes.NewReader(contents)) - if err != nil { - return nil, err - } - var ret []string - for _, sym := range f.Symbols { - const ( - // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#section-number-values - IMAGE_SYM_UNDEFINED = 0 - // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#storage-class - IMAGE_SYM_CLASS_EXTERNAL = 2 - ) - if sym.SectionNumber != IMAGE_SYM_UNDEFINED && sym.StorageClass == IMAGE_SYM_CLASS_EXTERNAL { - name := sym.Name - if f.Machine == pe.IMAGE_FILE_MACHINE_I386 { - // On 32-bit Windows, C symbols are decorated by calling - // convention. - // https://msdn.microsoft.com/en-us/library/56h2zst2.aspx#FormatC - if strings.HasPrefix(name, "_") || strings.HasPrefix(name, "@") { - // __cdecl, __stdcall, or __fastcall. Remove the prefix and - // suffix, if present. - name = name[1:] - if idx := strings.LastIndex(name, "@"); idx >= 0 { - name = name[:idx] - } - } else if idx := strings.LastIndex(name, "@@"); idx >= 0 { - // __vectorcall. Remove the suffix. - name = name[:idx] - } - } - ret = append(ret, name) - } - } - return ret, nil -}