[
  {
    "path": ".arcconfig",
    "content": "{\n  \"phabricator.uri\" : \"https://source.that.world/\"\n}"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n[*]\nindent_style=space\nindent_size=4\ntab_width=4\nend_of_line=lf\ncharset=utf-8\ntrim_trailing_whitespace=true\nmax_line_length=80\ninsert_final_newline=true\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: cargo\n    directory: \"/\"\n    labels: []\n    schedule:\n      interval: \"daily\"\n    rebase-strategy: disabled\n    open-pull-requests-limit: 2\n\n  - package-ecosystem: github-actions\n    directory: \"/\"\n    labels: []\n    schedule:\n      interval: \"daily\"\n    rebase-strategy: disabled\n    open-pull-requests-limit: 2\n"
  },
  {
    "path": ".github/workflows/audit.yml",
    "content": "name: Security audit\non:\n  pull_request:\n    paths: Cargo.lock\n  schedule:\n    - cron: '0 0 * * *'\njobs:\n  security_audit:\n    runs-on: ubuntu-latest\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Checkout sources\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 50\n\n      - name:          Run cargo audit\n        uses:          actions-rs/audit-check@v1.2.0\n        with:\n          token:       ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/check-style.yml",
    "content": "name:                  Check style\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n      - stable\n    tags:\n      - v*\n    paths-ignore:\n      - 'README.md'\njobs:\n  check-style:\n    name:              Check style\n    runs-on:           ubuntu-latest\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   stable\n          components:  clippy, rustfmt\n          override:    true\n\n      - name:          Checking style\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     fmt\n          toolchain:   stable\n          args:        --all -- --check\n"
  },
  {
    "path": ".github/workflows/clippy.yml",
    "content": "name:                  Check clippy\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n      - stable\n    tags:\n      - v*\n    paths-ignore:\n      - 'README.md'\njobs:\n  check-clippy:\n    name:              Check clippy\n    runs-on:           ubuntu-latest\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   stable\n          components:  clippy, rustfmt\n          override:    true\n\n      - name:          Checking clippy\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     clippy\n          toolchain:   stable\n          args:        --all\n\n      - name:          Checking clippy\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     clippy\n          toolchain:   stable\n          args:        --all --no-default-features --features std,hmac,lazy-static-context\n"
  },
  {
    "path": ".github/workflows/prepare_artifacts.sh",
    "content": "#!/bin/bash\nset -e # fail on any error\nset -u # treat unset variables as error\n\n# ARGUMENT $1 CARGO_TARGET\n#Set additional dir path\nif [ \"${1}\" == \"\" ]; then\n  dir=\"\"\nelse\n  dir=\"..\"\nfi\nmkdir -p ./artifacts/\ncd ./target/$1/release/\nls -a\necho \"_____ Find binary files in target _____\"\nfind . -maxdepth 1 -type f ! -size 0 -exec grep -IL . \"{}\" \\; | cut -c 3-\necho \"_____ Move binaries to artifacts folder _____\"\nfor binary in $(find . -maxdepth 1 -type f ! -size 0 -exec grep -IL . \"{}\" \\; | cut -c 3- )\ndo\n  mv -v $binary ../$dir/../artifacts/$binary\ndone\ncd ../$dir/..\necho \"_____ Clean target dir _____\"\nfind ./target/$1/{debug,release} -maxdepth 1 -type f -delete;\nrm -f  ./target/.rustc_info.json;\nrm -rf ./target/$1/{debug,release}/{deps,.fingerprint}/\n"
  },
  {
    "path": ".github/workflows/rust-windows.yml",
    "content": "# almost a copy of .github/workflows/rust.yml made in https://github.com/paritytech/libsecp256k1/pull/84\n# windows causes some troubles with sudo sccache and\n# caching within GHA https://github.com/Swatinem/rust-cache/issues/31\nname:                  Check, Test and Build on Windows\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n      - stable\n    tags:\n      - v*\n    paths-ignore:\n      - 'README.md'\n\njobs:\n  check:\n    name:              Check\n    strategy:\n      matrix:\n        platform:\n          - windows-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Install sudo for windows #https://github.com/actions/virtual-environments/issues/572\n        if: matrix.platform == 'windows-latest'\n        run: choco install sudo\n\n      - name:          Install LLVM for Windows\n        if:            matrix.platform == 'windows-latest'  && matrix.compiler == 'clang'\n        run:           |\n          choco install llvm\n          echo \"CC=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          refreshenv\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - name:          Set cache_hash ENV and prepare cache dir\n        run:           |\n          echo \"cache_hash=${{ runner.os }}-${{ steps.toolchain.outputs.rustc_hash }}-${{ matrix.compiler }}-${{ hashFiles('**/Cargo.toml') }}\" >> \"$GITHUB_ENV\"\n          mkdir -p $HOME/sccache\n          sudo chmod -R a+w $HOME/.cargo\n        shell:         bash\n\n      - name:          Cache cargo registry\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/registry\n          key:         cargo-registry-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo index\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/git\n          key:         cargo-git-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo build\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        target\n          key:         cargo-target-${{ env['cache_hash'] }}\n\n      - name:          Checking ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     check\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all  --verbose\n\n  test:\n    name:              Test\n    needs:             [check]\n    strategy:\n      matrix:\n        platform:\n          - windows-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Set default compiler\n        if:            matrix.compiler == 'clang' && matrix.platform != 'windows-latest'\n        run: |\n          echo \"CC=clang\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang++\" >> \"$GITHUB_ENV\"\n\n      - name:          Install sudo for windows #https://github.com/actions/virtual-environments/issues/572\n        if:            matrix.platform == 'windows-latest'\n        run:           choco install sudo\n\n      - name:          Install LLVM for Windows\n        if:            matrix.platform == 'windows-latest'  && matrix.compiler == 'clang'\n        run:           |\n          choco install llvm\n          echo \"CC=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          refreshenv\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - name:          Set cache_hash ENV and prepare cache dir\n        run:           |\n          echo \"cache_hash=${{ runner.os }}-${{ steps.toolchain.outputs.rustc_hash }}-${{ matrix.compiler }}-${{ hashFiles('**/Cargo.toml') }}\" >> \"$GITHUB_ENV\"\n          mkdir -p $HOME/sccache\n          sudo chmod -R a+w $HOME/.cargo\n        shell:         bash\n\n      - name:          Cache cargo registry\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/registry\n          key:         cargo-registry-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo index\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/git\n          key:         cargo-git-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo build\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        target\n          key:         cargo-target-${{ env['cache_hash'] }}\n\n      - name:          Testing ${{ matrix.platform }}-${{ matrix.toolchain }} (debug build)\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     test\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --verbose\n\n      - name:          Testing ${{ matrix.platform }}-${{ matrix.toolchain }} (release build)\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     test\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --release --verbose\n\n  build:\n    name:              Build\n    needs:             [check,test]\n    strategy:\n      matrix:\n        platform:\n          - windows-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n      # NOTE:          Enables the aes-ni instructions for RustCrypto dependency.\n      # Strip binaries\n      # If you change this please remember to also update .cargo/config\n      RUSTFLAGS:       \"-C target-feature=+aes,+sse2,+ssse3 -C link-arg=-s\"\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Set default compiler\n        if:            matrix.compiler == 'clang' && matrix.platform != 'windows-latest'\n        run: |\n          echo \"CC=clang\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang++\" >> \"$GITHUB_ENV\"\n\n      - name:          Install sudo for windows #https://github.com/actions/virtual-environments/issues/572\n        if: matrix.platform == 'windows-latest'\n        run: choco install sudo\n\n      - name:          Install LLVM for Windows\n        if:            matrix.platform == 'windows-latest'  && matrix.compiler == 'clang'\n        run:           |\n          choco install llvm\n          echo \"CC=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang-cl.exe --enable-64-bit\" >> \"$GITHUB_ENV\"\n          refreshenv\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - name:          Set cache_hash ENV and prepare cache dir\n        run:           |\n          echo \"cache_hash=${{ runner.os }}-${{ steps.toolchain.outputs.rustc_hash }}-${{ matrix.compiler }}-${{ hashFiles('**/Cargo.toml') }}\" >> \"$GITHUB_ENV\"\n          mkdir -p $HOME/sccache\n          sudo chmod -R a+w $HOME/.cargo\n        shell:         bash\n\n      - name:          Cache cargo registry\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/registry\n          key:         cargo-registry-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo index\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        $HOME/.cargo/git\n          key:         cargo-git-${{ env['cache_hash'] }}\n\n      - name:          Cache cargo build\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        target\n          key:         cargo-target-${{ env['cache_hash'] }}\n\n      - name:          Building ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --verbose --release\n\n      - name:          Building `no default` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features\n\n      - name:          Building `hmac` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features hmac\n\n      - name:          Building `static-context` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features static-context\n\n      - name:          Building `lazy-static-context` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features lazy-static-context\n\n      - name:          Prepare artifacts\n        run:           .github/workflows/prepare_artifacts.sh \"\"\n        shell:         bash\n\n      - name:          Upload artifacts\n        uses:          actions/upload-artifact@v3.1.0\n        with:\n          name:        ${{ matrix.platform }}.${{ matrix.toolchain }}.${{ matrix.compiler }}.zip\n          path:        artifacts/\n"
  },
  {
    "path": ".github/workflows/rust.yml",
    "content": "name:                  Check, Test and Build Suite\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n      - stable\n    tags:\n      - v*\n    paths-ignore:\n      - 'README.md'\n\njobs:\n  check:\n    name:              Check\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - macos-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Set default compiler\n        if:            matrix.compiler == 'clang'\n        run: |\n          echo \"CC=clang\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang++\" >> \"$GITHUB_ENV\"\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - uses:          Swatinem/rust-cache@22c9328bcba27aa81a32b1bef27c7e3c78052531 # v2.0.1\n\n      - name:          Cache sccache\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        \"$HOME/sccache\"\n          key:         sccache-${{ env['cache_hash'] }}\n\n      - name:          Install & start sccache for ${{ matrix.platform }}\n        shell:         bash\n        run:           .github/workflows/sccache.sh ${{ runner.os}}\n\n      - name:          Sccache statistics\n        run:           sccache --show-stats\n\n      # here comes different part\n      - name:          Checking ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     check\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all  --verbose\n\n      - name:          Stop sccache\n        if:            always()\n        run:           sccache --stop-server\n\n  test:\n    name:              Test\n    needs:             [check]\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - macos-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Set default compiler\n        if:            matrix.compiler == 'clang'\n        run: |\n          echo \"CC=clang\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang++\" >> \"$GITHUB_ENV\"\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - uses:          Swatinem/rust-cache@22c9328bcba27aa81a32b1bef27c7e3c78052531 # v2.0.1\n\n      - name:          Cache sccache\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        \"$HOME/sccache\"\n          key:         sccache-${{ env['cache_hash'] }}\n\n      - name:          Install & start sccache for ${{ matrix.platform }}\n        shell:         bash\n        run:           .github/workflows/sccache.sh ${{ runner.os}}\n\n      - name:          Sccache statistics\n        run:           sccache --show-stats\n\n      # here comes different part\n      - name:          Testing ${{ matrix.platform }}-${{ matrix.toolchain }} (debug build)\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     test\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --verbose\n\n      - name:          Testing ${{ matrix.platform }}-${{ matrix.toolchain }} (release build)\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     test\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --release --verbose\n\n      - name:          Stop sccache\n        if:            always()\n        run:           sccache --stop-server\n\n  build:\n    name:              Build\n    needs:             [check,test]\n    strategy:\n      matrix:\n        platform:\n          - ubuntu-latest\n          - macos-latest\n        toolchain:\n          - stable\n          - nightly\n        compiler:\n          - clang\n          - gcc\n    runs-on:           ${{ matrix.platform }}\n    env:\n      RUST_BACKTRACE:  full\n      # NOTE:          Enables the aes-ni instructions for RustCrypto dependency.\n      # Strip binaries\n      # If you change this please remember to also update .cargo/config\n      RUSTFLAGS:       \"-C target-feature=+aes,+sse2,+ssse3 -C link-arg=-s\"\n    steps:\n\n      - name:          Cancel Previous Runs\n        uses:          styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # 0.11.0\n\n      - name:          Set default compiler\n        if:            matrix.compiler == 'clang'\n        run: |\n          echo \"CC=clang\" >> \"$GITHUB_ENV\"\n          echo \"CXX=clang++\" >> \"$GITHUB_ENV\"\n\n      - name:          Checkout sources & submodules\n        uses:          actions/checkout@v3.1.0\n        with:\n          fetch-depth: 5\n          submodules:  recursive\n\n      - name:          Install toolchain\n        id:            toolchain\n        uses:          actions-rs/toolchain@v1.0.7\n        with:\n          profile:     minimal\n          toolchain:   ${{ matrix.toolchain }}\n          components:  clippy, rustfmt\n          override:    true\n\n      - uses:          Swatinem/rust-cache@22c9328bcba27aa81a32b1bef27c7e3c78052531 # v2.0.1\n\n      - name:          Cache sccache\n        uses:          actions/cache@v3.0.11\n        with:\n          path:        \"$HOME/sccache\"\n          key:         sccache-${{ env['cache_hash'] }}\n\n      - name:          Install & start sccache for ${{ matrix.platform }}\n        shell:         bash\n        run:           .github/workflows/sccache.sh ${{ runner.os}}\n\n      - name:          Sccache statistics\n        run:           sccache --show-stats\n\n      # here comes different part\n      - name:          Building ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --all --verbose --release\n\n      - name:          Building `no default` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features\n\n      - name:          Building `hmac` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features hmac\n\n      - name:          Building `static-context` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features static-context\n\n      - name:          Building `lazy-static-context` ${{ matrix.platform }}-${{ matrix.toolchain }}\n        uses:          actions-rs/cargo@v1.0.3\n        with:\n          command:     build\n          toolchain:   ${{ matrix.toolchain }}\n          args:        --verbose --no-default-features --features lazy-static-context\n\n      - name:          Stop sccache\n        if:            always()\n        run:           sccache --stop-server\n\n      - name:          Prepare artifacts\n        run:           .github/workflows/prepare_artifacts.sh \"\"\n        shell:         bash\n\n      - name:          Upload artifacts\n        uses:          actions/upload-artifact@v3.1.0\n        with:\n          name:        ${{ matrix.platform }}.${{ matrix.toolchain }}.${{ matrix.compiler }}.zip\n          path:        artifacts/\n"
  },
  {
    "path": ".github/workflows/sccache.sh",
    "content": "#!/bin/bash\n\nset -ex\n\nexport SCCACHE_CACHE_SIZE=\"1G\"\nexport SCCACHE_IDLE_TIMEOUT=0\nexport SCCACHE_DIR=\"$HOME/sccache\"\nOS=$1\nVERSION=\"0.2.13\"\n\necho \"Current OS: $OS\"\ncase $OS in\n\"macOS\")\n  PLATFORM=\"x86_64-apple-darwin\"\n  ;;\n\"Linux\")\n  PLATFORM=\"x86_64-unknown-linux-musl\"\n  ;;\n\"Windows\")\n  PLATFORM=\"x86_64-pc-windows-msvc\"\n  VERSION=\"0.2.14\"\n  ;;\nesac\necho \"Target arch: \" $PLATFORM\nBASENAME=\"sccache-$VERSION-$PLATFORM\"\nURL=\"https://github.com/mozilla/sccache/releases/download/$VERSION/$BASENAME.tar.gz\"\necho \"Download sccache from \" \"$URL\"\ncurl -LO \"$URL\"\ntar -xzvf \"$BASENAME.tar.gz\"\nls $BASENAME/\necho \"$(pwd)/$BASENAME\" >> \"$GITHUB_PATH\"\necho \"RUSTC_WRAPPER=sccache\" >> \"$GITHUB_ENV\"\n./$BASENAME/sccache --start-server\n"
  },
  {
    "path": ".gitignore",
    "content": "/target/\n**/*.rs.bk\nCargo.lock\n*.swp\n/.idea\n/shell.nix\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nThe format is based on [Keep a Changelog].\n\n[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/\n\n## [0.5.0] - 2021-05-18\n- Add standard non-overflowing signature parsing `Signature::parse_standard`. The previous behavior `Signature::parse` is considered non-standard and renamed to `Signature::parse_overflowing`. Unless you have a specific need, you should switch to use the new `Signature::parse_standard` function. (PR #67)\n\n## [0.3.5] - 2020-02-06\n- Implement `std::error::Error` and `Display` for `Error`. (PR #29)\n- Fix the PartialEq impl of Field. (PR #30)\n- Add `LowerHex` implementation for `SecretKey` and `Scalar`. (PR #32)\n- Put signing behind feature flag. (PR #33)\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"libsecp256k1\"\ndescription = \"Pure Rust secp256k1 implementation.\"\nlicense = \"Apache-2.0\"\nversion = \"0.7.2\"\nauthors = [\"Wei Tang <hi@that.world>\"]\nrepository = \"https://github.com/paritytech/libsecp256k1\"\nkeywords = [\"crypto\", \"ECDSA\", \"secp256k1\", \"bitcoin\", \"no_std\"]\nedition = \"2018\"\nresolver = \"2\"\n\n[dependencies]\nlibsecp256k1-core = { version = \"0.3.0\", path = \"core\", default-features = false }\narrayref = \"0.3\"\nrand = { version = \"0.8\", default-features = false }\ndigest = \"0.9\"\nbase64 = { version = \"0.22\", default-features = false }\nhmac-drbg = { version = \"0.3\", optional = true }\nsha2 = { version = \"0.9\", optional = true, default-features = false }\ntypenum = { version = \"1.12\", optional = true }\nserde = { version = \"1.0.104\", features = [\"derive\"], default-features = false }\nlazy_static = { version = \"1.4.0\", optional = true }\n\n[dev-dependencies]\nsecp256k1-test = { package = \"secp256k1\", version = \"0.20.3\", features = [\"rand-std\", \"recovery\"] }\nclear_on_drop = \"0.2\"\nserde_json = \"1.0\"\nhex = \"0.4\"\nhex-literal = \"0.3.3\"\nbincode = \"1.3.3\"\n\n[build-dependencies]\nlibsecp256k1-gen-ecmult = { version = \"0.3.0\", path = \"gen/ecmult\" }\nlibsecp256k1-gen-genmult = { version = \"0.3.0\", path = \"gen/genmult\" }\n\n[features]\ndefault = [\"std\", \"hmac\", \"static-context\"]\nstd = [\"libsecp256k1-core/std\", \"sha2/std\", \"rand/std\", \"serde/std\", \"base64/std\"]\nhmac = [\"hmac-drbg\", \"sha2\", \"typenum\"]\nstatic-context = []\nlazy-static-context = [\"static-context\", \"lazy_static\", \"std\"]\n\n[workspace]\nmembers = [\n  \"./gen/ecmult\",\n  \"./gen/genmult\",\n]\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "_Please note that this repository is no longer maintained. You can use [k256](https://crates.io/crates/k256) instead._\n\n# SECP256K1 implementation in pure Rust\n\n* [Cargo](https://crates.io/crates/libsecp256k1)\n* [Documentation](https://docs.rs/libsecp256k1)\n\nSECP256K1 implementation with `no_std` support. Currently we have implementation for:\n\n* Convert a private key to a public key.\n* Sign messages.\n* Signature verification.\n* Public key recovery from signed messages.\n* Shared secrets.\n\n## Feature flags\n\n* `std`: If disabled, works in `no_std` environment. Enabled by default.\n* `hmac`: Add certain features that requires the HMAC-DRBG. This includes\n  signing. Enabled by default.\n* `static-context`: To speed up computation, the library uses a pre-computed\n  table context for many `ecmult` operations. This feature flag puts the context\n  directly as static variables. If disabled, the context must be created from\n  heap manually. Increases binary size, enabled by default.\n* `lazy-static-context`: Instead of storing the pre-computed table context as\n  static variables, store it as a variable that dynamically allocates the\n  context in heap via `lazy_static`. It overwrites `static-context`. Impact\n  bootstrap performance and only available in `std`, disabled by default.\n\n## Development workflow\n\n### Branch\n\nThis repository uses `develop` branch for development. Changes are periodically\nmerged to `master` branch.\n\n### Pull request\n\nAll changes (except new releases) are handled through pull requests. Please open\nyour PR against `develop` branch.\n\n### Versioning\n\n`libsecp256k1` follows [Semantic Versioning](https://semver.org/). An unreleased crate\nin the repository will have the `-dev` suffix in the end, and we do rolling\nreleases.\n\nWhen you make a pull request against this repository, please also update the\naffected crates' versions, using the following rules. Note that the rules should\nbe applied recursively -- if a change modifies any upper crate's dependency\n(even just the `Cargo.toml` file), then the upper crate will also need to apply\nthose rules.\n\nAdditionally, if your change is notable, then you should also modify the\ncorresponding `CHANGELOG.md` file, in the \"Unreleased\" section.\n\nIf the affected crate already has `-dev` suffix:\n\n* If your change is a patch, then you do not have to update any versions.\n* If your change introduces a new feature, please check if the local version\n  already had its minor version bumped, if not, bump it.\n* If your change modifies the current interface, please check if the local\n  version already had its major version bumped, if not, bump it.\n\nIf the affected crate does not yet have `-dev` suffix:\n\n* If your change is a patch, then bump the patch version, and add `-dev` suffix.\n* If your change introduces a new feature, then bump the minor version, and add\n  `-dev` suffix.\n* If your change modifies the current interface, then bump the major version,\n  and add `-dev` suffix.\n\nIf your pull request introduces a new crate, please set its version to\n`1.0.0-dev`.\n"
  },
  {
    "path": "benches/public_key.rs",
    "content": "#![feature(test)]\n\nextern crate test;\n\nuse libsecp256k1::PublicKey;\nuse secp256k1_test::{rand::thread_rng, Secp256k1};\nuse test::Bencher;\n\n#[bench]\nfn bench_public_key_parse(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let (_, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n    let pubkey_arr = secp_pubkey.serialize_uncompressed();\n    assert!(pubkey_arr.len() == 65);\n    let mut pubkey_a = [0u8; 65];\n    pubkey_a[0..65].copy_from_slice(&pubkey_arr[0..65]);\n    b.iter(|| {\n        let _pubkey = PublicKey::parse(&pubkey_a).unwrap();\n    });\n}\n\n#[bench]\nfn bench_public_key_serialize(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let (_, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n    let pubkey_arr = secp_pubkey.serialize_uncompressed();\n    assert!(pubkey_arr.len() == 65);\n    let mut pubkey_a = [0u8; 65];\n    pubkey_a[0..65].copy_from_slice(&pubkey_arr[0..65]);\n    let pubkey = PublicKey::parse(&pubkey_a).unwrap();\n    b.iter(|| {\n        let _serialized = pubkey.serialize();\n    });\n}\n\n#[bench]\nfn bench_public_key_serialize_compressed(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let (_, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n    let pubkey_arr = secp_pubkey.serialize_uncompressed();\n    assert!(pubkey_arr.len() == 65);\n    let mut pubkey_a = [0u8; 65];\n    pubkey_a[0..65].copy_from_slice(&pubkey_arr[0..65]);\n    let pubkey = PublicKey::parse(&pubkey_a).unwrap();\n    b.iter(|| {\n        let _serialized = pubkey.serialize_compressed();\n    });\n}\n"
  },
  {
    "path": "benches/sign.rs",
    "content": "#![feature(test)]\n\nextern crate test;\n\nuse arrayref::array_ref;\nuse libsecp256k1::{sign, Message, SecretKey};\nuse secp256k1_test::{rand::thread_rng, Secp256k1};\nuse test::Bencher;\n\n#[bench]\nfn bench_sign_message(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let message = Message::parse(&[5u8; 32]);\n    let (secp_privkey, _) = secp256k1.generate_keypair(&mut thread_rng());\n    let seckey = SecretKey::parse(array_ref!(secp_privkey, 0, 32)).unwrap();\n\n    b.iter(|| {\n        let _ = sign(&message, &seckey);\n    });\n}\n"
  },
  {
    "path": "benches/signature.rs",
    "content": "#![feature(test)]\n\nextern crate test;\n\nuse libsecp256k1::Signature;\nuse secp256k1_test::{rand::thread_rng, Message as SecpMessage, Secp256k1};\nuse test::Bencher;\n\n#[bench]\nfn bench_signature_parse(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let message_arr = [5u8; 32];\n    let (privkey, _) = secp256k1.generate_keypair(&mut thread_rng());\n    let message = SecpMessage::from_slice(&message_arr).unwrap();\n    let signature = secp256k1.sign(&message, &privkey);\n    let signature_arr = signature.serialize_compact();\n    assert!(signature_arr.len() == 64);\n    let mut signature_a = [0u8; 64];\n    signature_a.copy_from_slice(&signature_arr[0..64]);\n\n    b.iter(|| {\n        let _signature = Signature::parse_standard_slice(&signature_a);\n    });\n}\n\n#[bench]\nfn bench_signature_serialize(b: &mut Bencher) {\n    let secp256k1 = Secp256k1::new();\n    let message_arr = [5u8; 32];\n    let (privkey, _) = secp256k1.generate_keypair(&mut thread_rng());\n    let message = SecpMessage::from_slice(&message_arr).unwrap();\n    let signature = secp256k1.sign(&message, &privkey);\n    let signature_arr = signature.serialize_compact();\n    assert!(signature_arr.len() == 64);\n    let mut signature_a = [0u8; 64];\n    signature_a.copy_from_slice(&signature_arr[0..64]);\n    let signature = Signature::parse_standard_slice(&signature_a).expect(\"parsed signature\");\n\n    b.iter(|| {\n        let _serialized = signature.serialize();\n    });\n}\n"
  },
  {
    "path": "build.rs",
    "content": "use std::{env, fs::File, io::Write, path::Path};\n\nfn main() {\n    let out_dir = env::var_os(\"OUT_DIR\").unwrap();\n\n    let const_path = Path::new(&out_dir).join(\"const.rs\");\n    let mut const_file = File::create(&const_path).expect(\"Create const.rs file failed\");\n    libsecp256k1_gen_ecmult::generate_to(&mut const_file).expect(\"Write const.rs file failed\");\n    const_file.flush().expect(\"Flush const.rs file failed\");\n\n    let gen_path = Path::new(&out_dir).join(\"const_gen.rs\");\n    let mut gen_file = File::create(&gen_path).expect(\"Create const_gen.rs file failed\");\n    libsecp256k1_gen_genmult::generate_to(&mut gen_file).expect(\"Write const_gen.rs file failed\");\n    gen_file.flush().expect(\"Flush const_gen.rs file failed\");\n}\n"
  },
  {
    "path": "core/Cargo.toml",
    "content": "[package]\nname = \"libsecp256k1-core\"\ndescription = \"Core functions for pure Rust secp256k1 implementation.\"\nlicense = \"Apache-2.0\"\nversion = \"0.3.0\"\nauthors = [\"Wei Tang <hi@that.world>\"]\nrepository = \"https://github.com/paritytech/libsecp256k1\"\nkeywords = [\"crypto\", \"ECDSA\", \"secp256k1\", \"bitcoin\", \"no_std\"]\nedition = \"2018\"\n\n[dependencies]\nsubtle = { version = \"2.2\", default-features = false }\ncrunchy = \"0.2\"\ndigest = \"0.9\"\n\n[features]\ndefault = [\"std\"]\nstd = [\"subtle/std\"]\n"
  },
  {
    "path": "core/src/der.rs",
    "content": "use core::{\n    convert::{AsMut, AsRef},\n    mem,\n};\n\nuse crate::{error::Error, scalar::Scalar};\n\npub struct SignatureArray([u8; 6 + 33 + 33], usize);\n\nimpl SignatureArray {\n    pub fn new(size: usize) -> Self {\n        SignatureArray([0u8; 6 + 33 + 33], size)\n    }\n\n    pub fn len(&self) -> usize {\n        self.1\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n}\n\nimpl AsRef<[u8]> for SignatureArray {\n    fn as_ref(&self) -> &[u8] {\n        &self.0[..self.1]\n    }\n}\n\nimpl AsMut<[u8]> for SignatureArray {\n    fn as_mut(&mut self) -> &mut [u8] {\n        &mut self.0[..self.1]\n    }\n}\n\npub struct Decoder<'a>(&'a [u8], usize);\n\nimpl<'a> Decoder<'a> {\n    pub fn new(arr: &'a [u8]) -> Self {\n        Decoder(arr, 0)\n    }\n\n    pub fn remaining_len(&self) -> usize {\n        self.0.len() - self.1\n    }\n\n    pub fn read(&mut self) -> Result<u8, Error> {\n        if self.1 >= self.0.len() {\n            Err(Error::InvalidSignature)\n        } else {\n            let v = self.0[self.1];\n            self.1 += 1;\n            Ok(v)\n        }\n    }\n\n    pub fn peek(&self, forward: usize) -> Result<u8, Error> {\n        if self.1 + forward >= self.0.len() {\n            Err(Error::InvalidSignature)\n        } else {\n            let v = self.0[self.1 + forward];\n            Ok(v)\n        }\n    }\n\n    pub fn peek_slice(&self, len: usize) -> Result<&[u8], Error> {\n        if (len == 0 && self.1 >= self.0.len()) || self.1 + len > self.0.len() {\n            Err(Error::InvalidSignature)\n        } else {\n            let v = &self.0[self.1..(self.1 + len)];\n            Ok(v)\n        }\n    }\n\n    pub fn skip(&mut self, len: usize) -> Result<(), Error> {\n        if (len == 0 && self.1 >= self.0.len()) || self.1 + len > self.0.len() {\n            Err(Error::InvalidSignature)\n        } else {\n            self.1 += len;\n            Ok(())\n        }\n    }\n\n    pub fn read_constructed_sequence(&mut self) -> Result<(), Error> {\n        let v = self.read()?;\n        if v == 0x30 {\n            Ok(())\n        } else {\n            Err(Error::InvalidSignature)\n        }\n    }\n\n    pub fn read_len(&mut self) -> Result<usize, Error> {\n        let b1 = self.read()?;\n        if b1 == 0xff {\n            return Err(Error::InvalidSignature);\n        }\n\n        // Short form\n        if b1 & 0x80 == 0 {\n            return Ok(b1 as usize);\n        }\n\n        // Infinite length is not allowed\n        if b1 == 0x80 {\n            return Err(Error::InvalidSignature);\n        }\n\n        let mut lenleft = (b1 & 0x7f) as usize;\n        if lenleft > self.remaining_len() {\n            return Err(Error::InvalidSignature);\n        }\n\n        if self.peek(0)? == 0 {\n            // Not the shortest possible length encoding\n            return Err(Error::InvalidSignature);\n        }\n\n        if lenleft > mem::size_of::<usize>() {\n            return Err(Error::InvalidSignature);\n        }\n\n        let mut ret = 0;\n        while lenleft > 0 {\n            ret = (ret << 8) | (self.read()? as usize);\n            if ret + lenleft > self.remaining_len() {\n                return Err(Error::InvalidSignature);\n            }\n            lenleft -= 1;\n        }\n\n        if ret < 128 {\n            // Not the shortest possible length encoding\n            return Err(Error::InvalidSignature);\n        }\n\n        Ok(ret)\n    }\n\n    pub fn read_integer(&mut self) -> Result<Scalar, Error> {\n        if self.read()? != 0x02 {\n            return Err(Error::InvalidSignature);\n        }\n\n        let mut rlen = self.read_len()?;\n        if rlen == 0 || rlen > self.remaining_len() {\n            return Err(Error::InvalidSignature);\n        }\n\n        if self.peek(0)? == 0x00 && rlen > 1 && (self.peek(1)? & 0x80) == 0x00 {\n            return Err(Error::InvalidSignature);\n        }\n\n        if self.peek(0)? == 0xff && rlen > 1 && (self.peek(1)? & 0x80) == 0x00 {\n            return Err(Error::InvalidSignature);\n        }\n\n        let mut overflow = false;\n        if self.peek(0)? & 0x80 == 0x80 {\n            overflow |= true;\n        }\n\n        // Skip leading zero bytes\n        while rlen > 0 && self.peek(0)? == 0 {\n            rlen -= 1;\n            self.read()?;\n        }\n\n        if rlen > 32 {\n            overflow |= true;\n        }\n\n        let mut int = Scalar::default();\n\n        if !overflow {\n            let mut b32 = [0u8; 32];\n            b32[32 - rlen..].copy_from_slice(self.peek_slice(rlen)?);\n            self.skip(rlen)?;\n\n            overflow |= bool::from(int.set_b32(&b32));\n        }\n\n        if overflow {\n            int = Scalar::default();\n        }\n\n        Ok(int)\n    }\n\n    pub fn read_seq_len_lax(&mut self) -> Result<usize, Error> {\n        let mut len = self.read()?;\n        if len & 0x80 != 0x00 {\n            len -= 0x80;\n            if len as usize > self.remaining_len() {\n                return Err(Error::InvalidSignature);\n            }\n            self.skip(len as usize)?;\n        }\n\n        Ok(len as usize)\n    }\n\n    pub fn read_len_lax(&mut self) -> Result<usize, Error> {\n        let mut ret = 0usize;\n        let mut len = self.read()?;\n        if len & 0x80 != 0x00 {\n            len -= 0x80;\n            if len as usize > self.remaining_len() {\n                return Err(Error::InvalidSignature);\n            }\n            while len > 0 && self.peek(0)? == 0 {\n                self.skip(1)?;\n                len -= 1;\n            }\n            if (len as usize) >= mem::size_of::<usize>() {\n                return Err(Error::InvalidSignature);\n            }\n            while len > 0 {\n                ret = (ret << 8) + (self.read()? as usize);\n                len -= 1;\n            }\n        } else {\n            ret = len as usize;\n        }\n        if ret > self.remaining_len() {\n            return Err(Error::InvalidSignature);\n        }\n\n        Ok(ret)\n    }\n\n    pub fn read_integer_lax(&mut self) -> Result<Scalar, Error> {\n        // Integer tag byte.\n        if self.read()? != 0x02 {\n            return Err(Error::InvalidSignature);\n        }\n\n        let mut len = self.read_len_lax()?;\n\n        // Ignore leading zeroes.\n        while len > 0 && self.peek(0)? == 0 {\n            len -= 1;\n            self.skip(1)?;\n        }\n\n        let mut overflow = false;\n        // Copy value\n        if len > 32 {\n            overflow |= true;\n        }\n\n        let mut int = Scalar::default();\n\n        if !overflow {\n            let mut b32 = [0u8; 32];\n            b32[32 - len..].copy_from_slice(&self.peek_slice(len)?);\n            self.skip(len)?;\n\n            overflow |= bool::from(int.set_b32(&b32));\n        }\n\n        if overflow {\n            int = Scalar::default();\n        }\n\n        Ok(int)\n    }\n}\n"
  },
  {
    "path": "core/src/ecdh.rs",
    "content": "use crate::{\n    ecmult::ECMultContext,\n    group::{Affine, Jacobian},\n    scalar::Scalar,\n};\nuse digest::{generic_array::GenericArray, Digest};\n\nimpl ECMultContext {\n    pub fn ecdh_raw<D: Digest + Default>(\n        &self,\n        point: &Affine,\n        scalar: &Scalar,\n    ) -> Option<GenericArray<u8, D::OutputSize>> {\n        let mut digest: D = Default::default();\n\n        let mut pt = *point;\n        let s = *scalar;\n\n        if s.is_zero() {\n            return None;\n        }\n\n        let mut res = Jacobian::default();\n        self.ecmult_const(&mut res, &pt, &s);\n        pt.set_gej(&res);\n\n        pt.x.normalize();\n        pt.y.normalize();\n\n        let x = pt.x.b32();\n        let y = 0x02 | (if pt.y.is_odd() { 1 } else { 0 });\n\n        digest.update(&[y]);\n        digest.update(&x);\n        Some(digest.finalize_reset())\n    }\n}\n"
  },
  {
    "path": "core/src/ecdsa.rs",
    "content": "use crate::{\n    ecmult::{ECMultContext, ECMultGenContext},\n    field::Field,\n    group::{Affine, Jacobian},\n    scalar::Scalar,\n    Error,\n};\n\nconst P_MINUS_ORDER: Field = Field::new(0, 0, 0, 1, 0x45512319, 0x50B75FC4, 0x402DA172, 0x2FC9BAEE);\n\nconst ORDER_AS_FE: Field = Field::new(\n    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xBAAEDCE6, 0xAF48A03B, 0xBFD25E8C, 0xD0364141,\n);\n\nimpl ECMultContext {\n    pub fn verify_raw(\n        &self,\n        sigr: &Scalar,\n        sigs: &Scalar,\n        pubkey: &Affine,\n        message: &Scalar,\n    ) -> bool {\n        let c;\n        let (sn, u1, u2): (Scalar, Scalar, Scalar);\n\n        if sigr.is_zero() || sigs.is_zero() {\n            return false;\n        }\n\n        sn = sigs.inv_var();\n        u1 = &sn * message;\n        u2 = &sn * sigr;\n        let mut pubkeyj: Jacobian = Jacobian::default();\n        pubkeyj.set_ge(pubkey);\n        let mut pr: Jacobian = Jacobian::default();\n        self.ecmult(&mut pr, &pubkeyj, &u2, &u1);\n        if pr.is_infinity() {\n            return false;\n        }\n\n        c = sigr.b32();\n        let mut xr: Field = Default::default();\n        let _ = xr.set_b32(&c);\n\n        if pr.eq_x_var(&xr) {\n            return true;\n        }\n        if xr >= P_MINUS_ORDER {\n            return false;\n        }\n        xr += ORDER_AS_FE;\n        if pr.eq_x_var(&xr) {\n            return true;\n        }\n        false\n    }\n\n    pub fn recover_raw(\n        &self,\n        sigr: &Scalar,\n        sigs: &Scalar,\n        rec_id: u8,\n        message: &Scalar,\n    ) -> Result<Affine, Error> {\n        debug_assert!(rec_id < 4);\n\n        if sigr.is_zero() || sigs.is_zero() {\n            return Err(Error::InvalidSignature);\n        }\n\n        let brx = sigr.b32();\n        let mut fx = Field::default();\n        let overflow = fx.set_b32(&brx);\n        debug_assert!(overflow);\n\n        if rec_id & 2 > 0 {\n            if fx >= P_MINUS_ORDER {\n                return Err(Error::InvalidSignature);\n            }\n            fx += ORDER_AS_FE;\n        }\n        let mut x = Affine::default();\n        if !x.set_xo_var(&fx, rec_id & 1 > 0) {\n            return Err(Error::InvalidSignature);\n        }\n        let mut xj = Jacobian::default();\n        xj.set_ge(&x);\n        let rn = sigr.inv();\n        let mut u1 = &rn * message;\n        u1 = -u1;\n        let u2 = &rn * sigs;\n        let mut qj = Jacobian::default();\n        self.ecmult(&mut qj, &xj, &u2, &u1);\n\n        let mut pubkey = Affine::default();\n        pubkey.set_gej_var(&qj);\n\n        if pubkey.is_infinity() {\n            Err(Error::InvalidSignature)\n        } else {\n            Ok(pubkey)\n        }\n    }\n}\n\nimpl ECMultGenContext {\n    pub fn sign_raw(\n        &self,\n        seckey: &Scalar,\n        message: &Scalar,\n        nonce: &Scalar,\n    ) -> Result<(Scalar, Scalar, u8), Error> {\n        let mut rp = Jacobian::default();\n        self.ecmult_gen(&mut rp, nonce);\n        let mut r = Affine::default();\n        r.set_gej(&rp);\n        r.x.normalize();\n        r.y.normalize();\n        let b = r.x.b32();\n        let mut sigr = Scalar::default();\n        let overflow = bool::from(sigr.set_b32(&b));\n        debug_assert!(!sigr.is_zero());\n        debug_assert!(!overflow);\n\n        let mut recid = (if overflow { 2 } else { 0 }) | (if r.y.is_odd() { 1 } else { 0 });\n        let mut n = &sigr * seckey;\n        n += message;\n        let mut sigs = nonce.inv();\n        sigs *= &n;\n        n.clear();\n        rp.clear();\n        r.clear();\n        if sigs.is_zero() {\n            return Err(Error::InvalidMessage);\n        }\n        if sigs.is_high() {\n            sigs = -sigs;\n            recid ^= 1;\n        }\n        Ok((sigr, sigs, recid))\n    }\n}\n"
  },
  {
    "path": "core/src/ecmult.rs",
    "content": "use crate::{\n    field::Field,\n    group::{globalz_set_table_gej, set_table_gej_var, Affine, AffineStorage, Jacobian, AFFINE_G},\n    scalar::Scalar,\n};\nuse alloc::{\n    alloc::{alloc, Layout},\n    boxed::Box,\n    vec,\n    vec::Vec,\n};\nuse subtle::Choice;\n\npub const WINDOW_A: usize = 5;\npub const WINDOW_G: usize = 16;\npub const ECMULT_TABLE_SIZE_A: usize = 1 << (WINDOW_A - 2);\npub const ECMULT_TABLE_SIZE_G: usize = 1 << (WINDOW_G - 2);\npub const WNAF_BITS: usize = 256;\n\nfn odd_multiples_table_storage_var(pre: &mut [AffineStorage], a: &Jacobian) {\n    let mut prej: Vec<Jacobian> = Vec::with_capacity(pre.len());\n    for _ in 0..pre.len() {\n        prej.push(Jacobian::default());\n    }\n    let mut prea: Vec<Affine> = Vec::with_capacity(pre.len());\n    for _ in 0..pre.len() {\n        prea.push(Affine::default());\n    }\n    let mut zr: Vec<Field> = Vec::with_capacity(pre.len());\n    for _ in 0..pre.len() {\n        zr.push(Field::default());\n    }\n\n    odd_multiples_table(&mut prej, &mut zr, a);\n    set_table_gej_var(&mut prea, &prej, &zr);\n\n    for i in 0..pre.len() {\n        pre[i] = prea[i].into();\n    }\n}\n\n/// Context for accelerating the computation of a*P + b*G.\npub struct ECMultContext {\n    pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G],\n}\n\nimpl ECMultContext {\n    /// Create a new `ECMultContext` from raw values.\n    ///\n    /// # Safety\n    /// The function is unsafe because incorrect value of `pre_g` can lead to\n    /// crypto logic failure. You most likely do not want to use this function,\n    /// but `ECMultContext::new_boxed`.\n    pub const unsafe fn new_from_raw(pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G]) -> Self {\n        Self { pre_g }\n    }\n\n    /// Inspect raw values of `ECMultContext`.\n    pub fn inspect_raw(&self) -> &[AffineStorage; ECMULT_TABLE_SIZE_G] {\n        &self.pre_g\n    }\n\n    /// Generate a new `ECMultContext` on the heap. Note that this function is expensive.\n    pub fn new_boxed() -> Box<Self> {\n        // This unsafe block allocates a new, unitialized `ECMultContext` and\n        // then fills in the value. This is to avoid allocating it on stack\n        // because the struct is big. All values in `ECMultContext` are manually\n        // initialized after allocation.\n        let mut this = unsafe {\n            let ptr = alloc(Layout::new::<ECMultContext>()) as *mut ECMultContext;\n            let mut this = Box::from_raw(ptr);\n\n            for i in 0..ECMULT_TABLE_SIZE_G {\n                this.pre_g[i] = AffineStorage::default();\n            }\n\n            this\n        };\n\n        let mut gj = Jacobian::default();\n        gj.set_ge(&AFFINE_G);\n        odd_multiples_table_storage_var(&mut this.pre_g, &gj);\n\n        this\n    }\n}\n\n/// Set a batch of group elements equal to the inputs given in jacobian\n/// coordinates. Not constant time.\npub fn set_all_gej_var(a: &[Jacobian]) -> Vec<Affine> {\n    let mut az: Vec<Field> = Vec::with_capacity(a.len());\n    for point in a {\n        if !point.is_infinity() {\n            az.push(point.z);\n        }\n    }\n    let azi: Vec<Field> = inv_all_var(&az);\n\n    let mut ret = vec![Affine::default(); a.len()];\n\n    let mut count = 0;\n    for i in 0..a.len() {\n        ret[i].infinity = a[i].infinity;\n        if !a[i].is_infinity() {\n            ret[i].set_gej_zinv(&a[i], &azi[count]);\n            count += 1;\n        }\n    }\n    ret\n}\n\n/// Calculate the (modular) inverses of a batch of field\n/// elements. Requires the inputs' magnitudes to be at most 8. The\n/// output magnitudes are 1 (but not guaranteed to be\n/// normalized).\npub fn inv_all_var(fields: &[Field]) -> Vec<Field> {\n    if fields.is_empty() {\n        return Vec::new();\n    }\n\n    let mut ret = Vec::with_capacity(fields.len());\n    ret.push(fields[0]);\n\n    for i in 1..fields.len() {\n        ret.push(Field::default());\n        ret[i] = ret[i - 1] * fields[i];\n    }\n\n    let mut u = ret[fields.len() - 1].inv_var();\n\n    for i in (1..fields.len()).rev() {\n        let j = i;\n        let i = i - 1;\n        ret[j] = ret[i] * u;\n        u *= fields[j];\n    }\n\n    ret[0] = u;\n    ret\n}\n\nconst GEN_BLIND: Scalar = Scalar([\n    2217680822, 850875797, 1046150361, 1330484644, 4015777837, 2466086288, 2052467175, 2084507480,\n]);\nconst GEN_INITIAL: Jacobian = Jacobian {\n    x: Field::new_raw(\n        586608, 43357028, 207667908, 262670128, 142222828, 38529388, 267186148, 45417712,\n        115291924, 13447464,\n    ),\n    y: Field::new_raw(\n        12696548, 208302564, 112025180, 191752716, 143238548, 145482948, 228906000, 69755164,\n        243572800, 210897016,\n    ),\n    z: Field::new_raw(\n        3685368, 75404844, 20246216, 5748944, 73206666, 107661790, 110806176, 73488774, 5707384,\n        104448710,\n    ),\n    infinity: false,\n};\n\n/// Context for accelerating the computation of a*G.\npub struct ECMultGenContext {\n    prec: [[AffineStorage; 16]; 64],\n    blind: Scalar,\n    initial: Jacobian,\n}\n\nimpl ECMultGenContext {\n    /// Create a new `ECMultGenContext` from raw values.\n    ///\n    /// # Safety\n    /// The function is unsafe because incorrect value of `pre_g` can lead to\n    /// crypto logic failure. You most likely do not want to use this function,\n    /// but `ECMultGenContext::new_boxed`.\n    pub const unsafe fn new_from_raw(prec: [[AffineStorage; 16]; 64]) -> Self {\n        Self {\n            prec,\n            blind: GEN_BLIND,\n            initial: GEN_INITIAL,\n        }\n    }\n\n    /// Inspect `ECMultGenContext` values.\n    pub fn inspect_raw(&self) -> &[[AffineStorage; 16]; 64] {\n        &self.prec\n    }\n\n    /// Generate a new `ECMultGenContext` on the heap. Note that this function is expensive.\n    pub fn new_boxed() -> Box<Self> {\n        // This unsafe block allocates a new, unitialized `ECMultGenContext` and\n        // then fills in the value. This is to avoid allocating it on stack\n        // because the struct is big. All values in `ECMultGenContext` are\n        // manually initialized after allocation.\n        let mut this = unsafe {\n            let ptr = alloc(Layout::new::<ECMultGenContext>()) as *mut ECMultGenContext;\n            let mut this = Box::from_raw(ptr);\n\n            for j in 0..64 {\n                for i in 0..16 {\n                    this.prec[j][i] = AffineStorage::default();\n                }\n            }\n\n            this.blind = GEN_BLIND;\n            this.initial = GEN_INITIAL;\n\n            this\n        };\n\n        let mut gj = Jacobian::default();\n        gj.set_ge(&AFFINE_G);\n\n        // Construct a group element with no known corresponding scalar (nothing up my sleeve).\n        let mut nums_32 = [0u8; 32];\n        debug_assert!(b\"The scalar for this x is unknown\".len() == 32);\n        for (i, v) in b\"The scalar for this x is unknown\".iter().enumerate() {\n            nums_32[i] = *v;\n        }\n        let mut nums_x = Field::default();\n        assert!(nums_x.set_b32(&nums_32));\n        let mut nums_ge = Affine::default();\n        assert!(nums_ge.set_xo_var(&nums_x, false));\n        let mut nums_gej = Jacobian::default();\n        nums_gej.set_ge(&nums_ge);\n        nums_gej = nums_gej.add_ge_var(&AFFINE_G, None);\n\n        // Compute prec.\n        let mut precj: Vec<Jacobian> = Vec::with_capacity(1024);\n        for _ in 0..1024 {\n            precj.push(Jacobian::default());\n        }\n        let mut gbase = gj;\n        let mut numsbase = nums_gej;\n        for j in 0..64 {\n            precj[j * 16] = numsbase;\n            for i in 1..16 {\n                precj[j * 16 + i] = precj[j * 16 + i - 1].add_var(&gbase, None);\n            }\n            for _ in 0..4 {\n                gbase = gbase.double_var(None);\n            }\n            numsbase = numsbase.double_var(None);\n            if j == 62 {\n                numsbase = numsbase.neg();\n                numsbase = numsbase.add_var(&nums_gej, None);\n            }\n        }\n        let prec = set_all_gej_var(&precj);\n\n        for j in 0..64 {\n            for i in 0..16 {\n                let pg: AffineStorage = prec[j * 16 + i].into();\n                this.prec[j][i] = pg;\n            }\n        }\n\n        this\n    }\n}\n\npub fn odd_multiples_table(prej: &mut [Jacobian], zr: &mut [Field], a: &Jacobian) {\n    debug_assert!(prej.len() == zr.len());\n    debug_assert!(!prej.is_empty());\n    debug_assert!(!a.is_infinity());\n\n    let d = a.double_var(None);\n    let d_ge = Affine {\n        x: d.x,\n        y: d.y,\n        infinity: false,\n    };\n\n    let mut a_ge = Affine::default();\n    a_ge.set_gej_zinv(a, &d.z);\n    prej[0].x = a_ge.x;\n    prej[0].y = a_ge.y;\n    prej[0].z = a.z;\n    prej[0].infinity = false;\n\n    zr[0] = d.z;\n    for i in 1..prej.len() {\n        prej[i] = prej[i - 1].add_ge_var(&d_ge, Some(&mut zr[i]));\n    }\n\n    let l = prej.last().unwrap().z * d.z;\n    prej.last_mut().unwrap().z = l;\n}\n\nfn odd_multiples_table_globalz_windowa(\n    pre: &mut [Affine; ECMULT_TABLE_SIZE_A],\n    globalz: &mut Field,\n    a: &Jacobian,\n) {\n    let mut prej: [Jacobian; ECMULT_TABLE_SIZE_A] = Default::default();\n    let mut zr: [Field; ECMULT_TABLE_SIZE_A] = Default::default();\n\n    odd_multiples_table(&mut prej, &mut zr, a);\n    globalz_set_table_gej(pre, globalz, &prej, &zr);\n}\n\nfn table_get_ge(r: &mut Affine, pre: &[Affine], n: i32, w: usize) {\n    debug_assert!(n & 1 == 1);\n    debug_assert!(n >= -((1 << (w - 1)) - 1));\n    debug_assert!(n <= ((1 << (w - 1)) - 1));\n    if n > 0 {\n        *r = pre[((n - 1) / 2) as usize];\n    } else {\n        *r = pre[((-n - 1) / 2) as usize].neg();\n    }\n}\n\nfn table_get_ge_const(r: &mut Affine, pre: &[Affine], n: i32, w: usize) {\n    let abs_n = n * (if n > 0 { 1 } else { 0 } * 2 - 1);\n    let idx_n = abs_n / 2;\n    debug_assert!(n & 1 == 1);\n    debug_assert!(n >= -((1 << (w - 1)) - 1));\n    debug_assert!(n <= ((1 << (w - 1)) - 1));\n    for m in 0..pre.len() {\n        let flag = m == idx_n as usize;\n        r.x.cmov(&pre[m].x, flag);\n        r.y.cmov(&pre[m].y, flag);\n    }\n    r.infinity = false;\n    let neg_y = r.y.neg(1);\n    r.y.cmov(&neg_y, n != abs_n);\n}\n\nfn table_get_ge_storage(r: &mut Affine, pre: &[AffineStorage], n: i32, w: usize) {\n    debug_assert!(n & 1 == 1);\n    debug_assert!(n >= -((1 << (w - 1)) - 1));\n    debug_assert!(n <= ((1 << (w - 1)) - 1));\n    if n > 0 {\n        *r = pre[((n - 1) / 2) as usize].into();\n    } else {\n        *r = pre[((-n - 1) / 2) as usize].into();\n        *r = r.neg();\n    }\n}\n\npub fn ecmult_wnaf(wnaf: &mut [i32], a: &Scalar, w: usize) -> i32 {\n    let mut s = *a;\n    let mut last_set_bit: i32 = -1;\n    let mut bit = 0;\n    let mut sign = 1;\n    let mut carry = 0;\n\n    debug_assert!(wnaf.len() <= 256);\n    debug_assert!(w >= 2 && w <= 31);\n\n    for i in 0..wnaf.len() {\n        wnaf[i] = 0;\n    }\n\n    if s.bits(255, 1) > 0 {\n        s = -s;\n        sign = -1;\n    }\n\n    while bit < wnaf.len() {\n        let mut now;\n        let mut word;\n        if s.bits(bit, 1) == carry as u32 {\n            bit += 1;\n            continue;\n        }\n\n        now = w;\n        if now > wnaf.len() - bit {\n            now = wnaf.len() - bit;\n        }\n\n        word = (s.bits_var(bit, now) as i32) + carry;\n\n        carry = (word >> (w - 1)) & 1;\n        word -= carry << w;\n\n        wnaf[bit] = sign * word;\n        last_set_bit = bit as i32;\n\n        bit += now;\n    }\n    debug_assert!(carry == 0);\n    debug_assert!({\n        let mut t = true;\n        while bit < 256 {\n            t = t && (s.bits(bit, 1) == 0);\n            bit += 1;\n        }\n        t\n    });\n    last_set_bit + 1\n}\n\npub fn ecmult_wnaf_const(wnaf: &mut [i32], a: &Scalar, w: usize) -> i32 {\n    let mut s = *a;\n    let mut word = 0;\n\n    /* Note that we cannot handle even numbers by negating them to be\n     * odd, as is done in other implementations, since if our scalars\n     * were specified to have width < 256 for performance reasons,\n     * their negations would have width 256 and we'd lose any\n     * performance benefit. Instead, we use a technique from Section\n     * 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for\n     * even) or 2 (for odd) to the number we are encoding, returning a\n     * skew value indicating this, and having the caller compensate\n     * after doing the multiplication. */\n\n    /* Negative numbers will be negated to keep their bit\n     * representation below the maximum width */\n    let flip = s.is_high();\n    /* We add 1 to even numbers, 2 to odd ones, noting that negation\n     * flips parity */\n    let bit = flip ^ !s.is_even();\n    /* We add 1 to even numbers, 2 to odd ones, noting that negation\n     * flips parity */\n    let neg_s = -s;\n    let not_neg_one = !neg_s.is_one();\n    s.cadd_bit(if bit { 1 } else { 0 }, not_neg_one);\n    /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so\n     * caller expects that we added two to it and flipped it. In fact\n     * for -1 these operations are identical. We only flipped, but\n     * since skewing is required (in the sense that the skew must be 1\n     * or 2, never zero) and flipping is not, we need to change our\n     * flags to claim that we only skewed. */\n    let mut global_sign = if flip { -1 } else { 1 };\n    s.cond_neg_assign(Choice::from(flip as u8));\n    global_sign *= if not_neg_one { 1 } else { 0 } * 2 - 1;\n    let skew = 1 << (if bit { 1 } else { 0 });\n\n    let mut u_last: i32 = s.shr_int(w) as i32;\n    let mut u: i32 = 0;\n    while word * w < WNAF_BITS {\n        u = s.shr_int(w) as i32;\n        let even = (u & 1) == 0;\n        let sign = 2 * (if u_last > 0 { 1 } else { 0 }) - 1;\n        u += sign * if even { 1 } else { 0 };\n        u_last -= sign * if even { 1 } else { 0 } * (1 << w);\n\n        wnaf[word] = (u_last as i32 * global_sign as i32) as i32;\n        word += 1;\n\n        u_last = u;\n    }\n    wnaf[word] = u * global_sign as i32;\n\n    debug_assert!(s.is_zero());\n    let wnaf_size = (WNAF_BITS + w - 1) / w;\n    debug_assert!(word == wnaf_size);\n\n    skew\n}\n\nimpl ECMultContext {\n    pub fn ecmult(&self, r: &mut Jacobian, a: &Jacobian, na: &Scalar, ng: &Scalar) {\n        let mut tmpa = Affine::default();\n        let mut pre_a: [Affine; ECMULT_TABLE_SIZE_A] = Default::default();\n        let mut z = Field::default();\n        let mut wnaf_na = [0i32; 256];\n        let mut wnaf_ng = [0i32; 256];\n        let bits_na = ecmult_wnaf(&mut wnaf_na, na, WINDOW_A);\n        let mut bits = bits_na;\n        odd_multiples_table_globalz_windowa(&mut pre_a, &mut z, a);\n\n        let bits_ng = ecmult_wnaf(&mut wnaf_ng, &ng, WINDOW_G);\n        if bits_ng > bits {\n            bits = bits_ng;\n        }\n\n        r.set_infinity();\n        for i in (0..bits).rev() {\n            let mut n;\n            *r = r.double_var(None);\n\n            n = wnaf_na[i as usize];\n            if i < bits_na && n != 0 {\n                table_get_ge(&mut tmpa, &pre_a, n, WINDOW_A);\n                *r = r.add_ge_var(&tmpa, None);\n            }\n            n = wnaf_ng[i as usize];\n            if i < bits_ng && n != 0 {\n                table_get_ge_storage(&mut tmpa, &self.pre_g, n, WINDOW_G);\n                *r = r.add_zinv_var(&tmpa, &z);\n            }\n        }\n\n        if !r.is_infinity() {\n            r.z *= &z;\n        }\n    }\n\n    pub fn ecmult_const(&self, r: &mut Jacobian, a: &Affine, scalar: &Scalar) {\n        const WNAF_SIZE: usize = (WNAF_BITS + (WINDOW_A - 1) - 1) / (WINDOW_A - 1);\n\n        let mut tmpa = Affine::default();\n        let mut pre_a: [Affine; ECMULT_TABLE_SIZE_A] = Default::default();\n        let mut z = Field::default();\n\n        let mut wnaf_1 = [0i32; 1 + WNAF_SIZE];\n\n        let sc = *scalar;\n        let skew_1 = ecmult_wnaf_const(&mut wnaf_1, &sc, WINDOW_A - 1);\n\n        /* Calculate odd multiples of a.  All multiples are brought to\n         * the same Z 'denominator', which is stored in Z. Due to\n         * secp256k1' isomorphism we can do all operations pretending\n         * that the Z coordinate was 1, use affine addition formulae,\n         * and correct the Z coordinate of the result once at the end.\n         */\n        r.set_ge(a);\n        odd_multiples_table_globalz_windowa(&mut pre_a, &mut z, r);\n        for i in 0..ECMULT_TABLE_SIZE_A {\n            pre_a[i].y.normalize_weak();\n        }\n\n        /* first loop iteration (separated out so we can directly set\n         * r, rather than having it start at infinity, get doubled\n         * several times, then have its new value added to it) */\n        let i = wnaf_1[WNAF_SIZE];\n        debug_assert!(i != 0);\n        table_get_ge_const(&mut tmpa, &pre_a, i, WINDOW_A);\n        r.set_ge(&tmpa);\n\n        /* remaining loop iterations */\n        for i in (0..WNAF_SIZE).rev() {\n            for _ in 0..(WINDOW_A - 1) {\n                let r2 = *r;\n                r.double_nonzero_in_place(&r2, None);\n            }\n\n            let n = wnaf_1[i];\n            table_get_ge_const(&mut tmpa, &pre_a, n, WINDOW_A);\n            debug_assert!(n != 0);\n            *r = r.add_ge(&tmpa);\n        }\n\n        r.z *= &z;\n\n        /* Correct for wNAF skew */\n        let mut correction = *a;\n        let mut correction_1_stor: AffineStorage;\n        let a2_stor: AffineStorage;\n        let mut tmpj = Jacobian::default();\n        tmpj.set_ge(&correction);\n        tmpj = tmpj.double_var(None);\n        correction.set_gej(&tmpj);\n        correction_1_stor = (*a).into();\n        a2_stor = correction.into();\n\n        /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */\n        correction_1_stor.cmov(&a2_stor, skew_1 == 2);\n\n        /* Apply the correction */\n        correction = correction_1_stor.into();\n        correction = correction.neg();\n        *r = r.add_ge(&correction)\n    }\n}\n\nimpl ECMultGenContext {\n    pub fn ecmult_gen(&self, r: &mut Jacobian, gn: &Scalar) {\n        let mut adds = AffineStorage::default();\n        *r = self.initial;\n\n        let mut gnb = gn + &self.blind;\n        let mut add = Affine::default();\n        add.infinity = false;\n\n        for j in 0..64 {\n            let mut bits = gnb.bits(j * 4, 4);\n            for i in 0..16 {\n                adds.cmov(&self.prec[j][i], i as u32 == bits);\n            }\n            add = adds.into();\n            *r = r.add_ge(&add);\n            #[allow(unused_assignments)]\n            {\n                bits = 0;\n            }\n        }\n        add.clear();\n        gnb.clear();\n    }\n}\n"
  },
  {
    "path": "core/src/error.rs",
    "content": "#[derive(Debug, Clone, Copy, Eq, PartialEq)]\npub enum Error {\n    InvalidSignature,\n    InvalidPublicKey,\n    InvalidSecretKey,\n    InvalidRecoveryId,\n    InvalidMessage,\n    InvalidInputLength,\n    TweakOutOfRange,\n    InvalidAffine,\n}\n\n#[cfg(feature = \"std\")]\nimpl std::error::Error for Error {}\n\nimpl core::fmt::Display for Error {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        match self {\n            Error::InvalidSignature => write!(f, \"Invalid signature\"),\n            Error::InvalidPublicKey => write!(f, \"Invalid public key\"),\n            Error::InvalidSecretKey => write!(f, \"Invalid secret key\"),\n            Error::InvalidRecoveryId => write!(f, \"Invalid recovery ID\"),\n            Error::InvalidMessage => write!(f, \"Invalid message\"),\n            Error::InvalidInputLength => write!(f, \"Invalid input length\"),\n            Error::TweakOutOfRange => write!(f, \"Tweak out of range\"),\n            Error::InvalidAffine => write!(f, \"Invalid Affine\"),\n        }\n    }\n}\n"
  },
  {
    "path": "core/src/field.rs",
    "content": "use core::{\n    cmp::Ordering,\n    ops::{Add, AddAssign, Mul, MulAssign},\n};\n\nmacro_rules! debug_assert_bits {\n    ($x: expr, $n: expr) => {\n        debug_assert!($x >> $n == 0);\n    };\n}\n\n#[derive(Debug, Clone, Copy)]\n/// Field element for secp256k1.\npub struct Field {\n    /// Store representation of X.\n    /// X = sum(i=0..9, n[i]*2^(i*26)) mod p\n    /// where p = 2^256 - 0x1000003D1\n    ///\n    /// The least signifiant byte is in the front.\n    n: [u32; 10],\n    magnitude: u32,\n    normalized: bool,\n}\n\nimpl Field {\n    pub const fn new_raw(\n        d9: u32,\n        d8: u32,\n        d7: u32,\n        d6: u32,\n        d5: u32,\n        d4: u32,\n        d3: u32,\n        d2: u32,\n        d1: u32,\n        d0: u32,\n    ) -> Self {\n        Self {\n            n: [d0, d1, d2, d3, d4, d5, d6, d7, d8, d9],\n            magnitude: 1,\n            normalized: false,\n        }\n    }\n\n    pub const fn new(\n        d7: u32,\n        d6: u32,\n        d5: u32,\n        d4: u32,\n        d3: u32,\n        d2: u32,\n        d1: u32,\n        d0: u32,\n    ) -> Self {\n        Self {\n            n: [\n                d0 & 0x3ffffff,\n                (d0 >> 26) | ((d1 & 0xfffff) << 6),\n                (d1 >> 20) | ((d2 & 0x3fff) << 12),\n                (d2 >> 14) | ((d3 & 0xff) << 18),\n                (d3 >> 8) | ((d4 & 0x3) << 24),\n                (d4 >> 2) & 0x3ffffff,\n                (d4 >> 28) | ((d5 & 0x3fffff) << 4),\n                (d5 >> 22) | ((d6 & 0xffff) << 10),\n                (d6 >> 16) | ((d7 & 0x3ff) << 16),\n                (d7 >> 10),\n            ],\n            magnitude: 1,\n            normalized: true,\n        }\n    }\n\n    pub fn from_int(a: u32) -> Field {\n        let mut f = Field::default();\n        f.set_int(a);\n        f\n    }\n\n    fn verify(&self) -> bool {\n        let m = if self.normalized { 1 } else { 2 } * self.magnitude;\n        let mut r = true;\n        r = r && (self.n[0] <= 0x3ffffff * m);\n        r = r && (self.n[1] <= 0x3ffffff * m);\n        r = r && (self.n[2] <= 0x3ffffff * m);\n        r = r && (self.n[3] <= 0x3ffffff * m);\n        r = r && (self.n[4] <= 0x3ffffff * m);\n        r = r && (self.n[5] <= 0x3ffffff * m);\n        r = r && (self.n[6] <= 0x3ffffff * m);\n        r = r && (self.n[7] <= 0x3ffffff * m);\n        r = r && (self.n[8] <= 0x3ffffff * m);\n        r = r && (self.n[9] <= 0x03fffff * m);\n        r = r && (self.magnitude <= 32);\n        if self.normalized {\n            r = r && self.magnitude <= 1;\n            if r && (self.n[9] == 0x03fffff) {\n                let mid = self.n[8]\n                    & self.n[7]\n                    & self.n[6]\n                    & self.n[5]\n                    & self.n[4]\n                    & self.n[3]\n                    & self.n[2];\n                if mid == 0x3ffffff {\n                    r = r && ((self.n[1] + 0x40 + ((self.n[0] + 0x3d1) >> 26)) <= 0x3ffffff)\n                }\n            }\n        }\n        r\n    }\n\n    /// Normalize a field element.\n    pub fn normalize(&mut self) {\n        let mut t0 = self.n[0];\n        let mut t1 = self.n[1];\n        let mut t2 = self.n[2];\n        let mut t3 = self.n[3];\n        let mut t4 = self.n[4];\n        let mut t5 = self.n[5];\n        let mut t6 = self.n[6];\n        let mut t7 = self.n[7];\n        let mut t8 = self.n[8];\n        let mut t9 = self.n[9];\n\n        let mut m: u32;\n        let mut x = t9 >> 22;\n        t9 &= 0x03fffff;\n\n        t0 += x * 0x3d1;\n        t1 += x << 6;\n        t1 += t0 >> 26;\n        t0 &= 0x3ffffff;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        m = t2;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        m &= t3;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        m &= t4;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        m &= t5;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        m &= t6;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        m &= t7;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n        m &= t8;\n\n        debug_assert!(t9 >> 23 == 0);\n\n        x = (t9 >> 22)\n            | (if t9 == 0x03fffff { 1 } else { 0 }\n                & if m == 0x3ffffff { 1 } else { 0 }\n                & (if (t1 + 0x40 + ((t0 + 0x3d1) >> 26)) > 0x3ffffff {\n                    1\n                } else {\n                    0\n                }));\n\n        t0 += x * 0x3d1;\n        t1 += x << 6;\n        t1 += t0 >> 26;\n        t0 &= 0x3ffffff;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n\n        debug_assert!(t9 >> 22 == x);\n\n        t9 &= 0x03fffff;\n\n        self.n = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9];\n        self.magnitude = 1;\n        self.normalized = true;\n        debug_assert!(self.verify());\n    }\n\n    /// Weakly normalize a field element: reduce it magnitude to 1,\n    /// but don't fully normalize.\n    pub fn normalize_weak(&mut self) {\n        let mut t0 = self.n[0];\n        let mut t1 = self.n[1];\n        let mut t2 = self.n[2];\n        let mut t3 = self.n[3];\n        let mut t4 = self.n[4];\n        let mut t5 = self.n[5];\n        let mut t6 = self.n[6];\n        let mut t7 = self.n[7];\n        let mut t8 = self.n[8];\n        let mut t9 = self.n[9];\n\n        let x = t9 >> 22;\n        t9 &= 0x03fffff;\n\n        t0 += x * 0x3d1;\n        t1 += x << 6;\n        t1 += t0 >> 26;\n        t0 &= 0x3ffffff;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n\n        debug_assert!(t9 >> 23 == 0);\n\n        self.n = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9];\n        self.magnitude = 1;\n        debug_assert!(self.verify());\n    }\n\n    /// Normalize a field element, without constant-time guarantee.\n    pub fn normalize_var(&mut self) {\n        let mut t0 = self.n[0];\n        let mut t1 = self.n[1];\n        let mut t2 = self.n[2];\n        let mut t3 = self.n[3];\n        let mut t4 = self.n[4];\n        let mut t5 = self.n[5];\n        let mut t6 = self.n[6];\n        let mut t7 = self.n[7];\n        let mut t8 = self.n[8];\n        let mut t9 = self.n[9];\n\n        let mut m: u32;\n        let mut x = t9 >> 22;\n        t9 &= 0x03fffff;\n\n        t0 += x * 0x3d1;\n        t1 += x << 6;\n        t1 += t0 >> 26;\n        t0 &= 0x3ffffff;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        m = t2;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        m &= t3;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        m &= t4;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        m &= t5;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        m &= t6;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        m &= t7;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n        m &= t8;\n\n        debug_assert!(t9 >> 23 == 0);\n\n        x = (t9 >> 22)\n            | (if t9 == 0x03fffff { 1 } else { 0 }\n                & if m == 0x3ffffff { 1 } else { 0 }\n                & (if (t1 + 0x40 + ((t0 + 0x3d1) >> 26)) > 0x3ffffff {\n                    1\n                } else {\n                    0\n                }));\n\n        if x > 0 {\n            t0 += 0x3d1;\n            t1 += x << 6;\n            t1 += t0 >> 26;\n            t0 &= 0x3ffffff;\n            t2 += t1 >> 26;\n            t1 &= 0x3ffffff;\n            t3 += t2 >> 26;\n            t2 &= 0x3ffffff;\n            t4 += t3 >> 26;\n            t3 &= 0x3ffffff;\n            t5 += t4 >> 26;\n            t4 &= 0x3ffffff;\n            t6 += t5 >> 26;\n            t5 &= 0x3ffffff;\n            t7 += t6 >> 26;\n            t6 &= 0x3ffffff;\n            t8 += t7 >> 26;\n            t7 &= 0x3ffffff;\n            t9 += t8 >> 26;\n            t8 &= 0x3ffffff;\n\n            debug_assert!(t9 >> 22 == x);\n\n            t9 &= 0x03fffff;\n        }\n\n        self.n = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9];\n        self.magnitude = 1;\n        self.normalized = true;\n        debug_assert!(self.verify());\n    }\n\n    /// Verify whether a field element represents zero i.e. would\n    /// normalize to a zero value. The field implementation may\n    /// optionally normalize the input, but this should not be relied\n    /// upon.\n    pub fn normalizes_to_zero(&self) -> bool {\n        let mut t0 = self.n[0];\n        let mut t1 = self.n[1];\n        let mut t2 = self.n[2];\n        let mut t3 = self.n[3];\n        let mut t4 = self.n[4];\n        let mut t5 = self.n[5];\n        let mut t6 = self.n[6];\n        let mut t7 = self.n[7];\n        let mut t8 = self.n[8];\n        let mut t9 = self.n[9];\n\n        let mut z0: u32;\n        let mut z1: u32;\n\n        let x = t9 >> 22;\n        t9 &= 0x03fffff;\n\n        t0 += x * 0x3d1;\n        t1 += x << 6;\n        t1 += t0 >> 26;\n        t0 &= 0x3ffffff;\n        z0 = t0;\n        z1 = t0 ^ 0x3d0;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        z0 |= t1;\n        z1 &= t1 ^ 0x40;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        z0 |= t2;\n        z1 &= t2;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        z0 |= t3;\n        z1 &= t3;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        z0 |= t4;\n        z1 &= t4;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        z0 |= t5;\n        z1 &= t5;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        z0 |= t6;\n        z1 &= t6;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        z0 |= t7;\n        z1 &= t7;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n        z0 |= t8;\n        z1 &= t8;\n        z0 |= t9;\n        z1 &= t9 ^ 0x3c00000;\n\n        debug_assert!(t9 >> 23 == 0);\n\n        z0 == 0 || z1 == 0x3ffffff\n    }\n\n    /// Verify whether a field element represents zero i.e. would\n    /// normalize to a zero value. The field implementation may\n    /// optionally normalize the input, but this should not be relied\n    /// upon.\n    pub fn normalizes_to_zero_var(&self) -> bool {\n        let mut t0: u32;\n        let mut t1: u32;\n        let mut t2: u32;\n        let mut t3: u32;\n        let mut t4: u32;\n        let mut t5: u32;\n        let mut t6: u32;\n        let mut t7: u32;\n        let mut t8: u32;\n        let mut t9: u32;\n        let mut z0: u32;\n        let mut z1: u32;\n        let x: u32;\n\n        t0 = self.n[0];\n        t9 = self.n[9];\n\n        x = t9 >> 22;\n        t0 += x * 0x3d1;\n\n        z0 = t0 & 0x3ffffff;\n        z1 = z0 ^ 0x3d0;\n\n        if z0 != 0 && z1 != 0x3ffffff {\n            return false;\n        }\n\n        t1 = self.n[1];\n        t2 = self.n[2];\n        t3 = self.n[3];\n        t4 = self.n[4];\n        t5 = self.n[5];\n        t6 = self.n[6];\n        t7 = self.n[7];\n        t8 = self.n[8];\n\n        t9 &= 0x03fffff;\n        t1 += x << 6;\n\n        t1 += t0 >> 26;\n        t2 += t1 >> 26;\n        t1 &= 0x3ffffff;\n        z0 |= t1;\n        z1 &= t1 ^ 0x40;\n        t3 += t2 >> 26;\n        t2 &= 0x3ffffff;\n        z0 |= t2;\n        z1 &= t2;\n        t4 += t3 >> 26;\n        t3 &= 0x3ffffff;\n        z0 |= t3;\n        z1 &= t3;\n        t5 += t4 >> 26;\n        t4 &= 0x3ffffff;\n        z0 |= t4;\n        z1 &= t4;\n        t6 += t5 >> 26;\n        t5 &= 0x3ffffff;\n        z0 |= t5;\n        z1 &= t5;\n        t7 += t6 >> 26;\n        t6 &= 0x3ffffff;\n        z0 |= t6;\n        z1 &= t6;\n        t8 += t7 >> 26;\n        t7 &= 0x3ffffff;\n        z0 |= t7;\n        z1 &= t7;\n        t9 += t8 >> 26;\n        t8 &= 0x3ffffff;\n        z0 |= t8;\n        z1 &= t8;\n        z0 |= t9;\n        z1 &= t9 ^ 0x3c00000;\n\n        debug_assert!(t9 >> 23 == 0);\n\n        z0 == 0 || z1 == 0x3ffffff\n    }\n\n    /// Set a field element equal to a small integer. Resulting field\n    /// element is normalized.\n    pub fn set_int(&mut self, a: u32) {\n        self.n = [a, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n        self.magnitude = 1;\n        self.normalized = true;\n        debug_assert!(self.verify());\n    }\n\n    /// Verify whether a field element is zero. Requires the input to\n    /// be normalized.\n    pub fn is_zero(&self) -> bool {\n        debug_assert!(self.normalized);\n        debug_assert!(self.verify());\n        (self.n[0]\n            | self.n[1]\n            | self.n[2]\n            | self.n[3]\n            | self.n[4]\n            | self.n[5]\n            | self.n[6]\n            | self.n[7]\n            | self.n[8]\n            | self.n[9])\n            == 0\n    }\n\n    /// Check the \"oddness\" of a field element. Requires the input to\n    /// be normalized.\n    pub fn is_odd(&self) -> bool {\n        debug_assert!(self.normalized);\n        debug_assert!(self.verify());\n        self.n[0] & 1 != 0\n    }\n\n    /// Sets a field element equal to zero, initializing all fields.\n    pub fn clear(&mut self) {\n        self.magnitude = 0;\n        self.normalized = true;\n        self.n = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n    }\n\n    /// Set a field element equal to 32-byte big endian value. If\n    /// successful, the resulting field element is normalized.\n    #[must_use]\n    pub fn set_b32(&mut self, a: &[u8; 32]) -> bool {\n        self.n[0] = (a[31] as u32)\n            | ((a[30] as u32) << 8)\n            | ((a[29] as u32) << 16)\n            | (((a[28] & 0x3) as u32) << 24);\n        self.n[1] = (((a[28] >> 2) & 0x3f) as u32)\n            | ((a[27] as u32) << 6)\n            | ((a[26] as u32) << 14)\n            | (((a[25] & 0xf) as u32) << 22);\n        self.n[2] = (((a[25] >> 4) & 0xf) as u32)\n            | ((a[24] as u32) << 4)\n            | ((a[23] as u32) << 12)\n            | (((a[22] as u32) & 0x3f) << 20);\n        self.n[3] = (((a[22] >> 6) & 0x3) as u32)\n            | ((a[21] as u32) << 2)\n            | ((a[20] as u32) << 10)\n            | ((a[19] as u32) << 18);\n        self.n[4] = (a[18] as u32)\n            | ((a[17] as u32) << 8)\n            | ((a[16] as u32) << 16)\n            | (((a[15] & 0x3) as u32) << 24);\n        self.n[5] = (((a[15] >> 2) & 0x3f) as u32)\n            | ((a[14] as u32) << 6)\n            | ((a[13] as u32) << 14)\n            | (((a[12] as u32) & 0xf) << 22);\n        self.n[6] = (((a[12] >> 4) & 0xf) as u32)\n            | ((a[11] as u32) << 4)\n            | ((a[10] as u32) << 12)\n            | (((a[9] & 0x3f) as u32) << 20);\n        self.n[7] = (((a[9] >> 6) & 0x3) as u32)\n            | ((a[8] as u32) << 2)\n            | ((a[7] as u32) << 10)\n            | ((a[6] as u32) << 18);\n        self.n[8] = (a[5] as u32)\n            | ((a[4] as u32) << 8)\n            | ((a[3] as u32) << 16)\n            | (((a[2] & 0x3) as u32) << 24);\n        self.n[9] = (((a[2] >> 2) & 0x3f) as u32) | ((a[1] as u32) << 6) | ((a[0] as u32) << 14);\n\n        if self.n[9] == 0x03fffff\n            && (self.n[8] & self.n[7] & self.n[6] & self.n[5] & self.n[4] & self.n[3] & self.n[2])\n                == 0x3ffffff\n            && (self.n[1] + 0x40 + ((self.n[0] + 0x3d1) >> 26)) > 0x3ffffff\n        {\n            return false;\n        }\n\n        self.magnitude = 1;\n        self.normalized = true;\n        debug_assert!(self.verify());\n\n        true\n    }\n\n    pub fn fill_b32(&self, r: &mut [u8; 32]) {\n        debug_assert!(self.normalized);\n        debug_assert!(self.verify());\n\n        r[0] = ((self.n[9] >> 14) & 0xff) as u8;\n        r[1] = ((self.n[9] >> 6) & 0xff) as u8;\n        r[2] = (((self.n[9] & 0x3f) << 2) | ((self.n[8] >> 24) & 0x3)) as u8;\n        r[3] = ((self.n[8] >> 16) & 0xff) as u8;\n        r[4] = ((self.n[8] >> 8) & 0xff) as u8;\n        r[5] = (self.n[8] & 0xff) as u8;\n        r[6] = ((self.n[7] >> 18) & 0xff) as u8;\n        r[7] = ((self.n[7] >> 10) & 0xff) as u8;\n        r[8] = ((self.n[7] >> 2) & 0xff) as u8;\n        r[9] = (((self.n[7] & 0x3) << 6) | ((self.n[6] >> 20) & 0x3f)) as u8;\n        r[10] = ((self.n[6] >> 12) & 0xff) as u8;\n        r[11] = ((self.n[6] >> 4) & 0xff) as u8;\n        r[12] = (((self.n[6] & 0xf) << 4) | ((self.n[5] >> 22) & 0xf)) as u8;\n        r[13] = ((self.n[5] >> 14) & 0xff) as u8;\n        r[14] = ((self.n[5] >> 6) & 0xff) as u8;\n        r[15] = (((self.n[5] & 0x3f) << 2) | ((self.n[4] >> 24) & 0x3)) as u8;\n        r[16] = ((self.n[4] >> 16) & 0xff) as u8;\n        r[17] = ((self.n[4] >> 8) & 0xff) as u8;\n        r[18] = (self.n[4] & 0xff) as u8;\n        r[19] = ((self.n[3] >> 18) & 0xff) as u8;\n        r[20] = ((self.n[3] >> 10) & 0xff) as u8;\n        r[21] = ((self.n[3] >> 2) & 0xff) as u8;\n        r[22] = (((self.n[3] & 0x3) << 6) | ((self.n[2] >> 20) & 0x3f)) as u8;\n        r[23] = ((self.n[2] >> 12) & 0xff) as u8;\n        r[24] = ((self.n[2] >> 4) & 0xff) as u8;\n        r[25] = (((self.n[2] & 0xf) << 4) | ((self.n[1] >> 22) & 0xf)) as u8;\n        r[26] = ((self.n[1] >> 14) & 0xff) as u8;\n        r[27] = ((self.n[1] >> 6) & 0xff) as u8;\n        r[28] = (((self.n[1] & 0x3f) << 2) | ((self.n[0] >> 24) & 0x3)) as u8;\n        r[29] = ((self.n[0] >> 16) & 0xff) as u8;\n        r[30] = ((self.n[0] >> 8) & 0xff) as u8;\n        r[31] = (self.n[0] & 0xff) as u8;\n    }\n\n    /// Convert a field element to a 32-byte big endian\n    /// value. Requires the input to be normalized.\n    pub fn b32(&self) -> [u8; 32] {\n        let mut r = [0u8; 32];\n        self.fill_b32(&mut r);\n        r\n    }\n\n    /// Set a field element equal to the additive inverse of\n    /// another. Takes a maximum magnitude of the input as an\n    /// argument. The magnitude of the output is one higher.\n    pub fn neg_in_place(&mut self, other: &Field, m: u32) {\n        debug_assert!(other.magnitude <= m);\n        debug_assert!(other.verify());\n\n        self.n[0] = 0x3fffc2f * 2 * (m + 1) - other.n[0];\n        self.n[1] = 0x3ffffbf * 2 * (m + 1) - other.n[1];\n        self.n[2] = 0x3ffffff * 2 * (m + 1) - other.n[2];\n        self.n[3] = 0x3ffffff * 2 * (m + 1) - other.n[3];\n        self.n[4] = 0x3ffffff * 2 * (m + 1) - other.n[4];\n        self.n[5] = 0x3ffffff * 2 * (m + 1) - other.n[5];\n        self.n[6] = 0x3ffffff * 2 * (m + 1) - other.n[6];\n        self.n[7] = 0x3ffffff * 2 * (m + 1) - other.n[7];\n        self.n[8] = 0x3ffffff * 2 * (m + 1) - other.n[8];\n        self.n[9] = 0x03fffff * 2 * (m + 1) - other.n[9];\n\n        self.magnitude = m + 1;\n        self.normalized = false;\n        debug_assert!(self.verify());\n    }\n\n    /// Compute the additive inverse of this element. Takes the maximum\n    /// expected magnitude of this element as an argument.\n    pub fn neg(&self, m: u32) -> Field {\n        let mut ret = Field::default();\n        ret.neg_in_place(self, m);\n        ret\n    }\n\n    /// Multiplies the passed field element with a small integer\n    /// constant. Multiplies the magnitude by that small integer.\n    pub fn mul_int(&mut self, a: u32) {\n        self.n[0] *= a;\n        self.n[1] *= a;\n        self.n[2] *= a;\n        self.n[3] *= a;\n        self.n[4] *= a;\n        self.n[5] *= a;\n        self.n[6] *= a;\n        self.n[7] *= a;\n        self.n[8] *= a;\n        self.n[9] *= a;\n\n        self.magnitude *= a;\n        self.normalized = false;\n        debug_assert!(self.verify());\n    }\n\n    /// Compare two field elements. Requires both inputs to be\n    /// normalized.\n    pub fn cmp_var(&self, other: &Field) -> Ordering {\n        // Variable time compare implementation.\n        debug_assert!(self.normalized);\n        debug_assert!(other.normalized);\n        debug_assert!(self.verify());\n        debug_assert!(other.verify());\n\n        for i in (0..10).rev() {\n            if self.n[i] > other.n[i] {\n                return Ordering::Greater;\n            }\n            if self.n[i] < other.n[i] {\n                return Ordering::Less;\n            }\n        }\n        Ordering::Equal\n    }\n\n    pub fn eq_var(&self, other: &Field) -> bool {\n        let mut na = self.neg(1);\n        na += other;\n        na.normalizes_to_zero_var()\n    }\n\n    fn mul_inner(&mut self, a: &Field, b: &Field) {\n        const M: u64 = 0x3ffffff;\n        const R0: u64 = 0x3d10;\n        const R1: u64 = 0x400;\n\n        let (mut c, mut d): (u64, u64);\n        let (v0, v1, v2, v3, v4, v5, v6, v7, v8): (u64, u64, u64, u64, u64, u64, u64, u64, u64);\n        let (t9, t1, t0, t2, t3, t4, t5, t6, t7): (u32, u32, u32, u32, u32, u32, u32, u32, u32);\n\n        debug_assert_bits!(a.n[0], 30);\n        debug_assert_bits!(a.n[1], 30);\n        debug_assert_bits!(a.n[2], 30);\n        debug_assert_bits!(a.n[3], 30);\n        debug_assert_bits!(a.n[4], 30);\n        debug_assert_bits!(a.n[5], 30);\n        debug_assert_bits!(a.n[6], 30);\n        debug_assert_bits!(a.n[7], 30);\n        debug_assert_bits!(a.n[8], 30);\n        debug_assert_bits!(a.n[9], 26);\n        debug_assert_bits!(b.n[0], 30);\n        debug_assert_bits!(b.n[1], 30);\n        debug_assert_bits!(b.n[2], 30);\n        debug_assert_bits!(b.n[3], 30);\n        debug_assert_bits!(b.n[4], 30);\n        debug_assert_bits!(b.n[5], 30);\n        debug_assert_bits!(b.n[6], 30);\n        debug_assert_bits!(b.n[7], 30);\n        debug_assert_bits!(b.n[8], 30);\n        debug_assert_bits!(b.n[9], 26);\n\n        // [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n.\n        // px is a shorthand for sum(a[i]*b[x-i], i=0..x).\n        // Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0].\n\n        d = ((a.n[0] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[0] as u64));\n        // debug_assert_bits!(d, 64);\n\n        /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */\n        t9 = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(t9, 26);\n        debug_assert_bits!(d, 38);\n        /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */\n\n        c = (a.n[0] as u64) * (b.n[0] as u64);\n        debug_assert_bits!(c, 60);\n        /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */\n\n        d = d\n            .wrapping_add((a.n[1] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[1] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        v0 = d & M;\n        d >>= 26;\n        c += v0 * R0;\n        debug_assert_bits!(v0, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 61);\n        /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        t0 = (c & M) as u32;\n        c >>= 26;\n        c += v0 * R1;\n\n        debug_assert_bits!(t0, 26);\n        debug_assert_bits!(c, 37);\n        /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 62);\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        d = d\n            .wrapping_add((a.n[2] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[2] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        v1 = d & M;\n        d >>= 26;\n        c += v1 * R0;\n        debug_assert_bits!(v1, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 63);\n        /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        t1 = (c & M) as u32;\n        c >>= 26;\n        c += v1 * R1;\n        debug_assert_bits!(t1, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 62);\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[3] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[3] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        v2 = d & M;\n        d >>= 26;\n        c += v2 * R0;\n        debug_assert_bits!(v2, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 63);\n        /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        t2 = (c & M) as u32;\n        c >>= 26;\n        c += v2 * R1;\n        debug_assert_bits!(t2, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[4] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[4] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        v3 = d & M;\n        d >>= 26;\n        c += v3 * R0;\n        debug_assert_bits!(v3, 26);\n        debug_assert_bits!(d, 37);\n        // debug_assert_bits!(c, 64);\n        /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        t3 = (c & M) as u32;\n        c >>= 26;\n        c += v3 * R1;\n        debug_assert_bits!(t3, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[5] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[5] as u64));\n        debug_assert_bits!(d, 62);\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        v4 = d & M;\n        d >>= 26;\n        c += v4 * R0;\n        debug_assert_bits!(v4, 26);\n        debug_assert_bits!(d, 36);\n        // debug_assert_bits!(c, 64);\n        /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        t4 = (c & M) as u32;\n        c >>= 26;\n        c += v4 * R1;\n        debug_assert_bits!(t4, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[6] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[6] as u64));\n        debug_assert_bits!(d, 62);\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        v5 = d & M;\n        d >>= 26;\n        c += v5 * R0;\n        debug_assert_bits!(v5, 26);\n        debug_assert_bits!(d, 36);\n        // debug_assert_bits!(c, 64);\n        /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        t5 = (c & M) as u32;\n        c >>= 26;\n        c += v5 * R1;\n        debug_assert_bits!(t5, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[0] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[7] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[7] as u64));\n        debug_assert_bits!(d, 61);\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        v6 = d & M;\n        d >>= 26;\n        c += v6 * R0;\n        debug_assert_bits!(v6, 26);\n        debug_assert_bits!(d, 35);\n        // debug_assert_bits!(c, 64);\n        /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        t6 = (c & M) as u32;\n        c >>= 26;\n        c += v6 * R1;\n        debug_assert_bits!(t6, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[0] as u64));\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x8000007c00000007);\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add((a.n[8] as u64) * (b.n[9] as u64))\n            .wrapping_add((a.n[9] as u64) * (b.n[8] as u64));\n        debug_assert_bits!(d, 58);\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        v7 = d & M;\n        d >>= 26;\n        c += v7 * R0;\n        debug_assert_bits!(v7, 26);\n        debug_assert_bits!(d, 32);\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x800001703fffc2f7);\n        /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        t7 = (c & M) as u32;\n        c >>= 26;\n        c += v7 * R1;\n        debug_assert_bits!(t7, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add((a.n[0] as u64) * (b.n[8] as u64))\n            .wrapping_add((a.n[1] as u64) * (b.n[7] as u64))\n            .wrapping_add((a.n[2] as u64) * (b.n[6] as u64))\n            .wrapping_add((a.n[3] as u64) * (b.n[5] as u64))\n            .wrapping_add((a.n[4] as u64) * (b.n[4] as u64))\n            .wrapping_add((a.n[5] as u64) * (b.n[3] as u64))\n            .wrapping_add((a.n[6] as u64) * (b.n[2] as u64))\n            .wrapping_add((a.n[7] as u64) * (b.n[1] as u64))\n            .wrapping_add((a.n[8] as u64) * (b.n[0] as u64));\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x9000007b80000008);\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d = d.wrapping_add((a.n[9] as u64) * (b.n[9] as u64));\n        debug_assert_bits!(d, 57);\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        v8 = d & M;\n        d >>= 26;\n        c += v8 * R0;\n        debug_assert_bits!(v8, 26);\n        debug_assert_bits!(d, 31);\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x9000016fbfffc2f8);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        self.n[3] = t3;\n        debug_assert_bits!(self.n[3], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[4] = t4;\n        debug_assert_bits!(self.n[4], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[5] = t5;\n        debug_assert_bits!(self.n[5], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[6] = t6;\n        debug_assert_bits!(self.n[6], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[7] = t7;\n        debug_assert_bits!(self.n[7], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        self.n[8] = (c & M) as u32;\n        c >>= 26;\n        c += v8 * R1;\n        debug_assert_bits!(self.n[8], 26);\n        debug_assert_bits!(c, 39);\n        /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        c += d * R0 + t9 as u64;\n        debug_assert_bits!(c, 45);\n        /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[9] = (c & (M >> 4)) as u32;\n        c >>= 22;\n        c += d * (R1 << 4);\n        debug_assert_bits!(self.n[9], 22);\n        debug_assert_bits!(c, 46);\n        /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        d = c * (R0 >> 4) + t0 as u64;\n        debug_assert_bits!(d, 56);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[0] = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(self.n[0], 26);\n        debug_assert_bits!(d, 30);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d += c * (R1 >> 4) + t1 as u64;\n        debug_assert_bits!(d, 53);\n        debug_assert!(d <= 0x10000003ffffbf);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[1] = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(self.n[1], 26);\n        debug_assert_bits!(d, 27);\n        debug_assert!(d <= 0x4000000);\n        /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d += t2 as u64;\n        debug_assert_bits!(d, 27);\n        /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[2] = d as u32;\n        debug_assert_bits!(self.n[2], 27);\n        /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n    }\n\n    fn sqr_inner(&mut self, a: &Field) {\n        const M: u64 = 0x3ffffff;\n        const R0: u64 = 0x3d10;\n        const R1: u64 = 0x400;\n\n        let (mut c, mut d): (u64, u64);\n        let (v0, v1, v2, v3, v4, v5, v6, v7, v8): (u64, u64, u64, u64, u64, u64, u64, u64, u64);\n        let (t9, t0, t1, t2, t3, t4, t5, t6, t7): (u32, u32, u32, u32, u32, u32, u32, u32, u32);\n\n        debug_assert_bits!(a.n[0], 30);\n        debug_assert_bits!(a.n[1], 30);\n        debug_assert_bits!(a.n[2], 30);\n        debug_assert_bits!(a.n[3], 30);\n        debug_assert_bits!(a.n[4], 30);\n        debug_assert_bits!(a.n[5], 30);\n        debug_assert_bits!(a.n[6], 30);\n        debug_assert_bits!(a.n[7], 30);\n        debug_assert_bits!(a.n[8], 30);\n        debug_assert_bits!(a.n[9], 26);\n\n        // [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n.\n        // px is a shorthand for sum(a.n[i]*a.n[x-i], i=0..x).\n        // Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0].\n\n        d = (((a.n[0] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[6] as u64))\n            .wrapping_add(((a.n[4] * 2) as u64) * (a.n[5] as u64));\n        // debug_assert_bits!(d, 64);\n        /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */\n        t9 = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(t9, 26);\n        debug_assert_bits!(d, 38);\n        /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */\n\n        c = (a.n[0] as u64) * (a.n[0] as u64);\n        debug_assert_bits!(c, 60);\n        /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */\n        d = d\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add(((a.n[4] * 2) as u64) * (a.n[6] as u64))\n            .wrapping_add((a.n[5] as u64) * (a.n[5] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        v0 = d & M;\n        d >>= 26;\n        c += v0 * R0;\n        debug_assert_bits!(v0, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 61);\n        /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        t0 = (c & M) as u32;\n        c >>= 26;\n        c += v0 * R1;\n        debug_assert_bits!(t0, 26);\n        debug_assert_bits!(c, 37);\n        /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */\n\n        c = c.wrapping_add(((a.n[0] * 2) as u64) * (a.n[1] as u64));\n        debug_assert_bits!(c, 62);\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[4] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add(((a.n[5] * 2) as u64) * (a.n[6] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        v1 = d & M;\n        d >>= 26;\n        c += v1 * R0;\n        debug_assert_bits!(v1, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 63);\n        /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        t1 = (c & M) as u32;\n        c >>= 26;\n        c += v1 * R1;\n        debug_assert_bits!(t1, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[2] as u64))\n            .wrapping_add((a.n[1] as u64) * (a.n[1] as u64));\n        debug_assert_bits!(c, 62);\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[4] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[5] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add((a.n[6] as u64) * (a.n[6] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        v2 = d & M;\n        d >>= 26;\n        c += v2 * R0;\n        debug_assert_bits!(v2, 26);\n        debug_assert_bits!(d, 37);\n        debug_assert_bits!(c, 63);\n        /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        t2 = (c & M) as u32;\n        c >>= 26;\n        c += v2 * R1;\n        debug_assert_bits!(t2, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[3] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[2] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[4] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[5] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[6] * 2) as u64) * (a.n[7] as u64));\n        debug_assert_bits!(d, 63);\n        /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        v3 = d & M;\n        d >>= 26;\n        c += v3 * R0;\n        debug_assert_bits!(v3, 26);\n        debug_assert_bits!(d, 37);\n        // debug_assert_bits!(c, 64);\n        /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        t3 = (c & M) as u32;\n        c >>= 26;\n        c += v3 * R1;\n        debug_assert_bits!(t3, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[4] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[3] as u64))\n            .wrapping_add((a.n[2] as u64) * (a.n[2] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[5] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[6] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add((a.n[7] as u64) * (a.n[7] as u64));\n        debug_assert_bits!(d, 62);\n        /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        v4 = d & M;\n        d >>= 26;\n        c += v4 * R0;\n        debug_assert_bits!(v4, 26);\n        debug_assert_bits!(d, 36);\n        // debug_assert_bits!(c, 64);\n        /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        t4 = (c & M) as u32;\n        c >>= 26;\n        c += v4 * R1;\n        debug_assert_bits!(t4, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[5] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[4] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[3] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[6] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add(((a.n[7] * 2) as u64) * (a.n[8] as u64));\n        debug_assert_bits!(d, 62);\n        /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        v5 = d & M;\n        d >>= 26;\n        c += v5 * R0;\n        debug_assert_bits!(v5, 26);\n        debug_assert_bits!(d, 36);\n        // debug_assert_bits!(c, 64);\n        /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        t5 = (c & M) as u32;\n        c >>= 26;\n        c += v5 * R1;\n        debug_assert_bits!(t5, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[6] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[5] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[4] as u64))\n            .wrapping_add((a.n[3] as u64) * (a.n[3] as u64));\n        debug_assert_bits!(c, 63);\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        d = d\n            .wrapping_add(((a.n[7] * 2) as u64) * (a.n[9] as u64))\n            .wrapping_add((a.n[8] as u64) * (a.n[8] as u64));\n        debug_assert_bits!(d, 61);\n        /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        v6 = d & M;\n        d >>= 26;\n        c += v6 * R0;\n        debug_assert_bits!(v6, 26);\n        debug_assert_bits!(d, 35);\n        // debug_assert_bits!(c, 64);\n        /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        t6 = (c & M) as u32;\n        c >>= 26;\n        c += v6 * R1;\n        debug_assert_bits!(t6, 26);\n        debug_assert_bits!(c, 39);\n        /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[6] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[5] as u64))\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[4] as u64));\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x8000007C00000007);\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d = d.wrapping_add(((a.n[8] * 2) as u64) * (a.n[9] as u64));\n        debug_assert_bits!(d, 58);\n        /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        v7 = d & M;\n        d >>= 26;\n        c += v7 * R0;\n        debug_assert_bits!(v7, 26);\n        debug_assert_bits!(d, 32);\n        /* debug_assert_bits!(c, 64); */\n        debug_assert!(c <= 0x800001703FFFC2F7);\n        /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        t7 = (c & M) as u32;\n        c >>= 26;\n        c += v7 * R1;\n        debug_assert_bits!(t7, 26);\n        debug_assert_bits!(c, 38);\n        /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        c = c\n            .wrapping_add(((a.n[0] * 2) as u64) * (a.n[8] as u64))\n            .wrapping_add(((a.n[1] * 2) as u64) * (a.n[7] as u64))\n            .wrapping_add(((a.n[2] * 2) as u64) * (a.n[6] as u64))\n            .wrapping_add(((a.n[3] * 2) as u64) * (a.n[5] as u64))\n            .wrapping_add((a.n[4] as u64) * (a.n[4] as u64));\n        // debug_assert_bits!(c, 64);\n        debug_assert!(c <= 0x9000007B80000008);\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d = d.wrapping_add((a.n[9] as u64) * (a.n[9] as u64));\n        debug_assert_bits!(d, 57);\n        /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        v8 = d & M;\n        d >>= 26;\n        c += v8 * R0;\n        debug_assert_bits!(v8, 26);\n        debug_assert_bits!(d, 31);\n        /* debug_assert_bits!(c, 64); */\n        debug_assert!(c <= 0x9000016FBFFFC2F8);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        self.n[3] = t3;\n        debug_assert_bits!(self.n[3], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[4] = t4;\n        debug_assert_bits!(self.n[4], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[5] = t5;\n        debug_assert_bits!(self.n[5], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[6] = t6;\n        debug_assert_bits!(self.n[6], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[7] = t7;\n        debug_assert_bits!(self.n[7], 26);\n        /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        self.n[8] = (c & M) as u32;\n        c >>= 26;\n        c += v8 * R1;\n        debug_assert_bits!(self.n[8], 26);\n        debug_assert_bits!(c, 39);\n        /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        c += d * R0 + t9 as u64;\n        debug_assert_bits!(c, 45);\n        /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[9] = (c & (M >> 4)) as u32;\n        c >>= 22;\n        c += d * (R1 << 4);\n        debug_assert_bits!(self.n[9], 22);\n        debug_assert_bits!(c, 46);\n        /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n\n        d = c * (R0 >> 4) + t0 as u64;\n        debug_assert_bits!(d, 56);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[0] = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(self.n[0], 26);\n        debug_assert_bits!(d, 30);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d += c * (R1 >> 4) + t1 as u64;\n        debug_assert_bits!(d, 53);\n        debug_assert!(d <= 0x10000003FFFFBF);\n        /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[1] = (d & M) as u32;\n        d >>= 26;\n        debug_assert_bits!(self.n[1], 26);\n        debug_assert_bits!(d, 27);\n        debug_assert!(d <= 0x4000000);\n        /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        d += t2 as u64;\n        debug_assert_bits!(d, 27);\n        /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n        self.n[2] = d as u32;\n        debug_assert_bits!(self.n[2], 27);\n        /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */\n    }\n\n    /// Sets a field element to be the product of two others. Requires\n    /// the inputs' magnitudes to be at most 8. The output magnitude\n    /// is 1 (but not guaranteed to be normalized).\n    pub fn mul_in_place(&mut self, a: &Field, b: &Field) {\n        debug_assert!(a.magnitude <= 8);\n        debug_assert!(b.magnitude <= 8);\n        debug_assert!(a.verify());\n        debug_assert!(b.verify());\n        self.mul_inner(a, b);\n        self.magnitude = 1;\n        self.normalized = false;\n        debug_assert!(self.verify());\n    }\n\n    /// Sets a field element to be the square of another. Requires the\n    /// input's magnitude to be at most 8. The output magnitude is 1\n    /// (but not guaranteed to be normalized).\n    pub fn sqr_in_place(&mut self, a: &Field) {\n        debug_assert!(a.magnitude <= 8);\n        debug_assert!(a.verify());\n        self.sqr_inner(a);\n        self.magnitude = 1;\n        self.normalized = false;\n        debug_assert!(a.verify());\n    }\n\n    pub fn sqr(&self) -> Field {\n        let mut ret = Field::default();\n        ret.sqr_in_place(self);\n        ret\n    }\n\n    /// If a has a square root, it is computed in r and 1 is\n    /// returned. If a does not have a square root, the root of its\n    /// negation is computed and 0 is returned. The input's magnitude\n    /// can be at most 8. The output magnitude is 1 (but not\n    /// guaranteed to be normalized). The result in r will always be a\n    /// square itself.\n    pub fn sqrt(&self) -> (Field, bool) {\n        let mut x2 = self.sqr();\n        x2 *= self;\n\n        let mut x3 = x2.sqr();\n        x3 *= self;\n\n        let mut x6 = x3;\n        for _ in 0..3 {\n            x6 = x6.sqr();\n        }\n        x6 *= &x3;\n\n        let mut x9 = x6;\n        for _ in 0..3 {\n            x9 = x9.sqr();\n        }\n        x9 *= &x3;\n\n        let mut x11 = x9;\n        for _ in 0..2 {\n            x11 = x11.sqr();\n        }\n        x11 *= &x2;\n\n        let mut x22 = x11;\n        for _ in 0..11 {\n            x22 = x22.sqr();\n        }\n        x22 *= &x11;\n\n        let mut x44 = x22;\n        for _ in 0..22 {\n            x44 = x44.sqr();\n        }\n        x44 *= &x22;\n\n        let mut x88 = x44;\n        for _ in 0..44 {\n            x88 = x88.sqr();\n        }\n        x88 *= &x44;\n\n        let mut x176 = x88;\n        for _ in 0..88 {\n            x176 = x176.sqr();\n        }\n        x176 *= &x88;\n\n        let mut x220 = x176;\n        for _ in 0..44 {\n            x220 = x220.sqr();\n        }\n        x220 *= &x44;\n\n        let mut x223 = x220;\n        for _ in 0..3 {\n            x223 = x223.sqr();\n        }\n        x223 *= &x3;\n\n        let mut t1 = x223;\n        for _ in 0..23 {\n            t1 = t1.sqr();\n        }\n        t1 *= &x22;\n        for _ in 0..6 {\n            t1 = t1.sqr();\n        }\n        t1 *= &x2;\n        t1 = t1.sqr();\n        let r = t1.sqr();\n\n        t1 = r.sqr();\n        (r, &t1 == self)\n    }\n\n    /// Sets a field element to be the (modular) inverse of\n    /// another. Requires the input's magnitude to be at most 8. The\n    /// output magnitude is 1 (but not guaranteed to be normalized).\n    pub fn inv(&self) -> Field {\n        let mut x2 = self.sqr();\n        x2 *= self;\n\n        let mut x3 = x2.sqr();\n        x3 *= self;\n\n        let mut x6 = x3;\n        for _ in 0..3 {\n            x6 = x6.sqr();\n        }\n        x6 *= &x3;\n\n        let mut x9 = x6;\n        for _ in 0..3 {\n            x9 = x9.sqr();\n        }\n        x9 *= &x3;\n\n        let mut x11 = x9;\n        for _ in 0..2 {\n            x11 = x11.sqr();\n        }\n        x11 *= &x2;\n\n        let mut x22 = x11;\n        for _ in 0..11 {\n            x22 = x22.sqr();\n        }\n        x22 *= &x11;\n\n        let mut x44 = x22;\n        for _ in 0..22 {\n            x44 = x44.sqr();\n        }\n        x44 *= &x22;\n\n        let mut x88 = x44;\n        for _ in 0..44 {\n            x88 = x88.sqr();\n        }\n        x88 *= &x44;\n\n        let mut x176 = x88;\n        for _ in 0..88 {\n            x176 = x176.sqr();\n        }\n        x176 *= &x88;\n\n        let mut x220 = x176;\n        for _ in 0..44 {\n            x220 = x220.sqr();\n        }\n        x220 *= &x44;\n\n        let mut x223 = x220;\n        for _ in 0..3 {\n            x223 = x223.sqr();\n        }\n        x223 *= &x3;\n\n        let mut t1 = x223;\n        for _ in 0..23 {\n            t1 = t1.sqr();\n        }\n        t1 *= &x22;\n        for _ in 0..5 {\n            t1 = t1.sqr();\n        }\n        t1 *= self;\n        for _ in 0..3 {\n            t1 = t1.sqr();\n        }\n        t1 *= &x2;\n        for _ in 0..2 {\n            t1 = t1.sqr();\n        }\n        self * &t1\n    }\n\n    /// Potentially faster version of secp256k1_fe_inv, without\n    /// constant-time guarantee.\n    pub fn inv_var(&self) -> Field {\n        self.inv()\n    }\n\n    /// Checks whether a field element is a quadratic residue.\n    pub fn is_quad_var(&self) -> bool {\n        let (_, ret) = self.sqrt();\n        ret\n    }\n\n    /// If flag is true, set *r equal to *a; otherwise leave\n    /// it. Constant-time.\n    pub fn cmov(&mut self, other: &Field, flag: bool) {\n        self.n[0] = if flag { other.n[0] } else { self.n[0] };\n        self.n[1] = if flag { other.n[1] } else { self.n[1] };\n        self.n[2] = if flag { other.n[2] } else { self.n[2] };\n        self.n[3] = if flag { other.n[3] } else { self.n[3] };\n        self.n[4] = if flag { other.n[4] } else { self.n[4] };\n        self.n[5] = if flag { other.n[5] } else { self.n[5] };\n        self.n[6] = if flag { other.n[6] } else { self.n[6] };\n        self.n[7] = if flag { other.n[7] } else { self.n[7] };\n        self.n[8] = if flag { other.n[8] } else { self.n[8] };\n        self.n[9] = if flag { other.n[9] } else { self.n[9] };\n        self.magnitude = if flag {\n            other.magnitude\n        } else {\n            self.magnitude\n        };\n        self.normalized = if flag {\n            other.normalized\n        } else {\n            self.normalized\n        };\n    }\n}\n\nimpl Default for Field {\n    fn default() -> Field {\n        Self {\n            n: [0u32; 10],\n            magnitude: 0,\n            normalized: true,\n        }\n    }\n}\n\nimpl Add<Field> for Field {\n    type Output = Field;\n    fn add(self, other: Field) -> Field {\n        let mut ret = self;\n        ret.add_assign(&other);\n        ret\n    }\n}\n\nimpl<'a, 'b> Add<&'a Field> for &'b Field {\n    type Output = Field;\n    fn add(self, other: &'a Field) -> Field {\n        let mut ret = *self;\n        ret.add_assign(other);\n        ret\n    }\n}\n\nimpl<'a> AddAssign<&'a Field> for Field {\n    fn add_assign(&mut self, other: &'a Field) {\n        self.n[0] += other.n[0];\n        self.n[1] += other.n[1];\n        self.n[2] += other.n[2];\n        self.n[3] += other.n[3];\n        self.n[4] += other.n[4];\n        self.n[5] += other.n[5];\n        self.n[6] += other.n[6];\n        self.n[7] += other.n[7];\n        self.n[8] += other.n[8];\n        self.n[9] += other.n[9];\n\n        self.magnitude += other.magnitude;\n        self.normalized = false;\n        debug_assert!(self.verify());\n    }\n}\n\nimpl AddAssign<Field> for Field {\n    fn add_assign(&mut self, other: Field) {\n        self.add_assign(&other)\n    }\n}\n\nimpl Mul<Field> for Field {\n    type Output = Field;\n    fn mul(self, other: Field) -> Field {\n        let mut ret = Field::default();\n        ret.mul_in_place(&self, &other);\n        ret\n    }\n}\n\nimpl<'a, 'b> Mul<&'a Field> for &'b Field {\n    type Output = Field;\n    fn mul(self, other: &'a Field) -> Field {\n        let mut ret = Field::default();\n        ret.mul_in_place(self, other);\n        ret\n    }\n}\n\nimpl<'a> MulAssign<&'a Field> for Field {\n    fn mul_assign(&mut self, other: &'a Field) {\n        let mut ret = Field::default();\n        ret.mul_in_place(self, other);\n        *self = ret;\n    }\n}\n\nimpl MulAssign<Field> for Field {\n    fn mul_assign(&mut self, other: Field) {\n        self.mul_assign(&other)\n    }\n}\n\nimpl PartialEq for Field {\n    fn eq(&self, other: &Field) -> bool {\n        let mut na = self.neg(self.magnitude);\n        na += other;\n        na.normalizes_to_zero()\n    }\n}\n\nimpl Eq for Field {}\n\nimpl Ord for Field {\n    fn cmp(&self, other: &Field) -> Ordering {\n        self.cmp_var(other)\n    }\n}\n\nimpl PartialOrd for Field {\n    fn partial_cmp(&self, other: &Field) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Compact field element storage.\npub struct FieldStorage(pub [u32; 8]);\n\nimpl Default for FieldStorage {\n    fn default() -> FieldStorage {\n        FieldStorage([0; 8])\n    }\n}\n\nimpl FieldStorage {\n    pub const fn new(\n        d7: u32,\n        d6: u32,\n        d5: u32,\n        d4: u32,\n        d3: u32,\n        d2: u32,\n        d1: u32,\n        d0: u32,\n    ) -> Self {\n        Self([d0, d1, d2, d3, d4, d5, d6, d7])\n    }\n\n    pub fn cmov(&mut self, other: &FieldStorage, flag: bool) {\n        self.0[0] = if flag { other.0[0] } else { self.0[0] };\n        self.0[1] = if flag { other.0[1] } else { self.0[1] };\n        self.0[2] = if flag { other.0[2] } else { self.0[2] };\n        self.0[3] = if flag { other.0[3] } else { self.0[3] };\n        self.0[4] = if flag { other.0[4] } else { self.0[4] };\n        self.0[5] = if flag { other.0[5] } else { self.0[5] };\n        self.0[6] = if flag { other.0[6] } else { self.0[6] };\n        self.0[7] = if flag { other.0[7] } else { self.0[7] };\n    }\n}\n\nimpl From<FieldStorage> for Field {\n    fn from(a: FieldStorage) -> Field {\n        let mut r = Field::default();\n\n        r.n[0] = a.0[0] & 0x3FFFFFF;\n        r.n[1] = a.0[0] >> 26 | ((a.0[1] << 6) & 0x3FFFFFF);\n        r.n[2] = a.0[1] >> 20 | ((a.0[2] << 12) & 0x3FFFFFF);\n        r.n[3] = a.0[2] >> 14 | ((a.0[3] << 18) & 0x3FFFFFF);\n        r.n[4] = a.0[3] >> 8 | ((a.0[4] << 24) & 0x3FFFFFF);\n        r.n[5] = (a.0[4] >> 2) & 0x3FFFFFF;\n        r.n[6] = a.0[4] >> 28 | ((a.0[5] << 4) & 0x3FFFFFF);\n        r.n[7] = a.0[5] >> 22 | ((a.0[6] << 10) & 0x3FFFFFF);\n        r.n[8] = a.0[6] >> 16 | ((a.0[7] << 16) & 0x3FFFFFF);\n        r.n[9] = a.0[7] >> 10;\n\n        r.magnitude = 1;\n        r.normalized = true;\n\n        r\n    }\n}\n\nimpl Into<FieldStorage> for Field {\n    fn into(self) -> FieldStorage {\n        debug_assert!(self.normalized);\n        let mut r = FieldStorage::default();\n\n        r.0[0] = self.n[0] | self.n[1] << 26;\n        r.0[1] = self.n[1] >> 6 | self.n[2] << 20;\n        r.0[2] = self.n[2] >> 12 | self.n[3] << 14;\n        r.0[3] = self.n[3] >> 18 | self.n[4] << 8;\n        r.0[4] = self.n[4] >> 24 | self.n[5] << 2 | self.n[6] << 28;\n        r.0[5] = self.n[6] >> 4 | self.n[7] << 22;\n        r.0[6] = self.n[7] >> 10 | self.n[8] << 16;\n        r.0[7] = self.n[8] >> 16 | self.n[9] << 10;\n\n        r\n    }\n}\n"
  },
  {
    "path": "core/src/group.rs",
    "content": "use crate::field::{Field, FieldStorage};\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// A group element of the secp256k1 curve, in affine coordinates.\npub struct Affine {\n    pub x: Field,\n    pub y: Field,\n    pub infinity: bool,\n}\n\n#[derive(Debug, Clone, Copy)]\n/// A group element of the secp256k1 curve, in jacobian coordinates.\npub struct Jacobian {\n    pub x: Field,\n    pub y: Field,\n    pub z: Field,\n    pub infinity: bool,\n}\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Affine coordinate group element compact storage.\npub struct AffineStorage {\n    pub x: FieldStorage,\n    pub y: FieldStorage,\n}\n\nimpl Default for Affine {\n    fn default() -> Affine {\n        Affine {\n            x: Field::default(),\n            y: Field::default(),\n            infinity: false,\n        }\n    }\n}\n\nimpl Default for Jacobian {\n    fn default() -> Jacobian {\n        Jacobian {\n            x: Field::default(),\n            y: Field::default(),\n            z: Field::default(),\n            infinity: false,\n        }\n    }\n}\n\nimpl Default for AffineStorage {\n    fn default() -> AffineStorage {\n        AffineStorage {\n            x: FieldStorage::default(),\n            y: FieldStorage::default(),\n        }\n    }\n}\n\npub static AFFINE_INFINITY: Affine = Affine {\n    x: Field::new(0, 0, 0, 0, 0, 0, 0, 0),\n    y: Field::new(0, 0, 0, 0, 0, 0, 0, 0),\n    infinity: true,\n};\n\npub static JACOBIAN_INFINITY: Jacobian = Jacobian {\n    x: Field::new(0, 0, 0, 0, 0, 0, 0, 0),\n    y: Field::new(0, 0, 0, 0, 0, 0, 0, 0),\n    z: Field::new(0, 0, 0, 0, 0, 0, 0, 0),\n    infinity: true,\n};\n\npub static AFFINE_G: Affine = Affine::new(\n    Field::new(\n        0x79BE667E, 0xF9DCBBAC, 0x55A06295, 0xCE870B07, 0x029BFCDB, 0x2DCE28D9, 0x59F2815B,\n        0x16F81798,\n    ),\n    Field::new(\n        0x483ADA77, 0x26A3C465, 0x5DA4FBFC, 0x0E1108A8, 0xFD17B448, 0xA6855419, 0x9C47D08F,\n        0xFB10D4B8,\n    ),\n);\n\npub const CURVE_B: u32 = 7;\n\nimpl Affine {\n    /// Create a new affine.\n    pub const fn new(x: Field, y: Field) -> Self {\n        Self {\n            x,\n            y,\n            infinity: false,\n        }\n    }\n\n    /// Set a group element equal to the point with given X and Y\n    /// coordinates.\n    pub fn set_xy(&mut self, x: &Field, y: &Field) {\n        self.infinity = false;\n        self.x = *x;\n        self.y = *y;\n    }\n\n    /// Set a group element (affine) equal to the point with the given\n    /// X coordinate and a Y coordinate that is a quadratic residue\n    /// modulo p. The return value is true iff a coordinate with the\n    /// given X coordinate exists.\n    pub fn set_xquad(&mut self, x: &Field) -> bool {\n        self.x = *x;\n        let x2 = x.sqr();\n        let x3 = *x * x2;\n        self.infinity = false;\n        let mut c = Field::default();\n        c.set_int(CURVE_B);\n        c += x3;\n        let (v, ret) = c.sqrt();\n        self.y = v;\n        ret\n    }\n\n    /// Set a group element (affine) equal to the point with the given\n    /// X coordinate, and given oddness for Y. Return value indicates\n    /// whether the result is valid.\n    pub fn set_xo_var(&mut self, x: &Field, odd: bool) -> bool {\n        if !self.set_xquad(x) {\n            return false;\n        }\n        self.y.normalize_var();\n        if self.y.is_odd() != odd {\n            self.y = self.y.neg(1);\n        }\n        true\n    }\n\n    /// Check whether a group element is the point at infinity.\n    pub fn is_infinity(&self) -> bool {\n        self.infinity\n    }\n\n    /// Check whether a group element is valid (i.e., on the curve).\n    pub fn is_valid_var(&self) -> bool {\n        if self.is_infinity() {\n            return false;\n        }\n        let y2 = self.y.sqr();\n        let mut x3 = self.x.sqr();\n        x3 *= &self.x;\n        let mut c = Field::default();\n        c.set_int(CURVE_B);\n        x3 += &c;\n        x3.normalize_weak();\n        y2.eq_var(&x3)\n    }\n\n    pub fn neg_in_place(&mut self, other: &Affine) {\n        *self = *other;\n        self.y.normalize_weak();\n        self.y = self.y.neg(1);\n    }\n\n    pub fn neg(&self) -> Affine {\n        let mut ret = Affine::default();\n        ret.neg_in_place(self);\n        ret\n    }\n\n    /// Set a group element equal to another which is given in\n    /// jacobian coordinates.\n    pub fn set_gej(&mut self, a: &Jacobian) {\n        self.infinity = a.infinity;\n        let mut a = *a;\n        a.z = a.z.inv();\n        let z2 = a.z.sqr();\n        let z3 = a.z * z2;\n        a.x *= z2;\n        a.y *= z3;\n        a.z.set_int(1);\n        self.x = a.x;\n        self.y = a.y;\n    }\n\n    pub fn from_gej(a: &Jacobian) -> Self {\n        let mut ge = Self::default();\n        ge.set_gej(a);\n        ge\n    }\n\n    pub fn set_gej_var(&mut self, a: &Jacobian) {\n        let mut a = *a;\n        self.infinity = a.infinity;\n        if a.is_infinity() {\n            return;\n        }\n        a.z = a.z.inv_var();\n        let z2 = a.z.sqr();\n        let z3 = a.z * z2;\n        a.x *= &z2;\n        a.y *= &z3;\n        a.z.set_int(1);\n        self.x = a.x;\n        self.y = a.y;\n    }\n\n    pub fn set_gej_zinv(&mut self, a: &Jacobian, zi: &Field) {\n        let zi2 = zi.sqr();\n        let zi3 = zi2 * *zi;\n        self.x = a.x * zi2;\n        self.y = a.y * zi3;\n        self.infinity = a.infinity;\n    }\n\n    /// Clear a secp256k1_ge to prevent leaking sensitive information.\n    pub fn clear(&mut self) {\n        self.infinity = false;\n        self.x.clear();\n        self.y.clear();\n    }\n}\n\npub fn set_table_gej_var(r: &mut [Affine], a: &[Jacobian], zr: &[Field]) {\n    debug_assert!(r.len() == a.len());\n\n    let mut i = r.len() - 1;\n    let mut zi: Field;\n\n    if !r.is_empty() {\n        zi = a[i].z.inv();\n        r[i].set_gej_zinv(&a[i], &zi);\n\n        while i > 0 {\n            zi *= &zr[i];\n            i -= 1;\n            r[i].set_gej_zinv(&a[i], &zi);\n        }\n    }\n}\n\npub fn globalz_set_table_gej(r: &mut [Affine], globalz: &mut Field, a: &[Jacobian], zr: &[Field]) {\n    debug_assert!(r.len() == a.len() && a.len() == zr.len());\n\n    let mut i = r.len() - 1;\n    let mut zs: Field;\n\n    if !r.is_empty() {\n        r[i].x = a[i].x;\n        r[i].y = a[i].y;\n        *globalz = a[i].z;\n        r[i].infinity = false;\n        zs = zr[i];\n\n        while i > 0 {\n            if i != r.len() - 1 {\n                zs *= zr[i];\n            }\n            i -= 1;\n            r[i].set_gej_zinv(&a[i], &zs);\n        }\n    }\n}\n\nimpl Jacobian {\n    /// Create a new jacobian.\n    pub const fn new(x: Field, y: Field) -> Self {\n        Self {\n            x,\n            y,\n            infinity: false,\n            z: Field::new(0, 0, 0, 0, 0, 0, 0, 1),\n        }\n    }\n\n    /// Set a group element (jacobian) equal to the point at infinity.\n    pub fn set_infinity(&mut self) {\n        self.infinity = true;\n        self.x.clear();\n        self.y.clear();\n        self.z.clear();\n    }\n\n    /// Set a group element (jacobian) equal to another which is given\n    /// in affine coordinates.\n    pub fn set_ge(&mut self, a: &Affine) {\n        self.infinity = a.infinity;\n        self.x = a.x;\n        self.y = a.y;\n        self.z.set_int(1);\n    }\n\n    pub fn from_ge(a: &Affine) -> Self {\n        let mut gej = Self::default();\n        gej.set_ge(a);\n        gej\n    }\n\n    /// Compare the X coordinate of a group element (jacobian).\n    pub fn eq_x_var(&self, x: &Field) -> bool {\n        debug_assert!(!self.is_infinity());\n        let mut r = self.z.sqr();\n        r *= x;\n        let mut r2 = self.x;\n        r2.normalize_weak();\n        r.eq_var(&r2)\n    }\n\n    /// Set r equal to the inverse of a (i.e., mirrored around the X\n    /// axis).\n    pub fn neg_in_place(&mut self, a: &Jacobian) {\n        self.infinity = a.infinity;\n        self.x = a.x;\n        self.y = a.y;\n        self.z = a.z;\n        self.y.normalize_weak();\n        self.y = self.y.neg(1);\n    }\n\n    pub fn neg(&self) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.neg_in_place(self);\n        ret\n    }\n\n    /// Check whether a group element is the point at infinity.\n    pub fn is_infinity(&self) -> bool {\n        self.infinity\n    }\n\n    /// Check whether a group element's y coordinate is a quadratic residue.\n    pub fn has_quad_y_var(&self) -> bool {\n        if self.infinity {\n            return false;\n        }\n\n        let yz = self.y * self.z;\n        yz.is_quad_var()\n    }\n\n    /// Set r equal to the double of a. If rzr is not-NULL, r->z =\n    /// a->z * *rzr (where infinity means an implicit z = 0). a may\n    /// not be zero. Constant time.\n    pub fn double_nonzero_in_place(&mut self, a: &Jacobian, rzr: Option<&mut Field>) {\n        debug_assert!(!self.is_infinity());\n        self.double_var_in_place(a, rzr);\n    }\n\n    /// Set r equal to the double of a. If rzr is not-NULL, r->z =\n    /// a->z * *rzr (where infinity means an implicit z = 0).\n    pub fn double_var_in_place(&mut self, a: &Jacobian, rzr: Option<&mut Field>) {\n        self.infinity = a.infinity;\n        if self.infinity {\n            if let Some(rzr) = rzr {\n                rzr.set_int(1);\n            }\n            return;\n        }\n\n        if let Some(rzr) = rzr {\n            *rzr = a.y;\n            rzr.normalize_weak();\n            rzr.mul_int(2);\n        }\n\n        self.z = a.z * a.y;\n        self.z.mul_int(2);\n        let mut t1 = a.x.sqr();\n        t1.mul_int(3);\n        let mut t2 = t1.sqr();\n        let mut t3 = a.y.sqr();\n        t3.mul_int(2);\n        let mut t4 = t3.sqr();\n        t4.mul_int(2);\n        t3 *= &a.x;\n        self.x = t3;\n        self.x.mul_int(4);\n        self.x = self.x.neg(4);\n        self.x += &t2;\n        t2 = t2.neg(1);\n        t3.mul_int(6);\n        t3 += &t2;\n        self.y = t1 * t3;\n        t2 = t4.neg(2);\n        self.y += t2;\n    }\n\n    pub fn double_var(&self, rzr: Option<&mut Field>) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.double_var_in_place(&self, rzr);\n        ret\n    }\n\n    /// Set r equal to the sum of a and b. If rzr is non-NULL, r->z =\n    /// a->z * *rzr (a cannot be infinity in that case).\n    pub fn add_var_in_place(&mut self, a: &Jacobian, b: &Jacobian, rzr: Option<&mut Field>) {\n        if a.is_infinity() {\n            debug_assert!(rzr.is_none());\n            *self = *b;\n            return;\n        }\n        if b.is_infinity() {\n            if let Some(rzr) = rzr {\n                rzr.set_int(1);\n            }\n            *self = *a;\n            return;\n        }\n\n        self.infinity = false;\n        let z22 = b.z.sqr();\n        let z12 = a.z.sqr();\n        let u1 = a.x * z22;\n        let u2 = b.x * z12;\n        let mut s1 = a.y * z22;\n        s1 *= b.z;\n        let mut s2 = b.y * z12;\n        s2 *= a.z;\n        let mut h = u1.neg(1);\n        h += u2;\n        let mut i = s1.neg(1);\n        i += s2;\n        if h.normalizes_to_zero_var() {\n            if i.normalizes_to_zero_var() {\n                self.double_var_in_place(a, rzr);\n            } else {\n                if let Some(rzr) = rzr {\n                    rzr.set_int(0);\n                }\n                self.infinity = true;\n            }\n            return;\n        }\n        let i2 = i.sqr();\n        let h2 = h.sqr();\n        let mut h3 = h * h2;\n        h *= b.z;\n        if let Some(rzr) = rzr {\n            *rzr = h;\n        }\n        self.z = a.z * h;\n        let t = u1 * h2;\n        self.x = t;\n        self.x.mul_int(2);\n        self.x += h3;\n        self.x = self.x.neg(3);\n        self.x += i2;\n        self.y = self.x.neg(5);\n        self.y += t;\n        self.y *= i;\n        h3 *= s1;\n        h3 = h3.neg(1);\n        self.y += h3;\n    }\n\n    pub fn add_var(&self, b: &Jacobian, rzr: Option<&mut Field>) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.add_var_in_place(self, b, rzr);\n        ret\n    }\n\n    /// Set r equal to the sum of a and b (with b given in affine\n    /// coordinates, and not infinity).\n    pub fn add_ge_in_place(&mut self, a: &Jacobian, b: &Affine) {\n        const FE1: Field = Field::new(0, 0, 0, 0, 0, 0, 0, 1);\n\n        debug_assert!(!b.infinity);\n\n        let zz = a.z.sqr();\n        let mut u1 = a.x;\n        u1.normalize_weak();\n        let u2 = b.x * zz;\n        let mut s1 = a.y;\n        s1.normalize_weak();\n        let mut s2 = b.y * zz;\n        s2 *= a.z;\n        let mut t = u1;\n        t += u2;\n        let mut m = s1;\n        m += s2;\n        let mut rr = t.sqr();\n        let mut m_alt = u2.neg(1);\n        let tt = u1 * m_alt;\n        rr += tt;\n        let degenerate = m.normalizes_to_zero() && rr.normalizes_to_zero();\n        let mut rr_alt = s1;\n        rr_alt.mul_int(2);\n        m_alt += u1;\n\n        rr_alt.cmov(&rr, !degenerate);\n        m_alt.cmov(&m, !degenerate);\n\n        let mut n = m_alt.sqr();\n        let mut q = n * t;\n\n        n = n.sqr();\n        n.cmov(&m, degenerate);\n        t = rr_alt.sqr();\n        self.z = a.z * m_alt;\n        let infinity = {\n            let p = self.z.normalizes_to_zero();\n            let q = a.infinity;\n\n            match (p, q) {\n                (true, true) => false,\n                (true, false) => true,\n                (false, true) => false,\n                (false, false) => false,\n            }\n        };\n        self.z.mul_int(2);\n        q = q.neg(1);\n        t += q;\n        t.normalize_weak();\n        self.x = t;\n        t.mul_int(2);\n        t += q;\n        t *= rr_alt;\n        t += n;\n        self.y = t.neg(3);\n        self.y.normalize_weak();\n        self.x.mul_int(4);\n        self.y.mul_int(4);\n\n        self.x.cmov(&b.x, a.infinity);\n        self.y.cmov(&b.y, a.infinity);\n        self.z.cmov(&FE1, a.infinity);\n        self.infinity = infinity;\n    }\n\n    pub fn add_ge(&self, b: &Affine) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.add_ge_in_place(self, b);\n        ret\n    }\n\n    /// Set r equal to the sum of a and b (with b given in affine\n    /// coordinates). This is more efficient than\n    /// secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge\n    /// but without constant-time guarantee, and b is allowed to be\n    /// infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be\n    /// infinity in that case).\n    pub fn add_ge_var_in_place(&mut self, a: &Jacobian, b: &Affine, rzr: Option<&mut Field>) {\n        if a.is_infinity() {\n            debug_assert!(rzr.is_none());\n            self.set_ge(b);\n            return;\n        }\n        if b.is_infinity() {\n            if let Some(rzr) = rzr {\n                rzr.set_int(1);\n            }\n            *self = *a;\n            return;\n        }\n        self.infinity = false;\n\n        let z12 = a.z.sqr();\n        let mut u1 = a.x;\n        u1.normalize_weak();\n        let u2 = b.x * z12;\n        let mut s1 = a.y;\n        s1.normalize_weak();\n        let mut s2 = b.y * z12;\n        s2 *= a.z;\n        let mut h = u1.neg(1);\n        h += u2;\n        let mut i = s1.neg(1);\n        i += s2;\n        if h.normalizes_to_zero_var() {\n            if i.normalizes_to_zero_var() {\n                self.double_var_in_place(a, rzr);\n            } else {\n                if let Some(rzr) = rzr {\n                    rzr.set_int(0);\n                }\n                self.infinity = true;\n            }\n            return;\n        }\n        let i2 = i.sqr();\n        let h2 = h.sqr();\n        let mut h3 = h * h2;\n        if let Some(rzr) = rzr {\n            *rzr = h;\n        }\n        self.z = a.z * h;\n        let t = u1 * h2;\n        self.x = t;\n        self.x.mul_int(2);\n        self.x += h3;\n        self.x = self.x.neg(3);\n        self.x += i2;\n        self.y = self.x.neg(5);\n        self.y += t;\n        self.y *= i;\n        h3 *= s1;\n        h3 = h3.neg(1);\n        self.y += h3;\n    }\n\n    pub fn add_ge_var(&self, b: &Affine, rzr: Option<&mut Field>) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.add_ge_var_in_place(&self, b, rzr);\n        ret\n    }\n\n    /// Set r equal to the sum of a and b (with the inverse of b's Z\n    /// coordinate passed as bzinv).\n    pub fn add_zinv_var_in_place(&mut self, a: &Jacobian, b: &Affine, bzinv: &Field) {\n        if b.is_infinity() {\n            *self = *a;\n            return;\n        }\n        if a.is_infinity() {\n            self.infinity = b.infinity;\n            let bzinv2 = bzinv.sqr();\n            let bzinv3 = &bzinv2 * bzinv;\n            self.x = b.x * bzinv2;\n            self.y = b.y * bzinv3;\n            self.z.set_int(1);\n            return;\n        }\n        self.infinity = false;\n\n        let az = a.z * *bzinv;\n        let z12 = az.sqr();\n        let mut u1 = a.x;\n        u1.normalize_weak();\n        let u2 = b.x * z12;\n        let mut s1 = a.y;\n        s1.normalize_weak();\n        let mut s2 = b.y * z12;\n        s2 *= &az;\n        let mut h = u1.neg(1);\n        h += &u2;\n        let mut i = s1.neg(1);\n        i += &s2;\n        if h.normalizes_to_zero_var() {\n            if i.normalizes_to_zero_var() {\n                self.double_var_in_place(a, None);\n            } else {\n                self.infinity = true;\n            }\n            return;\n        }\n        let i2 = i.sqr();\n        let h2 = h.sqr();\n        let mut h3 = h * h2;\n        self.z = a.z;\n        self.z *= h;\n        let t = u1 * h2;\n        self.x = t;\n        self.x.mul_int(2);\n        self.x += h3;\n        self.x = self.x.neg(3);\n        self.x += i2;\n        self.y = self.x.neg(5);\n        self.y += t;\n        self.y *= i;\n        h3 *= s1;\n        h3 = h3.neg(1);\n        self.y += h3;\n    }\n\n    pub fn add_zinv_var(&mut self, b: &Affine, bzinv: &Field) -> Jacobian {\n        let mut ret = Jacobian::default();\n        ret.add_zinv_var_in_place(&self, b, bzinv);\n        ret\n    }\n\n    /// Clear a secp256k1_gej to prevent leaking sensitive\n    /// information.\n    pub fn clear(&mut self) {\n        self.infinity = false;\n        self.x.clear();\n        self.y.clear();\n        self.z.clear();\n    }\n\n    /// Rescale a jacobian point by b which must be\n    /// non-zero. Constant-time.\n    pub fn rescale(&mut self, s: &Field) {\n        debug_assert!(!s.is_zero());\n        let zz = s.sqr();\n        self.x *= &zz;\n        self.y *= &zz;\n        self.y *= s;\n        self.z *= s;\n    }\n}\n\nimpl From<AffineStorage> for Affine {\n    fn from(a: AffineStorage) -> Affine {\n        Affine::new(a.x.into(), a.y.into())\n    }\n}\n\nimpl Into<AffineStorage> for Affine {\n    fn into(mut self) -> AffineStorage {\n        debug_assert!(!self.is_infinity());\n        self.x.normalize();\n        self.y.normalize();\n        AffineStorage::new(self.x.into(), self.y.into())\n    }\n}\n\nimpl AffineStorage {\n    /// Create a new affine storage.\n    pub const fn new(x: FieldStorage, y: FieldStorage) -> Self {\n        Self { x, y }\n    }\n\n    /// If flag is true, set *r equal to *a; otherwise leave\n    /// it. Constant-time.\n    pub fn cmov(&mut self, a: &AffineStorage, flag: bool) {\n        self.x.cmov(&a.x, flag);\n        self.y.cmov(&a.y, flag);\n    }\n}\n"
  },
  {
    "path": "core/src/lib.rs",
    "content": "//! Core libraries for libsecp256k1.\n\n#![allow(\n    clippy::cast_ptr_alignment,\n    clippy::identity_op,\n    clippy::many_single_char_names,\n    clippy::needless_range_loop,\n    clippy::suspicious_op_assign_impl,\n    clippy::too_many_arguments,\n    clippy::type_complexity\n)]\n#![deny(\n    unused_import_braces,\n    unused_imports,\n    unused_comparisons,\n    unused_must_use,\n    unused_variables,\n    non_shorthand_field_patterns,\n    unreachable_code,\n    unused_parens\n)]\n#![cfg_attr(not(feature = \"std\"), no_std)]\nextern crate alloc;\n\n#[macro_use]\nmod field;\n#[macro_use]\nmod group;\nmod der;\nmod ecdh;\nmod ecdsa;\nmod ecmult;\nmod error;\nmod scalar;\n\npub use crate::error::Error;\n\n/// Curve related structs.\npub mod curve {\n    pub use crate::{\n        field::{Field, FieldStorage},\n        group::{Affine, AffineStorage, Jacobian, AFFINE_G, CURVE_B},\n        scalar::Scalar,\n    };\n\n    pub use crate::ecmult::{ECMultContext, ECMultGenContext};\n}\n\n/// Utilities to manipulate the secp256k1 curve parameters.\npub mod util {\n    pub const TAG_PUBKEY_EVEN: u8 = 0x02;\n    pub const TAG_PUBKEY_ODD: u8 = 0x03;\n    pub const TAG_PUBKEY_FULL: u8 = 0x04;\n    pub const TAG_PUBKEY_HYBRID_EVEN: u8 = 0x06;\n    pub const TAG_PUBKEY_HYBRID_ODD: u8 = 0x07;\n\n    pub const MESSAGE_SIZE: usize = 32;\n    pub const SECRET_KEY_SIZE: usize = 32;\n    pub const RAW_PUBLIC_KEY_SIZE: usize = 64;\n    pub const FULL_PUBLIC_KEY_SIZE: usize = 65;\n    pub const COMPRESSED_PUBLIC_KEY_SIZE: usize = 33;\n    pub const SIGNATURE_SIZE: usize = 64;\n    pub const DER_MAX_SIGNATURE_SIZE: usize = 72;\n\n    pub use crate::{\n        ecmult::{\n            odd_multiples_table, ECMULT_TABLE_SIZE_A, ECMULT_TABLE_SIZE_G, WINDOW_A, WINDOW_G,\n        },\n        group::{globalz_set_table_gej, set_table_gej_var, AFFINE_INFINITY, JACOBIAN_INFINITY},\n    };\n\n    pub use crate::der::{Decoder, SignatureArray};\n}\n"
  },
  {
    "path": "core/src/scalar.rs",
    "content": "use core::ops::{Add, AddAssign, Mul, MulAssign, Neg};\nuse crunchy::unroll;\nuse subtle::Choice;\n\nconst SECP256K1_N: [u32; 8] = [\n    0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n];\n\nconst SECP256K1_N_C_0: u32 = !SECP256K1_N[0] + 1;\nconst SECP256K1_N_C_1: u32 = !SECP256K1_N[1];\nconst SECP256K1_N_C_2: u32 = !SECP256K1_N[2];\nconst SECP256K1_N_C_3: u32 = !SECP256K1_N[3];\nconst SECP256K1_N_C_4: u32 = 1;\n\nconst SECP256K1_N_H_0: u32 = 0x681B20A0;\nconst SECP256K1_N_H_1: u32 = 0xDFE92F46;\nconst SECP256K1_N_H_2: u32 = 0x57A4501D;\nconst SECP256K1_N_H_3: u32 = 0x5D576E73;\nconst SECP256K1_N_H_4: u32 = 0xFFFFFFFF;\nconst SECP256K1_N_H_5: u32 = 0xFFFFFFFF;\nconst SECP256K1_N_H_6: u32 = 0xFFFFFFFF;\nconst SECP256K1_N_H_7: u32 = 0x7FFFFFFF;\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// A 256-bit scalar value.\npub struct Scalar(pub [u32; 8]);\n\nimpl Scalar {\n    /// Clear a scalar to prevent the leak of sensitive data.\n    pub fn clear(&mut self) {\n        unsafe {\n            core::ptr::write_volatile(&mut self.0, [0u32; 8]);\n        }\n    }\n\n    /// Set a scalar to an unsigned integer.\n    pub fn set_int(&mut self, v: u32) {\n        self.0 = [v, 0, 0, 0, 0, 0, 0, 0];\n    }\n\n    /// Create a scalar from an unsigned integer.\n    pub fn from_int(v: u32) -> Self {\n        let mut scalar = Self::default();\n        scalar.set_int(v);\n        scalar\n    }\n\n    /// Access bits from a scalar. All requested bits must belong to\n    /// the same 32-bit limb.\n    pub fn bits(&self, offset: usize, count: usize) -> u32 {\n        debug_assert!((offset + count - 1) >> 5 == offset >> 5);\n        (self.0[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1)\n    }\n\n    /// Access bits from a scalar. Not constant time.\n    pub fn bits_var(&self, offset: usize, count: usize) -> u32 {\n        debug_assert!(count < 32);\n        debug_assert!(offset + count <= 256);\n        if (offset + count - 1) >> 5 == offset >> 5 {\n            self.bits(offset, count)\n        } else {\n            debug_assert!((offset >> 5) + 1 < 8);\n            ((self.0[offset >> 5] >> (offset & 0x1f))\n                | (self.0[(offset >> 5) + 1] << (32 - (offset & 0x1f))))\n                & ((1 << count) - 1)\n        }\n    }\n\n    #[must_use]\n    fn check_overflow(&self) -> Choice {\n        let mut yes: Choice = 0.into();\n        let mut no: Choice = 0.into();\n        no |= Choice::from((self.0[7] < SECP256K1_N[7]) as u8); /* No need for a > check. */\n        no |= Choice::from((self.0[6] < SECP256K1_N[6]) as u8); /* No need for a > check. */\n        no |= Choice::from((self.0[5] < SECP256K1_N[5]) as u8); /* No need for a > check. */\n        no |= Choice::from((self.0[4] < SECP256K1_N[4]) as u8);\n        yes |= Choice::from((self.0[4] > SECP256K1_N[4]) as u8) & !no;\n        no |= Choice::from((self.0[3] < SECP256K1_N[3]) as u8) & !yes;\n        yes |= Choice::from((self.0[3] > SECP256K1_N[3]) as u8) & !no;\n        no |= Choice::from((self.0[2] < SECP256K1_N[2]) as u8) & !yes;\n        yes |= Choice::from((self.0[2] > SECP256K1_N[2]) as u8) & !no;\n        no |= Choice::from((self.0[1] < SECP256K1_N[1]) as u8) & !yes;\n        yes |= Choice::from((self.0[1] > SECP256K1_N[1]) as u8) & !no;\n        yes |= Choice::from((self.0[0] >= SECP256K1_N[0]) as u8) & !no;\n\n        yes\n    }\n\n    fn reduce(&mut self, overflow: Choice) {\n        let o = overflow.unwrap_u8() as u64;\n        let mut t: u64;\n\n        t = (self.0[0] as u64) + o * (SECP256K1_N_C_0 as u64);\n        self.0[0] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += (self.0[1] as u64) + o * (SECP256K1_N_C_1 as u64);\n        self.0[1] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += (self.0[2] as u64) + o * (SECP256K1_N_C_2 as u64);\n        self.0[2] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += (self.0[3] as u64) + o * (SECP256K1_N_C_3 as u64);\n        self.0[3] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += (self.0[4] as u64) + o * (SECP256K1_N_C_4 as u64);\n        self.0[4] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += self.0[5] as u64;\n        self.0[5] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += self.0[6] as u64;\n        self.0[6] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n\n        t += self.0[7] as u64;\n        self.0[7] = (t & 0xFFFFFFFF) as u32;\n    }\n\n    /// Conditionally add a power of two to a scalar. The result is\n    /// not allowed to overflow.\n    pub fn cadd_bit(&mut self, mut bit: usize, flag: bool) {\n        let mut t: u64;\n        debug_assert!(bit < 256);\n        bit += if flag { 0 } else { usize::max_value() } & 0x100;\n        t = (self.0[0] as u64) + ((if (bit >> 5) == 0 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[0] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[1] as u64) + ((if (bit >> 5) == 1 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[1] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[2] as u64) + ((if (bit >> 5) == 2 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[2] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[3] as u64) + ((if (bit >> 5) == 3 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[3] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[4] as u64) + ((if (bit >> 5) == 4 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[4] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[5] as u64) + ((if (bit >> 5) == 5 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[5] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[6] as u64) + ((if (bit >> 5) == 6 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[6] = (t & 0xFFFFFFFF) as u32;\n        t >>= 32;\n        t += (self.0[7] as u64) + ((if (bit >> 5) == 7 { 1 } else { 0 }) << (bit & 0x1F));\n        self.0[7] = (t & 0xFFFFFFFF) as u32;\n        debug_assert!((t >> 32) == 0);\n        debug_assert!(!bool::from(self.check_overflow()));\n    }\n\n    /// Set a scalar from a big endian byte array, return whether it overflowed.\n    #[must_use]\n    pub fn set_b32(&mut self, b32: &[u8; 32]) -> Choice {\n        self.0[0] = (b32[31] as u32)\n            | ((b32[30] as u32) << 8)\n            | ((b32[29] as u32) << 16)\n            | ((b32[28] as u32) << 24);\n        self.0[1] = (b32[27] as u32)\n            | ((b32[26] as u32) << 8)\n            | ((b32[25] as u32) << 16)\n            | ((b32[24] as u32) << 24);\n        self.0[2] = (b32[23] as u32)\n            | ((b32[22] as u32) << 8)\n            | ((b32[21] as u32) << 16)\n            | ((b32[20] as u32) << 24);\n        self.0[3] = (b32[19] as u32)\n            | ((b32[18] as u32) << 8)\n            | ((b32[17] as u32) << 16)\n            | ((b32[16] as u32) << 24);\n        self.0[4] = (b32[15] as u32)\n            | ((b32[14] as u32) << 8)\n            | ((b32[13] as u32) << 16)\n            | ((b32[12] as u32) << 24);\n        self.0[5] = (b32[11] as u32)\n            | ((b32[10] as u32) << 8)\n            | ((b32[9] as u32) << 16)\n            | ((b32[8] as u32) << 24);\n        self.0[6] = (b32[7] as u32)\n            | ((b32[6] as u32) << 8)\n            | ((b32[5] as u32) << 16)\n            | ((b32[4] as u32) << 24);\n        self.0[7] = (b32[3] as u32)\n            | ((b32[2] as u32) << 8)\n            | ((b32[1] as u32) << 16)\n            | ((b32[0] as u32) << 24);\n\n        let overflow = self.check_overflow();\n        self.reduce(overflow);\n\n        overflow\n    }\n\n    /// Convert a scalar to a byte array.\n    pub fn b32(&self) -> [u8; 32] {\n        let mut bin = [0u8; 32];\n        self.fill_b32(&mut bin);\n        bin\n    }\n\n    /// Convert a scalar to a byte array.\n    pub fn fill_b32(&self, bin: &mut [u8; 32]) {\n        bin[0] = (self.0[7] >> 24) as u8;\n        bin[1] = (self.0[7] >> 16) as u8;\n        bin[2] = (self.0[7] >> 8) as u8;\n        bin[3] = (self.0[7]) as u8;\n        bin[4] = (self.0[6] >> 24) as u8;\n        bin[5] = (self.0[6] >> 16) as u8;\n        bin[6] = (self.0[6] >> 8) as u8;\n        bin[7] = (self.0[6]) as u8;\n        bin[8] = (self.0[5] >> 24) as u8;\n        bin[9] = (self.0[5] >> 16) as u8;\n        bin[10] = (self.0[5] >> 8) as u8;\n        bin[11] = (self.0[5]) as u8;\n        bin[12] = (self.0[4] >> 24) as u8;\n        bin[13] = (self.0[4] >> 16) as u8;\n        bin[14] = (self.0[4] >> 8) as u8;\n        bin[15] = (self.0[4]) as u8;\n        bin[16] = (self.0[3] >> 24) as u8;\n        bin[17] = (self.0[3] >> 16) as u8;\n        bin[18] = (self.0[3] >> 8) as u8;\n        bin[19] = (self.0[3]) as u8;\n        bin[20] = (self.0[2] >> 24) as u8;\n        bin[21] = (self.0[2] >> 16) as u8;\n        bin[22] = (self.0[2] >> 8) as u8;\n        bin[23] = (self.0[2]) as u8;\n        bin[24] = (self.0[1] >> 24) as u8;\n        bin[25] = (self.0[1] >> 16) as u8;\n        bin[26] = (self.0[1] >> 8) as u8;\n        bin[27] = (self.0[1]) as u8;\n        bin[28] = (self.0[0] >> 24) as u8;\n        bin[29] = (self.0[0] >> 16) as u8;\n        bin[30] = (self.0[0] >> 8) as u8;\n        bin[31] = (self.0[0]) as u8;\n    }\n\n    /// Check whether a scalar equals zero.\n    pub fn is_zero(&self) -> bool {\n        (self.0[0]\n            | self.0[1]\n            | self.0[2]\n            | self.0[3]\n            | self.0[4]\n            | self.0[5]\n            | self.0[6]\n            | self.0[7])\n            == 0\n    }\n\n    /// Check whether a scalar equals one.\n    pub fn is_one(&self) -> bool {\n        ((self.0[0] ^ 1)\n            | self.0[1]\n            | self.0[2]\n            | self.0[3]\n            | self.0[4]\n            | self.0[5]\n            | self.0[6]\n            | self.0[7])\n            == 0\n    }\n\n    /// Check whether a scalar is higher than the group order divided\n    /// by 2.\n    pub fn is_high(&self) -> bool {\n        let mut yes: Choice = 0.into();\n        let mut no: Choice = 0.into();\n        no |= Choice::from((self.0[7] < SECP256K1_N_H_7) as u8);\n        yes |= Choice::from((self.0[7] > SECP256K1_N_H_7) as u8) & !no;\n        no |= Choice::from((self.0[6] < SECP256K1_N_H_6) as u8) & !yes; /* No need for a > check. */\n        no |= Choice::from((self.0[5] < SECP256K1_N_H_5) as u8) & !yes; /* No need for a > check. */\n        no |= Choice::from((self.0[4] < SECP256K1_N_H_4) as u8) & !yes; /* No need for a > check. */\n        no |= Choice::from((self.0[3] < SECP256K1_N_H_3) as u8) & !yes;\n        yes |= Choice::from((self.0[3] > SECP256K1_N_H_3) as u8) & !no;\n        no |= Choice::from((self.0[2] < SECP256K1_N_H_2) as u8) & !yes;\n        yes |= Choice::from((self.0[2] > SECP256K1_N_H_2) as u8) & !no;\n        no |= Choice::from((self.0[1] < SECP256K1_N_H_1) as u8) & !yes;\n        yes |= Choice::from((self.0[1] > SECP256K1_N_H_1) as u8) & !no;\n        yes |= Choice::from((self.0[0] >= SECP256K1_N_H_0) as u8) & !no;\n        yes.into()\n    }\n\n    /// Conditionally negate a number, in constant time.\n    pub fn cond_neg_assign(&mut self, flag: Choice) {\n        let mask = u32::max_value() * flag.unwrap_u8() as u32;\n\n        let nonzero = 0xFFFFFFFFu64 * !self.is_zero() as u64;\n        let mut t = 1u64 * flag.unwrap_u8() as u64;\n\n        unroll! {\n            for i in 0..8 {\n                t += (self.0[i] ^ mask) as u64 + (SECP256K1_N[i] & mask) as u64;\n                self.0[i] = (t & nonzero) as u32;\n                t >>= 32;\n            }\n        }\n\n        let _ = t;\n    }\n}\n\nmacro_rules! define_ops {\n    ($c0: ident, $c1: ident, $c2: ident) => {\n        #[allow(unused_macros)]\n        macro_rules! muladd {\n            ($a: expr, $b: expr) => {\n                let a = $a;\n                let b = $b;\n                let t = (a as u64) * (b as u64);\n                let mut th = (t >> 32) as u32;\n                let tl = t as u32;\n                $c0 = $c0.wrapping_add(tl);\n                th = th.wrapping_add(if $c0 < tl { 1 } else { 0 });\n                $c1 = $c1.wrapping_add(th);\n                $c2 = $c2.wrapping_add(if $c1 < th { 1 } else { 0 });\n                debug_assert!($c1 >= th || $c2 != 0);\n            };\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! muladd_fast {\n            ($a: expr, $b: expr) => {\n                let a = $a;\n                let b = $b;\n                let t = (a as u64) * (b as u64);\n                let mut th = (t >> 32) as u32;\n                let tl = t as u32;\n                $c0 = $c0.wrapping_add(tl);\n                th = th.wrapping_add(if $c0 < tl { 1 } else { 0 });\n                $c1 = $c1.wrapping_add(th);\n                debug_assert!($c1 >= th);\n            };\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! muladd2 {\n            ($a: expr, $b: expr) => {\n                let a = $a;\n                let b = $b;\n                let t = (a as u64) * (b as u64);\n                let th = (t >> 32) as u32;\n                let tl = t as u32;\n                let mut th2 = th.wrapping_add(th);\n                $c2 = $c2.wrapping_add(if th2 < th { 1 } else { 0 });\n                debug_assert!(th2 >= th || $c2 != 0);\n                let tl2 = tl.wrapping_add(tl);\n                th2 = th2.wrapping_add(if tl2 < tl { 1 } else { 0 });\n                $c0 = $c0.wrapping_add(tl2);\n                th2 = th2.wrapping_add(if $c0 < tl2 { 1 } else { 0 });\n                $c2 = $c2.wrapping_add(if $c0 < tl2 && th2 == 0 { 1 } else { 0 });\n                debug_assert!($c0 >= tl2 || th2 != 0 || $c2 != 0);\n                $c1 = $c1.wrapping_add(th2);\n                $c2 = $c2.wrapping_add(if $c1 < th2 { 1 } else { 0 });\n                debug_assert!($c1 >= th2 || $c2 != 0);\n            };\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! sumadd {\n            ($a: expr) => {\n                let a = $a;\n                $c0 = $c0.wrapping_add(a);\n                let over = if $c0 < a { 1 } else { 0 };\n                $c1 = $c1.wrapping_add(over);\n                $c2 = $c2.wrapping_add(if $c1 < over { 1 } else { 0 });\n            };\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! sumadd_fast {\n            ($a: expr) => {\n                let a = $a;\n                $c0 = $c0.wrapping_add(a);\n                $c1 = $c1.wrapping_add(if $c0 < a { 1 } else { 0 });\n                debug_assert!($c1 != 0 || $c0 >= a);\n                debug_assert!($c2 == 0);\n            };\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! extract {\n            () => {{\n                #[allow(unused_assignments)]\n                {\n                    let n = $c0;\n                    $c0 = $c1;\n                    $c1 = $c2;\n                    $c2 = 0;\n                    n\n                }\n            }};\n        }\n\n        #[allow(unused_macros)]\n        macro_rules! extract_fast {\n            () => {{\n                #[allow(unused_assignments)]\n                {\n                    let n = $c0;\n                    $c0 = $c1;\n                    $c1 = 0;\n                    debug_assert!($c2 == 0);\n                    n\n                }\n            }};\n        }\n    };\n}\n\nimpl Scalar {\n    fn reduce_512(&mut self, l: &[u32; 16]) {\n        let (mut c0, mut c1, mut c2): (u32, u32, u32);\n        define_ops!(c0, c1, c2);\n\n        let mut c: u64;\n        let (n0, n1, n2, n3, n4, n5, n6, n7) =\n            (l[8], l[9], l[10], l[11], l[12], l[13], l[14], l[15]);\n        let (m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12): (\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n            u32,\n        );\n        let (p0, p1, p2, p3, p4, p5, p6, p7, p8): (u32, u32, u32, u32, u32, u32, u32, u32, u32);\n\n        c0 = l[0];\n        c1 = 0;\n        c2 = 0;\n        muladd_fast!(n0, SECP256K1_N_C_0);\n        m0 = extract_fast!();\n        sumadd_fast!(l[1]);\n        muladd!(n1, SECP256K1_N_C_0);\n        muladd!(n0, SECP256K1_N_C_1);\n        m1 = extract!();\n        sumadd!(l[2]);\n        muladd!(n2, SECP256K1_N_C_0);\n        muladd!(n1, SECP256K1_N_C_1);\n        muladd!(n0, SECP256K1_N_C_2);\n        m2 = extract!();\n        sumadd!(l[3]);\n        muladd!(n3, SECP256K1_N_C_0);\n        muladd!(n2, SECP256K1_N_C_1);\n        muladd!(n1, SECP256K1_N_C_2);\n        muladd!(n0, SECP256K1_N_C_3);\n        m3 = extract!();\n        sumadd!(l[4]);\n        muladd!(n4, SECP256K1_N_C_0);\n        muladd!(n3, SECP256K1_N_C_1);\n        muladd!(n2, SECP256K1_N_C_2);\n        muladd!(n1, SECP256K1_N_C_3);\n        sumadd!(n0);\n        m4 = extract!();\n        sumadd!(l[5]);\n        muladd!(n5, SECP256K1_N_C_0);\n        muladd!(n4, SECP256K1_N_C_1);\n        muladd!(n3, SECP256K1_N_C_2);\n        muladd!(n2, SECP256K1_N_C_3);\n        sumadd!(n1);\n        m5 = extract!();\n        sumadd!(l[6]);\n        muladd!(n6, SECP256K1_N_C_0);\n        muladd!(n5, SECP256K1_N_C_1);\n        muladd!(n4, SECP256K1_N_C_2);\n        muladd!(n3, SECP256K1_N_C_3);\n        sumadd!(n2);\n        m6 = extract!();\n        sumadd!(l[7]);\n        muladd!(n7, SECP256K1_N_C_0);\n        muladd!(n6, SECP256K1_N_C_1);\n        muladd!(n5, SECP256K1_N_C_2);\n        muladd!(n4, SECP256K1_N_C_3);\n        sumadd!(n3);\n        m7 = extract!();\n        muladd!(n7, SECP256K1_N_C_1);\n        muladd!(n6, SECP256K1_N_C_2);\n        muladd!(n5, SECP256K1_N_C_3);\n        sumadd!(n4);\n        m8 = extract!();\n        muladd!(n7, SECP256K1_N_C_2);\n        muladd!(n6, SECP256K1_N_C_3);\n        sumadd!(n5);\n        m9 = extract!();\n        muladd!(n7, SECP256K1_N_C_3);\n        sumadd!(n6);\n        m10 = extract!();\n        sumadd_fast!(n7);\n        m11 = extract_fast!();\n        debug_assert!(c0 <= 1);\n        m12 = c0;\n\n        /* Reduce 385 bits into 258. */\n        /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */\n        c0 = m0;\n        c1 = 0;\n        c2 = 0;\n        muladd_fast!(m8, SECP256K1_N_C_0);\n        p0 = extract_fast!();\n        sumadd_fast!(m1);\n        muladd!(m9, SECP256K1_N_C_0);\n        muladd!(m8, SECP256K1_N_C_1);\n        p1 = extract!();\n        sumadd!(m2);\n        muladd!(m10, SECP256K1_N_C_0);\n        muladd!(m9, SECP256K1_N_C_1);\n        muladd!(m8, SECP256K1_N_C_2);\n        p2 = extract!();\n        sumadd!(m3);\n        muladd!(m11, SECP256K1_N_C_0);\n        muladd!(m10, SECP256K1_N_C_1);\n        muladd!(m9, SECP256K1_N_C_2);\n        muladd!(m8, SECP256K1_N_C_3);\n        p3 = extract!();\n        sumadd!(m4);\n        muladd!(m12, SECP256K1_N_C_0);\n        muladd!(m11, SECP256K1_N_C_1);\n        muladd!(m10, SECP256K1_N_C_2);\n        muladd!(m9, SECP256K1_N_C_3);\n        sumadd!(m8);\n        p4 = extract!();\n        sumadd!(m5);\n        muladd!(m12, SECP256K1_N_C_1);\n        muladd!(m11, SECP256K1_N_C_2);\n        muladd!(m10, SECP256K1_N_C_3);\n        sumadd!(m9);\n        p5 = extract!();\n        sumadd!(m6);\n        muladd!(m12, SECP256K1_N_C_2);\n        muladd!(m11, SECP256K1_N_C_3);\n        sumadd!(m10);\n        p6 = extract!();\n        sumadd_fast!(m7);\n        muladd_fast!(m12, SECP256K1_N_C_3);\n        sumadd_fast!(m11);\n        p7 = extract_fast!();\n        p8 = c0 + m12;\n        debug_assert!(p8 <= 2);\n\n        /* Reduce 258 bits into 256. */\n        /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */\n        c = p0 as u64 + SECP256K1_N_C_0 as u64 * p8 as u64;\n        self.0[0] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p1 as u64 + SECP256K1_N_C_1 as u64 * p8 as u64;\n        self.0[1] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p2 as u64 + SECP256K1_N_C_2 as u64 * p8 as u64;\n        self.0[2] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p3 as u64 + SECP256K1_N_C_3 as u64 * p8 as u64;\n        self.0[3] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p4 as u64 + p8 as u64;\n        self.0[4] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p5 as u64;\n        self.0[5] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p6 as u64;\n        self.0[6] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n        c += p7 as u64;\n        self.0[7] = (c & 0xFFFFFFFF) as u32;\n        c >>= 32;\n\n        let overflow = self.check_overflow();\n        self.reduce(Choice::from(c as u8) | overflow);\n    }\n\n    fn mul_512(&self, b: &Scalar, l: &mut [u32; 16]) {\n        let (mut c0, mut c1, mut c2): (u32, u32, u32) = (0, 0, 0);\n        define_ops!(c0, c1, c2);\n\n        /* l[0..15] = a[0..7] * b[0..7]. */\n        muladd_fast!(self.0[0], b.0[0]);\n        l[0] = extract_fast!();\n        muladd!(self.0[0], b.0[1]);\n        muladd!(self.0[1], b.0[0]);\n        l[1] = extract!();\n        muladd!(self.0[0], b.0[2]);\n        muladd!(self.0[1], b.0[1]);\n        muladd!(self.0[2], b.0[0]);\n        l[2] = extract!();\n        muladd!(self.0[0], b.0[3]);\n        muladd!(self.0[1], b.0[2]);\n        muladd!(self.0[2], b.0[1]);\n        muladd!(self.0[3], b.0[0]);\n        l[3] = extract!();\n        muladd!(self.0[0], b.0[4]);\n        muladd!(self.0[1], b.0[3]);\n        muladd!(self.0[2], b.0[2]);\n        muladd!(self.0[3], b.0[1]);\n        muladd!(self.0[4], b.0[0]);\n        l[4] = extract!();\n        muladd!(self.0[0], b.0[5]);\n        muladd!(self.0[1], b.0[4]);\n        muladd!(self.0[2], b.0[3]);\n        muladd!(self.0[3], b.0[2]);\n        muladd!(self.0[4], b.0[1]);\n        muladd!(self.0[5], b.0[0]);\n        l[5] = extract!();\n        muladd!(self.0[0], b.0[6]);\n        muladd!(self.0[1], b.0[5]);\n        muladd!(self.0[2], b.0[4]);\n        muladd!(self.0[3], b.0[3]);\n        muladd!(self.0[4], b.0[2]);\n        muladd!(self.0[5], b.0[1]);\n        muladd!(self.0[6], b.0[0]);\n        l[6] = extract!();\n        muladd!(self.0[0], b.0[7]);\n        muladd!(self.0[1], b.0[6]);\n        muladd!(self.0[2], b.0[5]);\n        muladd!(self.0[3], b.0[4]);\n        muladd!(self.0[4], b.0[3]);\n        muladd!(self.0[5], b.0[2]);\n        muladd!(self.0[6], b.0[1]);\n        muladd!(self.0[7], b.0[0]);\n        l[7] = extract!();\n        muladd!(self.0[1], b.0[7]);\n        muladd!(self.0[2], b.0[6]);\n        muladd!(self.0[3], b.0[5]);\n        muladd!(self.0[4], b.0[4]);\n        muladd!(self.0[5], b.0[3]);\n        muladd!(self.0[6], b.0[2]);\n        muladd!(self.0[7], b.0[1]);\n        l[8] = extract!();\n        muladd!(self.0[2], b.0[7]);\n        muladd!(self.0[3], b.0[6]);\n        muladd!(self.0[4], b.0[5]);\n        muladd!(self.0[5], b.0[4]);\n        muladd!(self.0[6], b.0[3]);\n        muladd!(self.0[7], b.0[2]);\n        l[9] = extract!();\n        muladd!(self.0[3], b.0[7]);\n        muladd!(self.0[4], b.0[6]);\n        muladd!(self.0[5], b.0[5]);\n        muladd!(self.0[6], b.0[4]);\n        muladd!(self.0[7], b.0[3]);\n        l[10] = extract!();\n        muladd!(self.0[4], b.0[7]);\n        muladd!(self.0[5], b.0[6]);\n        muladd!(self.0[6], b.0[5]);\n        muladd!(self.0[7], b.0[4]);\n        l[11] = extract!();\n        muladd!(self.0[5], b.0[7]);\n        muladd!(self.0[6], b.0[6]);\n        muladd!(self.0[7], b.0[5]);\n        l[12] = extract!();\n        muladd!(self.0[6], b.0[7]);\n        muladd!(self.0[7], b.0[6]);\n        l[13] = extract!();\n        muladd_fast!(self.0[7], b.0[7]);\n        l[14] = extract_fast!();\n        debug_assert!(c1 == 0);\n        l[15] = c0;\n    }\n\n    fn sqr_512(&self, l: &mut [u32; 16]) {\n        let (mut c0, mut c1, mut c2): (u32, u32, u32) = (0, 0, 0);\n        define_ops!(c0, c1, c2);\n\n        /* l[0..15] = a[0..7]^2. */\n        muladd_fast!(self.0[0], self.0[0]);\n        l[0] = extract_fast!();\n        muladd2!(self.0[0], self.0[1]);\n        l[1] = extract!();\n        muladd2!(self.0[0], self.0[2]);\n        muladd!(self.0[1], self.0[1]);\n        l[2] = extract!();\n        muladd2!(self.0[0], self.0[3]);\n        muladd2!(self.0[1], self.0[2]);\n        l[3] = extract!();\n        muladd2!(self.0[0], self.0[4]);\n        muladd2!(self.0[1], self.0[3]);\n        muladd!(self.0[2], self.0[2]);\n        l[4] = extract!();\n        muladd2!(self.0[0], self.0[5]);\n        muladd2!(self.0[1], self.0[4]);\n        muladd2!(self.0[2], self.0[3]);\n        l[5] = extract!();\n        muladd2!(self.0[0], self.0[6]);\n        muladd2!(self.0[1], self.0[5]);\n        muladd2!(self.0[2], self.0[4]);\n        muladd!(self.0[3], self.0[3]);\n        l[6] = extract!();\n        muladd2!(self.0[0], self.0[7]);\n        muladd2!(self.0[1], self.0[6]);\n        muladd2!(self.0[2], self.0[5]);\n        muladd2!(self.0[3], self.0[4]);\n        l[7] = extract!();\n        muladd2!(self.0[1], self.0[7]);\n        muladd2!(self.0[2], self.0[6]);\n        muladd2!(self.0[3], self.0[5]);\n        muladd!(self.0[4], self.0[4]);\n        l[8] = extract!();\n        muladd2!(self.0[2], self.0[7]);\n        muladd2!(self.0[3], self.0[6]);\n        muladd2!(self.0[4], self.0[5]);\n        l[9] = extract!();\n        muladd2!(self.0[3], self.0[7]);\n        muladd2!(self.0[4], self.0[6]);\n        muladd!(self.0[5], self.0[5]);\n        l[10] = extract!();\n        muladd2!(self.0[4], self.0[7]);\n        muladd2!(self.0[5], self.0[6]);\n        l[11] = extract!();\n        muladd2!(self.0[5], self.0[7]);\n        muladd!(self.0[6], self.0[6]);\n        l[12] = extract!();\n        muladd2!(self.0[6], self.0[7]);\n        l[13] = extract!();\n        muladd_fast!(self.0[7], self.0[7]);\n        l[14] = extract_fast!();\n        debug_assert!(c1 == 0);\n        l[15] = c0;\n    }\n\n    pub fn mul_in_place(&mut self, a: &Scalar, b: &Scalar) {\n        let mut l = [0u32; 16];\n        a.mul_512(b, &mut l);\n        self.reduce_512(&l);\n    }\n\n    /// Shift a scalar right by some amount strictly between 0 and 16,\n    /// returning the low bits that were shifted off.\n    pub fn shr_int(&mut self, n: usize) -> u32 {\n        let ret: u32;\n        debug_assert!(n > 0);\n        debug_assert!(n < 16);\n        ret = self.0[0] & ((1 << n) - 1);\n        self.0[0] = (self.0[0] >> n) + (self.0[1] << (32 - n));\n        self.0[1] = (self.0[1] >> n) + (self.0[2] << (32 - n));\n        self.0[2] = (self.0[2] >> n) + (self.0[3] << (32 - n));\n        self.0[3] = (self.0[3] >> n) + (self.0[4] << (32 - n));\n        self.0[4] = (self.0[4] >> n) + (self.0[5] << (32 - n));\n        self.0[5] = (self.0[5] >> n) + (self.0[6] << (32 - n));\n        self.0[6] = (self.0[6] >> n) + (self.0[7] << (32 - n));\n        self.0[7] >>= n;\n        ret\n    }\n\n    pub fn sqr_in_place(&mut self, a: &Scalar) {\n        let mut l = [0u32; 16];\n        a.sqr_512(&mut l);\n        self.reduce_512(&l);\n    }\n\n    pub fn sqr(&self) -> Scalar {\n        let mut ret = Scalar::default();\n        ret.sqr_in_place(self);\n        ret\n    }\n\n    pub fn inv_in_place(&mut self, x: &Scalar) {\n        let u2 = x.sqr();\n        let x2 = u2 * *x;\n        let u5 = u2 * x2;\n        let x3 = u5 * u2;\n        let u9 = x3 * u2;\n        let u11 = u9 * u2;\n        let u13 = u11 * u2;\n\n        let mut x6 = u13.sqr();\n        x6 = x6.sqr();\n        x6 *= &u11;\n\n        let mut x8 = x6.sqr();\n        x8 = x8.sqr();\n        x8 *= &x2;\n\n        let mut x14 = x8.sqr();\n        for _ in 0..5 {\n            x14 = x14.sqr();\n        }\n        x14 *= &x6;\n\n        let mut x28 = x14.sqr();\n        for _ in 0..13 {\n            x28 = x28.sqr();\n        }\n        x28 *= &x14;\n\n        let mut x56 = x28.sqr();\n        for _ in 0..27 {\n            x56 = x56.sqr();\n        }\n        x56 *= &x28;\n\n        let mut x112 = x56.sqr();\n        for _ in 0..55 {\n            x112 = x112.sqr();\n        }\n        x112 *= &x56;\n\n        let mut x126 = x112.sqr();\n        for _ in 0..13 {\n            x126 = x126.sqr();\n        }\n        x126 *= &x14;\n\n        let mut t = x126;\n        for _ in 0..3 {\n            t = t.sqr();\n        }\n        t *= &u5;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &u5;\n        for _ in 0..5 {\n            t = t.sqr();\n        }\n        t *= &u11;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &u11;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..5 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..6 {\n            t = t.sqr();\n        }\n        t *= &u13;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &u5;\n        for _ in 0..3 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..5 {\n            t = t.sqr();\n        }\n        t *= &u9;\n        for _ in 0..6 {\n            t = t.sqr();\n        }\n        t *= &u5;\n        for _ in 0..10 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &x3;\n        for _ in 0..9 {\n            t = t.sqr();\n        }\n        t *= &x8;\n        for _ in 0..5 {\n            t = t.sqr();\n        }\n        t *= &u9;\n        for _ in 0..6 {\n            t = t.sqr();\n        }\n        t *= &u11;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &u13;\n        for _ in 0..5 {\n            t = t.sqr();\n        }\n        t *= &x2;\n        for _ in 0..6 {\n            t = t.sqr();\n        }\n        t *= &u13;\n        for _ in 0..10 {\n            t = t.sqr();\n        }\n        t *= &u13;\n        for _ in 0..4 {\n            t = t.sqr();\n        }\n        t *= &u9;\n        for _ in 0..6 {\n            t = t.sqr();\n        }\n        t *= x;\n        for _ in 0..8 {\n            t = t.sqr();\n        }\n        *self = t * x6;\n    }\n\n    pub fn inv(&self) -> Scalar {\n        let mut ret = Scalar::default();\n        ret.inv_in_place(self);\n        ret\n    }\n\n    pub fn inv_var(&self) -> Scalar {\n        self.inv()\n    }\n\n    pub fn is_even(&self) -> bool {\n        self.0[0] & 1 == 0\n    }\n}\n\nimpl Default for Scalar {\n    fn default() -> Scalar {\n        Scalar([0u32; 8])\n    }\n}\n\nimpl Add<Scalar> for Scalar {\n    type Output = Scalar;\n    fn add(mut self, other: Scalar) -> Scalar {\n        self.add_assign(&other);\n        self\n    }\n}\n\nimpl<'a, 'b> Add<&'a Scalar> for &'b Scalar {\n    type Output = Scalar;\n    fn add(self, other: &'a Scalar) -> Scalar {\n        let mut ret = *self;\n        ret.add_assign(other);\n        ret\n    }\n}\n\nimpl<'a> AddAssign<&'a Scalar> for Scalar {\n    fn add_assign(&mut self, other: &'a Scalar) {\n        let mut t = 0u64;\n\n        unroll! {\n            for i in 0..8 {\n                t += (self.0[i] as u64) + (other.0[i] as u64);\n                self.0[i] = (t & 0xFFFFFFFF) as u32;\n                t >>= 32;\n            }\n        }\n\n        let overflow = self.check_overflow();\n        self.reduce(Choice::from(t as u8) | overflow);\n    }\n}\n\nimpl AddAssign<Scalar> for Scalar {\n    fn add_assign(&mut self, other: Scalar) {\n        self.add_assign(&other)\n    }\n}\n\nimpl Mul<Scalar> for Scalar {\n    type Output = Scalar;\n    fn mul(self, other: Scalar) -> Scalar {\n        let mut ret = Scalar::default();\n        ret.mul_in_place(&self, &other);\n        ret\n    }\n}\n\nimpl<'a, 'b> Mul<&'a Scalar> for &'b Scalar {\n    type Output = Scalar;\n    fn mul(self, other: &'a Scalar) -> Scalar {\n        let mut ret = Scalar::default();\n        ret.mul_in_place(self, other);\n        ret\n    }\n}\n\nimpl<'a> MulAssign<&'a Scalar> for Scalar {\n    fn mul_assign(&mut self, other: &'a Scalar) {\n        let mut ret = Scalar::default();\n        ret.mul_in_place(self, other);\n        *self = ret;\n    }\n}\n\nimpl MulAssign<Scalar> for Scalar {\n    fn mul_assign(&mut self, other: Scalar) {\n        self.mul_assign(&other)\n    }\n}\n\nimpl Neg for Scalar {\n    type Output = Scalar;\n    fn neg(mut self) -> Scalar {\n        self.cond_neg_assign(1.into());\n        self\n    }\n}\n\nimpl<'a> Neg for &'a Scalar {\n    type Output = Scalar;\n    fn neg(self) -> Scalar {\n        let value = *self;\n        -value\n    }\n}\n\nimpl core::fmt::LowerHex for Scalar {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        for word in &self.0[..] {\n            for byte in word.to_be_bytes().iter() {\n                write!(f, \"{:02x}\", byte)?;\n            }\n        }\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "gen/ecmult/Cargo.toml",
    "content": "[package]\nname = \"libsecp256k1-gen-ecmult\"\ndescription = \"Generator function of const_gen for libsecp256k1.\"\nlicense = \"Apache-2.0\"\nversion = \"0.3.0\"\nauthors = [\"Wei Tang <hi@that.world>\"]\nedition = \"2018\"\nrepository = \"https://github.com/paritytech/libsecp256k1\"\nkeywords = [\"crypto\", \"ECDSA\", \"secp256k1\", \"bitcoin\", \"no_std\"]\n\n[dependencies]\nlibsecp256k1-core = { version = \"0.3.0\", path = \"../../core\" }\n"
  },
  {
    "path": "gen/ecmult/src/lib.rs",
    "content": "use libsecp256k1_core::curve::ECMultContext;\nuse std::{\n    fs::File,\n    io::{Error, Write},\n};\n\npub fn generate_to(file: &mut File) -> Result<(), Error> {\n    let context = ECMultContext::new_boxed();\n    let pre_g = context.inspect_raw().as_ref();\n\n    file.write_fmt(format_args!(\"[\"))?;\n    for pg in pre_g {\n        file.write_fmt(\n            format_args!(\n                \"    crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),\",\n                pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],\n                pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]\n            )\n        )?;\n    }\n    file.write_fmt(format_args!(\"]\"))?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "gen/genmult/Cargo.toml",
    "content": "[package]\nname = \"libsecp256k1-gen-genmult\"\ndescription = \"Generator function of const for libsecp256k1.\"\nlicense = \"Apache-2.0\"\nversion = \"0.3.0\"\nauthors = [\"Wei Tang <hi@that.world>\"]\nedition = \"2018\"\nrepository = \"https://github.com/paritytech/libsecp256k1\"\nkeywords = [\"crypto\", \"ECDSA\", \"secp256k1\", \"bitcoin\", \"no_std\"]\n\n[dependencies]\nlibsecp256k1-core = { version = \"0.3.0\", path = \"../../core\" }\n"
  },
  {
    "path": "gen/genmult/src/lib.rs",
    "content": "#![allow(clippy::needless_range_loop)]\n\nuse libsecp256k1_core::curve::ECMultGenContext;\nuse std::{\n    fs::File,\n    io::{Error, Write},\n};\n\npub fn generate_to(file: &mut File) -> Result<(), Error> {\n    let context = ECMultGenContext::new_boxed();\n    let prec = context.inspect_raw().as_ref();\n\n    file.write_fmt(format_args!(\"[\"))?;\n    for j in 0..64 {\n        file.write_fmt(format_args!(\"    [\"))?;\n        for i in 0..16 {\n            let pg = prec[j][i];\n            file.write_fmt(format_args!(\n                \"        crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),\",\n                pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],\n                pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]\n            ))?;\n        }\n        file.write_fmt(format_args!(\"    ],\"))?;\n    }\n    file.write_fmt(format_args!(\"]\"))?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "res/ecdsa_secp256k1_sha256_test.json",
    "content": "{\n  \"algorithm\" : \"ECDSA\",\n  \"generatorVersion\" : \"0.8r12\",\n  \"numberOfTests\" : 380,\n  \"header\" : [\n    \"Test vectors of type EcdsaVerify are meant for the verification\",\n    \"of ASN encoded ECDSA signatures.\"\n  ],\n  \"notes\" : {\n    \"BER\" : \"This is a signature with correct values for (r, s) but using some alternative BER encoding instead of DER encoding. Implementations should not accept such signatures to limit signature malleability.\",\n    \"EdgeCase\" : \"Edge case values such as r=1 and s=0 can lead to forgeries if the ECDSA implementation does not check boundaries and computes s^(-1)==0.\",\n    \"MissingZero\" : \"Some implementations of ECDSA and DSA incorrectly encode r and s by not including leading zeros in the ASN encoding of integers when necessary. Hence, some implementations (e.g. jdk) allow signatures with incorrect ASN encodings assuming that the signature is otherwise valid.\",\n    \"PointDuplication\" : \"Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.\"\n  },\n  \"schema\" : \"ecdsa_verify_schema.json\",\n  \"testGroups\" : [\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9\",\n        \"wx\" : \"00b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6f\",\n        \"wy\" : \"00f0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEuDj/ROW8F3vyEYnQdmCC/J2EMiaIf8l2\\nA3EQC37iCm/wyddb+6ezGmvKGXRJbutW3jVwcZVdg8Sxutqgshgy6Q==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 1,\n          \"comment\" : \"signature malleability\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647db37c21f4afd3203ae8dc4ae7794b0f87\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 2,\n          \"comment\" : \"Legacy:ASN encoding of r misses leading 0\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30440220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"acceptable\",\n          \"flags\" : [\n            \"MissingZero\"\n          ]\n        },\n        {\n          \"tcId\" : 3,\n          \"comment\" : \"valid\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 4,\n          \"comment\" : \"long form encoding of length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"308145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 5,\n          \"comment\" : \"length of sequence contains leading 0\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30820045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 6,\n          \"comment\" : \"wrong length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 7,\n          \"comment\" : \"wrong length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 8,\n          \"comment\" : \"uint32 overflow in length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30850100000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 9,\n          \"comment\" : \"uint64 overflow in length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3089010000000000000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 10,\n          \"comment\" : \"length of sequence = 2**31 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30847fffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 11,\n          \"comment\" : \"length of sequence = 2**32 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3084ffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 12,\n          \"comment\" : \"length of sequence = 2**40 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3085ffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 13,\n          \"comment\" : \"length of sequence = 2**64 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3088ffffffffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 14,\n          \"comment\" : \"incorrect length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30ff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 15,\n          \"comment\" : \"indefinite length without termination\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 16,\n          \"comment\" : \"indefinite length without termination\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045028000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 17,\n          \"comment\" : \"indefinite length without termination\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502806ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 18,\n          \"comment\" : \"removing sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 19,\n          \"comment\" : \"lonely sequence tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 20,\n          \"comment\" : \"appending 0's to sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 21,\n          \"comment\" : \"prepending 0's to sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30470000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 22,\n          \"comment\" : \"appending unused 0's to sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 23,\n          \"comment\" : \"appending null value to sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 24,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a4981773045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 25,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304925003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 26,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 27,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a2226498177022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 28,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304922252500022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 29,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d2223022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650004deadbeef02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 30,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222549817702206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 31,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652224250002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 32,\n          \"comment\" : \"including garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 33,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304daa00bb00cd003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 34,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304baa02aabb3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 35,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d2229aa00bb00cd00022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 36,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304b2227aa02aabb022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 37,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652228aa00bb00cd0002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 38,\n          \"comment\" : \"including undefined tags\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304b022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652226aa02aabb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 39,\n          \"comment\" : \"truncated length of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3081\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 40,\n          \"comment\" : \"using composition with indefinite length\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30803045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 41,\n          \"comment\" : \"using composition with indefinite length\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30492280022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 42,\n          \"comment\" : \"using composition with indefinite length\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 43,\n          \"comment\" : \"using composition with wrong tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30803145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 44,\n          \"comment\" : \"using composition with wrong tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30492280032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 45,\n          \"comment\" : \"using composition with wrong tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228003206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 46,\n          \"comment\" : \"Replacing sequence with NULL\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"0500\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 47,\n          \"comment\" : \"changing tag value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"2e45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 48,\n          \"comment\" : \"changing tag value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"2f45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 49,\n          \"comment\" : \"changing tag value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 50,\n          \"comment\" : \"changing tag value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3245022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 51,\n          \"comment\" : \"changing tag value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"ff45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 52,\n          \"comment\" : \"dropping value of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 53,\n          \"comment\" : \"using composition for sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304930010230442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 54,\n          \"comment\" : \"truncated sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 55,\n          \"comment\" : \"truncated sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 56,\n          \"comment\" : \"indefinite length\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 57,\n          \"comment\" : \"indefinite length with truncated delimiter\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba00\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 58,\n          \"comment\" : \"indefinite length with additional element\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba05000000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 59,\n          \"comment\" : \"indefinite length with truncated element\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba060811220000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 60,\n          \"comment\" : \"indefinite length with garbage\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000fe02beef\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 61,\n          \"comment\" : \"indefinite length with nonempty EOC\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0002beef\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 62,\n          \"comment\" : \"prepend empty sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30473000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 63,\n          \"comment\" : \"append empty sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba3000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 64,\n          \"comment\" : \"append garbage with high tag number\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31babf7f00\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 65,\n          \"comment\" : \"sequence of sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 66,\n          \"comment\" : \"truncated sequence: removed last 1 elements\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3023022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 67,\n          \"comment\" : \"repeating element in sequence\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3067022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 68,\n          \"comment\" : \"long form encoding of length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304602812100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 69,\n          \"comment\" : \"long form encoding of length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 70,\n          \"comment\" : \"length of integer contains leading 0\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30470282002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 71,\n          \"comment\" : \"length of integer contains leading 0\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028200206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 72,\n          \"comment\" : \"wrong length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 73,\n          \"comment\" : \"wrong length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 74,\n          \"comment\" : \"wrong length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 75,\n          \"comment\" : \"wrong length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 76,\n          \"comment\" : \"uint32 overflow in length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a0285010000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 77,\n          \"comment\" : \"uint32 overflow in length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028501000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 78,\n          \"comment\" : \"uint64 overflow in length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304e028901000000000000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 79,\n          \"comment\" : \"uint64 overflow in length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304e022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502890100000000000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 80,\n          \"comment\" : \"length of integer = 2**31 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304902847fffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 81,\n          \"comment\" : \"length of integer = 2**31 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502847fffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 82,\n          \"comment\" : \"length of integer = 2**32 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30490284ffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 83,\n          \"comment\" : \"length of integer = 2**32 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284ffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 84,\n          \"comment\" : \"length of integer = 2**40 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a0285ffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 85,\n          \"comment\" : \"length of integer = 2**40 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650285ffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 86,\n          \"comment\" : \"length of integer = 2**64 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d0288ffffffffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 87,\n          \"comment\" : \"length of integer = 2**64 - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650288ffffffffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 88,\n          \"comment\" : \"incorrect length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 89,\n          \"comment\" : \"incorrect length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 90,\n          \"comment\" : \"removing integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"302202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 91,\n          \"comment\" : \"lonely integer tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30230202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 92,\n          \"comment\" : \"lonely integer tag\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3024022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 93,\n          \"comment\" : \"appending 0's to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 94,\n          \"comment\" : \"appending 0's to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 95,\n          \"comment\" : \"prepending 0's to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30470223000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 96,\n          \"comment\" : \"prepending 0's to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022200006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"BER\"\n          ]\n        },\n        {\n          \"tcId\" : 97,\n          \"comment\" : \"appending unused 0's to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 98,\n          \"comment\" : \"appending null value to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 99,\n          \"comment\" : \"appending null value to integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 100,\n          \"comment\" : \"truncated length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3024028102206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 101,\n          \"comment\" : \"truncated length of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 102,\n          \"comment\" : \"Replacing integer with NULL\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3024050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 103,\n          \"comment\" : \"Replacing integer with NULL\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650500\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 104,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 105,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045012100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 106,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 107,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045042100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 108,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045ff2100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 109,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236500206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 110,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236501206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 111,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236503206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 112,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236504206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 113,\n          \"comment\" : \"changing tag value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365ff206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 114,\n          \"comment\" : \"dropping value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3024020002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 115,\n          \"comment\" : \"dropping value of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650200\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 116,\n          \"comment\" : \"using composition for integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304922250201000220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 117,\n          \"comment\" : \"using composition for integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222402016f021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 118,\n          \"comment\" : \"modify first byte of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022102813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 119,\n          \"comment\" : \"modify first byte of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206df18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 120,\n          \"comment\" : \"modify last byte of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323e502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 121,\n          \"comment\" : \"modify last byte of integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb313a\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 122,\n          \"comment\" : \"truncated integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832302206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 123,\n          \"comment\" : \"truncated integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 124,\n          \"comment\" : \"truncated integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 125,\n          \"comment\" : \"leading ff in integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30460222ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 126,\n          \"comment\" : \"leading ff in integer\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 127,\n          \"comment\" : \"replaced integer by infinity\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"302509018002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 128,\n          \"comment\" : \"replaced integer by infinity\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365090180\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 129,\n          \"comment\" : \"replacing integer with zero\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"302502010002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 130,\n          \"comment\" : \"replacing integer with zero\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 131,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022101813ef79ccefa9a56f7ba805f0e478583b90deabca4b05c4574e49b5899b964a602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 132,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30440220813ef79ccefa9a56f7ba805f0e47858643b030ef461f1bcdf53fde3ef94ce22402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 133,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30450221ff7ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 134,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ec10863310565a908457fa0f1b87a79bc4fcf10b9e0e4320ac021c106b31ddc02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 135,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30450221fe7ec10863310565a908457fa0f1b87a7c46f215435b4fa3ba8b1b64a766469b5a02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 136,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022101813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 137,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 138,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221016ff18a52dcc0336f7af62400a6dd9b7fc1e197d8aebe203c96c87232272172fb\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 139,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b824c83de0b502cdfc51723b51886b4f079\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 140,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650220900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce46\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 141,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221fe900e75ad233fcc908509dbff592264803e1e68275141dfc369378dcdd8de8d05\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 142,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221016ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 143,\n          \"comment\" : \"Modified r or s, e.g. by adding or subtracting the order of the group\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce46\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 144,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020100020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 145,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020100020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 146,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201000201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 147,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 148,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 149,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 150,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 151,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 152,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3008020100090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 153,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020100090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 154,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 155,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 156,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201010201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 157,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 158,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 159,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 160,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 161,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 162,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3008020101090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 163,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 164,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201ff020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 165,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201ff020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 166,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201ff0201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 167,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 168,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 169,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 170,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 171,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 172,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30080201ff090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 173,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201ff090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 174,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 175,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 176,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 177,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 178,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 179,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 180,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 181,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 182,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 183,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 184,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 185,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 186,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641400201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 187,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 188,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 189,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 190,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 191,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 192,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 193,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 194,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 195,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 196,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641420201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 197,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 198,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 199,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 200,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 201,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 202,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 203,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 204,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 205,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 206,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 207,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 208,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 209,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 210,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 211,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 212,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 213,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 214,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 215,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 216,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc300201ff\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 217,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 218,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 219,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 220,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 221,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 222,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30090380fe01\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 223,\n          \"comment\" : \"Signature with special case values for r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30090142\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"EdgeCase\"\n          ]\n        },\n        {\n          \"tcId\" : 224,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30060201010c0130\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 225,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30050201010c00\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 226,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30090c0225730c03732573\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 227,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30080201013003020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 228,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3003020101\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 229,\n          \"comment\" : \"Signature encoding contains wrong types.\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101010100\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 230,\n          \"comment\" : \"Edge case for Shamir multiplication\",\n          \"msg\" : \"3235353835\",\n          \"sig\" : \"3045022100dd1b7d09a7bd8218961034a39a87fecf5314f00c4d25eb58a07ac85e85eab516022035138c401ef8d3493d65c9002fe62b43aee568731b744548358996d9cc427e06\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 231,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"343236343739373234\",\n          \"sig\" : \"304502210095c29267d972a043d955224546222bba343fc1d4db0fec262a33ac61305696ae02206edfe96713aed56f8a28a6653f57e0b829712e5eddc67f34682b24f0676b2640\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 232,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"37313338363834383931\",\n          \"sig\" : \"3045022028f94a894e92024699e345fe66971e3edcd050023386135ab3939d550898fb25022100cd69c1a42be05a6ee1270c821479251e134c21858d800bda6f4e98b37196238e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 233,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3130333539333331363638\",\n          \"sig\" : \"3046022100be26b18f9549f89f411a9b52536b15aa270b84548d0e859a1952a27af1a77ac60221008f3e2b05632fc33715572af9124681113f2b84325b80154c044a544dc1a8fa12\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 234,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33393439343031323135\",\n          \"sig\" : \"3046022100b1a4b1478e65cc3eafdf225d1298b43f2da19e4bcff7eacc0a2e98cd4b74b114022100e8655ce1cfb33ebd30af8ce8e8ae4d6f7b50cd3e22af51bf69e0a2851760d52b\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 235,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31333434323933303739\",\n          \"sig\" : \"30440220325332021261f1bd18f2712aa1e2252da23796da8a4b1ff6ea18cafec7e171f2022040b4f5e287ee61fc3c804186982360891eaa35c75f05a43ecd48b35d984a6648\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 236,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33373036323131373132\",\n          \"sig\" : \"3046022100a23ad18d8fc66d81af0903890cbd453a554cb04cdc1a8ca7f7f78e5367ed88a0022100dc1c14d31e3fb158b73c764268c8b55579734a7e2a2c9b5ee5d9d0144ef652eb\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 237,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"333433363838373132\",\n          \"sig\" : \"304502202bdea41cda63a2d14bf47353bd20880a690901de7cd6e3cc6d8ed5ba0cdb1091022100c31599433036064073835b1e3eba8335a650c8fd786f94fe235ad7d41dc94c7a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 238,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31333531353330333730\",\n          \"sig\" : \"3046022100d7cd76ec01c1b1079eba9e2aa2a397243c4758c98a1ba0b7404a340b9b00ced6022100ca8affe1e626dd192174c2937b15bc48f77b5bdfe01f073a8aeaf7f24dc6c85b\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 239,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"36353533323033313236\",\n          \"sig\" : \"3045022100a872c744d936db21a10c361dd5c9063355f84902219652f6fc56dc95a7139d960220400df7575d9756210e9ccc77162c6b593c7746cfb48ac263c42750b421ef4bb9\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 240,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31353634333436363033\",\n          \"sig\" : \"30460221009fa9afe07752da10b36d3afcd0fe44bfc40244d75203599cf8f5047fa3453854022100af1f583fec4040ae7e68c968d2bb4b494eec3a33edc7c0ccf95f7f75bc2569c7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 241,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"34343239353339313137\",\n          \"sig\" : \"3045022100885640384d0d910efb177b46be6c3dc5cac81f0b88c3190bb6b5f99c2641f2050220738ed9bff116306d9caa0f8fc608be243e0b567779d8dab03e8e19d553f1dc8e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 242,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3130393533323631333531\",\n          \"sig\" : \"304502202d051f91c5a9d440c5676985710483bc4f1a6c611b10c95a2ff0363d90c2a45802210092206b19045a41a797cc2f3ac30de9518165e96d5b86341ecb3bcff231b3fd65\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 243,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"35393837333530303431\",\n          \"sig\" : \"3045022100f3ac2523967482f53d508522712d583f4379cd824101ff635ea0935117baa54f022027f10812227397e02cea96fb0e680761636dab2b080d1fc5d11685cbe8500cfe\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 244,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33343633303036383738\",\n          \"sig\" : \"304602210096447cf68c3ab7266ed7447de3ac52fed7cc08cbdfea391c18a9b8ab370bc913022100f0a1878b2c53f16e70fe377a5e9c6e86f18ae480a22bb499f5b32e7109c07385\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 245,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"39383137333230323837\",\n          \"sig\" : \"30450220530a0832b691da0b5619a0b11de6877f3c0971baaa68ed122758c29caaf46b7202210093761bb0a14ccf9f15b4b9ce73c6ec700bd015b8cb1cfac56837f4463f53074e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 246,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33323232303431303436\",\n          \"sig\" : \"30460221009c54c25500bde0b92d72d6ec483dc2482f3654294ca74de796b681255ed58a77022100988bac394a90ad89ce360984c0c149dcbd2684bb64498ace90bcf6b6af1c170e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 247,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"36363636333037313034\",\n          \"sig\" : \"3045022100e7909d41439e2f6af29136c7348ca2641a2b070d5b64f91ea9da7070c7a2618b022042d782f132fa1d36c2c88ba27c3d678d80184a5d1eccac7501f0b47e3d205008\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 248,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31303335393531383938\",\n          \"sig\" : \"304502205924873209593135a4c3da7bb381227f8a4b6aa9f34fe5bb7f8fbc131a039ffe022100e0e44ee4bbe370155bf0bbdec265bf9fe31c0746faab446de62e3631eacd111f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 249,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31383436353937313935\",\n          \"sig\" : \"3045022100eeb692c9b262969b231c38b5a7f60649e0c875cd64df88f33aa571fa3d29ab0e0220218b3a1eb06379c2c18cf51b06430786d1c64cd2d24c9b232b23e5bac7989acd\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 250,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33313336303436313839\",\n          \"sig\" : \"3045022100a40034177f36091c2b653684a0e3eb5d4bff18e4d09f664c2800e7cafda1daf802203a3ec29853704e52031c58927a800a968353adc3d973beba9172cbbeab4dd149\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 251,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"32363633373834323534\",\n          \"sig\" : \"3046022100b5d795cc75cea5c434fa4185180cd6bd21223f3d5a86da6670d71d95680dadbf022100ab1b277ef5ffe134460835e3d1402461ba104cb50b16f397fdc7a9abfefef280\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 252,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31363532313030353234\",\n          \"sig\" : \"3044022007dc2478d43c1232a4595608c64426c35510051a631ae6a5a6eb1161e57e42e102204a59ea0fdb72d12165cea3bf1ca86ba97517bd188db3dbd21a5a157850021984\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 253,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"35373438303831363936\",\n          \"sig\" : \"3046022100ddd20c4a05596ca868b558839fce9f6511ddd83d1ccb53f82e5269d559a01552022100a46e8cb8d626cf6c00ddedc3b5da7e613ac376445ee260743f06f79054c7d42a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 254,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"36333433393133343638\",\n          \"sig\" : \"30450221009cde6e0ede0a003f02fda0a01b59facfe5dec063318f279ce2de7a9b1062f7b702202886a5b8c679bdf8224c66f908fd6205492cb70b0068d46ae4f33a4149b12a52\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 255,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31353431313033353938\",\n          \"sig\" : \"3046022100c5771016d0dd6357143c89f684cd740423502554c0c59aa8c99584f1ff38f609022100ab4bfa0bb88ab99791b9b3ab9c4b02bd2a57ae8dde50b9064063fcf85315cfe5\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 256,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3130343738353830313238\",\n          \"sig\" : \"3045022100a24ebc0ec224bd67ae397cbe6fa37b3125adbd34891abe2d7c7356921916dfe6022034f6eb6374731bbbafc4924fb8b0bdcdda49456d724cdae6178d87014cb53d8c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 257,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3130353336323835353638\",\n          \"sig\" : \"304502202557d64a7aee2e0931c012e4fea1cd3a2c334edae68cdeb7158caf21b68e5a2402210080f93244956ffdc568c77d12684f7f004fa92da7e60ae94a1b98c422e23eda34\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 258,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"393533393034313035\",\n          \"sig\" : \"3046022100c4f2eccbb6a24350c8466450b9d61b207ee359e037b3dcedb42a3f2e6dd6aeb5022100cd9c394a65d0aa322e391eb76b2a1a687f8620a88adef3a01eb8e4fb05b6477a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 259,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"393738383438303339\",\n          \"sig\" : \"3046022100eff04781c9cbcd162d0a25a6e2ebcca43506c523385cb515d49ea38a1b12fcad022100ea5328ce6b36e56ab87acb0dcfea498bcec1bba86a065268f6eff3c41c4b0c9c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 260,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33363130363732343432\",\n          \"sig\" : \"3046022100f58b4e3110a64bf1b5db97639ee0e5a9c8dfa49dc59b679891f520fdf0584c87022100d32701ae777511624c1f8abbf02b248b04e7a9eb27938f524f3e8828ba40164a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 261,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31303534323430373035\",\n          \"sig\" : \"3045022100f8abecaa4f0c502de4bf5903d48417f786bf92e8ad72fec0bd7fcb7800c0bbe302204c7f9e231076a30b7ae36b0cebe69ccef1cd194f7cce93a5588fd6814f437c0e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 262,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"35313734343438313937\",\n          \"sig\" : \"304402205d5b38bd37ad498b2227a633268a8cca879a5c7c94a4e416bd0a614d09e606d2022012b8d664ea9991062ecbb834e58400e25c46007af84f6007d7f1685443269afe\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 263,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31393637353631323531\",\n          \"sig\" : \"304402200c1cd9fe4034f086a2b52d65b9d3834d72aebe7f33dfe8f976da82648177d8e3022013105782e3d0cfe85c2778dec1a848b27ac0ae071aa6da341a9553a946b41e59\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 264,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33343437323533333433\",\n          \"sig\" : \"3045022100ae7935fb96ff246b7b5d5662870d1ba587b03d6e1360baf47988b5c02ccc1a5b02205f00c323272083782d4a59f2dfd65e49de0693627016900ef7e61428056664b3\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 265,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"333638323634333138\",\n          \"sig\" : \"3045022000a134b5c6ccbcefd4c882b945baeb4933444172795fa6796aae149067547098022100a991b9efa2db276feae1c115c140770901839d87e60e7ec45a2b81cf3b437be6\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 266,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33323631313938363038\",\n          \"sig\" : \"304502202e4721363ad3992c139e5a1c26395d2c2d777824aa24fde075e0d7381171309d0221008bf083b6bbe71ecff22baed087d5a77eaeaf726bf14ace2c03fd6e37ba6c26f2\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 267,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"39363738373831303934\",\n          \"sig\" : \"304502206852e9d3cd9fe373c2d504877967d365ab1456707b6817a042864694e1960ccf022100f9b4d815ebd4cf77847b37952334d05b2045cb398d4c21ba207922a7a4714d84\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 268,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"34393538383233383233\",\n          \"sig\" : \"30440220188a8c5648dc79eace158cf886c62b5468f05fd95f03a7635c5b4c31f09af4c5022036361a0b571a00c6cd5e686ccbfcfa703c4f97e48938346d0c103fdc76dc5867\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 269,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"383234363337383337\",\n          \"sig\" : \"3045022100a74f1fb9a8263f62fc4416a5b7d584f4206f3996bb91f6fc8e73b9e92bad0e1302206815032e8c7d76c3ab06a86f33249ce9940148cb36d1f417c2e992e801afa3fa\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 270,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3131303230383333373736\",\n          \"sig\" : \"3045022007244865b72ff37e62e3146f0dc14682badd7197799135f0b00ade7671742bfe022100f27f3ddc7124b1b58579573a835650e7a8bad5eeb96e9da215cd7bf9a2a039ed\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 271,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"313333383731363438\",\n          \"sig\" : \"3045022100da7fdd05b5badabd619d805c4ee7d9a84f84ddd5cf9c5bf4d4338140d689ef08022028f1cf4fa1c3c5862cfa149c0013cf5fe6cf5076cae000511063e7de25bb38e5\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 272,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"333232313434313632\",\n          \"sig\" : \"3046022100d3027c656f6d4fdfd8ede22093e3c303b0133c340d615e7756f6253aea927238022100f6510f9f371b31068d68bfeeaa720eb9bbdc8040145fcf88d4e0b58de0777d2a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 273,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3130363836363535353436\",\n          \"sig\" : \"304402200bf6c0188dc9571cd0e21eecac5fbb19d2434988e9cc10244593ef3a98099f6902204864a562661f9221ec88e3dd0bc2f6e27ac128c30cc1a80f79ec670a22b042ee\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 274,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"3632313535323436\",\n          \"sig\" : \"3045022100ae459640d5d1179be47a47fa538e16d94ddea5585e7a244804a51742c686443a02206c8e30e530a634fae80b3ceb062978b39edbe19777e0a24553b68886181fd897\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 275,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"37303330383138373734\",\n          \"sig\" : \"304402201cf3517ba3bf2ab8b9ead4ebb6e866cb88a1deacb6a785d3b63b483ca02ac4950220249a798b73606f55f5f1c70de67cb1a0cff95d7dc50b3a617df861bad3c6b1c9\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 276,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"35393234353233373434\",\n          \"sig\" : \"3045022100e69b5238265ea35d77e4dd172288d8cea19810a10292617d5976519dc5757cb802204b03c5bc47e826bdb27328abd38d3056d77476b2130f3df6ec4891af08ba1e29\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 277,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31343935353836363231\",\n          \"sig\" : \"304402205f9d7d7c870d085fc1d49fff69e4a275812800d2cf8973e7325866cb40fa2b6f02206d1f5491d9f717a597a15fd540406486d76a44697b3f0d9d6dcef6669f8a0a56\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 278,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"34303035333134343036\",\n          \"sig\" : \"304402200a7d5b1959f71df9f817146ee49bd5c89b431e7993e2fdecab6858957da685ae02200f8aad2d254690bdc13f34a4fec44a02fd745a422df05ccbb54635a8b86b9609\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 279,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"33303936343537353132\",\n          \"sig\" : \"3044022079e88bf576b74bc07ca142395fda28f03d3d5e640b0b4ff0752c6d94cd553408022032cea05bd2d706c8f6036a507e2ab7766004f0904e2e5c5862749c0073245d6a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 280,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"32373834303235363230\",\n          \"sig\" : \"30450221009d54e037a00212b377bc8874798b8da080564bbdf7e07591b861285809d01488022018b4e557667a82bd95965f0706f81a29243fbdd86968a7ebeb43069db3b18c7f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 281,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"32363138373837343138\",\n          \"sig\" : \"304402202664f1ffa982fedbcc7cab1b8bc6e2cb420218d2a6077ad08e591ba9feab33bd022049f5c7cb515e83872a3d41b4cdb85f242ad9d61a5bfc01debfbb52c6c84ba728\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 282,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"31363432363235323632\",\n          \"sig\" : \"304502205827518344844fd6a7de73cbb0a6befdea7b13d2dee4475317f0f18ffc81524b022100b0a334b1f4b774a5a289f553224d286d239ef8a90929ed2d91423e024eb7fa66\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 283,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"36383234313839343336\",\n          \"sig\" : \"304602210097ab19bd139cac319325869218b1bce111875d63fb12098a04b0cd59b6fdd3a3022100bce26315c5dbc7b8cfc31425a9b89bccea7aa9477d711a4d377f833dcc28f820\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 284,\n          \"comment\" : \"special case hash\",\n          \"msg\" : \"343834323435343235\",\n          \"sig\" : \"3044022052c683144e44119ae2013749d4964ef67509278f6d38ba869adcfa69970e123d02203479910167408f45bda420a626ec9c4ec711c1274be092198b4187c018b562ca\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0\",\n        \"wx\" : \"07310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc362\",\n        \"wy\" : \"26a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEBzEPkKnq4UmghAL1QZSg97SsQnv42b1s\\ndoEHHcR9w2ImptN6xG1h/WAMC/G/+HaJ7RF92msOWTGK4BChl6JsoA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 285,\n          \"comment\" : \"k*G has a large x-coordinate\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"30360211014551231950b75fc4402da1722fc9baeb022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 286,\n          \"comment\" : \"r too large\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5\",\n        \"wx\" : \"00bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22\",\n        \"wy\" : \"705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvJfnWF7srUjhZoO8QJFwjhqTDGg/xHAB\\n1LODWU8sTiJwWYnPadrq3U5OS4FR7YiN/sIPsBco2J1Ws/OPKunIxQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 287,\n          \"comment\" : \"r,s are large\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463\",\n        \"wx\" : \"44ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252\",\n        \"wy\" : \"00b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERK0zmvvCHpq/e2AqXKU16jeBNbbRDYEx\\nC92Ck9HfMlK2P/fQd0dw+P4dFyL6g6zQL0NOT8EQoMyPbd3TfVbEYw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 288,\n          \"comment\" : \"r and s^-1 have a large Hamming weight\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e9a7582886089c62fb840cf3b83061cd1cff3ae4341808bb5bdee6191174177\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0\",\n        \"wx\" : \"1260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c\",\n        \"wy\" : \"5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEmDCEiyeJE4a9RUb7eDDriO1TXxZaIHT\\n7rrSHzfdh4xcmgwamt52c3qIEb1qf5KHyXjuOWqonBHkcinSzLVS8A==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 289,\n          \"comment\" : \"r and s^-1 have a large Hamming weight\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022024238e70b431b1a64efdf9032669939d4b77f249503fc6905feb7540dea3e6d2\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159\",\n        \"wx\" : \"1877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce\",\n        \"wy\" : \"00821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGHcEW+JdNKHQYA+dXADQZFoqVDebbO76\\n0ua/XCozUs6CGlMswXUe4dNtQcPWq06bFD5E7EbXNHjqanmlwOVBWQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 290,\n          \"comment\" : \"small r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101020101\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77\",\n        \"wx\" : \"455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50\",\n        \"wy\" : \"00aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERVQ5/MPS3uzt3q7OYOe9FzBPNuu2Aq31\\noi4Ljx20alCuw4+yuvIh6ajRiHx79iIt0YNGNOdyYzFa9tI2CdBPdw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 291,\n          \"comment\" : \"small r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101020102\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d\",\n        \"wx\" : \"2e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece718\",\n        \"wy\" : \"0449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELh9GawJMDDrOJDfeCRJ/7QS3BvlLGaIb\\nscKs81zs5xgESa41I9clNOlklyz9OzivC93ZYZ5a8iPk0aQPNM+fHQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 292,\n          \"comment\" : \"small r and s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3006020101020103\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 293,\n          \"comment\" : \"r is larger than n\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020103\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04dda95d7b0698de5d2d0b4f0034dbe35b50f978fcc518a84abf9c99efd96a25305adc08d6a63dbe831ab99cd9146e3c4c45492ad19521612542256d6af60e7888\",\n        \"wx\" : \"00dda95d7b0698de5d2d0b4f0034dbe35b50f978fcc518a84abf9c99efd96a2530\",\n        \"wy\" : \"5adc08d6a63dbe831ab99cd9146e3c4c45492ad19521612542256d6af60e7888\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004dda95d7b0698de5d2d0b4f0034dbe35b50f978fcc518a84abf9c99efd96a25305adc08d6a63dbe831ab99cd9146e3c4c45492ad19521612542256d6af60e7888\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE3aldewaY3l0tC08ANNvjW1D5ePzFGKhK\\nv5yZ79lqJTBa3AjWpj2+gxq5nNkUbjxMRUkq0ZUhYSVCJW1q9g54iA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 294,\n          \"comment\" : \"s is larger than n\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd04917c8\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866\",\n        \"wx\" : \"02ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee77\",\n        \"wy\" : \"7eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAu9NbWz9WpTx13hCJuPipsCkNsVYOWGf\\nOPtEcrX57nd+tKzU7r2lzXKHX/0qLyYinC3GtGUAkZpDLIZznzroZg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 295,\n          \"comment\" : \"small r and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"302702020101022100c58b162c58b162c58b162c58b162c58a1b242973853e16db75c8a1a71da4d39d\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08\",\n        \"wx\" : \"464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584\",\n        \"wy\" : \"00b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERk9P9xVynK5Qcso72AHTGVtnrsZemwGq\\n0gopQ9y8tYSxr9KdMaOaEdVwqhWXQ5s7LRlxvy8avxVDLQIHsQ0dCA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 296,\n          \"comment\" : \"smallish r and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"302c02072d9b4d347952cc022100fcbc5103d0da267477d1791461cf2aa44bf9d43198f79507bd8779d69a13108e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f\",\n        \"wx\" : \"157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4c\",\n        \"wy\" : \"00deadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFX+P3fNz619Jz88Q2LhTz5HLzX1mXDUi\\nun3XON23mkzerfGlxEjqPJ9BkaiZmr/MdXrG1kVn7wcsR/7GE0Q7jw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 297,\n          \"comment\" : \"100-bit r and small s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3032020d1033e67e37b32b445580bf4efc022100906f906f906f906f906f906f906f906ed8e426f7b1968c35a204236a579723d2\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa\",\n        \"wx\" : \"0934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0\",\n        \"wy\" : \"00d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECTSlN0ZsB0MOLEj+uZC7Gft4zsyc7kJO\\npNEwKRqiN/DU+S0jtGKAS1toxSVYwByZltv3J/zKu+7bliGkAFNa+g==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 298,\n          \"comment\" : \"small r and 100 bit s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3026020201010220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265\",\n        \"wx\" : \"00d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c65\",\n        \"wy\" : \"4a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1u8gvmbIk/dBqb+Q2bdGddHCoxKWOXrL\\nPvF0/QswDGVKDJVHjKADmRYtfw8tyJ79wrKKMPur4oWFcpWksMTiZQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 299,\n          \"comment\" : \"100-bit r and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3031020d062522bbd3ecbe7c39e93e7c260220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829\",\n        \"wx\" : \"00b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee06\",\n        \"wy\" : \"29c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtykdFATgwMB9q5NyGJ9L1Y0s6qjRXt5U\\nTZUUVFup7gYpyaY9XjCHacww7CdqQQ5kZKJ+6v2eWZ2xDwU6T+SoKQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 300,\n          \"comment\" : \"r and s^-1 are close to n\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640c1022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677\",\n        \"wx\" : \"00bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c\",\n        \"wy\" : \"1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEu3n2GFf3Q7+htucRHOQJQ3claWnk4VFZ\\nEj2VSKzDvmwfnZ+IYNz/0+s23Wwx/y5yJsIAnEyU2NfStWhr96vWdw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 301,\n          \"comment\" : \"s == 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020101\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 302,\n          \"comment\" : \"s == 0\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020100\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4\",\n        \"wx\" : \"00d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b4150874\",\n        \"wy\" : \"01b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1TO3iaSviQ+nqCofrljEBPmmKlC0mtr6\\ns0nFE7QVCHQBtBcbgD52s0qYYeEPe8KJoGb9Ab0p+EyYehCl+xjC1A==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 303,\n          \"comment\" : \"point at infinity during verify\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a\",\n        \"wx\" : \"3a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4\",\n        \"wy\" : \"221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOjFQeYyK9p0ebpgfOkVAK6HXMvS+gzDF\\nFk9J4Q7FVbQiG9hCvF5Nl+/zcWX2DjmYpCTXKkUM+V6kd8eCh9A0Og==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 304,\n          \"comment\" : \"edge case for signature malleability\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026\",\n        \"wx\" : \"3b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e80\",\n        \"wy\" : \"0de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOzffX7NHxpoPF9hcDHyoNzaIOoJeExQ9\\nD8/IEB6FHoAN48CQtsohulQ1FzMMBLEvlIxrrfFKY6v/3074x1NwJg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 305,\n          \"comment\" : \"edge case for signature malleability\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e\",\n        \"wx\" : \"00feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82c\",\n        \"wy\" : \"00e87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/rUWOw7OMP8+A8fVXEOA+i+oHuLANUlC\\n/28IyZ0M2CzofeBe4b2gidPk4kj6D3IRAqz//fUOZUvigUM5md+Jfg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 306,\n          \"comment\" : \"u1 == 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca605023\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2\",\n        \"wx\" : \"238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd4149228976\",\n        \"wy\" : \"40683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEI4ztABzyK4hT4C7cicvspQULp+BCp6d/\\nk4LNQUkiiXZAaD0wlGQ4QPKViQqkwYqjm0HXfdD7O7JwDk+ewoT/wg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 307,\n          \"comment\" : \"u1 == n - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf\",\n        \"wx\" : \"00961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35e\",\n        \"wy\" : \"00d2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElhz2SBfAbA5Rs8JzbJIv3hi9jEkG/Nf1\\n72bEZ4UI817SxdGBaM++cPLxI710GSMruS3WkRPilBBhiJSBxaAnvw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 308,\n          \"comment\" : \"u2 == 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384\",\n        \"wx\" : \"13681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b10288\",\n        \"wy\" : \"16528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE2gerhaM1Op88uKkXQUnQtEKn2TnloZ9\\nvcuCn+CxAogWUodg0Xc3bAnfed45VXwynMF1NRes/+j6LsKYAmuDhA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 309,\n          \"comment\" : \"u2 == n - 1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b89\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b\",\n        \"wx\" : \"5aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c2\",\n        \"wy\" : \"0091c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWqer/ba0CG1UMyXl15xulc5C+GbSu4SQ\\nljOgS7GqMcKRyACIeUkF4dozM22HTi+RzPRcxZGFvt5d1vP3rKrhiw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 310,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100e91e1ba6ba898620a46bcb51dc0b8b4ad1dc35dad892c4552d1847b2ce444637\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41\",\n        \"wx\" : \"277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e4\",\n        \"wy\" : \"64108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEACd3kbMFpFsrOVkLLwXTOSpsgYLO9OtU\\nASDg9cIGw+RkEIIz+wuMOsiS15744Pv5LtEzrdtFVCcBMlhNxS7vQQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 311,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100e36bf0cec06d9b841da81332812f74f30bbaec9f202319206c6f0b8a0a400ff7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49\",\n        \"wx\" : \"6efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1a\",\n        \"wy\" : \"00c75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbvoJK2jelGDwvMkZAFpfboDhnemJaL48\\n0sdwqZSb+xrHXm5Qh9ZVDV+b6x555QKTB7wlUjXi1dyZJBrDq4hsSQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 312,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100ea26b57af884b6c06e348efe139c1e4e9ec9518d60c340f6bac7d278ca08d8a6\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942\",\n        \"wx\" : \"72d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058\",\n        \"wy\" : \"00e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEctShnE+dLPWEjqQERbcNRpa18C1jLAxl\\nTMfX7rDG0FjoxM2ZQ+RZF0x6wB+nQhmOR+bBmmvbDE9sI3gxwbP5Qg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 313,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b1d27a7694c146244a5ad0bd0636d9d9ef3b9fb58385418d9c982105077d1b7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec\",\n        \"wx\" : \"2a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e7402\",\n        \"wy\" : \"58f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKo6i9Q3M7QwhdXW9+nzUfRxvEABB7A41\\nUSeUwb5+dAJY+MFxIu0wP9pxQ+tYvt5wKVtlMmYBOwsOvT8FMTf27A==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 314,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100d27a7694c146244a5ad0bd0636d9e12abe687897e8e9998ddbd4e59a78520d0f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946\",\n        \"wx\" : \"0088de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b8\",\n        \"wy\" : \"0c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiN5onOmvHpS+aiCJyKixJT/9u2yOnIYk\\nm6IgABpK07gMSZjlSEL0E7ntsYJay7YzXoHk0YSysByL69yF0fKJRg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 315,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100a4f4ed29828c4894b5a17a0c6db3c256c2221449228a92dff7d76ca8206dd8dd\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9\",\n        \"wx\" : \"00fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7\",\n        \"wy\" : \"00b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/qLTH3D5DV+z4A4YasQqs8FhXO5xTgtO\\nETGz1NgiW/ewN6GN8qwVND8w90Bn3fKegX1fd/jc4FcU2lnAlPDNqQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 316,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220694c146244a5ad0bd0636d9e12bc9e09e60e68b90d0b5e6c5dddd0cb694d8799\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0\",\n        \"wx\" : \"7258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db\",\n        \"wy\" : \"17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcliRHj1CM0kWZHnb4Lg0Gvf70D0KfhDt\\nzLNrbO6lo9sXrCuJknkRKPo7ltwvvUyjv6eC7ygy/GZWlD2xjnNGsA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 317,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203d7f487c07bfc5f30846938a3dcef696444707cf9677254a92b06c63ab867d22\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470\",\n        \"wx\" : \"4f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914\",\n        \"wy\" : \"00c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAETyhGHepkR01rs00Umcl9N7npVjPfHO7q\\nrNRQFsmLORTIgYgQuMwG3bQOihJhxSj6pYlFXVpt+Tt3vF4OSTx0cA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 318,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206c7648fc0fbf8a06adb8b839f97b4ff7a800f11b1e37c593b261394599792ba4\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b\",\n        \"wx\" : \"74f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66\",\n        \"wy\" : \"00eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPKoFPtdjsqRppteYHEnMrOTfeMoKb6X\\nTte2jFwvXWbv8PB8VvmHplf0IZYgX1iMDx2W/YpjpfI4tI9Hh4j+Ow==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 319,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0221009be363a286f23f6322c205449d320baad417953ecb70f6214e90d49d7d1f26a8\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad\",\n        \"wx\" : \"195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6a\",\n        \"wy\" : \"00b2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGVtRp8xKIbgnSnCpDed5gUw8jKNYMoII\\nwJop8za4LWqyQWt8kv/9wpw7EoLdKnek0E3390UgRzk9hJmJxc7prQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 320,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022029798c5c45bdf58b4a7b2fdc2c46ab4af1218c7eeb9f0f27a88f1267674de3b0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0\",\n        \"wx\" : \"622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa\",\n        \"wy\" : \"736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYi/HRzIDS+wt3zvBbTSz0fejJ90qjBm6\\ntLtP46JLWKpzay8vrnb0367MkJYzOwEyjVHrP9qckifpDQtEmYPE8A==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 321,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02200b70f22ca2bb3cefadca1a5711fa3a59f4695385eb5aedf3495d0b6d00f8fd85\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93\",\n        \"wx\" : \"1f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c7\",\n        \"wy\" : \"0827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH3+FyvLXVQ56+bZQI+u03ONFAxFpIwnb\\nJplpuDS2EccIJ/RbeAIOy7r0hP3Vv6rmhw8RhMIVgbr274K9e1MPkw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 322,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d\",\n        \"wx\" : \"49c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377a\",\n        \"wy\" : \"00efc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEScGX3ICtHaR6Q0K5OJPo4fsLuU/DOoPn\\ng8ALJMeBN3rvwg2pK6x2KVH3JHS+zHNNTMIrqBuJXigv2sTfevDzfQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 323,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202252d685e831b6cf095e4f0535eeaf0ddd3bfa91c210c9d9dc17224702eaf88f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c\",\n        \"wx\" : \"00d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe\",\n        \"wy\" : \"7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2MtoUXthalZACqOGhjXlS29plZii9hZ3\\nV2VJgLr2rL5+yM9EnISaoDRhow762kFFPFfG5vvJO7xvpJrabcBVXA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 324,\n          \"comment\" : \"edge case for u1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022075135abd7c425b60371a477f09ce0f274f64a8c6b061a07b5d63e93c65046c53\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750\",\n        \"wx\" : \"030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3\",\n        \"wy\" : \"00b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAwcT+2Pyqm/iyt8bIO/CWcd0Rdr6h9rD\\nmLhAZco0ffOyJ4GN4aObWJywcdg+UxfMzcIzjlHjEv4x2Nw0pIAXUA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 325,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100d55555555555555555555555555555547c74934474db157d2a8c3f088aced62a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950\",\n        \"wx\" : \"00babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7\",\n        \"wy\" : \"252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEurs2d7CVWALY6SmkE1VkDq8eoTU/incT\\nMcSUbjSAr6clLxlsh+09KlnTsbVZE3/tABP+zvwZ+1qSaCubylG5UA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 326,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100c1777c8853938e536213c02464a936000ba1e21c0fc62075d46c624e23b52f31\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9\",\n        \"wx\" : \"1aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60\",\n        \"wy\" : \"00bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGqsgGHk0cREaig6bFD/eAvyVkgeW06Y9\\n4ym0JDlvumC75BMHBRdHkkQbMY06ox3+hXeCHptEbsVz0nLgNsTr6Q==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 327,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022030bbb794db588363b40679f6c182a50d3ce9679acdd3ffbe36d7813dacbdc818\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75\",\n        \"wx\" : \"008cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff\",\n        \"wy\" : \"47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjLC5CUmcg+qAbNiFsd1GegEZ8GqIoCdu\\nsM/aJ0U1qP9HtUKIM7w/LIv52QQRWM8zcYpplhzQFym8ABHR5YardQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 328,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202c37fd995622c4fb7fffffffffffffffc7cee745110cb45ab558ed7c90c15a2f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0\",\n        \"wx\" : \"008f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d\",\n        \"wy\" : \"3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjwPPGkInK7FTJyMJP3Lm/urIXhcA6fvp\\npqLdZC10v107iacYna2M91/CL28ViqJ/nCygDaynhb4zWPK9o4YsoA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 329,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02207fd995622c4fb7ffffffffffffffffff5d883ffab5b32652ccdcaa290fccb97d\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12\",\n        \"wx\" : \"44de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8ace\",\n        \"wy\" : \"00a2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERN47nHpXqMnoIJUnU0IefZh7s9efcfAT\\ngFyJfgGPis6iRgdYyPmNP9zhIalDZZ43LDJv/y5fwq5/o/edquE8Eg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 330,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100ffb32ac4589f6ffffffffffffffffffebb107ff56b664ca599b954521f9972fa\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204\",\n        \"wx\" : \"6fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a\",\n        \"wy\" : \"0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEb7iytI4zAxJorWpRdITciDnqkPZmnqDH\\nrDIz4qwxOUoKyLvn9zwv9N+ZeHJ6wd/C/VhkfSDzH5kQUxa2RnHyBA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 331,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205622c4fb7fffffffffffffffffffffff928a8f1c7ac7bec1808b9f61c01ec327\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c\",\n        \"wx\" : \"00bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6\",\n        \"wy\" : \"00f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvqcRIqBIaT6QX/YCs8+d0Yr2m5/J2EMd\\nKx3Sa5Qsleb0PHuLletiCCwS2529p/445Fy+SkiGkH+4G9sMXqkkbA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 332,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022044104104104104104104104104104103b87853fd3b7d3f8e175125b4382f25ed\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391\",\n        \"wx\" : \"00da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156\",\n        \"wy\" : \"00e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2pGMcxugaiDLlO8zt3jpgaQEowXxlB/j\\nNma0WwM1MVbiuyaU9XW0UYO+eOXJtSEL879Ij9TIKUUW2JVyyk9TkQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 333,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202739ce739ce739ce739ce739ce739ce705560298d1f2f08dc419ac273a5b54d9\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5\",\n        \"wx\" : \"3007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d\",\n        \"wy\" : \"5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMAfpLDk32t55ZN+jWw7/Ax9+sCrtCgMU\\nQREGzetw/j1adUb8BVKZeyDj1vQT514stm4RYyJpcRS3m6xzS/xNxQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 334,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100b777777777777777777777777777777688e6a1fe808a97a348671222ff16b863\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567\",\n        \"wx\" : \"60e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9b\",\n        \"wy\" : \"00d2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYOc071Yk08vw3dN1ARvWY9bWrrxkTrWZ\\n/fmNvc0YzpvS2Qs6wx8TmvgyzM9sy7ssbqEfqXNw3JkG2kdNfYp1Zw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 335,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206492492492492492492492492492492406dd3a19b8d5fb875235963c593bd2d3\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c\",\n        \"wx\" : \"0085a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba337\",\n        \"wy\" : \"69744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEhakA6XhY9pPAt9+iYeOA2tbqBG0fZd3u\\n7dX32K8LozdpdE0VrdT2wLw7DaKuyTs0y4xl+TQN33TnsACe7szOPA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 336,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100955555555555555555555555555555547c74934474db157d2a8c3f088aced62c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed\",\n        \"wx\" : \"38066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046\",\n        \"wy\" : \"00a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOAZvddiO/EyT3jb0ngN7I0zBix3lYIdQ\\npiyrA0VAEEaj6EvtjPy4Ge9NVQRE8s5LZRdmtp4uKQH4iDb/kANP7Q==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 337,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89\",\n        \"wx\" : \"0098f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabf\",\n        \"wy\" : \"00a33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmPaBd9yVwbTL+lJFSIylI6fVYpRw0DXW\\nIaRDxy85qr+jPSlUb6HGSPLH1cz3DPHOSrebXbGsBZ2+zQaNvf8biQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 338,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304502207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022100bffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191\",\n        \"wx\" : \"5c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277\",\n        \"wy\" : \"00e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXCu/ojybmtB/A4qom0kwvyZ9lAHkJV3p\\n6NoKUHjsgnfj6IKjHV5qN54Hk5g8ze05uVxDU6sv8B6lNpukewwxkQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 339,\n          \"comment\" : \"edge case for u2\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220185ddbca6dac41b1da033cfb60c152869e74b3cd66e9ffdf1b6bc09ed65ee40c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc\",\n        \"wx\" : \"2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385\",\n        \"wy\" : \"3547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\\nBc02R7FXo4U1R4CCmESO215wGt6EzV+xrJVnul6Ptoprkz7EtcyEzA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 340,\n          \"comment\" : \"point duplication during verification\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022100d612c2984c2afa416aa7f2882a486d4a8426cb6cfc91ed5b737278f9fca8be68\",\n          \"result\" : \"valid\",\n          \"flags\" : [\n            \"PointDuplication\"\n          ]\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763\",\n        \"wx\" : \"2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385\",\n        \"wy\" : \"00cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\\nBc02R7FXo4XKuH99Z7txJKGP5SF7MqBOU2qYRaFwSXWUbME6SjN3Yw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 341,\n          \"comment\" : \"duplication bug\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022100d612c2984c2afa416aa7f2882a486d4a8426cb6cfc91ed5b737278f9fca8be68\",\n          \"result\" : \"invalid\",\n          \"flags\" : [\n            \"PointDuplication\"\n          ]\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff\",\n        \"wx\" : \"008aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e\",\n        \"wy\" : \"1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiqLGT6nGQ3Vjq/vL0AsgSNSMGMFSoqb0\\nkDbedkfr6C4c5kOHmVxooGD6O8A5mwXMBu7H1Zj3UEGkkX5pK39R/w==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 342,\n          \"comment\" : \"comparison with point at infinity \",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0022033333333333333333333333333333332f222f8faefdb533f265d461c29a47373\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd\",\n        \"wx\" : \"391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71f\",\n        \"wy\" : \"00dd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEORQn/37ngBPBSux9lqigYiCSmKeDg16U\\n/WVJ1QL/9x/dZiTsNDrZ/PTZhyGB5Z+EL5ukzMrgmmwJcvtqxrTGvQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 343,\n          \"comment\" : \"extreme value for k and edgecase s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e\",\n        \"wx\" : \"00e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138e\",\n        \"wy\" : \"00c1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE52K4ohm08YAhnMepBZJF5JYb0ZHAOJl4\\nnHo0uJ6ME47BUz7wQZu3N24L/ekxnRCgaWh5HZ6g7tnBzmNFrtl1ng==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 344,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022100b6db6db6db6db6db6db6db6db6db6db5f30f30127d33e02aad96438927022e9c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175\",\n        \"wx\" : \"009aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952\",\n        \"wy\" : \"00fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmu2w0oHbFk4TAADFaX+uDzBe+Ei+b/+0\\nOsWT+7lQ6VL6b2MzWb3NgrVrC5+WWwN3idRrmoFBt5GyrvpxP5bBdQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 345,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3046022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502210099999999999999999999999999999998d668eaf0cf91f9bd7317d2547ced5a5a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd\",\n        \"wx\" : \"008ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee\",\n        \"wy\" : \"1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEitRF22KBYmDk5of9GITki5/AY20DFUfW\\nMxXnkuGb+u4d5k+Z1fHNi27Jyw94emVK6GmTuj2xAI70PP8GhMsivQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 346,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566\",\n        \"wx\" : \"1f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32\",\n        \"wy\" : \"00e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH1eZyVvokGOyTybkDLkowahop2+wCUYH\\n6AQ9tAnJHDLnVyToE6QZHjqDkAfwji6Jc4iwbUoA3m3mDlNtkfq1Zg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 347,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d\",\n        \"wx\" : \"00a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc\",\n        \"wy\" : \"28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEozMaThtCI+wsAn7dSCySihTtNY2T8dQh\\nfTmr9p/LXMwo1oTSqqvNY4N3XKpiOd4m1MaTe7YD7LQZYIL0z/1QnQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 348,\n          \"comment\" : \"extreme value for k\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d\",\n        \"wx\" : \"3f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb24818\",\n        \"wy\" : \"5ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEPzlSGZd0x885s4tmyxBCpiYNhoCAOEXk\\n1DOtujuySBhepJW2jLx+1Bc+5jyQQtxQJiXH634h+wLKmpEU4KOhjQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 349,\n          \"comment\" : \"extreme value for k and edgecase s\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698\",\n        \"wx\" : \"00cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e\",\n        \"wy\" : \"054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzfuMD0IuFE4TfCQSyGwXH1/j+j9bu1RO\\nkHYojzzteG4FT9ByG3fBHHm+rLPJQhGwoZvaCGUu/q+SUTo7ChY2mA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 350,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100b6db6db6db6db6db6db6db6db6db6db5f30f30127d33e02aad96438927022e9c\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d\",\n        \"wx\" : \"73598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3\",\n        \"wy\" : \"00cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc1mKahxoJ4+mv9DOQGTmgjW8HA9rIKko\\nEIvjNnMPh+PLrmElGbUDLsyFrtgRJxqV/nk51dNGAUC6MY9NFKujHQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 351,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802210099999999999999999999999999999998d668eaf0cf91f9bd7317d2547ced5a5a\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d\",\n        \"wx\" : \"58debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a1\",\n        \"wy\" : \"6773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWN69mn7iydWRMkeKVECuTV1+1Dcwg2n5\\nLqhsghg/EKFnc+dvXtv02g5PG9/6wPVyV+HfpGWEKTEwmiQkX9pqXQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 352,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f\",\n        \"wx\" : \"008b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b\",\n        \"wy\" : \"00950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEi5BN5HlnNAxfjDVypyCSTvdXhjf+qxlJ\\nrLJBpaasP1uVCQRJb5gksdY/MxO64huJ+uia/fyBG17OA/1aowGGTw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 353,\n          \"comment\" : \"extreme value for k and s^-1\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b\",\n        \"wx\" : \"00f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a\",\n        \"wy\" : \"346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9IkrbVJcdx4DXyolJwjzeE5II4YEtPlN\\nxW6qHlRtlBo0axqgvOaLHFDltS9Qn7VSLlwl4Ci8j4Y0Au23vK2LGw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 354,\n          \"comment\" : \"extreme value for k\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\",\n        \"wx\" : \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n        \"wy\" : \"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\\nWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuA==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 355,\n          \"comment\" : \"testing point duplication\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 356,\n          \"comment\" : \"testing point duplication\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777\",\n        \"wx\" : \"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n        \"wy\" : \"00b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\\nWfKBWxb4F5i3xSWI2Vw7mqJbBAPx7vdXAuhLt1l6q+ZjuC9vBO8ndw==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 357,\n          \"comment\" : \"testing point duplication\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 358,\n          \"comment\" : \"testing point duplication\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952\",\n          \"result\" : \"invalid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152\",\n        \"wx\" : \"782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963\",\n        \"wy\" : \"00af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeCyO0X47Kng7VGTzOwllKnHGeOBexR6E\\n4rz8Zjo96WOvmstCgLjH98QvTvmrpiRewewXEv04oPqWQY2M1qphUg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 359,\n          \"comment\" : \"pseudorandom signature\",\n          \"msg\" : \"\",\n          \"sig\" : \"3046022100f80ae4f96cdbc9d853f83d47aae225bf407d51c56b7776cd67d0dc195d99a9dc022100b303e26be1f73465315221f0b331528807a1a9b6eb068ede6eebeaaa49af8a36\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 360,\n          \"comment\" : \"pseudorandom signature\",\n          \"msg\" : \"4d7367\",\n          \"sig\" : \"30450220109cd8ae0374358984a8249c0a843628f2835ffad1df1a9a69aa2fe72355545c022100ac6f00daf53bd8b1e34da329359b6e08019c5b037fed79ee383ae39f85a159c6\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 361,\n          \"comment\" : \"pseudorandom signature\",\n          \"msg\" : \"313233343030\",\n          \"sig\" : \"3045022100d035ee1f17fdb0b2681b163e33c359932659990af77dca632012b30b27a057b302201939d9f3b2858bc13e3474cb50e6a82be44faa71940f876c1cba4c3e989202b6\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 362,\n          \"comment\" : \"pseudorandom signature\",\n          \"msg\" : \"0000000000000000000000000000000000000000\",\n          \"sig\" : \"304402204f053f563ad34b74fd8c9934ce59e79c2eb8e6eca0fef5b323ca67d5ac7ed23802204d4b05daa0719e773d8617dce5631c5fd6f59c9bdc748e4b55c970040af01be5\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1\",\n        \"wx\" : \"6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff\",\n        \"wy\" : \"01060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\\n4bulQapAyv8AAAABBgSS1aVnPg8l2NUPt+WMSdhtRtQhaVXgqj1A4Q==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 363,\n          \"comment\" : \"y-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"304402206d6a4f556ccce154e7fb9f19e76c3deca13d59cc2aeb4ecad968aab2ded45965022053b9fa74803ede0fc4441bf683d56c564d3e274e09ccf47390badd1471c05fb7\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 364,\n          \"comment\" : \"y-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100aad503de9b9fd66b948e9acf596f0a0e65e700b28b26ec56e6e45e846489b3c4022100fff223c5d0765447e8447a3f9d31fd0696e89d244422022ff61a110b2a8c2f04\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 365,\n          \"comment\" : \"y-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"30460221009182cebd3bb8ab572e167174397209ef4b1d439af3b200cdf003620089e43225022100abb88367d15fe62d1efffb6803da03109ee22e90bc9c78e8b4ed23630b82ea9d\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e\",\n        \"wx\" : \"6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff\",\n        \"wy\" : \"00fffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\\n4bulQapAyv/////++fttKlqYwfDaJyrwSBpztieSuSvelqoeVcK7Tg==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 366,\n          \"comment\" : \"y-coordinate of the public key is large\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"304502203854a3998aebdf2dbc28adac4181462ccac7873907ab7f212c42db0e69b56ed8022100c12c09475c772fd0c1b2060d5163e42bf71d727e4ae7c03eeba954bf50b43bb3\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 367,\n          \"comment\" : \"y-coordinate of the public key is large\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100e94dbdc38795fe5c904d8f16d969d3b587f0a25d2de90b6d8c5c53ff887e3607022100856b8c963e9b68dade44750bf97ec4d11b1a0a3804f4cb79aa27bdea78ac14e4\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 368,\n          \"comment\" : \"y-coordinate of the public key is large\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3044022049fc102a08ca47b60e0858cd0284d22cddd7233f94aaffbb2db1dd2cf08425e102205b16fca5a12cdb39701697ad8e39ffd6bdec0024298afaa2326aea09200b14d6\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d\",\n        \"wx\" : \"013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0\",\n        \"wy\" : \"00f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAAAAAT/SIkjWTZX3PCm0irSGMYUL5QP9\\nAPhGi18PcOD27nqkO8LG/SWx2CaSQcvdnbsNrJbcliMfQwcF+DhxfQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 369,\n          \"comment\" : \"x-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3045022041efa7d3f05a0010675fcb918a45c693da4b348df21a59d6f9cd73e0d831d67a022100bbab52596c1a1d9484296cdc92cbf07e665259a13791a8fe8845e2c07cf3fc67\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 370,\n          \"comment\" : \"x-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100b615698c358b35920dd883eca625a6c5f7563970cdfc378f8fe0cee17092144c022100da0b84cd94a41e049ef477aeac157b2a9bfa6b7ac8de06ed3858c5eede6ddd6d\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 371,\n          \"comment\" : \"x-coordinate of the public key is small\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"304602210087cf8c0eb82d44f69c60a2ff5457d3aaa322e7ec61ae5aecfd678ae1c1932b0e022100c522c4eea7eafb82914cbf5c1ff76760109f55ddddcf58274d41c9bc4311e06e\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"0425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35\",\n        \"wx\" : \"25afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dffffffff\",\n        \"wy\" : \"00fa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a0342000425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJa/WiayrrtZ8Hylt5ZQG+MVQ9XFGoLTs\\nLJeHbf/////6RqduUgMi37xJHsTwzBl0IPxOpYg9j23VPDVLxPZ8NQ==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 372,\n          \"comment\" : \"x-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3045022062f48ef71ace27bf5a01834de1f7e3f948b9dce1ca1e911d5e13d3b104471d82022100a1570cc0f388768d3ba7df7f212564caa256ff825df997f21f72f5280d53011f\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 373,\n          \"comment\" : \"x-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100f6b0e2f6fe020cf7c0c20137434344ed7add6c4be51861e2d14cbda472a6ffb40221009be93722c1a3ad7d4cf91723700cb5486de5479d8c1b38ae4e8e5ba1638e9732\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 374,\n          \"comment\" : \"x-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3045022100db09d8460f05eff23bc7e436b67da563fa4b4edb58ac24ce201fa8a358125057022046da116754602940c8999c8d665f786c50f5772c0a3cdbda075e77eabc64df16\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"04d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff\",\n        \"wx\" : \"00d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb9\",\n        \"wy\" : \"3f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a03420004d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0S5sZrZ3NMPITSYBz1013Al+J2N/CspK\\nT9t0tqrdO7k/W9/4i9VzbfiY5pkAbtdQ8RzwfFhmzXrXDHEh/////w==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 375,\n          \"comment\" : \"y-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"30450220592c41e16517f12fcabd98267674f974b588e9f35d35406c1a7bb2ed1d19b7b8022100c19a5f942607c3551484ff0dc97281f0cdc82bc48e2205a0645c0cf3d7f59da0\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 376,\n          \"comment\" : \"y-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100be0d70887d5e40821a61b68047de4ea03debfdf51cdf4d4b195558b959a032b20221008266b4d270e24414ecacb14c091a233134b918d37320c6557d60ad0a63544ac4\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 377,\n          \"comment\" : \"y-coordinate of the public key has many trailing 1's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100fae92dfcb2ee392d270af3a5739faa26d4f97bfd39ed3cbee4d29e26af3b206a02210093645c80605595e02c09a0dc4b17ac2a51846a728b3e8d60442ed6449fd3342b\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    },\n    {\n      \"key\" : {\n        \"curve\" : \"secp256k1\",\n        \"keySize\" : 256,\n        \"type\" : \"EcPublicKey\",\n        \"uncompressed\" : \"046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb\",\n        \"wx\" : \"6d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000\",\n        \"wy\" : \"00e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb\"\n      },\n      \"keyDer\" : \"3056301006072a8648ce3d020106052b8104000a034200046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb\",\n      \"keyPem\" : \"-----BEGIN PUBLIC KEY-----\\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbUp/YNR3Sk8KqLve25U8fup5CUB+MWR1\\nVmS8KAAAAADmWdNOTfONnoyeqt+6NmEsdpGVvobHeqw/NueLU4aA+w==\\n-----END PUBLIC KEY-----\",\n      \"sha\" : \"SHA-256\",\n      \"type\" : \"EcdsaVerify\",\n      \"tests\" : [\n        {\n          \"tcId\" : 378,\n          \"comment\" : \"x-coordinate of the public key has many trailing 0's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"30450220176a2557566ffa518b11226694eb9802ed2098bfe278e5570fe1d5d7af18a943022100ed6e2095f12a03f2eaf6718f430ec5fe2829fd1646ab648701656fd31221b97d\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 379,\n          \"comment\" : \"x-coordinate of the public key has many trailing 0's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3045022060be20c3dbc162dd34d26780621c104bbe5dace630171b2daef0d826409ee5c2022100bd8081b27762ab6e8f425956bf604e332fa066a99b59f87e27dc1198b26f5caa\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        },\n        {\n          \"tcId\" : 380,\n          \"comment\" : \"x-coordinate of the public key has many trailing 0's\",\n          \"msg\" : \"4d657373616765\",\n          \"sig\" : \"3046022100edf03cf63f658883289a1a593d1007895b9f236d27c9c1f1313089aaed6b16ae022100e5b22903f7eb23adc2e01057e39b0408d495f694c83f306f1216c9bf87506074\",\n          \"result\" : \"valid\",\n          \"flags\" : []\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "rustfmt.toml",
    "content": ""
  },
  {
    "path": "src/lib.rs",
    "content": "//! Pure Rust implementation of the secp256k1 curve and fast ECDSA\n//! signatures. The secp256k1 curve is used extensively in Bitcoin and\n//! Ethereum-alike cryptocurrencies.\n\n#![deny(\n    unused_import_braces,\n    unused_imports,\n    unused_comparisons,\n    unused_must_use,\n    unused_variables,\n    non_shorthand_field_patterns,\n    unreachable_code,\n    unused_parens\n)]\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\npub use libsecp256k1_core::*;\n\nuse arrayref::{array_mut_ref, array_ref};\nuse base64::{engine::Engine as _, prelude::BASE64_STANDARD};\nuse core::convert::TryFrom;\nuse digest::{generic_array::GenericArray, Digest};\nuse rand::Rng;\n\n#[cfg(feature = \"std\")]\nuse core::fmt;\n#[cfg(feature = \"hmac\")]\nuse hmac_drbg::HmacDRBG;\n#[cfg(feature = \"std\")]\nuse serde::{de, ser::Serializer, Deserialize, Serialize};\n#[cfg(feature = \"hmac\")]\nuse sha2::Sha256;\n#[cfg(feature = \"hmac\")]\nuse typenum::U32;\n\nuse crate::{\n    curve::{Affine, ECMultContext, ECMultGenContext, Field, Jacobian, Scalar},\n    util::{Decoder, SignatureArray},\n};\n\n#[cfg(feature = \"lazy-static-context\")]\nlazy_static::lazy_static! {\n    /// A static ECMult context.\n    pub static ref ECMULT_CONTEXT: Box<ECMultContext> = ECMultContext::new_boxed();\n\n    /// A static ECMultGen context.\n    pub static ref ECMULT_GEN_CONTEXT: Box<ECMultGenContext> = ECMultGenContext::new_boxed();\n}\n\n#[cfg(all(feature = \"static-context\", not(feature = \"lazy-static-context\")))]\n/// A static ECMult context.\n// Correct `pre_g` values are fed into `ECMultContext::new_from_raw`, generated by build script.\npub static ECMULT_CONTEXT: ECMultContext =\n    unsafe { ECMultContext::new_from_raw(include!(concat!(env!(\"OUT_DIR\"), \"/const.rs\"))) };\n\n#[cfg(all(feature = \"static-context\", not(feature = \"lazy-static-context\")))]\n/// A static ECMultGen context.\n// Correct `prec` values are fed into `ECMultGenContext::new_from_raw`, generated by build script.\npub static ECMULT_GEN_CONTEXT: ECMultGenContext =\n    unsafe { ECMultGenContext::new_from_raw(include!(concat!(env!(\"OUT_DIR\"), \"/const_gen.rs\"))) };\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Public key on a secp256k1 curve.\npub struct PublicKey(Affine);\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Secret key (256-bit) on a secp256k1 curve.\npub struct SecretKey(Scalar);\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// An ECDSA signature.\npub struct Signature {\n    pub r: Scalar,\n    pub s: Scalar,\n}\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Tag used for public key recovery from signatures.\npub struct RecoveryId(u8);\n\n#[derive(Debug, Clone, Copy, Eq, PartialEq)]\n/// Hashed message input to an ECDSA signature.\npub struct Message(pub Scalar);\n\n#[derive(Debug, Clone, Eq, PartialEq)]\n/// Shared secret using ECDH.\npub struct SharedSecret<D: Digest>(GenericArray<u8, D::OutputSize>);\n\nimpl<D> Copy for SharedSecret<D>\nwhere\n    D: Copy + Digest,\n    GenericArray<u8, D::OutputSize>: Copy,\n{\n}\n\n/// Format for public key parsing.\npub enum PublicKeyFormat {\n    /// Compressed public key, 33 bytes.\n    Compressed,\n    /// Full length public key, 65 bytes.\n    Full,\n    /// Raw public key, 64 bytes.\n    Raw,\n}\n\nimpl PublicKey {\n    pub fn from_secret_key_with_context(\n        seckey: &SecretKey,\n        context: &ECMultGenContext,\n    ) -> PublicKey {\n        let mut pj = Jacobian::default();\n        context.ecmult_gen(&mut pj, &seckey.0);\n        let mut p = Affine::default();\n        p.set_gej(&pj);\n        PublicKey(p)\n    }\n\n    #[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n    pub fn from_secret_key(seckey: &SecretKey) -> PublicKey {\n        Self::from_secret_key_with_context(seckey, &ECMULT_GEN_CONTEXT)\n    }\n\n    pub fn parse_slice(p: &[u8], format: Option<PublicKeyFormat>) -> Result<PublicKey, Error> {\n        let format = match (p.len(), format) {\n            (util::FULL_PUBLIC_KEY_SIZE, None)\n            | (util::FULL_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Full)) => PublicKeyFormat::Full,\n            (util::COMPRESSED_PUBLIC_KEY_SIZE, None)\n            | (util::COMPRESSED_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Compressed)) => {\n                PublicKeyFormat::Compressed\n            }\n            (util::RAW_PUBLIC_KEY_SIZE, None)\n            | (util::RAW_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Raw)) => PublicKeyFormat::Raw,\n            _ => return Err(Error::InvalidInputLength),\n        };\n\n        match format {\n            PublicKeyFormat::Full => {\n                let mut a = [0; util::FULL_PUBLIC_KEY_SIZE];\n                a.copy_from_slice(p);\n                Self::parse(&a)\n            }\n            PublicKeyFormat::Raw => {\n                use util::TAG_PUBKEY_FULL;\n\n                let mut a = [0; util::FULL_PUBLIC_KEY_SIZE];\n                a[0] = TAG_PUBKEY_FULL;\n                a[1..].copy_from_slice(p);\n                Self::parse(&a)\n            }\n            PublicKeyFormat::Compressed => {\n                let mut a = [0; util::COMPRESSED_PUBLIC_KEY_SIZE];\n                a.copy_from_slice(p);\n                Self::parse_compressed(&a)\n            }\n        }\n    }\n\n    pub fn parse(p: &[u8; util::FULL_PUBLIC_KEY_SIZE]) -> Result<PublicKey, Error> {\n        use util::{TAG_PUBKEY_FULL, TAG_PUBKEY_HYBRID_EVEN, TAG_PUBKEY_HYBRID_ODD};\n\n        if !(p[0] == TAG_PUBKEY_FULL\n            || p[0] == TAG_PUBKEY_HYBRID_EVEN\n            || p[0] == TAG_PUBKEY_HYBRID_ODD)\n        {\n            return Err(Error::InvalidPublicKey);\n        }\n        let mut x = Field::default();\n        let mut y = Field::default();\n        if !x.set_b32(array_ref!(p, 1, 32)) {\n            return Err(Error::InvalidPublicKey);\n        }\n        if !y.set_b32(array_ref!(p, 33, 32)) {\n            return Err(Error::InvalidPublicKey);\n        }\n        let mut elem = Affine::default();\n        elem.set_xy(&x, &y);\n        if (p[0] == TAG_PUBKEY_HYBRID_EVEN || p[0] == TAG_PUBKEY_HYBRID_ODD)\n            && (y.is_odd() != (p[0] == TAG_PUBKEY_HYBRID_ODD))\n        {\n            return Err(Error::InvalidPublicKey);\n        }\n        if elem.is_infinity() {\n            return Err(Error::InvalidPublicKey);\n        }\n        if elem.is_valid_var() {\n            Ok(PublicKey(elem))\n        } else {\n            Err(Error::InvalidPublicKey)\n        }\n    }\n\n    pub fn parse_compressed(\n        p: &[u8; util::COMPRESSED_PUBLIC_KEY_SIZE],\n    ) -> Result<PublicKey, Error> {\n        use util::{TAG_PUBKEY_EVEN, TAG_PUBKEY_ODD};\n\n        if !(p[0] == TAG_PUBKEY_EVEN || p[0] == TAG_PUBKEY_ODD) {\n            return Err(Error::InvalidPublicKey);\n        }\n        let mut x = Field::default();\n        if !x.set_b32(array_ref!(p, 1, 32)) {\n            return Err(Error::InvalidPublicKey);\n        }\n        let mut elem = Affine::default();\n        elem.set_xo_var(&x, p[0] == TAG_PUBKEY_ODD);\n        if elem.is_infinity() {\n            return Err(Error::InvalidPublicKey);\n        }\n        if elem.is_valid_var() {\n            Ok(PublicKey(elem))\n        } else {\n            Err(Error::InvalidPublicKey)\n        }\n    }\n\n    pub fn serialize(&self) -> [u8; util::FULL_PUBLIC_KEY_SIZE] {\n        use util::TAG_PUBKEY_FULL;\n\n        debug_assert!(!self.0.is_infinity());\n\n        let mut ret = [0u8; 65];\n        let mut elem = self.0;\n\n        elem.x.normalize_var();\n        elem.y.normalize_var();\n        elem.x.fill_b32(array_mut_ref!(ret, 1, 32));\n        elem.y.fill_b32(array_mut_ref!(ret, 33, 32));\n        ret[0] = TAG_PUBKEY_FULL;\n\n        ret\n    }\n\n    pub fn serialize_compressed(&self) -> [u8; util::COMPRESSED_PUBLIC_KEY_SIZE] {\n        use util::{TAG_PUBKEY_EVEN, TAG_PUBKEY_ODD};\n\n        debug_assert!(!self.0.is_infinity());\n\n        let mut ret = [0u8; 33];\n        let mut elem = self.0;\n\n        elem.x.normalize_var();\n        elem.y.normalize_var();\n        elem.x.fill_b32(array_mut_ref!(ret, 1, 32));\n        ret[0] = if elem.y.is_odd() {\n            TAG_PUBKEY_ODD\n        } else {\n            TAG_PUBKEY_EVEN\n        };\n\n        ret\n    }\n\n    pub fn tweak_add_assign_with_context(\n        &mut self,\n        tweak: &SecretKey,\n        context: &ECMultContext,\n    ) -> Result<(), Error> {\n        let mut r = Jacobian::default();\n        let a = Jacobian::from_ge(&self.0);\n        let one = Scalar::from_int(1);\n        context.ecmult(&mut r, &a, &one, &tweak.0);\n\n        if r.is_infinity() {\n            return Err(Error::TweakOutOfRange);\n        }\n\n        self.0.set_gej(&r);\n        Ok(())\n    }\n\n    #[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n    pub fn tweak_add_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {\n        self.tweak_add_assign_with_context(tweak, &ECMULT_CONTEXT)\n    }\n\n    pub fn tweak_mul_assign_with_context(\n        &mut self,\n        tweak: &SecretKey,\n        context: &ECMultContext,\n    ) -> Result<(), Error> {\n        if tweak.0.is_zero() {\n            return Err(Error::TweakOutOfRange);\n        }\n\n        let mut r = Jacobian::default();\n        let zero = Scalar::from_int(0);\n        let pt = Jacobian::from_ge(&self.0);\n        context.ecmult(&mut r, &pt, &tweak.0, &zero);\n\n        self.0.set_gej(&r);\n        Ok(())\n    }\n\n    #[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n    pub fn tweak_mul_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {\n        self.tweak_mul_assign_with_context(tweak, &ECMULT_CONTEXT)\n    }\n\n    pub fn combine(keys: &[PublicKey]) -> Result<Self, Error> {\n        let mut qj = Jacobian::default();\n        qj.set_infinity();\n\n        for key in keys {\n            qj = qj.add_ge(&key.0);\n        }\n\n        if qj.is_infinity() {\n            return Err(Error::InvalidPublicKey);\n        }\n\n        let q = Affine::from_gej(&qj);\n        Ok(PublicKey(q))\n    }\n}\n\nimpl Into<Affine> for PublicKey {\n    fn into(self) -> Affine {\n        self.0\n    }\n}\n\nimpl TryFrom<Affine> for PublicKey {\n    type Error = Error;\n\n    fn try_from(value: Affine) -> Result<Self, Self::Error> {\n        if value.is_infinity() || !value.is_valid_var() {\n            Err(Error::InvalidAffine)\n        } else {\n            Ok(PublicKey(value))\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl Serialize for PublicKey {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,\n    {\n        if serializer.is_human_readable() {\n            serializer.serialize_str(&BASE64_STANDARD.encode(&self.serialize()[..]))\n        } else {\n            serializer.serialize_bytes(&self.serialize())\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nstruct PublicKeyStrVisitor;\n\n#[cfg(feature = \"std\")]\nimpl<'de> de::Visitor<'de> for PublicKeyStrVisitor {\n    type Value = PublicKey;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter\n            .write_str(\"a bytestring of either 33 (compressed), 64 (raw), or 65 bytes in length\")\n    }\n\n    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>\n    where\n        E: de::Error,\n    {\n        let value: &[u8] = &BASE64_STANDARD.decode(value).map_err(|e| E::custom(e))?;\n        let key_format = match value.len() {\n            33 => PublicKeyFormat::Compressed,\n            64 => PublicKeyFormat::Raw,\n            65 => PublicKeyFormat::Full,\n            _ => return Err(E::custom(Error::InvalidInputLength)),\n        };\n        PublicKey::parse_slice(value, Some(key_format))\n            .map_err(|_e| E::custom(Error::InvalidPublicKey))\n    }\n}\n\n#[cfg(feature = \"std\")]\nstruct PublicKeyBytesVisitor;\n\n#[cfg(feature = \"std\")]\nimpl<'de> de::Visitor<'de> for PublicKeyBytesVisitor {\n    type Value = PublicKey;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(\n            \"a byte slice that is either 33 (compressed), 64 (raw), or 65 bytes in length\",\n        )\n    }\n\n    fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>\n    where\n        E: de::Error,\n    {\n        PublicKey::parse_slice(value, None).map_err(|_e| E::custom(Error::InvalidPublicKey))\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'de> Deserialize<'de> for PublicKey {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: de::Deserializer<'de>,\n    {\n        if deserializer.is_human_readable() {\n            deserializer.deserialize_str(PublicKeyStrVisitor)\n        } else {\n            deserializer.deserialize_bytes(PublicKeyBytesVisitor)\n        }\n    }\n}\n\nimpl SecretKey {\n    pub fn parse(p: &[u8; util::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> {\n        let mut elem = Scalar::default();\n        if !bool::from(elem.set_b32(p)) {\n            Self::try_from(elem)\n        } else {\n            Err(Error::InvalidSecretKey)\n        }\n    }\n\n    pub fn parse_slice(p: &[u8]) -> Result<SecretKey, Error> {\n        if p.len() != util::SECRET_KEY_SIZE {\n            return Err(Error::InvalidInputLength);\n        }\n\n        let mut a = [0; 32];\n        a.copy_from_slice(p);\n        Self::parse(&a)\n    }\n\n    pub fn random<R: Rng>(rng: &mut R) -> SecretKey {\n        loop {\n            let mut ret = [0u8; util::SECRET_KEY_SIZE];\n            rng.fill_bytes(&mut ret);\n\n            if let Ok(key) = Self::parse(&ret) {\n                return key;\n            }\n        }\n    }\n\n    pub fn serialize(&self) -> [u8; util::SECRET_KEY_SIZE] {\n        self.0.b32()\n    }\n\n    pub fn tweak_add_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {\n        let v = self.0 + tweak.0;\n        if v.is_zero() {\n            return Err(Error::TweakOutOfRange);\n        }\n        self.0 = v;\n        Ok(())\n    }\n\n    pub fn tweak_mul_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {\n        if tweak.0.is_zero() {\n            return Err(Error::TweakOutOfRange);\n        }\n\n        self.0 *= &tweak.0;\n        Ok(())\n    }\n\n    pub fn inv(&self) -> Self {\n        SecretKey(self.0.inv())\n    }\n\n    pub fn clear(&mut self) {\n        self.0.clear();\n    }\n\n    pub fn is_zero(&self) -> bool {\n        self.0.is_zero()\n    }\n}\n\nimpl Default for SecretKey {\n    fn default() -> SecretKey {\n        let mut elem = Scalar::default();\n        let overflowed = bool::from(elem.set_b32(&[\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            0x00, 0x00, 0x00, 0x01,\n        ]));\n        debug_assert!(!overflowed);\n        debug_assert!(!elem.is_zero());\n        SecretKey(elem)\n    }\n}\n\nimpl Into<Scalar> for SecretKey {\n    fn into(self) -> Scalar {\n        self.0\n    }\n}\n\nimpl TryFrom<Scalar> for SecretKey {\n    type Error = Error;\n\n    fn try_from(scalar: Scalar) -> Result<Self, Error> {\n        if scalar.is_zero() {\n            Err(Error::InvalidSecretKey)\n        } else {\n            Ok(Self(scalar))\n        }\n    }\n}\n\nimpl core::fmt::LowerHex for SecretKey {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        let scalar = self.0;\n\n        write!(f, \"{:x}\", scalar)\n    }\n}\n\nimpl Signature {\n    /// Parse an possibly overflowing signature.\n    ///\n    /// A SECP256K1 signature is usually required to be within 0 and curve\n    /// order. This function, however, allows signatures larger than curve order\n    /// by taking the signature and minus curve order.\n    ///\n    /// Note that while this function is technically safe, it is non-standard,\n    /// meaning you will have compatibility issues if you also use other\n    /// SECP256K1 libraries. It's not recommended to use this function. Please\n    /// use `parse_standard` instead.\n    pub fn parse_overflowing(p: &[u8; util::SIGNATURE_SIZE]) -> Signature {\n        let mut r = Scalar::default();\n        let mut s = Scalar::default();\n\n        // Okay for signature to overflow\n        let _ = r.set_b32(array_ref!(p, 0, 32));\n        let _ = s.set_b32(array_ref!(p, 32, 32));\n\n        Signature { r, s }\n    }\n\n    /// Parse a standard SECP256K1 signature. The signature is required to be\n    /// within 0 and curve order. Returns error if it overflows.\n    pub fn parse_standard(p: &[u8; util::SIGNATURE_SIZE]) -> Result<Signature, Error> {\n        let mut r = Scalar::default();\n        let mut s = Scalar::default();\n\n        // It's okay for the signature to overflow here, it's checked below.\n        let overflowed_r = r.set_b32(array_ref!(p, 0, 32));\n        let overflowed_s = s.set_b32(array_ref!(p, 32, 32));\n\n        if bool::from(overflowed_r | overflowed_s) {\n            return Err(Error::InvalidSignature);\n        }\n\n        Ok(Signature { r, s })\n    }\n\n    /// Parse a possibly overflowing signature slice. See also\n    /// `parse_overflowing`.\n    ///\n    /// It's not recommended to use this function. Please use\n    /// `parse_standard_slice` instead.\n    pub fn parse_overflowing_slice(p: &[u8]) -> Result<Signature, Error> {\n        if p.len() != util::SIGNATURE_SIZE {\n            return Err(Error::InvalidInputLength);\n        }\n\n        let mut a = [0; util::SIGNATURE_SIZE];\n        a.copy_from_slice(p);\n        Ok(Self::parse_overflowing(&a))\n    }\n\n    /// Parse a standard signature slice. See also `parse_standard`.\n    pub fn parse_standard_slice(p: &[u8]) -> Result<Signature, Error> {\n        if p.len() != util::SIGNATURE_SIZE {\n            return Err(Error::InvalidInputLength);\n        }\n\n        let mut a = [0; util::SIGNATURE_SIZE];\n        a.copy_from_slice(p);\n        Ok(Self::parse_standard(&a)?)\n    }\n\n    /// Parse a DER-encoded byte slice to a signature.\n    pub fn parse_der(p: &[u8]) -> Result<Signature, Error> {\n        let mut decoder = Decoder::new(p);\n\n        decoder.read_constructed_sequence()?;\n        let rlen = decoder.read_len()?;\n\n        if rlen != decoder.remaining_len() {\n            return Err(Error::InvalidSignature);\n        }\n\n        let r = decoder.read_integer()?;\n        let s = decoder.read_integer()?;\n\n        if decoder.remaining_len() != 0 {\n            return Err(Error::InvalidSignature);\n        }\n\n        Ok(Signature { r, s })\n    }\n\n    /// Converts a \"lax DER\"-encoded byte slice to a signature. This is basically\n    /// only useful for validating signatures in the Bitcoin blockchain from before\n    /// 2016. It should never be used in new applications. This library does not\n    /// support serializing to this \"format\"\n    pub fn parse_der_lax(p: &[u8]) -> Result<Signature, Error> {\n        let mut decoder = Decoder::new(p);\n\n        decoder.read_constructed_sequence()?;\n        decoder.read_seq_len_lax()?;\n\n        let r = decoder.read_integer_lax()?;\n        let s = decoder.read_integer_lax()?;\n\n        Ok(Signature { r, s })\n    }\n\n    /// Normalizes a signature to a \"low S\" form. In ECDSA, signatures are\n    /// of the form (r, s) where r and s are numbers lying in some finite\n    /// field. The verification equation will pass for (r, s) iff it passes\n    /// for (r, -s), so it is possible to ``modify'' signatures in transit\n    /// by flipping the sign of s. This does not constitute a forgery since\n    /// the signed message still cannot be changed, but for some applications,\n    /// changing even the signature itself can be a problem. Such applications\n    /// require a \"strong signature\". It is believed that ECDSA is a strong\n    /// signature except for this ambiguity in the sign of s, so to accommodate\n    /// these applications libsecp256k1 will only accept signatures for which\n    /// s is in the lower half of the field range. This eliminates the\n    /// ambiguity.\n    ///\n    /// However, for some systems, signatures with high s-values are considered\n    /// valid. (For example, parsing the historic Bitcoin blockchain requires\n    /// this.) For these applications we provide this normalization function,\n    /// which ensures that the s value lies in the lower half of its range.\n    pub fn normalize_s(&mut self) {\n        if self.s.is_high() {\n            self.s = -self.s;\n        }\n    }\n\n    /// Serialize a signature to a standard byte representation. This is the\n    /// reverse of `parse_standard`.\n    pub fn serialize(&self) -> [u8; util::SIGNATURE_SIZE] {\n        let mut ret = [0u8; 64];\n        self.r.fill_b32(array_mut_ref!(ret, 0, 32));\n        self.s.fill_b32(array_mut_ref!(ret, 32, 32));\n        ret\n    }\n\n    /// Serialize a signature to a DER encoding. This is the reverse of\n    /// `parse_der`.\n    pub fn serialize_der(&self) -> SignatureArray {\n        fn fill_scalar_with_leading_zero(scalar: &Scalar) -> [u8; 33] {\n            let mut ret = [0u8; 33];\n            scalar.fill_b32(array_mut_ref!(ret, 1, 32));\n            ret\n        }\n\n        let r_full = fill_scalar_with_leading_zero(&self.r);\n        let s_full = fill_scalar_with_leading_zero(&self.s);\n\n        fn integer_slice(full: &[u8; 33]) -> &[u8] {\n            let mut len = 33;\n            while len > 1 && full[full.len() - len] == 0 && full[full.len() - len + 1] < 0x80 {\n                len -= 1;\n            }\n            &full[(full.len() - len)..]\n        }\n\n        let r = integer_slice(&r_full);\n        let s = integer_slice(&s_full);\n\n        let mut ret = SignatureArray::new(6 + r.len() + s.len());\n        {\n            let l = ret.as_mut();\n            l[0] = 0x30;\n            l[1] = 4 + r.len() as u8 + s.len() as u8;\n            l[2] = 0x02;\n            l[3] = r.len() as u8;\n            l[4..(4 + r.len())].copy_from_slice(r);\n            l[4 + r.len()] = 0x02;\n            l[5 + r.len()] = s.len() as u8;\n            l[(6 + r.len())..(6 + r.len() + s.len())].copy_from_slice(s);\n        }\n\n        ret\n    }\n}\n\nimpl Message {\n    pub fn parse(p: &[u8; util::MESSAGE_SIZE]) -> Message {\n        let mut m = Scalar::default();\n\n        // Okay for message to overflow.\n        let _ = m.set_b32(p);\n\n        Message(m)\n    }\n\n    pub fn parse_slice(p: &[u8]) -> Result<Message, Error> {\n        if p.len() != util::MESSAGE_SIZE {\n            return Err(Error::InvalidInputLength);\n        }\n\n        let mut a = [0; util::MESSAGE_SIZE];\n        a.copy_from_slice(p);\n        Ok(Self::parse(&a))\n    }\n\n    pub fn serialize(&self) -> [u8; util::MESSAGE_SIZE] {\n        self.0.b32()\n    }\n}\n\nimpl RecoveryId {\n    /// Parse recovery ID starting with 0.\n    pub fn parse(p: u8) -> Result<RecoveryId, Error> {\n        if p < 4 {\n            Ok(RecoveryId(p))\n        } else {\n            Err(Error::InvalidRecoveryId)\n        }\n    }\n\n    /// Parse recovery ID as Ethereum RPC format, starting with 27.\n    pub fn parse_rpc(p: u8) -> Result<RecoveryId, Error> {\n        if p >= 27 && p < 27 + 4 {\n            RecoveryId::parse(p - 27)\n        } else {\n            Err(Error::InvalidRecoveryId)\n        }\n    }\n\n    pub fn serialize(&self) -> u8 {\n        self.0\n    }\n}\n\nimpl Into<u8> for RecoveryId {\n    fn into(self) -> u8 {\n        self.0\n    }\n}\n\nimpl Into<i32> for RecoveryId {\n    fn into(self) -> i32 {\n        self.0 as i32\n    }\n}\n\nimpl<D: Digest + Default> SharedSecret<D> {\n    pub fn new_with_context(\n        pubkey: &PublicKey,\n        seckey: &SecretKey,\n        context: &ECMultContext,\n    ) -> Result<SharedSecret<D>, Error> {\n        let inner = match context.ecdh_raw::<D>(&pubkey.0, &seckey.0) {\n            Some(val) => val,\n            None => return Err(Error::InvalidSecretKey),\n        };\n\n        Ok(SharedSecret(inner))\n    }\n\n    #[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n    pub fn new(pubkey: &PublicKey, seckey: &SecretKey) -> Result<SharedSecret<D>, Error> {\n        Self::new_with_context(pubkey, seckey, &ECMULT_CONTEXT)\n    }\n}\n\nimpl<D: Digest> AsRef<[u8]> for SharedSecret<D> {\n    fn as_ref(&self) -> &[u8] {\n        &self.0.as_ref()\n    }\n}\n\n/// Check signature is a valid message signed by public key, using the given context.\npub fn verify_with_context(\n    message: &Message,\n    signature: &Signature,\n    pubkey: &PublicKey,\n    context: &ECMultContext,\n) -> bool {\n    context.verify_raw(&signature.r, &signature.s, &pubkey.0, &message.0)\n}\n\n#[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n/// Check signature is a valid message signed by public key.\npub fn verify(message: &Message, signature: &Signature, pubkey: &PublicKey) -> bool {\n    verify_with_context(message, signature, pubkey, &ECMULT_CONTEXT)\n}\n\n/// Recover public key from a signed message, using the given context.\npub fn recover_with_context(\n    message: &Message,\n    signature: &Signature,\n    recovery_id: &RecoveryId,\n    context: &ECMultContext,\n) -> Result<PublicKey, Error> {\n    context\n        .recover_raw(&signature.r, &signature.s, recovery_id.0, &message.0)\n        .map(PublicKey)\n}\n\n#[cfg(any(feature = \"static-context\", feature = \"lazy-static-context\"))]\n/// Recover public key from a signed message.\npub fn recover(\n    message: &Message,\n    signature: &Signature,\n    recovery_id: &RecoveryId,\n) -> Result<PublicKey, Error> {\n    recover_with_context(message, signature, recovery_id, &ECMULT_CONTEXT)\n}\n\n#[cfg(feature = \"hmac\")]\n/// Sign a message using the secret key, with the given context.\npub fn sign_with_context(\n    message: &Message,\n    seckey: &SecretKey,\n    context: &ECMultGenContext,\n) -> (Signature, RecoveryId) {\n    let seckey_b32 = seckey.0.b32();\n    let message_b32 = message.0.b32();\n\n    let mut drbg = HmacDRBG::<Sha256>::new(&seckey_b32, &message_b32, &[]);\n    let mut nonce = Scalar::default();\n    let mut overflow;\n\n    let result;\n    loop {\n        let generated = drbg.generate::<U32>(None);\n        overflow = bool::from(nonce.set_b32(array_ref!(generated, 0, 32)));\n\n        if !overflow && !nonce.is_zero() {\n            if let Ok(val) = context.sign_raw(&seckey.0, &message.0, &nonce) {\n                result = val;\n                break;\n            }\n        }\n    }\n\n    #[allow(unused_assignments)]\n    {\n        nonce = Scalar::default();\n    }\n    let (sigr, sigs, recid) = result;\n\n    (Signature { r: sigr, s: sigs }, RecoveryId(recid))\n}\n\n#[cfg(all(\n    feature = \"hmac\",\n    any(feature = \"static-context\", feature = \"lazy-static-context\")\n))]\n/// Sign a message using the secret key.\npub fn sign(message: &Message, seckey: &SecretKey) -> (Signature, RecoveryId) {\n    sign_with_context(message, seckey, &ECMULT_GEN_CONTEXT)\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::SecretKey;\n    use hex_literal::hex;\n\n    #[test]\n    fn secret_key_inverse_is_sane() {\n        let sk = SecretKey::parse(&[1; 32]).unwrap();\n        let inv = sk.inv();\n        let invinv = inv.inv();\n        assert_eq!(sk, invinv);\n        // Check that the inverse of `[1; 32]` is same as rust-secp256k1\n        assert_eq!(\n            inv,\n            SecretKey::parse(&hex!(\n                \"1536f1d756d1abf83aaf173bc5ee3fc487c93010f18624d80bd6d4038fadd59e\"\n            ))\n            .unwrap()\n        )\n    }\n\n    #[test]\n    fn secret_key_clear_is_correct() {\n        let mut sk = SecretKey::parse(&[1; 32]).unwrap();\n        sk.clear();\n        assert_eq!(sk.is_zero(), true);\n    }\n}\n"
  },
  {
    "path": "tests/serde.rs",
    "content": "#![cfg(feature = \"std\")]\n\nuse libsecp256k1::*;\n\nconst DEBUG_SECRET_KEY: [u8; 32] = [1u8; 32];\n// Public key for debug secret key\nconst SERIALIZED_DEBUG_PUBLIC_KEY: &str =\n    \"\\\"BBuExVZ7EmRAmV0+1aq6BWXXHhg0YEgZ/5wX9enV3QePcL6vj1iLVBUH/tamQsWrQt/fgSCn9jneUSLUemmo6NE=\\\"\";\n\nfn debug_public_key() -> PublicKey {\n    let skey = SecretKey::parse(&DEBUG_SECRET_KEY).unwrap();\n    PublicKey::from_secret_key(&skey)\n}\n\n#[test]\nfn test_serialize_public_key() {\n    let pkey = debug_public_key();\n    let serialized_pkey = serde_json::to_string(&pkey).unwrap();\n    assert_eq!(serialized_pkey, SERIALIZED_DEBUG_PUBLIC_KEY);\n}\n\n#[test]\nfn test_deserialize_public_key() {\n    let pkey: PublicKey = serde_json::from_str(&SERIALIZED_DEBUG_PUBLIC_KEY).unwrap();\n    assert_eq!(pkey, debug_public_key());\n}\n\n#[test]\nfn test_public_key_bincode_serde() {\n    let pkey = debug_public_key();\n    let serialized_pkey: Vec<u8> = bincode::serialize(&pkey).unwrap();\n    let pkey2 = bincode::deserialize(&serialized_pkey).unwrap();\n    assert_eq!(pkey, pkey2);\n}\n"
  },
  {
    "path": "tests/verify.rs",
    "content": "use libsecp256k1::*;\nuse secp256k1_test::{\n    key, rand::thread_rng, Error as SecpError, Message as SecpMessage, Secp256k1,\n    Signature as SecpSignature,\n};\n\n#[cfg(feature = \"hmac\")]\nmod signatures {\n    use crate::{recover, sign, verify, Message, PublicKey, SecretKey, SharedSecret, Signature};\n    use secp256k1_test::{\n        ecdh::SharedSecret as SecpSharedSecret,\n        key,\n        rand::thread_rng,\n        recovery::{\n            RecoverableSignature as SecpRecoverableSignature, RecoveryId as SecpRecoveryId,\n        },\n        All, Message as SecpMessage, Secp256k1, Signature as SecpSignature,\n    };\n    use sha2::Sha256;\n\n    fn genkey(\n        secp256k1: &Secp256k1<All>,\n    ) -> (key::PublicKey, key::SecretKey, PublicKey, SecretKey) {\n        let (secp_privkey, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n        let pubkey_a = secp_pubkey.serialize_uncompressed();\n        assert_eq!(pubkey_a.len(), 65);\n        let pubkey = PublicKey::parse(&pubkey_a).unwrap();\n        let mut seckey_a = [0u8; 32];\n        for i in 0..32 {\n            seckey_a[i] = secp_privkey[i];\n        }\n        let seckey = SecretKey::parse(&seckey_a).unwrap();\n\n        (secp_pubkey, secp_privkey, pubkey, seckey)\n    }\n\n    #[test]\n    fn test_signature_der() {\n        let secp256k1 = Secp256k1::new();\n\n        let message_arr = [5u8; 32];\n        let (privkey, _) = secp256k1.generate_keypair(&mut thread_rng());\n\n        assert!(privkey[..].len() == 32);\n        let mut privkey_a = [0u8; 32];\n        for i in 0..32 {\n            privkey_a[i] = privkey[i];\n        }\n\n        let ctx_privkey = SecretKey::parse(&privkey_a).unwrap();\n        let ctx_message = Message::parse(&message_arr);\n\n        let (signature, _) = sign(&ctx_message, &ctx_privkey);\n        let reconstructed = Signature::parse_der(signature.serialize_der().as_ref()).unwrap();\n        assert_eq!(signature, reconstructed);\n    }\n\n    #[test]\n    fn test_sign_verify() {\n        let secp256k1 = Secp256k1::new();\n\n        let message_arr = [6u8; 32];\n        let (secp_privkey, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n\n        let secp_message = SecpMessage::from_slice(&message_arr).unwrap();\n        let pubkey_a = secp_pubkey.serialize_uncompressed();\n        assert_eq!(pubkey_a.len(), 65);\n        let pubkey = PublicKey::parse(&pubkey_a).unwrap();\n        let mut seckey_a = [0u8; 32];\n        for i in 0..32 {\n            seckey_a[i] = secp_privkey[i];\n        }\n        let seckey = SecretKey::parse(&seckey_a).unwrap();\n        let message = Message::parse(&message_arr);\n\n        let (sig, recid) = sign(&message, &seckey);\n\n        // Self verify\n        assert!(verify(&message, &sig, &pubkey));\n\n        // Self recover\n        let recovered_pubkey = recover(&message, &sig, &recid).unwrap();\n        let rpa = recovered_pubkey.serialize();\n        let opa = pubkey.serialize();\n        let rpr: &[u8] = &rpa;\n        let opr: &[u8] = &opa;\n        assert_eq!(rpr, opr);\n\n        let signature_a = sig.serialize();\n        let secp_recid = SecpRecoveryId::from_i32(recid.into()).unwrap();\n        let secp_rec_signature =\n            SecpRecoverableSignature::from_compact(&signature_a, secp_recid).unwrap();\n        let secp_signature = SecpSignature::from_compact(&signature_a).unwrap();\n\n        // External verify\n        secp256k1\n            .verify(&secp_message, &secp_signature, &secp_pubkey)\n            .unwrap();\n\n        // External recover\n        let recovered_pubkey = secp256k1\n            .recover(&secp_message, &secp_rec_signature)\n            .unwrap();\n        let rpa = recovered_pubkey.serialize_uncompressed();\n        let rpr: &[u8] = &rpa;\n        assert_eq!(rpr, opr);\n    }\n\n    #[test]\n    fn test_failing_sign_verify() {\n        let seckey_a: [u8; 32] = [\n            169, 195, 92, 103, 2, 159, 75, 46, 158, 79, 249, 49, 208, 28, 48, 210, 5, 47, 136, 77,\n            21, 51, 224, 54, 213, 165, 90, 122, 233, 199, 0, 248,\n        ];\n        let seckey = SecretKey::parse(&seckey_a).unwrap();\n        let pubkey = PublicKey::from_secret_key(&seckey);\n        let message_arr = [6u8; 32];\n        let message = Message::parse(&message_arr);\n\n        let (sig, recid) = sign(&message, &seckey);\n        let tmp: u8 = recid.into();\n        assert_eq!(tmp, 1u8);\n\n        let recovered_pubkey = recover(&message, &sig, &recid).unwrap();\n        let rpa = recovered_pubkey.serialize();\n        let opa = pubkey.serialize();\n        let rpr: &[u8] = &rpa;\n        let opr: &[u8] = &opa;\n        assert_eq!(rpr, opr);\n    }\n\n    #[test]\n    fn test_shared_secret() {\n        let secp256k1 = Secp256k1::new();\n\n        let (spub1, ssec1, pub1, sec1) = genkey(&secp256k1);\n        let (spub2, ssec2, pub2, sec2) = genkey(&secp256k1);\n\n        let shared1 = SharedSecret::<Sha256>::new(&pub1, &sec2).unwrap();\n        let shared2 = SharedSecret::<Sha256>::new(&pub2, &sec1).unwrap();\n\n        let secp_shared1 = SecpSharedSecret::new(&spub1, &ssec2);\n        let secp_shared2 = SecpSharedSecret::new(&spub2, &ssec1);\n\n        assert_eq!(shared1.as_ref(), shared2.as_ref());\n\n        for i in 0..32 {\n            assert_eq!(shared1.as_ref()[i], secp_shared1[i]);\n        }\n\n        for i in 0..32 {\n            assert_eq!(shared2.as_ref()[i], secp_shared2[i]);\n        }\n    }\n}\n\n#[test]\nfn test_verify() {\n    let secp256k1 = Secp256k1::new();\n\n    let message_arr = [5u8; 32];\n    let (privkey, pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n    let message = SecpMessage::from_slice(&message_arr).unwrap();\n    let signature = secp256k1.sign(&message, &privkey);\n\n    let pubkey_a = pubkey.serialize_uncompressed();\n    assert_eq!(pubkey_a.len(), 65);\n\n    let ctx_pubkey = PublicKey::parse(&pubkey_a).unwrap();\n    let ctx_message = Message::parse(&message_arr);\n    let signature_a = signature.serialize_compact();\n    assert_eq!(signature_a.len(), 64);\n    let ctx_sig = Signature::parse_standard(&signature_a).expect(\"signature is valid\");\n\n    secp256k1.verify(&message, &signature, &pubkey).unwrap();\n    assert!(verify(&ctx_message, &ctx_sig, &ctx_pubkey));\n    let mut f_ctx_sig = ctx_sig;\n    f_ctx_sig.r.set_int(0);\n    if f_ctx_sig.r != ctx_sig.r {\n        assert!(!ECMULT_CONTEXT.verify_raw(\n            &f_ctx_sig.r,\n            &ctx_sig.s,\n            &ctx_pubkey.into(),\n            &ctx_message.0\n        ));\n    }\n    f_ctx_sig.r.set_int(1);\n    if f_ctx_sig.r != ctx_sig.r {\n        assert!(!ECMULT_CONTEXT.verify_raw(\n            &f_ctx_sig.r,\n            &ctx_sig.s,\n            &ctx_pubkey.into(),\n            &ctx_message.0\n        ));\n    }\n}\n\n#[test]\nfn secret_clear_on_drop() {\n    let secret: [u8; 32] = [1; 32];\n    let mut seckey = SecretKey::parse(&secret).unwrap();\n\n    clear_on_drop::clear::Clear::clear(&mut seckey);\n    assert_eq!(seckey, SecretKey::default());\n}\n\n#[test]\nfn test_recover() {\n    let secp256k1 = Secp256k1::new();\n\n    let message_arr = [5u8; 32];\n    let (privkey, pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n    let message = SecpMessage::from_slice(&message_arr).unwrap();\n    let signature = secp256k1.sign_recoverable(&message, &privkey);\n\n    let pubkey_a = pubkey.serialize_uncompressed();\n    assert_eq!(pubkey_a.len(), 65);\n\n    let ctx_message = Message::parse(&message_arr);\n    let (rec_id, signature_a) = signature.serialize_compact();\n    assert_eq!(signature_a.len(), 64);\n    let ctx_sig = Signature::parse_standard(&signature_a).expect(\"signature is valid\");\n\n    // secp256k1.recover(&message, &signature).unwrap();\n    let ctx_pubkey = recover(\n        &ctx_message,\n        &ctx_sig,\n        &RecoveryId::parse(rec_id.to_i32() as u8).unwrap(),\n    )\n    .unwrap();\n    let sp = ctx_pubkey.serialize();\n\n    let sps: &[u8] = &sp;\n    let gps: &[u8] = &pubkey_a;\n    assert_eq!(sps, gps);\n}\n\nfn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {\n    if hex.len() % 2 == 1 || hex.len() > target.len() * 2 {\n        return Err(());\n    }\n\n    let mut b = 0;\n    let mut idx = 0;\n    for c in hex.bytes() {\n        b <<= 4;\n        match c {\n            b'A'..=b'F' => b |= c - b'A' + 10,\n            b'a'..=b'f' => b |= c - b'a' + 10,\n            b'0'..=b'9' => b |= c - b'0',\n            _ => return Err(()),\n        }\n        if (idx & 1) == 1 {\n            target[idx / 2] = b;\n            b = 0;\n        }\n        idx += 1;\n    }\n    Ok(idx / 2)\n}\n\nmacro_rules! hex {\n    ($hex:expr) => {{\n        let mut result = vec![0; $hex.len() / 2];\n        from_hex($hex, &mut result).expect(\"valid hex string\");\n        result\n    }};\n}\n\n#[test]\nfn test_signature_der_lax() {\n    macro_rules! check_lax_sig {\n        ($hex:expr) => {{\n            let sig = hex!($hex);\n            assert!(Signature::parse_der_lax(&sig[..]).is_ok());\n        }};\n    }\n\n    check_lax_sig!(\"304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c\");\n    check_lax_sig!(\"304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f\");\n    check_lax_sig!(\"3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a\");\n    check_lax_sig!(\"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\");\n    check_lax_sig!(\"3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1\");\n    check_lax_sig!(\"3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60\");\n    check_lax_sig!(\"3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf\");\n}\n\n#[test]\nfn test_low_s() {\n    // nb this is a transaction on testnet\n    // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9\n    //      input number 3\n    let sig = hex!(\"3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\");\n    let pk = hex!(\"031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43\");\n    let msg = hex!(\"a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d\");\n\n    let secp = Secp256k1::new();\n    let mut sig = Signature::parse_der(&sig[..]).unwrap();\n    let pk = key::PublicKey::from_slice(&pk[..]).unwrap();\n    let msg = SecpMessage::from_slice(&msg[..]).unwrap();\n\n    // without normalization we expect this will fail\n    assert_eq!(\n        secp.verify(\n            &msg,\n            &SecpSignature::from_compact(&sig.serialize()).unwrap(),\n            &pk\n        ),\n        Err(SecpError::IncorrectSignature)\n    );\n    // after normalization it should pass\n    sig.normalize_s();\n    assert_eq!(\n        secp.verify(\n            &msg,\n            &SecpSignature::from_compact(&sig.serialize()).unwrap(),\n            &pk\n        ),\n        Ok(())\n    );\n}\n\n#[test]\nfn test_convert_key1() {\n    let secret: [u8; 32] = [\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x01,\n    ];\n    let expected: &[u8] = &[\n        0x04, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87,\n        0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16,\n        0xf8, 0x17, 0x98, 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc,\n        0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0,\n        0x8f, 0xfb, 0x10, 0xd4, 0xb8,\n    ];\n    let seckey = SecretKey::parse(&secret).unwrap();\n    let pubkey = PublicKey::from_secret_key(&seckey);\n    assert_eq!(expected, &pubkey.serialize()[..]);\n    let pubkey_compressed = PublicKey::parse_compressed(&pubkey.serialize_compressed()).unwrap();\n    assert_eq!(expected, &pubkey_compressed.serialize()[..]);\n}\n\n#[test]\nfn test_convert_key2() {\n    let secret: [u8; 32] = [\n        0x4d, 0x5d, 0xb4, 0x10, 0x7d, 0x23, 0x7d, 0xf6, 0xa3, 0xd5, 0x8e, 0xe5, 0xf7, 0x0a, 0xe6,\n        0x3d, 0x73, 0xd7, 0x65, 0x8d, 0x40, 0x26, 0xf2, 0xee, 0xfd, 0x2f, 0x20, 0x4c, 0x81, 0x68,\n        0x2c, 0xb7,\n    ];\n    let expected: &[u8] = &[\n        0x04, 0x3f, 0xa8, 0xc0, 0x8c, 0x65, 0xa8, 0x3f, 0x6b, 0x4e, 0xa3, 0xe0, 0x4e, 0x1c, 0xc7,\n        0x0c, 0xbe, 0x3c, 0xd3, 0x91, 0x49, 0x9e, 0x3e, 0x05, 0xab, 0x7d, 0xed, 0xf2, 0x8a, 0xff,\n        0x9a, 0xfc, 0x53, 0x82, 0x00, 0xff, 0x93, 0xe3, 0xf2, 0xb2, 0xcb, 0x50, 0x29, 0xf0, 0x3c,\n        0x7e, 0xbe, 0xe8, 0x20, 0xd6, 0x3a, 0x4c, 0x5a, 0x95, 0x41, 0xc8, 0x3a, 0xce, 0xbe, 0x29,\n        0x3f, 0x54, 0xca, 0xcf, 0x0e,\n    ];\n    let seckey = SecretKey::parse(&secret).unwrap();\n    let pubkey = PublicKey::from_secret_key(&seckey);\n    assert_eq!(expected, &pubkey.serialize()[..]);\n    let pubkey_compressed = PublicKey::parse_compressed(&pubkey.serialize_compressed()).unwrap();\n    assert_eq!(expected, &pubkey_compressed.serialize()[..]);\n}\n\n#[test]\nfn test_convert_anykey() {\n    let secp256k1 = Secp256k1::new();\n    let (secp_privkey, secp_pubkey) = secp256k1.generate_keypair(&mut thread_rng());\n\n    let mut secret = [0u8; 32];\n    for i in 0..32 {\n        secret[i] = secp_privkey[i];\n    }\n\n    let seckey = SecretKey::parse(&secret).unwrap();\n    let pubkey = PublicKey::from_secret_key(&seckey);\n    let public = pubkey.serialize();\n    let public_compressed = pubkey.serialize_compressed();\n    let pubkey_r: &[u8] = &public;\n    let pubkey_compressed_r: &[u8] = &public_compressed;\n\n    let secp_pubkey_a = secp_pubkey.serialize_uncompressed();\n    assert_eq!(secp_pubkey_a.len(), 65);\n    let secp_pubkey_compressed_a = secp_pubkey.serialize();\n    assert_eq!(secp_pubkey_compressed_a.len(), 33);\n    let secp_pubkey_r: &[u8] = &secp_pubkey_a;\n    let secp_pubkey_compressed_r: &[u8] = &secp_pubkey_compressed_a;\n\n    assert_eq!(secp_pubkey_r, pubkey_r);\n    assert_eq!(secp_pubkey_compressed_r, pubkey_compressed_r);\n}\n\n#[test]\nfn test_pubkey_combine() {\n    let pk1 = PublicKey::parse(&[\n        4, 126, 60, 36, 91, 73, 177, 194, 111, 11, 3, 99, 246, 204, 86, 122, 109, 85, 28, 43, 169,\n        243, 35, 76, 152, 90, 76, 241, 17, 108, 232, 215, 115, 15, 19, 23, 164, 151, 43, 28, 44,\n        59, 141, 167, 134, 112, 105, 251, 15, 193, 183, 224, 238, 154, 204, 230, 163, 216, 235,\n        112, 77, 239, 98, 135, 132,\n    ])\n    .unwrap();\n    let pk2 = PublicKey::parse(&[\n        4, 40, 127, 167, 223, 38, 53, 6, 223, 67, 83, 204, 60, 226, 227, 107, 231, 172, 34, 3, 187,\n        79, 112, 167, 0, 217, 118, 69, 218, 189, 208, 150, 190, 54, 186, 220, 95, 80, 220, 183,\n        202, 117, 160, 18, 84, 245, 181, 23, 32, 51, 73, 178, 173, 92, 118, 92, 122, 83, 49, 54,\n        195, 194, 16, 229, 39,\n    ])\n    .unwrap();\n    let cpk = PublicKey::parse(&[\n        4, 101, 166, 20, 152, 34, 76, 121, 113, 139, 80, 13, 92, 122, 96, 38, 194, 205, 149, 93,\n        19, 147, 132, 195, 173, 42, 86, 26, 221, 170, 127, 180, 168, 145, 21, 75, 45, 248, 90, 114,\n        118, 62, 196, 194, 143, 245, 204, 184, 16, 175, 202, 175, 228, 207, 112, 219, 94, 237, 75,\n        105, 186, 56, 102, 46, 147,\n    ])\n    .unwrap();\n\n    assert_eq!(PublicKey::combine(&[pk1, pk2]).unwrap(), cpk);\n}\n\n#[test]\nfn test_pubkey_equality() {\n    for _ in 0..10 {\n        let secret = SecretKey::random(&mut rand::rngs::OsRng);\n        let public = PublicKey::from_secret_key(&secret);\n\n        let public2 = PublicKey::parse(&public.serialize()).unwrap();\n        let public3 = PublicKey::parse_compressed(&public.serialize_compressed()).unwrap();\n\n        // Reflexivity\n        assert_eq!(public, public);\n        assert_eq!(public2, public2);\n        assert_eq!(public3, public3);\n\n        // Symmetry\n        assert_eq!(public2, public);\n        assert_eq!(public, public2);\n        assert_eq!(public2, public3);\n        assert_eq!(public3, public2);\n\n        // Transitivity\n        assert_eq!(public, public3);\n        assert_eq!(public3, public);\n    }\n}\n"
  },
  {
    "path": "tests/wycheproof.rs",
    "content": "use serde::Deserialize;\nuse sha2::Digest;\nuse std::collections::HashMap;\n\n#[derive(Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[allow(dead_code)]\nstruct TestCollection {\n    algorithm: String,\n    generator_version: String,\n    number_of_tests: usize,\n    header: Vec<String>,\n    notes: HashMap<String, String>,\n    schema: String,\n    test_groups: Vec<TestGroup>,\n}\n\n#[derive(Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[allow(dead_code)]\nstruct TestGroup {\n    key: TestKey,\n    key_der: String,\n    key_pem: String,\n    sha: String,\n    #[serde(rename = \"type\")]\n    typ: String,\n    tests: Vec<TestUnit>,\n}\n\n#[derive(Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[allow(dead_code)]\nstruct TestKey {\n    curve: String,\n    key_size: usize,\n    #[serde(rename = \"type\")]\n    typ: String,\n    uncompressed: String,\n    wx: String,\n    wy: String,\n}\n\n#[derive(Deserialize)]\n#[serde(rename_all = \"camelCase\")]\n#[allow(dead_code)]\nstruct TestUnit {\n    tc_id: usize,\n    comment: String,\n    msg: String,\n    sig: String,\n    result: TestResult,\n    flags: Vec<String>,\n}\n\n#[derive(Deserialize, PartialEq, Eq, Debug)]\n#[serde(rename_all = \"camelCase\")]\nenum TestResult {\n    Valid,\n    Acceptable,\n    Invalid,\n}\n\nenum TestError {\n    MessageDecoding,\n    SignatureDecoding,\n    Verification,\n}\n\nfn test_unit(test: &TestUnit, key: &libsecp256k1::PublicKey) -> Result<(), TestError> {\n    println!(\"tcId: {}, comment: {}\", test.tc_id, test.comment);\n\n    let msg_raw = hex::decode(&test.msg).unwrap();\n    let sig_raw = hex::decode(&test.sig).unwrap();\n\n    let msg_hashed_raw = sha2::Sha256::digest(&msg_raw);\n    let msg = libsecp256k1::Message::parse_slice(&msg_hashed_raw)\n        .map_err(|_| TestError::MessageDecoding)?;\n    let sig =\n        libsecp256k1::Signature::parse_der(&sig_raw).map_err(|_| TestError::SignatureDecoding)?;\n\n    if libsecp256k1::verify(&msg, &sig, &key) {\n        Ok(())\n    } else {\n        Err(TestError::Verification)\n    }\n}\n\n#[test]\nfn test_wycheproof() {\n    let test_collection_str = include_str!(\"../res/ecdsa_secp256k1_sha256_test.json\");\n    let test_collection: TestCollection = serde_json::from_str(test_collection_str).unwrap();\n\n    for test_group in test_collection.test_groups {\n        assert_eq!(test_group.key.typ, \"EcPublicKey\");\n        assert_eq!(test_group.key.curve, \"secp256k1\");\n        assert_eq!(test_group.key.key_size, 256);\n\n        let key_raw = hex::decode(test_group.key.uncompressed).unwrap();\n        let key = libsecp256k1::PublicKey::parse_slice(&key_raw, None).unwrap();\n\n        for test in test_group.tests {\n            let res = test_unit(&test, &key);\n\n            match res {\n                Ok(()) => assert!(test.result == TestResult::Valid),\n                Err(TestError::Verification) => assert_eq!(test.result, TestResult::Invalid),\n                Err(TestError::MessageDecoding) => assert_eq!(test.result, TestResult::Invalid),\n                // libsecp256k1 do not use any legacy formats, so \"acceptable\"\n                // result in wycheproof is considered the same as invalid.\n                Err(TestError::SignatureDecoding) => assert!(\n                    test.result == TestResult::Acceptable || test.result == TestResult::Invalid\n                ),\n            }\n        }\n    }\n}\n"
  }
]