Full Code of supranational/blst for AI

master f62244ef50ad cached
229 files
3.7 MB
968.7k tokens
1673 symbols
1 requests
Download .txt
Showing preview only (3,871K chars total). Download the full file or copy to clipboard to get everything.
Repository: supranational/blst
Branch: master
Commit: f62244ef50ad
Files: 229
Total size: 3.7 MB

Directory structure:
gitextract_z39wz_mc/

├── .gitattributes
├── .github/
│   └── workflows/
│       ├── ci.yml
│       ├── codeql-analysis.yml
│       └── golang-lint.yml
├── .gitignore
├── .golangci.yml
├── .lgtm.yml
├── .travis.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── bindings/
│   ├── blst.h
│   ├── blst.hpp
│   ├── blst.swg
│   ├── blst_aux.h
│   ├── c#/
│   │   ├── poc.cs
│   │   ├── poc.csproj
│   │   ├── run.me
│   │   └── supranational.blst.cs
│   ├── go/
│   │   ├── README.md
│   │   ├── blst.go
│   │   ├── blst.tgo
│   │   ├── blst_htoc_test.go
│   │   ├── blst_miller_loop_test.go
│   │   ├── blst_minpk.tgo
│   │   ├── blst_minpk_test.go
│   │   ├── blst_minsig_test.go
│   │   ├── blst_misc.tgo
│   │   ├── blst_px.tgo
│   │   ├── blst_wasm.go
│   │   ├── cgo_assembly.S
│   │   ├── cgo_server.c
│   │   ├── generate.py
│   │   └── rb_tree.go
│   ├── rust/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── benches/
│   │   │   └── blst_benches.rs
│   │   ├── build.rs
│   │   ├── publish.sh
│   │   ├── rustfmt.toml
│   │   └── src/
│   │       ├── bindings.rs
│   │       ├── lib.rs
│   │       ├── pippenger-no_std.rs
│   │       ├── pippenger-test_mod.rs
│   │       └── pippenger.rs
│   ├── vectors/
│   │   └── hash_to_curve/
│   │       ├── BLS12381G1_XMD_SHA-256_SSWU_NU_.json
│   │       ├── BLS12381G1_XMD_SHA-256_SSWU_RO_.json
│   │       ├── BLS12381G2_XMD_SHA-256_SSWU_NU_.json
│   │       ├── BLS12381G2_XMD_SHA-256_SSWU_RO_.json
│   │       ├── README
│   │       ├── expand_message_xmd_SHA256_256.json
│   │       └── expand_message_xmd_SHA256_38.json
│   └── zig/
│       ├── README.md
│       ├── blst.zig
│       ├── c.zig
│       ├── generate.py
│       └── tests.zig
├── build/
│   ├── assembly.S
│   ├── bindings_trim.pl
│   ├── cheri/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_384-armv8.S
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── div3w-armv8.S
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   └── sha256-armv8.S
│   ├── coff/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── elf/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── mach-o/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── refresh.sh
│   ├── srcroot.go
│   └── win64/
│       ├── add_mod_256-armv8.asm
│       ├── add_mod_256-x86_64.asm
│       ├── add_mod_384-armv8.asm
│       ├── add_mod_384-x86_64.asm
│       ├── add_mod_384x384-x86_64.asm
│       ├── blst.def
│       ├── ct_inverse_mod_256-armv8.asm
│       ├── ct_inverse_mod_256-x86_64.asm
│       ├── ct_inverse_mod_384-armv8.asm
│       ├── ct_is_square_mod_384-armv8.asm
│       ├── ct_is_square_mod_384-x86_64.asm
│       ├── ctq_inverse_mod_384-x86_64.asm
│       ├── ctx_inverse_mod_384-x86_64.asm
│       ├── div3w-armv8.asm
│       ├── div3w-x86_64.asm
│       ├── dll.c
│       ├── mul_mont_256-armv8.asm
│       ├── mul_mont_384-armv8.asm
│       ├── mulq_mont_256-x86_64.asm
│       ├── mulq_mont_384-x86_64.asm
│       ├── mulx_mont_256-x86_64.asm
│       ├── mulx_mont_384-x86_64.asm
│       ├── sha256-armv8.asm
│       └── sha256-x86_64.asm
├── build.bat
├── build.sh
├── build.zig
├── build.zig.zon
└── src/
    ├── aggregate.c
    ├── asm/
    │   ├── add_mod_256-armv8.pl
    │   ├── add_mod_256-x86_64.pl
    │   ├── add_mod_384-armv8.pl
    │   ├── add_mod_384-x86_64.pl
    │   ├── add_mod_384x384-x86_64.pl
    │   ├── arm-xlate.pl
    │   ├── ct_inverse_mod_256-armv8.pl
    │   ├── ct_inverse_mod_256-x86_64.pl
    │   ├── ct_inverse_mod_384-armv8.pl
    │   ├── ct_is_square_mod_384-armv8.pl
    │   ├── ct_is_square_mod_384-x86_64.pl
    │   ├── ctq_inverse_mod_384-x86_64.pl
    │   ├── ctx_inverse_mod_384-x86_64.pl
    │   ├── div3w-armv8.pl
    │   ├── div3w-x86_64.pl
    │   ├── mul_mont_256-armv8.pl
    │   ├── mul_mont_384-armv8.pl
    │   ├── mulq_mont_256-x86_64.pl
    │   ├── mulq_mont_384-x86_64.pl
    │   ├── mulx_mont_256-x86_64.pl
    │   ├── mulx_mont_384-x86_64.pl
    │   ├── sha256-armv8.pl
    │   ├── sha256-portable-x86_64.pl
    │   ├── sha256-x86_64.pl
    │   └── x86_64-xlate.pl
    ├── blst_t.hpp
    ├── bulk_addition.c
    ├── bytes.h
    ├── client_min_pk.c
    ├── client_min_sig.c
    ├── consts.c
    ├── consts.h
    ├── cpuid.c
    ├── e1.c
    ├── e2.c
    ├── ec_mult.h
    ├── ec_ops.h
    ├── errors.h
    ├── exp.c
    ├── exports.c
    ├── fields.h
    ├── fp12_tower.c
    ├── hash_to_field.c
    ├── keygen.c
    ├── map_to_g1.c
    ├── map_to_g2.c
    ├── multi_scalar.c
    ├── no_asm.h
    ├── pairing.c
    ├── pentaroot-addchain.h
    ├── pentaroot.c
    ├── point.h
    ├── rb_tree.c
    ├── recip-addchain.h
    ├── recip.c
    ├── server.c
    ├── sha256.h
    ├── sqrt-addchain.h
    ├── sqrt.c
    ├── vect.c
    └── vect.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
*.pl linguist-language=assembly
*.h linguist-language=c
*.tgo linguist-language=go


================================================
FILE: .github/workflows/ci.yml
================================================
name: build

on:
  push:
    branches:
    - '**'
  workflow_dispatch:
    branches:
    - '**'
  pull_request:
    branches:
    - master

jobs:
  rust-n-go:
    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        os: [ ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-latest ]

    steps:
    - uses: actions/checkout@v6

    - name: Get date
      id: get-date
      run: echo "date=$(date -u +%Y-%m)" >> $GITHUB_OUTPUT
      shell: bash

    - uses: actions/cache@v5
      with:
        path: |
          ~/.cargo/registry
          **/Cargo.lock
          **/bindings/rust/target
          ~/.wasmtime
        key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ steps.get-date.outputs.date }}

    - name: Environment
      shell: bash
      run: |
        lscpu 2>/dev/null && echo --- || true
        sysctl hw 2>/dev/null && echo --- || true
        env | sort

    - name: Install Wasmtime
      if: ${{ runner.os == 'Linux' }}
      shell: bash
      run: if [ ! -d ~/.wasmtime/bin ]; then curl https://wasmtime.dev/install.sh -sSf | bash; fi

    - name: Rust
      shell: bash
      run: |
        rustc --version --verbose
        export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
        cd bindings/rust
        sed "s/^crit/#crit/" Cargo.toml > Cargo.$$.toml && \
        mv Cargo.$$.toml Cargo.toml
        if [ "$GITHUB_EVENT_NAME" != "pull_request" ]; then
            cargo update
        fi
        cargo test --release
        echo '--- test portable'
        echo
        cargo test --release --features=portable
        echo '--- test no-threads'
        echo
        cargo test --release --features=no-threads
        echo '--- test serde-secret'
        echo
        cargo test --release --features=serde-secret
        echo '--- test no_std'
        echo
        echo 'set -e'                                       > ulimit-s
        echo 'export RUST_MIN_STACK=$(($1 * 1024)); shift'  >> ulimit-s
        echo 'exec "$@"'                                    >> ulimit-s
        triplet=`rustc -vV | awk '/host:/ {print $2}' | tr 'a-z-' 'A-Z_'`
        stack_size=`[ $RUNNER_OS = "Windows" ] && echo 65 || echo 56`
        env BLST_TEST_NO_STD= \
            CARGO_TARGET_${triplet}_RUNNER="bash ulimit-s $stack_size" \
            cargo test --release
        if [ -x ~/.wasmtime/bin/wasmtime ]; then
            echo '--- test wasm32-wasip1'
            echo
            rustup target add wasm32-wasip1
            env CARGO_TARGET_WASM32_WASIP1_RUNNER=~/.wasmtime/bin/wasmtime \
                cargo test --release --target=wasm32-wasip1
            cargo clean -p blst --release --target=wasm32-wasip1
            echo
        fi
        if [ $RUNNER_OS = "Linux" ]; then
            if [ `uname -p` = "x86_64" ]; then
                echo '--- test -mlvi-hardening'
                echo
                env CC=clang CFLAGS="-mlvi-hardening -D__SGX_LVI_HARDENING__" \
                    cargo test --release
                echo '--- build x86_64-fortanix-unknown-sgx'
                echo
                rustup target add x86_64-fortanix-unknown-sgx
                cargo test --no-run --release --target=x86_64-fortanix-unknown-sgx
                cargo clean -p blst --release --target=x86_64-fortanix-unknown-sgx
                echo
            fi
            echo '--- dry-run publish'
            echo
            ./publish.sh --dry-run
        elif [ $RUNNER_OS = "macOS" ]; then
            if [ $RUNNER_ARCH = "ARM64" ]; then
                echo '--- test x86_64-apple-darwin'
                echo
                rustup target add x86_64-apple-darwin
                cargo test --release --target=x86_64-apple-darwin
                cargo clean -p blst --release --target=x86_64-apple-darwin
                echo
            else
                echo '--- build aarch64-apple-darwin'
                echo
                rustup target add aarch64-apple-darwin
                cargo test --no-run --release --target=aarch64-apple-darwin
                cargo clean -p blst --release --target=aarch64-apple-darwin
                echo
            fi
            echo '--- build aarch64-apple-ios'
            echo
            rustup target add aarch64-apple-ios
            env IPHONEOS_DEPLOYMENT_TARGET=10.0 \
                cargo test --no-run --release --target=aarch64-apple-ios
            cargo clean -p blst --release --target=aarch64-apple-ios
            echo
        elif [ $RUNNER_OS = "Windows" -a $RUNNER_ARCH = "X64" ]; then
            if which clang-cl > /dev/null 2>&1; then
                echo '-- test i686-pc-windows-msvc'
                echo
                rustup target add i686-pc-windows-msvc
                cargo test --release --target=i686-pc-windows-msvc
                cargo clean -p blst --release --target=i686-pc-windows-msvc
                echo
            fi
            echo '-- test x86_64-pc-windows-gnu'
            echo
            rustup target add x86_64-pc-windows-gnu
            cargo test --release --target=x86_64-pc-windows-gnu
            cargo clean -p blst --release --target=x86_64-pc-windows-gnu
            echo
        fi
        echo
        echo '--- cargo clippy'
        echo
        echo 'msrv = "1.56"' > .clippy.toml
        cargo clippy --release
        cargo clean -p blst
        cargo clean -p blst --release
        rm -rf target/.rustc_info.json
        rm -rf target/package
        rm -rf target/{debug,release}/incremental
        rm -rf target/*/{debug,release}/incremental
        rm -rf ~/.cargo/registry/src
        rm -rf ~/.cargo/registry/index/*/.cache
        mkdir -p ~/.wasmtime

    - name: Go
      if: ${{ runner.os != 'Windows' || runner.arch != 'ARM64' }}
      shell: bash
      run: |
        go version 2>/dev/null || exit 0
        if ! (grep -q -e '^flags.*\badx\b' /proc/cpuinfo) 2>/dev/null; then
            export CGO_CFLAGS="-O -D__BLST_PORTABLE__"
        fi
        cd bindings/go
        go test -test.v

  misc-ubuntu-latest:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v6

    - uses: actions/cache@v5
      with:
        path: ~/swig
        key: ${{ runner.os }}-swig-github

    - uses: actions/setup-java@v5
      with:
        distribution: temurin
        java-version: 11

    - uses: actions/setup-node@v6
      with:
        node-version: '20.x'

    - name: Environment
      run: |
        lscpu
        echo ---
        env | sort

    - name: Python
      run: if [ -x bindings/python/run.me ]; then bindings/python/run.me; fi

    - name: Java
      run: if [ -x bindings/java/run.me ]; then bindings/java/run.me; fi

    - name: Node.js
      run: |
        node_js=bindings/node.js
        if [ -x $node_js/run.me ]; then
            if [ ! -x ~/swig/bin/swig ]; then
              ( git clone --branch v4.3.0 https://github.com/swig/swig;
                cd swig;
                ./autogen.sh;
                ./configure --prefix=$HOME/swig;
                make;
                make install;
                (cd ~/swig/share/swig && ln -s `ls` current)
              )
            fi
            env PATH=~/swig/bin:$PATH SWIG_LIB=~/swig/share/swig/current \
                $node_js/run.me
        fi
    - name: node-gyp
      run: |
        node_js=bindings/node.js
        if [ -f $node_js/binding.gyp -a -f $node_js/blst_wrap.cpp ]; then
            npm install --global node-gyp || true
            if which node-gyp > /dev/null 2>&1; then
              ( export PATH=~/swig/bin:$PATH SWIG_LIB=~/swig/share/swig/current;
                cd $node_js;
                node-gyp configure;
                node-gyp build;
                env NODE_PATH=build/Release: node runnable.js;
              )
            fi
        fi
    - name: TypeScript
      run: |
        node_js=bindings/node.js
        if [ -f $node_js/blst.hpp.ts -a -f $node_js/blst.node ]; then
            npm install --global typescript || true
            if which tsc > /dev/null 2>&1; then
              ( cd $node_js;
                npm install @types/node;
                tsc runnable.ts --ignoreConfig --types node --module commonjs;
                env NODE_PATH=.: node runnable.js;
              )
           fi
        fi

    - name: Emscripten
      uses: docker://emscripten/emsdk
      with:
        args: >
          bindings/emscripten/run.me -O2

    - name: C#
      run: |
        if [ -x bindings/c#/run.me ]; then
            bindings/c#/run.me;
            if which dotnet > /dev/null 2>&1; then
                cd bindings/c#
                [ -f libblst.dll.so ] || ../../build.sh -dll
                dotnet run -c Release
            fi
        fi

    - uses: actions/cache@v5
      with:
        path: |
          ~/.cache/zig
          ~/zig-x86_64-linux-*
          ~/.wasmtime
        key: ${{ runner.os }}-zig-github

    - name: Zig
      run: |
        ver=0.15.2
        base_dir=zig-x86_64-linux-$ver
        if [ ! -d ~/$base_dir ]; then
            curl -sSf https://ziglang.org/download/$ver/$base_dir.tar.xz | unxz -c | tar xf - --directory ~
        fi
        if [ -x ~/$base_dir/zig ]; then
            PATH=~/$base_dir:$PATH
            zig build test --summary new
            echo '--- test wasm32-wasi'
            if [ ! -d ~/.wasmtime ]; then
                curl https://wasmtime.dev/install.sh -sSf | bash
            fi
            PATH=~/.wasmtime/bin:$PATH
            zig build test -Dtarget=wasm32-wasi -fwasmtime --summary new
        fi


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "CodeQL"

on:
  push:
    branches:
      - '**'
    paths:
      - 'src/*'
      - 'bindings/c#/*'
      - '.github/workflows/codeql-analysis.yml'
  pull_request:
    branches:
      - master
    paths:
      - 'src/*'
      - 'bindings/c#/*'
  #schedule:
  #  - cron: '0 23+ * * 4'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest

    permissions:
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'cpp', 'csharp' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v6
      with:
        # We must fetch at least the immediate parents so that if this is
        # a pull request then we can checkout the head.
        fetch-depth: 2

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v4
      with:
        languages: ${{ matrix.language }}
        queries: security-extended

    - if: matrix.language == 'cpp'
      name: Custom build
      run: ./build.sh -m32 -ffreestanding

    - if: matrix.language != 'cpp'
      name: Autobuild
      uses: github/codeql-action/autobuild@v4

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v4



================================================
FILE: .github/workflows/golang-lint.yml
================================================
name: golang-lint

on:
  push:
    branches:
      - '**'
    paths:
      - 'bindings/go/*.go'
      - '.github/workflows/golang-lint.yml'
      - '.golangci.yml'
  pull_request:
    branches:
      - master
    paths:
      - 'bindings/go/*.go'

jobs:
  golang-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: '>=1.21'
          cache: false
      - name: "go version"
        run: go version
      - uses: golangci/golangci-lint-action@v9
        with:
          # Require: The version of golangci-lint to use.
          # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
          # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
          version: v2.9

          # Optional: working directory, useful for monorepos
          # working-directory: somedir

          # Optional: golangci-lint command line arguments.
          #
          # Note: By default, the `.golangci.yml` file should be at the root of the repository.
          # The location of the configuration file can be changed by using `--config=`
          # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 

          # Optional: show only new issues if it's a pull request. The default value is `false`.
          # only-new-issues: true

          # Optional: if set to true, then all caching functionality will be completely disabled,
          #           takes precedence over all other caching options.
          skip-cache: true

          # Optional: if set to true, then the action won't cache or restore ~/go/pkg.
          # skip-pkg-cache: true

          # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build.
          # skip-build-cache: true

          # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
          # install-mode: "goinstall"


================================================
FILE: .gitignore
================================================
# Prerequisites
*.d

# Object files
*.o
*.ko
*.obj
*.elf

# Linker output
*.ilk
*.map
*.exp

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo

# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

# Debug files
*.dSYM/
*.su
*.idb
*.pdb

# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

# Open swap files
*.swp

# Emacs backup files
*~

# Rust build 
Cargo.lock
bindings/rust/target
bindings/rust/blst

# These are customarily filled with swig artefacts
bindings/python
bindings/java
bindings/node.js

bindings/emscripten
bin/
obj/

zig-out
.zig-cache


================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
  default: all
  disable:
    # just whining
    - copyloopvar                       # go>=1.22
    - cyclop
    - dupword
    - forbidigo
    - funlen
    - gochecknoglobals
    - gochecknoinits
    - gocognit
    - gocritic
    - gocyclo
    - godot
    - intrange                          # go>=1.22
    - lll
    - mnd
    - nestif
    - nlreturn
    - varnamelen
    - whitespace
    - wsl
    - wsl_v5
    # auto-generation artefact
    - dupl
    # maybe some day...
    - godoclint
    - godox
    - maintidx
    # maybe some day in tests...
    - forcetypeassert
    - nonamedreturns
    - perfsprint
    - testpackage
    # 83 active linters remaining including gosec, gosimple, govet, etc.
  settings:
    revive:
      enable-all-rules: true
      rules:
        - name: add-constant
          disabled: true
        - name: argument-limit
          disabled: true
        - name: cognitive-complexity    # similar to 'gocognit' above
          disabled: true
        - name: cyclomatic              # similar to 'cyclop' & 'gocyclo' above
          disabled: true
        - name: empty-block
          disabled: true
        - name: empty-lines
          disabled: true
        - name: flag-parameter
          disabled: true
        - name: function-length         # similar to 'funlen' above
          disabled: true
        - name: function-result-limit
          disabled: true
        - name: increment-decrement
          disabled: true
        - name: line-length-limit       # similar to 'lll' above
          disabled: true
        - name: max-public-structs
          disabled: true
        - name: package-directory-mismatch
          disabled: true
        - name: receiver-naming
          disabled: true
        - name: var-naming
          disabled: true
        - name: unchecked-type-assertion # similar to 'forcetypeassert' above
          disabled: true
        - name: unexported-naming
          disabled: true
        - name: unhandled-error
          arguments:
            - fmt.Println
            - fmt.Printf
        - name: use-any                 # applicable to go>=1.18 only
          disabled: true
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    paths:
      - third_party$
      - builtin$
      - examples$
formatters:
  exclusions:
    generated: lax
    paths:
      - third_party$
      - builtin$
      - examples$


================================================
FILE: .lgtm.yml
================================================
queries:
  - include: "*"
  - exclude: cpp/unused-static-function
  - exclude: cpp/include-non-header
  - exclude: cs/call-to-unmanaged-code
  - exclude: cs/unmanaged-code

extraction:
  cpp:
    index:
      build_command:
      - ./build.sh -m32
  go:
    index:
      build_command:
      - (cd bindings/go; go test -c)

  csharp:
    index:
      nuget_restore: false



================================================
FILE: .travis.yml
================================================
branches:
    only:
      - /.*/

language: rust

git:
    quiet: true

os:
    - linux

arch:
    - arm64
    - s390x

before_script:
    - lscpu 2>/dev/null && echo --- || true
    - env | sort

script:
    - if [ "$TRAVIS_LANGUAGE" = "rust" ]; then
          if [ "$TRAVIS_OS_NAME" = "windows" ]; then
              rustup set default-host x86_64-pc-windows-msvc;
              export ML=-nologo;
          fi;
          ( cd bindings/rust;
            if [ -f target/Cargo.lock ]; then
                mv -f target/Cargo.lock .;
            fi;
            NOW=`date +%s`;
            REF=.cargo/registry/index/*/.last-updated;
            THEN=`(stat -c %Y "$TRAVIS_HOME"/$REF || stat -f %m "$TRAVIS_HOME"/$REF) 2>/dev/null`;
            if [ $(($NOW - ${THEN:-0})) -gt 604800 ]; then
                env CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse cargo update;
            fi;
            cargo test --release )
      fi
    - if which go > /dev/null 2>&1; then
          go version;
          if ! (grep -q -e '^flags.*\badx\b' /proc/cpuinfo) 2>/dev/null; then
              export CGO_CFLAGS="-O -D__BLST_PORTABLE__";
          fi;
          (cd bindings/go; go test -test.v)
      fi

matrix:
    include:
      - os: linux
        arch: arm64
        language: go

notifications:
    email: false

before_cache:
    - if [ "$TRAVIS_LANGUAGE" = "rust" ]; then
        ( cd bindings/rust;
          cargo clean -p blst; cargo clean -p blst --release;
          rm -rf target/.rustc_info.json;
          rm -rf target/{debug,release}/incremental;
          mv -f Cargo.lock target )
      fi
    - (cd "$TRAVIS_HOME"; rm -rf .cargo/registry/src)
    - (cd "$TRAVIS_HOME"; rm -rf .cargo/registry/index/*/.cache)

cache:
    cargo: true
    directories:
      - bindings/rust/target



================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
[![Actions status](https://github.com/supranational/blst/workflows/build/badge.svg)](https://github.com/supranational/blst/actions) [![CodeQL status](https://github.com/supranational/blst/workflows/CodeQL/badge.svg)](https://github.com/supranational/blst/actions/workflows/codeql-analysis.yml)
<div align="left">
  <img src=blst_logo_small.png>
</div>

# blst
blst (pronounced 'blast') is a BLS12-381 signature library focused on performance and security. It is written in C and assembly.

## Table of Contents

  * [Status](#status)
  * [General notes on implementation](#general-notes-on-implementation)
  * [Platform and Language Compatibility](#platform-and-language-compatibility)
  * [API](#api)
  * [Introductory Tutorial](#introductory-tutorial)
    + [Public Keys and Signatures](#public-keys-and-signatures)
    + [Signature Verification](#signature-verification)
    + [Signature Aggregation](#signature-aggregation)
    + [Serialization Format](#serialization-format)
  * [Build](#build)
    + [C static library](#c-static-library)
  * [Language-specific notes](#language-specific-notes)
    + [Go](#go)
    + [Rust](#rust)
  * [Repository Structure](#repository-structure)
  * [Performance](#performance)
  * [License](#license)

## Status
**This library is under active development**

An initial audit of this library was conducted by NCC Group in January 2021 and can be found [here](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf).

Formal verification of this library by Galois is on-going and can be found [here](https://github.com/GaloisInc/BLST-Verification).

This library is compliant with the following IETF draft specifications:
- [IETF BLS Signature V6](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature)
- [IETF RFC 9380 Hashing to Elliptic Curves](https://www.rfc-editor.org/rfc/rfc9380.html)

The serialization formatting is implemented according to [the ZCash definition](#serialization-format).

## General notes on implementation
The goal of the blst library is to provide a foundational component for applications and other libraries that require high performance and formally verified BLS12-381 operations. With that in mind some decisions are made to maximize the public good beyond BLS12-381. For example, the field operations are optimized for general 384-bit usage, as opposed to tuned specifically for the 381-bit BLS12-381 curve parameters. With the formal verification of these foundational components, we believe they can provide a reliable building block for other curves that would like high performance and an extra element of security.

The library deliberately abstains from dealing with memory management and multi-threading, with the rationale that these ultimately belong in language-specific bindings. Another responsibility that is left to application is random number generation. All this in the name of run-time neutrality, which makes integration into more stringent environments like Intel SGX or ARM TrustZone trivial.

## Platform and Language Compatibility

This library primarily supports x86_64 and ARM64 hardware platforms, and Linux, Mac, and Windows operating systems. But it does have a portable replacement for the assembly modules, which can be compiled for a plethora of other platforms. Problem reports for these will be considered and are likely to be addressed.

This repository includes explicit bindings for:
- [Go](bindings/go)
- [Rust](bindings/rust)

Unless deemed appropriate to implement, bindings for other languages will be provided using [SWIG](http://swig.org). Proof-of-concept scripts are available for:
- [Python](bindings/python)
- [Java](bindings/java)
- [Node.js](bindings/node.js)
- [Emscripten](bindings/emscripten)
- [C#](bindings/c%23)
- [Zig](bindings/zig)

## API

The blst API is defined in the C header [bindings/blst.h](bindings/blst.h). The API can be categorized as follows, with some example operations:
- Field Operations (add, sub, mul, neg, inv, to/from Montgomery)
- Curve Operations (add, double, mul, to/from affine, group check)
- Intermediate (hash to curve, pairing, serdes)
- BLS12-381 signature (sign, verify, aggregate)

Note: there is also an auxiliary header file, [bindings/blst_aux.h](bindings/blst_aux.h), that is used as a staging area for experimental interfaces that may or may not get promoted to blst.h.

## Introductory Tutorial

Programming is understanding, and understanding implies mastering the lingo. So we have a pair of additive groups being mapped to multiplicative one... What does it mean? Well, this tutorial is not about explaining that, but rather about making the connection between what you're supposed to know about [pairing-based cryptography](https://en.wikipedia.org/wiki/Pairing-based_cryptography) and the interface provided by the library.

### Public Keys and Signatures

We have two elliptic curves, E1 and E2, points on which are contained in `blst_p1` and `blst_p2`, or `blst_p1_affine` and `blst_p2_affine` structures. Elements in the multiplicative group are held in a `blst_fp12` structure. One of the curves, or more specifically, a subset of points that form a cyclic group, is chosen for public keys, and another, for signatures. The choice is denoted by the subroutines' suffixes, `_pk_in_g1` or `_pk_in_g2`. The most common choice appears to be the former, that is, `blst_p1` for public keys, and `blst_p2` for signatures. But it all starts with a secret key...

The secret key is held in a 256-bit `blst_scalar` structure which can be instantiated with either [`blst_keygen`](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature#section-2.3), or deserialized with `blst_scalar_from_bendian` or `blst_scalar_from_lendian` from a previously serialized byte sequence. It shouldn't come as surprise that there are two uses for a secret key:

- generating the associated public key, either with `blst_sk_to_pk_in_g1` or `blst_sk_to_pk_in_g2`;
- performing a sign operation, either with `blst_sign_pk_in_g1` or `blst_sign_pk_in_g2`;

As for signing, unlike what your intuition might suggest, `blst_sign_*` doesn't sign a message, but rather a point on the corresponding elliptic curve. You can obtain this point from a message by calling `blst_hash_to_g2` or `blst_encode_to_g2` (see the [IETF hash-to-curve](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve#section-3) draft for distinction). Another counter-intuitive aspect is the apparent g1 vs. g2 naming mismatch, in the sense that `blst_sign_pk_in_g1` accepts output from `blst_hash_to_g2`, and `blst_sign_pk_in_g2` accepts output from `blst_hash_to_g1`. This is because, as you should recall, public keys and signatures come from complementary groups.

Now that you have a public key and signature, as points on corresponding elliptic curves, you can serialize them with `blst_p1_serialize`/`blst_p1_compress` and `blst_p2_serialize`/`blst_p2_compress` and send the resulting byte sequences over the network for deserialization/uncompression and verification.

### Signature Verification

Even though there are "single-shot" `blst_core_verify_pk_in_g1` and `blst_core_verify_pk_in_g2`, you should really familiarize yourself with the more generalized pairing interface. `blst_pairing` is an opaque structure, and the only thing you know about it is `blst_pairing_sizeof`, which is how much memory you're supposed to allocate for it. In order to verify an aggregated signature for a set of public keys and messages, or just one[!], you would:
```
blst_pairing_init(ctx, hash_or_encode, domain_separation_tag);
blst_pairing_aggregate_pk_in_g1(ctx, PK[0], aggregated_signature, message[0]);
blst_pairing_aggregate_pk_in_g1(ctx, PK[1], NULL, message[1]);
...
blst_pairing_commit(ctx);
result = blst_pairing_finalverify(ctx, NULL);
```
**The essential point to note** is that it's the caller's responsibility to ensure that public keys are group-checked with `blst_p1_affine_in_g1`. This is because it's a relatively expensive operation and it's naturally assumed that the application would cache the check's outcome. Signatures are group-checked internally. Not shown in the pseudo-code snippet above, but `aggregate` and `commit` calls return `BLST_ERROR` denoting success or failure in performing the operation. Call to `finalverify`, on the other hand, returns boolean.

Another, potentially more useful usage pattern is:
```
blst_p2_affine_in_g2(signature);
blst_aggregated_in_g2(gtsig, signature);
blst_pairing_init(ctx, hash_or_encode, domain_separation_tag);
blst_pairing_aggregate_pk_in_g1(ctx, PK[0], NULL, message[0]);
blst_pairing_aggregate_pk_in_g1(ctx, PK[1], NULL, message[1]);
...
blst_pairing_commit(ctx);
result = blst_pairing_finalverify(ctx, gtsig);
```
What is useful about it is that `aggregated_signature` can be handled in a separate thread. And while we are at it, aggregate calls can also be executed in different threads. This naturally implies that each thread will operate on its own `blst_pairing` context, which will have to be combined with `blst_pairing_merge` as threads join.

### Signature Aggregation

Aggregation is a trivial operation of performing point additions, with `blst_p2_add_or_double_affine` or `blst_p1_add_or_double_affine`. Note that the accumulator is a non-affine point.

---

That's about what you need to know to get started with nitty-gritty of actual function declarations.

### Serialization Format

From the ZCash BLS12-381 specification

* Fq elements are encoded in big-endian form. They occupy 48 bytes in this form.
* Fq2 elements are encoded in big-endian form, meaning that the Fq2 element c0 + c1 * u is represented by the Fq element c1 followed by the Fq element c0. This means Fq2 elements occupy 96 bytes in this form.
* The group G1 uses Fq elements for coordinates. The group G2 uses Fq2 elements for coordinates.
* G1 and G2 elements can be encoded in uncompressed form (the x-coordinate followed by the y-coordinate) or in compressed form (just the x-coordinate). G1 elements occupy 96 bytes in uncompressed form, and 48 bytes in compressed form. G2 elements occupy 192 bytes in uncompressed form, and 96 bytes in compressed form.

The most-significant three bits of a G1 or G2 encoding should be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element:

* The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form.
* The second-most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding should be set to zero.
* The third-most significant bit is set if (and only if) this point is in compressed form _and_ it is not the point at infinity _and_ its y-coordinate is the lexicographically largest of the two associated with the encoded x-coordinate.

## Build
The build process is very simple and only requires a C compiler. It's integrated into the Go and Rust ecosystems, so that respective users would go about as they would with any other external module. Otherwise, a binary library would have to be compiled.

### C static library
A static library called libblst.a can be built in the current working directory of the user's choice:

Linux, Mac, and Windows (in MinGW or Cygwin environments)
```
/some/where/build.sh
```

Windows (Visual C)
```
\some\where\build.bat
```

If final application crashes with an "illegal instruction" exception [after copying to another system], pass <nobr>`-D__BLST_PORTABLE__`</nobr> on `build.sh` command line. If you don't use build.sh, complement the `CFLAGS` environment variable with the said command line option. If you compile a Go application, you will need to modify the `CGO_CFLAGS` variable instead. And if you compile a Rust application, you can pass <nobr>`--features portable`</nobr> to `cargo build`. Alternatively, if you compile on an older Intel system, but will execute application on a newer one, consider instead passing <nobr>`--features force-adx`</nobr> for better performance.

## Language-specific notes

### [Go](bindings/go)
There are two primary modes of operation that can be chosen based on type definitions in the application.

For minimal-pubkey-size operations:
```
type PublicKey = blst.P1Affine
type Signature = blst.P2Affine
type AggregateSignature = blst.P2Aggregate
type AggregatePublicKey = blst.P1Aggregate
```

For minimal-signature-size operations:
```
type PublicKey = blst.P2Affine
type Signature = blst.P1Affine
type AggregateSignature = blst.P1Aggregate
type AggregatePublicKey = blst.P2Aggregate
```

For more details see the Go binding [readme](bindings/go/README.md).

### [Rust](bindings/rust)
[`blst`](https://crates.io/crates/blst) is the Rust binding crate.

To use min-pk version:
```
use blst::min_pk::*;
```

To use min-sig version:
```
use blst::min_sig::*;
```

For more details see the Rust binding [readme](bindings/rust/README.md).

## Repository Structure

**Root** - Contains various configuration files, documentation, licensing, and a build script
* **Bindings** - Contains the files that define the blst interface
    * blst.h - provides C API to blst library
    * blst_aux.h - contains experimental functions not yet committed for long-term maintenance
    * blst.hpp - provides foundational class-oriented C++ interface to blst library
    * blst.swg - provides SWIG definitions for creating blst bindings for other languages, such as Java and Python
    * **C#** - folder containing C# bindings and an example of how to use them
    * **Emscripten**  - folder containing an example of how to use Emscripten WebAssembly bindings from Javascript
    * **Go** - folder containing Go bindings for blst, including tests and benchmarks
    * **Java** - folder containing an example of how to use SWIG Java bindings for blst
    * **Node.js** - folder containing an example of how to use SWIG Javascript bindings for blst
    * **Python** - folder containing an example of how to use SWIG Python bindings for blst
    * **Rust** - folder containing Rust bindings for blst, including tests and benchmarks
    * **Vectors**
        * **Hash_to_curve**: folder containing test for hash_to_curve from IETF specification
* **Src** - folder containing C code for lower level blst functions such as field operations, extension field operations, hash-to-field, and more
    * **Asm** - folder containing Perl scripts that are used to generate assembly code for different hardware platforms including x86 with ADX instructions, x86 without ADX instructions, and ARMv8, and [ABI](https://en.wikipedia.org/wiki/Application_binary_interface)[1]
* **Build** - this folder containing a set of pre-generated assembly files for a variety of operating systems and maintenance scripts.
    * **Cheri** - assembly code for use on [CHERI](https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/) platforms
    * **Coff** - assembly code for use on Windows systems with GNU or LLVM toolchain
    * **Elf** - assembly code for use on Unix systems
    * **Mach-o** - assembly code for use on Apple operating systems
    * **Win64** - assembly code for use on Windows systems with Microsoft toolchain

[1]: See [refresh.sh](build/refresh.sh) for usage. This method allows for simple reuse of optimized assembly across various platforms with minimal effort.

## Performance
Currently both the [Go](bindings/go) and [Rust](bindings/rust) bindings provide benchmarks for a variety of signature related operations.

## License
The blst library is licensed under the [Apache License Version 2.0](LICENSE) software license.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting a Vulnerability

To report security issues please send an e-mail to hello@supranational.net. 

For sensitive information or critical issues, please contact the above e-mail address with 'CRITICAL' in the subject line and we will respond with a mechanism to securely communicate.

Please try to provide a clear description of any issue reported, along with how to reproduce the issue if possible.


================================================
FILE: bindings/blst.h
================================================
/*
 * Copyright Supranational LLC
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef __BLST_H__
#define __BLST_H__

#ifdef __SIZE_TYPE__
typedef __SIZE_TYPE__ size_t;
#else
#include <stddef.h>
#endif

#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) \
                            && defined(__UINT64_TYPE__)
typedef __UINT8_TYPE__  uint8_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
#else
#include <stdint.h>
#endif

#ifdef __cplusplus
extern "C" {
#elif !defined(__STDC_VERSION__) || __STDC_VERSION__<202311
# if defined(__BLST_CGO__)
typedef _Bool bool; /* it's assumed that cgo calls modern enough compiler */
# elif defined(__BLST_RUST_BINDGEN__) || defined(__BLST_ZIG__)
#  define bool _Bool
# elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901
#  include <stdbool.h>
# elif !defined(bool)
#  define bool int
#  define __blst_h_bool__
# endif
#endif

#ifdef SWIG
# define DEFNULL =NULL
#elif defined __cplusplus
# define DEFNULL =0
#else
# define DEFNULL
#endif

typedef enum {
    BLST_SUCCESS = 0,
    BLST_BAD_ENCODING,
    BLST_POINT_NOT_ON_CURVE,
    BLST_POINT_NOT_IN_GROUP,
    BLST_AGGR_TYPE_MISMATCH,
    BLST_VERIFY_FAIL,
    BLST_PK_IS_INFINITY,
    BLST_BAD_SCALAR,
} BLST_ERROR;

typedef uint8_t byte;
typedef uint64_t limb_t;

typedef struct { byte b[256/8]; } blst_scalar;
typedef struct { limb_t l[256/8/sizeof(limb_t)]; } blst_fr;
typedef struct { limb_t l[384/8/sizeof(limb_t)]; } blst_fp;
/* 0 is "real" part, 1 is "imaginary" */
typedef struct { blst_fp fp[2]; } blst_fp2;
typedef struct { blst_fp2 fp2[3]; } blst_fp6;
typedef struct { blst_fp6 fp6[2]; } blst_fp12;

void blst_scalar_from_uint32(blst_scalar *out, const uint32_t a[8]);
void blst_uint32_from_scalar(uint32_t out[8], const blst_scalar *a);
void blst_scalar_from_uint64(blst_scalar *out, const uint64_t a[4]);
void blst_uint64_from_scalar(uint64_t out[4], const blst_scalar *a);
void blst_scalar_from_bendian(blst_scalar *out, const byte a[32]);
void blst_bendian_from_scalar(byte out[32], const blst_scalar *a);
void blst_scalar_from_lendian(blst_scalar *out, const byte a[32]);
void blst_lendian_from_scalar(byte out[32], const blst_scalar *a);
bool blst_scalar_fr_check(const blst_scalar *a);
bool blst_sk_check(const blst_scalar *a);
bool blst_sk_add_n_check(blst_scalar *out, const blst_scalar *a,
                                           const blst_scalar *b);
bool blst_sk_sub_n_check(blst_scalar *out, const blst_scalar *a,
                                           const blst_scalar *b);
bool blst_sk_mul_n_check(blst_scalar *out, const blst_scalar *a,
                                           const blst_scalar *b);
void blst_sk_inverse(blst_scalar *out, const blst_scalar *a);
bool blst_scalar_from_le_bytes(blst_scalar *out, const byte *in, size_t len);
bool blst_scalar_from_be_bytes(blst_scalar *out, const byte *in, size_t len);

#ifndef SWIG
/*
 * BLS12-381-specific Fr operations.
 */
void blst_fr_add(blst_fr *ret, const blst_fr *a, const blst_fr *b);
void blst_fr_sub(blst_fr *ret, const blst_fr *a, const blst_fr *b);
void blst_fr_mul_by_3(blst_fr *ret, const blst_fr *a);
void blst_fr_lshift(blst_fr *ret, const blst_fr *a, size_t count);
void blst_fr_rshift(blst_fr *ret, const blst_fr *a, size_t count);
void blst_fr_mul(blst_fr *ret, const blst_fr *a, const blst_fr *b);
void blst_fr_sqr(blst_fr *ret, const blst_fr *a);
void blst_fr_cneg(blst_fr *ret, const blst_fr *a, bool flag);
void blst_fr_eucl_inverse(blst_fr *ret, const blst_fr *a);
void blst_fr_inverse(blst_fr *ret, const blst_fr *a);

void blst_fr_from_uint64(blst_fr *ret, const uint64_t a[4]);
void blst_uint64_from_fr(uint64_t ret[4], const blst_fr *a);
void blst_fr_from_scalar(blst_fr *ret, const blst_scalar *a);
void blst_scalar_from_fr(blst_scalar *ret, const blst_fr *a);

/*
 * BLS12-381-specific Fp operations.
 */
void blst_fp_add(blst_fp *ret, const blst_fp *a, const blst_fp *b);
void blst_fp_sub(blst_fp *ret, const blst_fp *a, const blst_fp *b);
void blst_fp_mul_by_3(blst_fp *ret, const blst_fp *a);
void blst_fp_mul_by_8(blst_fp *ret, const blst_fp *a);
void blst_fp_lshift(blst_fp *ret, const blst_fp *a, size_t count);
void blst_fp_mul(blst_fp *ret, const blst_fp *a, const blst_fp *b);
void blst_fp_sqr(blst_fp *ret, const blst_fp *a);
void blst_fp_cneg(blst_fp *ret, const blst_fp *a, bool flag);
void blst_fp_eucl_inverse(blst_fp *ret, const blst_fp *a);
void blst_fp_inverse(blst_fp *ret, const blst_fp *a);
bool blst_fp_sqrt(blst_fp *ret, const blst_fp *a);

void blst_fp_from_uint32(blst_fp *ret, const uint32_t a[12]);
void blst_uint32_from_fp(uint32_t ret[12], const blst_fp *a);
void blst_fp_from_uint64(blst_fp *ret, const uint64_t a[6]);
void blst_uint64_from_fp(uint64_t ret[6], const blst_fp *a);
void blst_fp_from_bendian(blst_fp *ret, const byte a[48]);
void blst_bendian_from_fp(byte ret[48], const blst_fp *a);
void blst_fp_from_lendian(blst_fp *ret, const byte a[48]);
void blst_lendian_from_fp(byte ret[48], const blst_fp *a);

/*
 * BLS12-381-specific Fp2 operations.
 */
void blst_fp2_add(blst_fp2 *ret, const blst_fp2 *a, const blst_fp2 *b);
void blst_fp2_sub(blst_fp2 *ret, const blst_fp2 *a, const blst_fp2 *b);
void blst_fp2_mul_by_3(blst_fp2 *ret, const blst_fp2 *a);
void blst_fp2_mul_by_8(blst_fp2 *ret, const blst_fp2 *a);
void blst_fp2_lshift(blst_fp2 *ret, const blst_fp2 *a, size_t count);
void blst_fp2_mul(blst_fp2 *ret, const blst_fp2 *a, const blst_fp2 *b);
void blst_fp2_sqr(blst_fp2 *ret, const blst_fp2 *a);
void blst_fp2_cneg(blst_fp2 *ret, const blst_fp2 *a, bool flag);
void blst_fp2_eucl_inverse(blst_fp2 *ret, const blst_fp2 *a);
void blst_fp2_inverse(blst_fp2 *ret, const blst_fp2 *a);
bool blst_fp2_sqrt(blst_fp2 *ret, const blst_fp2 *a);

/*
 * BLS12-381-specific Fp12 operations.
 */
void blst_fp12_sqr(blst_fp12 *ret, const blst_fp12 *a);
void blst_fp12_cyclotomic_sqr(blst_fp12 *ret, const blst_fp12 *a);
void blst_fp12_mul(blst_fp12 *ret, const blst_fp12 *a, const blst_fp12 *b);
void blst_fp12_mul_by_xy00z0(blst_fp12 *ret, const blst_fp12 *a,
                                             const blst_fp6 *xy00z0);
void blst_fp12_conjugate(blst_fp12 *a);
void blst_fp12_inverse(blst_fp12 *ret, const blst_fp12 *a);
/* caveat lector! |n| has to be non-zero and not more than 3! */
void blst_fp12_frobenius_map(blst_fp12 *ret, const blst_fp12 *a, size_t n);
bool blst_fp12_is_equal(const blst_fp12 *a, const blst_fp12 *b);
bool blst_fp12_is_one(const blst_fp12 *a);
bool blst_fp12_in_group(const blst_fp12 *a);
const blst_fp12 *blst_fp12_one(void);
#endif  // SWIG

/*
 * BLS12-381-specific point operations.
 */
typedef struct { blst_fp x, y, z; } blst_p1;
typedef struct { blst_fp x, y; } blst_p1_affine;

void blst_p1_add(blst_p1 *out, const blst_p1 *a, const blst_p1 *b);
void blst_p1_add_or_double(blst_p1 *out, const blst_p1 *a, const blst_p1 *b);
void blst_p1_add_affine(blst_p1 *out, const blst_p1 *a,
                                      const blst_p1_affine *b);
void blst_p1_add_or_double_affine(blst_p1 *out, const blst_p1 *a,
                                                const blst_p1_affine *b);
void blst_p1_double(blst_p1 *out, const blst_p1 *a);
void blst_p1_mult(blst_p1 *out, const blst_p1 *p, const byte *scalar,
                                                  size_t nbits);
void blst_p1_cneg(blst_p1 *p, bool cbit);
void blst_p1_to_affine(blst_p1_affine *out, const blst_p1 *in);
void blst_p1_from_affine(blst_p1 *out, const blst_p1_affine *in);
bool blst_p1_on_curve(const blst_p1 *p);
bool blst_p1_in_g1(const blst_p1 *p);
bool blst_p1_is_equal(const blst_p1 *a, const blst_p1 *b);
bool blst_p1_is_inf(const blst_p1 *a);
const blst_p1 *blst_p1_generator(void);

bool blst_p1_affine_on_curve(const blst_p1_affine *p);
bool blst_p1_affine_in_g1(const blst_p1_affine *p);
bool blst_p1_affine_is_equal(const blst_p1_affine *a, const blst_p1_affine *b);
bool blst_p1_affine_is_inf(const blst_p1_affine *a);
const blst_p1_affine *blst_p1_affine_generator(void);

typedef struct { blst_fp2 x, y, z; } blst_p2;
typedef struct { blst_fp2 x, y; } blst_p2_affine;

void blst_p2_add(blst_p2 *out, const blst_p2 *a, const blst_p2 *b);
void blst_p2_add_or_double(blst_p2 *out, const blst_p2 *a, const blst_p2 *b);
void blst_p2_add_affine(blst_p2 *out, const blst_p2 *a,
                                      const blst_p2_affine *b);
void blst_p2_add_or_double_affine(blst_p2 *out, const blst_p2 *a,
                                                const blst_p2_affine *b);
void blst_p2_double(blst_p2 *out, const blst_p2 *a);
void blst_p2_mult(blst_p2 *out, const blst_p2 *p, const byte *scalar,
                                                  size_t nbits);
void blst_p2_cneg(blst_p2 *p, bool cbit);
void blst_p2_to_affine(blst_p2_affine *out, const blst_p2 *in);
void blst_p2_from_affine(blst_p2 *out, const blst_p2_affine *in);
bool blst_p2_on_curve(const blst_p2 *p);
bool blst_p2_in_g2(const blst_p2 *p);
bool blst_p2_is_equal(const blst_p2 *a, const blst_p2 *b);
bool blst_p2_is_inf(const blst_p2 *a);
const blst_p2 *blst_p2_generator(void);

bool blst_p2_affine_on_curve(const blst_p2_affine *p);
bool blst_p2_affine_in_g2(const blst_p2_affine *p);
bool blst_p2_affine_is_equal(const blst_p2_affine *a, const blst_p2_affine *b);
bool blst_p2_affine_is_inf(const blst_p2_affine *a);
const blst_p2_affine *blst_p2_affine_generator(void);

/*
 * Multi-scalar multiplications and other multi-point operations.
 */

void blst_p1s_to_affine(blst_p1_affine dst[], const blst_p1 *const points[],
                        size_t npoints);
void blst_p1s_add(blst_p1 *ret, const blst_p1_affine *const points[],
                                size_t npoints);

size_t blst_p1s_mult_wbits_precompute_sizeof(size_t wbits, size_t npoints);
void blst_p1s_mult_wbits_precompute(blst_p1_affine table[], size_t wbits,
                                    const blst_p1_affine *const points[],
                                    size_t npoints);
size_t blst_p1s_mult_wbits_scratch_sizeof(size_t npoints);
void blst_p1s_mult_wbits(blst_p1 *ret, const blst_p1_affine table[],
                         size_t wbits, size_t npoints,
                         const byte *const scalars[], size_t nbits,
                         limb_t *scratch);

size_t blst_p1s_mult_pippenger_scratch_sizeof(size_t npoints);
void blst_p1s_mult_pippenger(blst_p1 *ret, const blst_p1_affine *const points[],
                             size_t npoints, const byte *const scalars[],
                             size_t nbits, limb_t *scratch);
void blst_p1s_tile_pippenger(blst_p1 *ret, const blst_p1_affine *const points[],
                             size_t npoints, const byte *const scalars[],
                             size_t nbits, limb_t *scratch,
                             size_t bit0, size_t window);

void blst_p2s_to_affine(blst_p2_affine dst[], const blst_p2 *const points[],
                        size_t npoints);
void blst_p2s_add(blst_p2 *ret, const blst_p2_affine *const points[],
                                size_t npoints);

size_t blst_p2s_mult_wbits_precompute_sizeof(size_t wbits, size_t npoints);
void blst_p2s_mult_wbits_precompute(blst_p2_affine table[], size_t wbits,
                                    const blst_p2_affine *const points[],
                                    size_t npoints);
size_t blst_p2s_mult_wbits_scratch_sizeof(size_t npoints);
void blst_p2s_mult_wbits(blst_p2 *ret, const blst_p2_affine table[],
                         size_t wbits, size_t npoints,
                         const byte *const scalars[], size_t nbits,
                         limb_t *scratch);

size_t blst_p2s_mult_pippenger_scratch_sizeof(size_t npoints);
void blst_p2s_mult_pippenger(blst_p2 *ret, const blst_p2_affine *const points[],
                             size_t npoints, const byte *const scalars[],
                             size_t nbits, limb_t *scratch);
void blst_p2s_tile_pippenger(blst_p2 *ret, const blst_p2_affine *const points[],
                             size_t npoints, const byte *const scalars[],
                             size_t nbits, limb_t *scratch,
                             size_t bit0, size_t window);

/*
 * Hash-to-curve operations.
 */
#ifndef SWIG
void blst_map_to_g1(blst_p1 *out, const blst_fp *u, const blst_fp *v DEFNULL);
void blst_map_to_g2(blst_p2 *out, const blst_fp2 *u, const blst_fp2 *v DEFNULL);
#endif

void blst_encode_to_g1(blst_p1 *out,
                       const byte *msg, size_t msg_len,
                       const byte *DST DEFNULL, size_t DST_len DEFNULL,
                       const byte *aug DEFNULL, size_t aug_len DEFNULL);
void blst_hash_to_g1(blst_p1 *out,
                     const byte *msg, size_t msg_len,
                     const byte *DST DEFNULL, size_t DST_len DEFNULL,
                     const byte *aug DEFNULL, size_t aug_len DEFNULL);

void blst_encode_to_g2(blst_p2 *out,
                       const byte *msg, size_t msg_len,
                       const byte *DST DEFNULL, size_t DST_len DEFNULL,
                       const byte *aug DEFNULL, size_t aug_len DEFNULL);
void blst_hash_to_g2(blst_p2 *out,
                     const byte *msg, size_t msg_len,
                     const byte *DST DEFNULL, size_t DST_len DEFNULL,
                     const byte *aug DEFNULL, size_t aug_len DEFNULL);

/*
 * Zcash-compatible serialization/deserialization.
 */
void blst_p1_serialize(byte out[96], const blst_p1 *in);
void blst_p1_compress(byte out[48], const blst_p1 *in);
void blst_p1_affine_serialize(byte out[96], const blst_p1_affine *in);
void blst_p1_affine_compress(byte out[48], const blst_p1_affine *in);
BLST_ERROR blst_p1_uncompress(blst_p1_affine *out, const byte in[48]);
BLST_ERROR blst_p1_deserialize(blst_p1_affine *out, const byte in[96]);

void blst_p2_serialize(byte out[192], const blst_p2 *in);
void blst_p2_compress(byte out[96], const blst_p2 *in);
void blst_p2_affine_serialize(byte out[192], const blst_p2_affine *in);
void blst_p2_affine_compress(byte out[96], const blst_p2_affine *in);
BLST_ERROR blst_p2_uncompress(blst_p2_affine *out, const byte in[96]);
BLST_ERROR blst_p2_deserialize(blst_p2_affine *out, const byte in[192]);

/*
 * Specification defines two variants, 'minimal-signature-size' and
 * 'minimal-pubkey-size'. To unify appearance we choose to distinguish
 * them by suffix referring to the public key type, more specifically
 * _pk_in_g1 corresponds to 'minimal-pubkey-size' and _pk_in_g2 - to
 * 'minimal-signature-size'. It might appear a bit counterintuitive
 * in sign call, but no matter how you twist it, something is bound to
 * turn a little odd.
 */
/*
 * Secret-key operations.
 */
void blst_keygen(blst_scalar *out_SK, const byte *IKM, size_t IKM_len,
                 const byte *info DEFNULL, size_t info_len DEFNULL);
void blst_sk_to_pk_in_g1(blst_p1 *out_pk, const blst_scalar *SK);
void blst_sign_pk_in_g1(blst_p2 *out_sig, const blst_p2 *hash,
                                          const blst_scalar *SK);
void blst_sk_to_pk_in_g2(blst_p2 *out_pk, const blst_scalar *SK);
void blst_sign_pk_in_g2(blst_p1 *out_sig, const blst_p1 *hash,
                                          const blst_scalar *SK);

/*
 * Pairing interface.
 */
#ifndef SWIG
void blst_miller_loop(blst_fp12 *ret, const blst_p2_affine *Q,
                                      const blst_p1_affine *P);
void blst_miller_loop_n(blst_fp12 *ret, const blst_p2_affine *const Qs[],
                                        const blst_p1_affine *const Ps[],
                                        size_t n);
void blst_final_exp(blst_fp12 *ret, const blst_fp12 *f);
void blst_precompute_lines(blst_fp6 Qlines[68], const blst_p2_affine *Q);
void blst_miller_loop_lines(blst_fp12 *ret, const blst_fp6 Qlines[68],
                                            const blst_p1_affine *P);
bool blst_fp12_finalverify(const blst_fp12 *gt1, const blst_fp12 *gt2);
#endif

#ifdef __BLST_CGO__
typedef limb_t blst_pairing;
#elif defined(__BLST_RUST_BINDGEN__)
typedef struct {} blst_pairing;
#else
typedef struct blst_opaque blst_pairing;
#endif

size_t blst_pairing_sizeof(void);
void blst_pairing_init(blst_pairing *new_ctx, bool hash_or_encode,
                       const byte *DST DEFNULL, size_t DST_len DEFNULL);
const byte *blst_pairing_get_dst(const blst_pairing *ctx);
void blst_pairing_commit(blst_pairing *ctx);
BLST_ERROR blst_pairing_aggregate_pk_in_g2(blst_pairing *ctx,
                                           const blst_p2_affine *PK,
                                           const blst_p1_affine *signature,
                                           const byte *msg, size_t msg_len,
                                           const byte *aug DEFNULL,
                                           size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g2(blst_pairing *ctx,
                                            const blst_p2_affine *PK,
                                            bool pk_grpchk,
                                            const blst_p1_affine *signature,
                                            bool sig_grpchk,
                                            const byte *msg, size_t msg_len,
                                            const byte *aug DEFNULL,
                                            size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g2(blst_pairing *ctx,
                                                 const blst_p2_affine *PK,
                                                 const blst_p1_affine *sig,
                                                 const byte *scalar,
                                                 size_t nbits,
                                                 const byte *msg,
                                                 size_t msg_len,
                                                 const byte *aug DEFNULL,
                                                 size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g2(blst_pairing *ctx,
                                                  const blst_p2_affine *PK,
                                                  bool pk_grpchk,
                                                  const blst_p1_affine *sig,
                                                  bool sig_grpchk,
                                                  const byte *scalar,
                                                  size_t nbits,
                                                  const byte *msg,
                                                  size_t msg_len,
                                                  const byte *aug DEFNULL,
                                                  size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_aggregate_pk_in_g1(blst_pairing *ctx,
                                           const blst_p1_affine *PK,
                                           const blst_p2_affine *signature,
                                           const byte *msg, size_t msg_len,
                                           const byte *aug DEFNULL,
                                           size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g1(blst_pairing *ctx,
                                            const blst_p1_affine *PK,
                                            bool pk_grpchk,
                                            const blst_p2_affine *signature,
                                            bool sig_grpchk,
                                            const byte *msg, size_t msg_len,
                                            const byte *aug DEFNULL,
                                            size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g1(blst_pairing *ctx,
                                                 const blst_p1_affine *PK,
                                                 const blst_p2_affine *sig,
                                                 const byte *scalar,
                                                 size_t nbits,
                                                 const byte *msg,
                                                 size_t msg_len,
                                                 const byte *aug DEFNULL,
                                                 size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g1(blst_pairing *ctx,
                                                  const blst_p1_affine *PK,
                                                  bool pk_grpchk,
                                                  const blst_p2_affine *sig,
                                                  bool sig_grpchk,
                                                  const byte *scalar,
                                                  size_t nbits,
                                                  const byte *msg,
                                                  size_t msg_len,
                                                  const byte *aug DEFNULL,
                                                  size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_merge(blst_pairing *ctx, const blst_pairing *ctx1);
bool blst_pairing_finalverify(const blst_pairing *ctx,
                              const blst_fp12 *gtsig DEFNULL);


/*
 * Customarily applications aggregate signatures separately.
 * In which case application would have to pass NULLs for |signature|
 * to blst_pairing_aggregate calls and pass aggregated signature
 * collected with these calls to blst_pairing_finalverify. Inputs are
 * Zcash-compatible "straight-from-wire" byte vectors, compressed or
 * not.
 */
BLST_ERROR blst_aggregate_in_g1(blst_p1 *out, const blst_p1 *in,
                                              const byte *zwire);
BLST_ERROR blst_aggregate_in_g2(blst_p2 *out, const blst_p2 *in,
                                              const byte *zwire);

void blst_aggregated_in_g1(blst_fp12 *out, const blst_p1_affine *signature);
void blst_aggregated_in_g2(blst_fp12 *out, const blst_p2_affine *signature);

/*
 * "One-shot" CoreVerify entry points.
 */
BLST_ERROR blst_core_verify_pk_in_g1(const blst_p1_affine *pk,
                                     const blst_p2_affine *signature,
                                     bool hash_or_encode,
                                     const byte *msg, size_t msg_len,
                                     const byte *DST DEFNULL,
                                     size_t DST_len DEFNULL,
                                     const byte *aug DEFNULL,
                                     size_t aug_len DEFNULL);
BLST_ERROR blst_core_verify_pk_in_g2(const blst_p2_affine *pk,
                                     const blst_p1_affine *signature,
                                     bool hash_or_encode,
                                     const byte *msg, size_t msg_len,
                                     const byte *DST DEFNULL,
                                     size_t DST_len DEFNULL,
                                     const byte *aug DEFNULL,
                                     size_t aug_len DEFNULL);

extern const blst_p1_affine BLS12_381_G1;
extern const blst_p1_affine BLS12_381_NEG_G1;
extern const blst_p2_affine BLS12_381_G2;
extern const blst_p2_affine BLS12_381_NEG_G2;

#include "blst_aux.h"

#ifdef __cplusplus
}
#elif defined(__blst_h_bool__)
# undef __blst_h_bool__
# undef bool
#endif
#endif


================================================
FILE: bindings/blst.hpp
================================================
/*
 * Copyright Supranational LLC
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef __BLST_HPP__
#define __BLST_HPP__

#if !defined(SWIG) && __cplusplus < 201103L \
                   && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L)
# error "C++11 or later is required to compile <blst>/bindings/blst.hpp"
#endif

#include <string>
#include <cstring>
#include <vector>
#include <memory>

namespace blst {

#ifdef __clang__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wextern-c-compat"
#endif

#include "blst.h"

#ifdef __clang__
# pragma GCC diagnostic pop
#endif

struct bytes_t {
    const byte* ptr;
    size_t len;

    bytes_t() = default;
    bytes_t(const byte* p, size_t l) : ptr{p}, len{l} {}
    template<template<typename, typename...> class C, typename T>
    bytes_t(const C<T>& c)
    {
        static_assert(sizeof(T) == 1, "unsupported type");
        ptr = reinterpret_cast<const byte*>(c.data());
        len = c.size();
    }
    template<template<typename, size_t> class C, typename T, size_t N>
    bytes_t(const C<T, N>& c)
    {
        static_assert(sizeof(T) == 1, "unsupported type");
        ptr = reinterpret_cast<const byte*>(c.data());
        len = c.size();
    }
};

class P1_Affine;
class P1;
class P2_Affine;
class P2;
class Pairing;

inline const byte *C_bytes(const void *ptr)
{   return static_cast<const byte*>(ptr);   }

/*
 * As for SecretKey being struct and not class, and lack of constructors
 * with one accepting for example |IKM|. We can't make assumptions about
 * application's policy toward handling secret key material. Hence it's
 * argued that application is entitled for transparent structure, not
 * opaque or semi-opaque class. And in the context it's appropriate not
 * to "entice" developers with idiomatic constructors:-) Though this
 * doesn't really apply to SWIG-assisted interfaces...
 */
struct SecretKey {
#ifdef SWIG
private:
#endif
    blst_scalar key;

#ifdef SWIG
public:
#endif
#ifndef SWIG
    void keygen(const byte* IKM, size_t IKM_len,
                const std::string& info = "")
    {   blst_keygen(&key, IKM, IKM_len, C_bytes(info.data()), info.size());   }
    void keygen_v3(const byte* IKM, size_t IKM_len,
                   const std::string& info = "")
    {   blst_keygen_v3(&key, IKM, IKM_len, C_bytes(info.data()), info.size());   }
    void keygen_v4_5(const byte* IKM, size_t IKM_len,
                     const byte* salt, size_t salt_len,
                     const std::string& info = "")
    {   blst_keygen_v4_5(&key, IKM, IKM_len, salt, salt_len,
                               C_bytes(info.data()), info.size());
    }
    void keygen_v5(const byte* IKM, size_t IKM_len,
                   const byte* salt, size_t salt_len,
                   const std::string& info = "")
    {   blst_keygen_v5(&key, IKM, IKM_len, salt, salt_len,
                             C_bytes(info.data()), info.size());
    }
#endif
    void keygen(bytes_t IKM, const std::string& info = "")
    {   keygen(IKM.ptr, IKM.len, info);   }
    void keygen_v3(bytes_t IKM, const std::string& info = "")
    {   keygen_v3(IKM.ptr, IKM.len, info);   }
    void keygen_v4_5(bytes_t IKM, bytes_t salt, const std::string& info = "")
    {   keygen_v4_5(IKM.ptr, IKM.len, salt.ptr, salt.len, info);   }
    void keygen_v5(bytes_t IKM, bytes_t salt, const std::string& info = "")
    {   keygen_v5(IKM.ptr, IKM.len, salt.ptr, salt.len, info);   }
    void derive_master_eip2333(const byte* IKM, size_t IKM_len)
    {   blst_derive_master_eip2333(&key, IKM, IKM_len);   }
    void derive_child_eip2333(const SecretKey& SK, unsigned int child_index)
    {   blst_derive_child_eip2333(&key, &SK.key, child_index);   }

    void from_bendian(const byte in[32]) { blst_scalar_from_bendian(&key, in); }
    void from_lendian(const byte in[32]) { blst_scalar_from_lendian(&key, in); }

    void to_bendian(byte out[32]) const
    {   blst_bendian_from_scalar(out, &key);   }
    void to_lendian(byte out[32]) const
    {   blst_lendian_from_scalar(out, &key);   }
};

class Scalar {
private:
    blst_scalar val;

public:
    Scalar() { memset(&val, 0, sizeof(val)); }
    Scalar(const byte* scalar, size_t nbits)
    {   blst_scalar_from_le_bytes(&val, scalar, (nbits+7)/8);   }
#ifndef SWIG
    Scalar(const byte *msg, size_t msg_len, const std::string& DST)
    {   (void)hash_to(msg, msg_len, DST);   }

    Scalar* hash_to(const byte *msg, size_t msg_len, const std::string& DST = "")
    {   byte elem[48];
        blst_expand_message_xmd(elem, sizeof(elem), msg, msg_len,
                                                    C_bytes(DST.data()), DST.size());
        blst_scalar_from_be_bytes(&val, elem, sizeof(elem));
        return this;
    }
#endif
    Scalar(bytes_t msg, const std::string& DST)
    {   (void)hash_to(msg.ptr, msg.len, DST);   }
    Scalar* hash_to(bytes_t msg, const std::string& DST = "")
    {   return hash_to(msg.ptr, msg.len, DST);   }

    Scalar dup() const { return *this; }
    Scalar* from_bendian(const byte *msg, size_t msg_len)
    {   blst_scalar_from_be_bytes(&val, msg, msg_len); return this;   }
    Scalar* from_lendian(const byte *msg, size_t msg_len)
    {   blst_scalar_from_le_bytes(&val, msg, msg_len); return this;   }
    void to_bendian(byte out[32]) const
    {   blst_bendian_from_scalar(out, &val);   }
    void to_lendian(byte out[32]) const
    {   blst_lendian_from_scalar(out, &val);   }

    Scalar* add(const Scalar& a)
    {   if (!blst_sk_add_n_check(&val, &val, a))
            throw BLST_BAD_SCALAR;
        return this;
    }
    Scalar* add(const SecretKey& a)
    {   if (!blst_sk_add_n_check(&val, &val, &a.key))
            throw BLST_BAD_SCALAR;
        return this;
    }
    Scalar* sub(const Scalar& a)
    {   if (!blst_sk_sub_n_check(&val, &val, a))
            throw BLST_BAD_SCALAR;
        return this;
    }
    Scalar* mul(const Scalar& a)
    {   if (!blst_sk_mul_n_check(&val, &val, a))
            throw BLST_BAD_SCALAR;
        return this;
    }
    Scalar* inverse()
    {   blst_sk_inverse(&val, &val); return this;   }

private:
    friend class P1;
    friend class P2;
    operator const blst_scalar*() const { return &val; }
    operator const byte*() const        { return val.b; }
};

class P1_Affine {
private:
    blst_p1_affine point;

    P1_Affine(const blst_p1_affine *cptr) { point = *cptr; }
public:
    P1_Affine() { memset(&point, 0, sizeof(point)); }
#ifndef SWIG
    P1_Affine(const byte *in)
    {   BLST_ERROR err = blst_p1_deserialize(&point, in);
        if (err != BLST_SUCCESS)
            throw err;
    }
#endif
    P1_Affine(const byte *in, size_t len)
    {   if (len == 0 || len != (in[0]&0x80 ? 48 : 96))
            throw BLST_BAD_ENCODING;
        BLST_ERROR err = blst_p1_deserialize(&point, in);
        if (err != BLST_SUCCESS)
            throw err;
    }
    P1_Affine(const P1& jacobian);

    P1_Affine dup() const { return *this; }
    P1 to_jacobian() const;
    void serialize(byte out[96]) const
    {   blst_p1_affine_serialize(out, &point);   }
    void compress(byte out[48]) const
    {   blst_p1_affine_compress(out, &point);   }
    bool on_curve() const { return blst_p1_affine_on_curve(&point); }
    bool in_group() const { return blst_p1_affine_in_g1(&point);    }
    bool is_inf() const   { return blst_p1_affine_is_inf(&point);   }
    bool is_equal(const P1_Affine& p) const
    {   return blst_p1_affine_is_equal(&point, &p.point);   }
#ifndef SWIG
    BLST_ERROR core_verify(const P2_Affine& pk, bool hash_or_encode,
                           const byte* msg, size_t msg_len,
                           const std::string& DST = "",
                           const byte* aug = nullptr, size_t aug_len = 0) const;
#endif
    BLST_ERROR core_verify(const P2_Affine& pk, bool hash_or_encode,
                           bytes_t msg, const std::string& DST = "",
                           bytes_t aug = {nullptr, 0}) const
    {   return core_verify(pk, hash_or_encode, msg.ptr, msg.len, DST,
                                               aug.ptr, aug.len);
    }
    static P1_Affine generator()
    {   return P1_Affine(blst_p1_affine_generator());   }

private:
    friend class Pairing;
    friend class P2_Affine;
    friend class PT;
    friend class P1;
    friend class P1_Affines;
    operator const blst_p1_affine*() const { return &point; }
    operator blst_p1_affine*()             { return &point; }
};

class P1 {
private:
    blst_p1 point;

    P1(const blst_p1 *cptr) { point = *cptr; }
public:
    P1() { memset(&point, 0, sizeof(point)); }
    P1(const SecretKey& sk) { blst_sk_to_pk_in_g1(&point, &sk.key); }
#ifndef SWIG
    P1(const byte *in)
    {   blst_p1_affine a;
        BLST_ERROR err = blst_p1_deserialize(&a, in);
        if (err != BLST_SUCCESS)
            throw err;
        blst_p1_from_affine(&point, &a);
    }
#endif
    P1(const byte *in, size_t len)
    {   if (len == 0 || len != (in[0]&0x80 ? 48 : 96))
            throw BLST_BAD_ENCODING;
        blst_p1_affine a;
        BLST_ERROR err = blst_p1_deserialize(&a, in);
        if (err != BLST_SUCCESS)
            throw err;
        blst_p1_from_affine(&point, &a);
    }
    P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); }

    P1 dup() const                      { return *this; }
    P1_Affine to_affine() const         { return P1_Affine(*this);           }
    void serialize(byte out[96]) const  { blst_p1_serialize(out, &point);    }
    void compress(byte out[48]) const   { blst_p1_compress(out, &point);     }
    bool on_curve() const               { return blst_p1_on_curve(&point);   }
    bool in_group() const               { return blst_p1_in_g1(&point);      }
    bool is_inf() const                 { return blst_p1_is_inf(&point);     }
    bool is_equal(const P1& p) const
    {   return blst_p1_is_equal(&point, &p.point);   }
    void aggregate(const P1_Affine& in)
    {   if (blst_p1_affine_in_g1(in))
            blst_p1_add_or_double_affine(&point, &point, in);
        else
            throw BLST_POINT_NOT_IN_GROUP;
    }
    P1* sign_with(const SecretKey& sk)
    {   blst_sign_pk_in_g2(&point, &point, &sk.key); return this;   }
    P1* sign_with(const Scalar& scalar)
    {   blst_sign_pk_in_g2(&point, &point, scalar); return this;   }
    P1* hash_to(bytes_t msg, const std::string& DST = "",
                bytes_t aug = {nullptr, 0})
    {   blst_hash_to_g1(&point, msg.ptr, msg.len, C_bytes(DST.data()), DST.size(),
                                aug.ptr, aug.len);
        return this;
    }
    P1* encode_to(bytes_t msg, const std::string& DST = "",
                  bytes_t aug = {nullptr, 0})
    {   blst_encode_to_g1(&point, msg.ptr, msg.len, C_bytes(DST.data()), DST.size(),
                                  aug.ptr, aug.len);
        return this;
    }
#ifndef SWIG
    P1* hash_to(const byte* msg, size_t msg_len,
                const std::string& DST = "",
                const byte* aug = nullptr, size_t aug_len = 0)
    {   blst_hash_to_g1(&point, msg, msg_len, C_bytes(DST.data()), DST.size(),
                                aug, aug_len);
        return this;
    }
    P1* encode_to(const byte* msg, size_t msg_len,
                  const std::string& DST = "",
                  const byte* aug = nullptr, size_t aug_len = 0)
    {   blst_encode_to_g1(&point, msg, msg_len, C_bytes(DST.data()), DST.size(),
                                  aug, aug_len);
        return this;
    }
#endif
    P1* mult(const byte* scalar, size_t nbits)
    {   blst_p1_mult(&point, &point, scalar, nbits); return this;   }
    P1* mult(const Scalar& scalar)
    {   blst_p1_mult(&point, &point, scalar, 255); return this;   }
    P1* cneg(bool flag)
    {   blst_p1_cneg(&point, flag); return this;   }
    P1* neg()
    {   blst_p1_cneg(&point, true); return this;   }
    P1* add(const P1& a)
    {   blst_p1_add_or_double(&point, &point, a); return this;   }
    P1* add(const P1_Affine &a)
    {   blst_p1_add_or_double_affine(&point, &point, a); return this;   }
    P1* dbl()
    {   blst_p1_double(&point, &point); return this;   }
#ifndef SWIG
    static P1 add(const P1& a, const P1& b)
    {   P1 ret; blst_p1_add_or_double(ret, a, b); return ret;   }
    static P1 add(const P1& a, const P1_Affine& b)
    {   P1 ret; blst_p1_add_or_double_affine(ret, a, b); return ret;   }
    static P1 dbl(const P1& a)
    {   P1 ret; blst_p1_double(ret, a); return ret;   }
#endif
    static P1 generator()
    {   return P1(blst_p1_generator());   }

private:
    friend class P1_Affine;
    friend class P1_Affines;
    operator const blst_p1*() const { return &point; }
    operator blst_p1*()             { return &point; }
};

class P1_Affines {
private:
    struct p1_affine_no_init {
        blst_p1_affine point;
        p1_affine_no_init() { }
        operator blst_p1_affine*()              { return &point; }
        operator const blst_p1_affine*() const  { return &point; }
    };

    std::vector<p1_affine_no_init> table;
    size_t wbits, npoints;

public:
#ifndef SWIG
    P1_Affines() {}
    P1_Affines(size_t wbits, const P1_Affine* const points[], size_t npoints)
    {   this->wbits = wbits;
        this->npoints = npoints;
        table.resize(npoints << (wbits-1));
        blst_p1s_mult_wbits_precompute(table.at(0), wbits,
                        reinterpret_cast<const blst_p1_affine *const*>(points),
                        npoints);
    }
    P1_Affines(size_t wbits, const P1_Affine points[], size_t npoints)
    {   const P1_Affine* const ptrs[2] = { points, nullptr };
        P1_Affines(wbits, ptrs, npoints);
    }
    P1_Affines(size_t wbits, const std::vector<P1_Affine>& points)
    {   P1_Affines(wbits, &points.at(0), points.size());   }

    P1_Affines(size_t wbits, const P1* const points[], size_t npoints)
    {   size_t cap = npoints << (wbits-1);

        this->wbits = wbits;
        this->npoints = npoints;
        table.resize(cap);
        blst_p1s_to_affine(table.at(cap-npoints),
                           reinterpret_cast<const blst_p1 *const*>(points),
                           npoints);
        const blst_p1_affine* const ptrs[2] = { table[cap-npoints], nullptr };
        blst_p1s_mult_wbits_precompute(table[0], wbits, ptrs, npoints);
    }
    P1_Affines(size_t wbits, const P1 points[], size_t npoints)
    {   const P1* const ptrs[2] = { points, nullptr };
        P1_Affines(wbits, ptrs, npoints);
    }
    P1_Affines(size_t wbits, const std::vector<P1>& points)
    {   P1_Affines(wbits, &points.at(0), points.size());   }

    P1_Affines(const P1* const points[], size_t npoints)
    {   this->wbits = 0;
        this->npoints = npoints;
        table.resize(npoints);
        blst_p1s_to_affine(table.at(0),
                           reinterpret_cast<const blst_p1 *const*>(points),
                           npoints);
    }
    P1_Affines(const P1 points[], size_t npoints)
    {   const P1* const ptrs[2] = { points, nullptr };
        P1_Affines(ptrs, npoints);
    }
    P1_Affines(const std::vector<P1>& points)
    {   P1_Affines(&points.at(0), points.size());   }

    P1 mult(const byte* const scalars[], size_t nbits) const
    {   P1 ret;

        if (wbits != 0) {
            size_t sz = blst_p1s_mult_wbits_scratch_sizeof(npoints);
            std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
            blst_p1s_mult_wbits(ret, table.at(0), wbits, npoints,
                                     scalars, nbits, scratch.get());
        } else {
            size_t sz = blst_p1s_mult_pippenger_scratch_sizeof(npoints);
            std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
            const blst_p1_affine* const ptrs[2] = { table.at(0), nullptr };
            blst_p1s_mult_pippenger(ret, ptrs, npoints,
                                         scalars, nbits, scratch.get());
        }
        return ret;
    }

    static std::vector<P1_Affine> from(const P1* const points[], size_t npoints)
    {   std::vector<P1_Affine> ret;
        ret.resize(npoints);
        blst_p1s_to_affine(reinterpret_cast<blst_p1_affine*>(&ret.at(0)),
                           reinterpret_cast<const blst_p1 *const*>(points),
                           npoints);
        return ret;
    }
    static std::vector<P1_Affine> from(const P1 points[], size_t npoints)
    {   const P1* const ptrs[2] = { points, nullptr };
        return from(ptrs, npoints);
    }
    static std::vector<P1_Affine> from(const std::vector<P1>& points)
    {   return from(&points.at(0), points.size());   }
#endif

    static P1 mult_pippenger(const P1_Affine* const points[], size_t npoints,
                             const byte* const scalars[], size_t nbits)
    {   P1 ret;
        size_t sz = blst_p1s_mult_pippenger_scratch_sizeof(npoints);
        std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
        blst_p1s_mult_pippenger(ret,
                    reinterpret_cast<const blst_p1_affine *const*>(points),
                    npoints, scalars, nbits, scratch.get());
        return ret;
    }
#ifndef SWIG
    static P1 mult_pippenger(const P1_Affine points[], size_t npoints,
                             const byte* const scalars[], size_t nbits)
    {   const P1_Affine* const ptrs[2] = { points, nullptr };
        return mult_pippenger(ptrs, npoints, scalars, nbits);
    }
    static P1 mult_pippenger(const std::vector<P1_Affine>& points,
                             const byte* const scalars[], size_t nbits)
    {   return mult_pippenger(&points.at(0), points.size(), scalars, nbits);   }
#endif

    static P1 add(const P1_Affine* const points[], size_t npoints)
    {   P1 ret;
        blst_p1s_add(ret,
                     reinterpret_cast<const blst_p1_affine *const*>(points),
                     npoints);
        return ret;
    }
#ifndef SWIG
    static P1 add(const P1_Affine points[], size_t npoints)
    {   const P1_Affine* const ptrs[2] = { points, nullptr };
        return add(ptrs, npoints);
    }
    static P1 add(const std::vector<P1_Affine>& points)
    {   return add(&points.at(0), points.size());   }
#endif
};

class P2_Affine {
private:
    blst_p2_affine point;

    P2_Affine(const blst_p2_affine *cptr) { point = *cptr; }
public:
    P2_Affine() { memset(&point, 0, sizeof(point)); }
#ifndef SWIG
    P2_Affine(const byte *in)
    {   BLST_ERROR err = blst_p2_deserialize(&point, in);
        if (err != BLST_SUCCESS)
            throw err;
    }
#endif
    P2_Affine(const byte *in, size_t len)
    {   if (len == 0 || len != (in[0]&0x80 ? 96 : 192))
            throw BLST_BAD_ENCODING;
        BLST_ERROR err = blst_p2_deserialize(&point, in);
        if (err != BLST_SUCCESS)
            throw err;
    }
    P2_Affine(const P2& jacobian);

    P2_Affine dup() const { return *this; }
    P2 to_jacobian() const;
    void serialize(byte out[192]) const
    {   blst_p2_affine_serialize(out, &point);   }
    void compress(byte out[96]) const
    {   blst_p2_affine_compress(out, &point);   }
    bool on_curve() const { return blst_p2_affine_on_curve(&point); }
    bool in_group() const { return blst_p2_affine_in_g2(&point);    }
    bool is_inf() const   { return blst_p2_affine_is_inf(&point);   }
    bool is_equal(const P2_Affine& p) const
    {   return blst_p2_affine_is_equal(&point, &p.point);   }
#ifndef SWIG
    BLST_ERROR core_verify(const P1_Affine& pk, bool hash_or_encode,
                           const byte* msg, size_t msg_len,
                           const std::string& DST = "",
                           const byte* aug = nullptr, size_t aug_len = 0) const;
#endif
    BLST_ERROR core_verify(const P1_Affine& pk, bool hash_or_encode,
                           bytes_t msg, const std::string& DST = "",
                           bytes_t aug = {nullptr, 0}) const
    {   return core_verify(pk, hash_or_encode, msg.ptr, msg.len, DST,
                                               aug.ptr, aug.len);
    }
    static P2_Affine generator()
    {   return P2_Affine(blst_p2_affine_generator());   }

private:
    friend class Pairing;
    friend class P1_Affine;
    friend class PT;
    friend class P2;
    friend class P2_Affines;
    operator const blst_p2_affine*() const { return &point; }
    operator blst_p2_affine*()             { return &point; }
};

class P2 {
private:
    blst_p2 point;

    P2(const blst_p2 *cptr) { point = *cptr; }
public:
    P2() { memset(&point, 0, sizeof(point)); }
    P2(const SecretKey& sk) { blst_sk_to_pk_in_g2(&point, &sk.key); }
#ifndef SWIG
    P2(const byte *in)
    {   blst_p2_affine a;
        BLST_ERROR err = blst_p2_deserialize(&a, in);
        if (err != BLST_SUCCESS)
            throw err;
        blst_p2_from_affine(&point, &a);
    }
#endif
    P2(const byte *in, size_t len)
    {   if (len == 0 || len != (in[0]&0x80 ? 96 : 192))
            throw BLST_BAD_ENCODING;
        blst_p2_affine a;
        BLST_ERROR err = blst_p2_deserialize(&a, in);
        if (err != BLST_SUCCESS)
            throw err;
        blst_p2_from_affine(&point, &a);
    }
    P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); }

    P2 dup() const                      { return *this; }
    P2_Affine to_affine() const         { return P2_Affine(*this);          }
    void serialize(byte out[192]) const { blst_p2_serialize(out, &point);   }
    void compress(byte out[96]) const   { blst_p2_compress(out, &point);    }
    bool on_curve() const               { return blst_p2_on_curve(&point);  }
    bool in_group() const               { return blst_p2_in_g2(&point);     }
    bool is_inf() const                 { return blst_p2_is_inf(&point);    }
    bool is_equal(const P2& p) const
    {   return blst_p2_is_equal(&point, &p.point);   }
    void aggregate(const P2_Affine& in)
    {   if (blst_p2_affine_in_g2(in))
            blst_p2_add_or_double_affine(&point, &point, in);
        else
            throw BLST_POINT_NOT_IN_GROUP;
    }
    P2* sign_with(const SecretKey& sk)
    {   blst_sign_pk_in_g1(&point, &point, &sk.key); return this;   }
    P2* sign_with(const Scalar& scalar)
    {   blst_sign_pk_in_g1(&point, &point, scalar); return this;   }
    P2* hash_to(bytes_t msg, const std::string& DST = "",
                bytes_t aug = {nullptr, 0})
    {   blst_hash_to_g2(&point, msg.ptr, msg.len, C_bytes(DST.data()), DST.size(),
                                aug.ptr, aug.len);
        return this;
    }
    P2* encode_to(bytes_t msg, const std::string& DST = "",
                  bytes_t aug = {nullptr, 0})
    {   blst_encode_to_g2(&point, msg.ptr, msg.len, C_bytes(DST.data()), DST.size(),
                                  aug.ptr, aug.len);
        return this;
    }
#ifndef SWIG
    P2* hash_to(const byte* msg, size_t msg_len,
                const std::string& DST = "",
                const byte* aug = nullptr, size_t aug_len = 0)
    {   blst_hash_to_g2(&point, msg, msg_len, C_bytes(DST.data()), DST.size(),
                                aug, aug_len);
        return this;
    }
    P2* encode_to(const byte* msg, size_t msg_len,
                  const std::string& DST = "",
                  const byte* aug = nullptr, size_t aug_len = 0)
    {   blst_encode_to_g2(&point, msg, msg_len, C_bytes(DST.data()), DST.size(),
                                  aug, aug_len);
        return this;
    }
#endif

    P2* mult(const byte* scalar, size_t nbits)
    {   blst_p2_mult(&point, &point, scalar, nbits); return this;   }
    P2* mult(const Scalar& scalar)
    {   blst_p2_mult(&point, &point, scalar, 255); return this;   }
    P2* cneg(bool flag)
    {   blst_p2_cneg(&point, flag); return this;   }
    P2* neg()
    {   blst_p2_cneg(&point, true); return this;   }
    P2* add(const P2& a)
    {   blst_p2_add_or_double(&point, &point, a); return this;   }
    P2* add(const P2_Affine &a)
    {   blst_p2_add_or_double_affine(&point, &point, a); return this;   }
    P2* dbl()
    {   blst_p2_double(&point, &point); return this;   }
#ifndef SWIG
    static P2 add(const P2& a, const P2& b)
    {   P2 ret; blst_p2_add_or_double(ret, a, b); return ret;   }
    static P2 add(const P2& a, const P2_Affine& b)
    {   P2 ret; blst_p2_add_or_double_affine(ret, a, b); return ret;   }
    static P2 dbl(const P2& a)
    {   P2 ret; blst_p2_double(ret, a); return ret;   }
#endif
    static P2 generator()
    {   return P2(blst_p2_generator());   }

private:
    friend class P2_Affine;
    friend class P2_Affines;
    operator const blst_p2*() const { return &point; }
    operator blst_p2*()             { return &point; }
};

class P2_Affines {
private:
    struct p2_affine_no_init {
        blst_p2_affine point;
        p2_affine_no_init() { }
        operator blst_p2_affine*()              { return &point; }
        operator const blst_p2_affine*() const  { return &point; }
    };

    std::vector<p2_affine_no_init> table;
    size_t wbits, npoints;

public:
#ifndef SWIG
    P2_Affines() {}
    P2_Affines(size_t wbits, const P2_Affine* const points[], size_t npoints)
    {   this->wbits = wbits;
        this->npoints = npoints;
        table.resize(npoints << (wbits-1));
        blst_p2s_mult_wbits_precompute(table.at(0), wbits,
                        reinterpret_cast<const blst_p2_affine *const*>(points),
                        npoints);
    }
    P2_Affines(size_t wbits, const P2_Affine points[], size_t npoints)
    {   const P2_Affine* const ptrs[2] = { points, nullptr };
        P2_Affines(wbits, ptrs, npoints);
    }
    P2_Affines(size_t wbits, const std::vector<P2_Affine>& points)
    {   P2_Affines(wbits, &points.at(0), points.size());   }

    P2_Affines(size_t wbits, const P2* const points[], size_t npoints)
    {   size_t cap = npoints << (wbits-1);

        this->wbits = wbits;
        this->npoints = npoints;
        table.resize(cap);
        blst_p2s_to_affine(table.at(cap-npoints),
                           reinterpret_cast<const blst_p2 *const*>(points),
                           npoints);
        const blst_p2_affine* const ptrs[2] = { table[cap-npoints], nullptr };
        blst_p2s_mult_wbits_precompute(table[0], wbits, ptrs, npoints);
    }
    P2_Affines(size_t wbits, const P2 points[], size_t npoints)
    {   const P2* const ptrs[2] = { points, nullptr };
        P2_Affines(wbits, ptrs, npoints);
    }
    P2_Affines(size_t wbits, const std::vector<P2>& points)
    {   P2_Affines(wbits, &points.at(0), points.size());   }

    P2_Affines(const P2* const points[], size_t npoints)
    {   this->wbits = 0;
        this->npoints = npoints;
        table.resize(npoints);
        blst_p2s_to_affine(table.at(0),
                           reinterpret_cast<const blst_p2 *const*>(points),
                           npoints);
    }
    P2_Affines(const P2 points[], size_t npoints)
    {   const P2* const ptrs[2] = { points, nullptr };
        P2_Affines(ptrs, npoints);
    }
    P2_Affines(const std::vector<P2>& points)
    {   P2_Affines(&points.at(0), points.size());   }

    P2 mult(const byte* const scalars[], size_t nbits) const
    {   P2 ret;

        if (wbits != 0) {
            size_t sz = blst_p2s_mult_wbits_scratch_sizeof(npoints);
            std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
            blst_p2s_mult_wbits(ret, table.at(0), wbits, npoints,
                                     scalars, nbits, scratch.get());
        } else {
            size_t sz = blst_p2s_mult_pippenger_scratch_sizeof(npoints);
            std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
            const blst_p2_affine* const ptrs[2] = { table.at(0), nullptr };
            blst_p2s_mult_pippenger(ret, ptrs, npoints,
                                         scalars, nbits, scratch.get());
        }
        return ret;
    }

    static std::vector<P2_Affine> from(const P2* const points[], size_t npoints)
    {   std::vector<P2_Affine> ret;
        ret.resize(npoints);
        blst_p2s_to_affine(reinterpret_cast<blst_p2_affine*>(&ret.at(0)),
                           reinterpret_cast<const blst_p2 *const*>(points),
                           npoints);
        return ret;
    }
    static std::vector<P2_Affine> from(const P2 points[], size_t npoints)
    {   const P2* const ptrs[2] = { points, nullptr };
        return from(ptrs, npoints);
    }
    static std::vector<P2_Affine> from(const std::vector<P2>& points)
    {   return from(&points.at(0), points.size());   }
#endif

    static P2 mult_pippenger(const P2_Affine* const points[], size_t npoints,
                             const byte* const scalars[], size_t nbits)
    {   P2 ret;
        size_t sz = blst_p2s_mult_pippenger_scratch_sizeof(npoints);
        std::unique_ptr<limb_t[]> scratch{new limb_t[sz/sizeof(limb_t)]};
        blst_p2s_mult_pippenger(ret,
                    reinterpret_cast<const blst_p2_affine *const*>(points),
                    npoints, scalars, nbits, scratch.get());
        return ret;
    }
#ifndef SWIG
    static P2 mult_pippenger(const P2_Affine points[], size_t npoints,
                             const byte* const scalars[], size_t nbits)
    {   const P2_Affine* const ptrs[2] = { points, nullptr };
        return mult_pippenger(ptrs, npoints, scalars, nbits);
    }
    static P2 mult_pippenger(const std::vector<P2_Affine>& points,
                             const byte* const scalars[], size_t nbits)
    {   return mult_pippenger(&points.at(0), points.size(), scalars, nbits);   }
#endif

    static P2 add(const P2_Affine* const points[], size_t npoints)
    {   P2 ret;
        blst_p2s_add(ret,
                     reinterpret_cast<const blst_p2_affine *const*>(points),
                     npoints);
        return ret;
    }
#ifndef SWIG
    static P2 add(const P2_Affine points[], size_t npoints)
    {   const P2_Affine* const ptrs[2] = { points, nullptr };
        return add(ptrs, npoints);
    }
    static P2 add(const std::vector<P2_Affine>& points)
    {   return add(&points.at(0), points.size());   }
#endif
};

inline P1_Affine::P1_Affine(const P1& jacobian)
{   blst_p1_to_affine(&point, jacobian);   }
inline P2_Affine::P2_Affine(const P2& jacobian)
{   blst_p2_to_affine(&point, jacobian);   }

inline P1 P1_Affine::to_jacobian() const { P1 ret(*this); return ret; }
inline P2 P2_Affine::to_jacobian() const { P2 ret(*this); return ret; }

inline P1 G1() { return P1::generator();  }
inline P2 G2() { return P2::generator();  }

#ifndef SWIG
inline BLST_ERROR P1_Affine::core_verify(const P2_Affine& pk,
                                         bool hash_or_encode,
                                         const byte* msg, size_t msg_len,
                                         const std::string& DST,
                                         const byte* aug, size_t aug_len) const
{   return blst_core_verify_pk_in_g2(pk, &point, hash_or_encode,
                                         msg, msg_len,
                                         C_bytes(DST.data()), DST.size(),
                                         aug, aug_len);
}
inline BLST_ERROR P2_Affine::core_verify(const P1_Affine& pk,
                                         bool hash_or_encode,
                                         const byte* msg, size_t msg_len,
                                         const std::string& DST,
                                         const byte* aug, size_t aug_len) const
{   return blst_core_verify_pk_in_g1(pk, &point, hash_or_encode,
                                         msg, msg_len,
                                         C_bytes(DST.data()), DST.size(),
                                         aug, aug_len);
}
#endif

class PT {
private:
    blst_fp12 value;

    PT(const blst_fp12 *v)  { value = *v; }
public:
    PT(const P1_Affine& p)  { blst_aggregated_in_g1(&value, p); }
    PT(const P2_Affine& q)  { blst_aggregated_in_g2(&value, q); }
    PT(const P2_Affine& q, const P1_Affine& p)
    {   blst_miller_loop(&value, q, p);   }
    PT(const P1_Affine& p, const P2_Affine& q) : PT(q, p) {}
    PT(const P2& q, const P1& p)
    {   blst_miller_loop(&value, P2_Affine(q), P1_Affine(p));   }
    PT(const P1& p, const P2& q) : PT(q, p) {}

    PT dup() const          { return *this; }
    bool is_one() const     { return blst_fp12_is_one(&value); }
    bool is_equal(const PT& p) const
    {   return blst_fp12_is_equal(&value, p);   }
    PT* sqr()               { blst_fp12_sqr(&value, &value);    return this; }
    PT* mul(const PT& p)    { blst_fp12_mul(&value, &value, p); return this; }
    PT* final_exp()         { blst_final_exp(&value, &value);   return this; }
    bool in_group() const   { return blst_fp12_in_group(&value); }
    void to_bendian(byte out[48*12]) const
    {   blst_bendian_from_fp12(out, &value);   }

    static bool finalverify(const PT& gt1, const PT& gt2)
    {   return blst_fp12_finalverify(gt1, gt2);   }
    static PT one() { return PT(blst_fp12_one()); }

private:
    friend class Pairing;
    operator const blst_fp12*() const { return &value; }
};

class Pairing {
private:
    operator blst_pairing*()
    {   return reinterpret_cast<blst_pairing *>(this);   }
    operator const blst_pairing*() const
    {   return reinterpret_cast<const blst_pairing *>(this);   }

    void init(bool hash_or_encode, const byte* DST, size_t DST_len)
    {   // Copy DST to heap, std::string can be volatile, especially in SWIG:-(
        byte *dst = new byte[DST_len];
        memcpy(dst, DST, DST_len);
        blst_pairing_init(*this, hash_or_encode, dst, DST_len);
    }

public:
#ifndef SWIG
    void* operator new(size_t)
    {   return new uint64_t[blst_pairing_sizeof()/sizeof(uint64_t)];   }
    void operator delete(void *ptr)
    {   delete[] static_cast<uint64_t*>(ptr);   }

    Pairing(bool hash_or_encode, const std::string& DST)
    {   init(hash_or_encode, C_bytes(DST.data()), DST.size());   }
#endif
#ifndef SWIGJAVA
    Pairing(bool hash_or_encode, const byte* DST, size_t DST_len)
    {   init(hash_or_encode, DST, DST_len);   }
    ~Pairing() { delete[] blst_pairing_get_dst(*this); }
#endif

    BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
                         bytes_t msg, bytes_t aug = {nullptr, 0})
    {   return blst_pairing_aggregate_pk_in_g1(*this, *pk, *sig,
                         msg.ptr, msg.len, aug.ptr, aug.len);
    }
    BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
                         bytes_t msg, bytes_t aug = {nullptr, 0})
    {   return blst_pairing_aggregate_pk_in_g2(*this, *pk, *sig,
                         msg.ptr, msg.len, aug.ptr, aug.len);
    }
    BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
                               const byte* scalar, size_t nbits,
                               bytes_t msg, bytes_t aug = {nullptr, 0})
    {   return blst_pairing_mul_n_aggregate_pk_in_g1(*this, *pk, *sig,
                               scalar, nbits, msg.ptr, msg.len, aug.ptr, aug.len);
    }
    BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
                               const byte* scalar, size_t nbits,
                               bytes_t msg, bytes_t aug = {nullptr, 0})
    {   return blst_pairing_mul_n_aggregate_pk_in_g2(*this, *pk, *sig,
                               scalar, nbits, msg.ptr, msg.len, aug.ptr, aug.len);
    }
#ifndef SWIG
    BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
                         const byte* msg, size_t msg_len,
                         const byte* aug = nullptr, size_t aug_len = 0)
    {   return blst_pairing_aggregate_pk_in_g1(*this, *pk, *sig,
                         msg, msg_len, aug, aug_len);
    }
    BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
                         const byte* msg, size_t msg_len,
                         const byte* aug = nullptr, size_t aug_len = 0)
    {   return blst_pairing_aggregate_pk_in_g2(*this, *pk, *sig,
                         msg, msg_len, aug, aug_len);
    }
    BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
                               const byte* scalar, size_t nbits,
                               const byte* msg, size_t msg_len,
                               const byte* aug = nullptr, size_t aug_len = 0)
    {   return blst_pairing_mul_n_aggregate_pk_in_g1(*this, *pk, *sig,
                               scalar, nbits, msg, msg_len, aug, aug_len);
    }
    BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
                               const byte* scalar, size_t nbits,
                               const byte* msg, size_t msg_len,
                               const byte* aug = nullptr, size_t aug_len = 0)
    {   return blst_pairing_mul_n_aggregate_pk_in_g2(*this, *pk, *sig,
                               scalar, nbits, msg, msg_len, aug, aug_len);
    }
#endif
    void commit()
    {   blst_pairing_commit(*this);   }
    BLST_ERROR merge(const Pairing* ctx)
    {   return blst_pairing_merge(*this, *ctx);   }
    bool finalverify(const PT* sig = nullptr) const
    {   return sig == nullptr ? blst_pairing_finalverify(*this, nullptr)
                              : blst_pairing_finalverify(*this, *sig);
    }
    void raw_aggregate(const P2_Affine* q, const P1_Affine* p)
    {   blst_pairing_raw_aggregate(*this, *q, *p);   }
    PT as_fp12()
    {   return PT(blst_pairing_as_fp12(*this));   }
};

} // namespace blst

#endif


================================================
FILE: bindings/blst.swg
================================================
// Copyright Supranational LLC
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

%module blst
%rename("%(strip:[blst_])s") "";    // prefix is redundant in named module

%include "exception.i"
#ifdef __cplusplus
%include "std_string.i"
%typemap(out) SELF* OUTPUT = SWIGTYPE*; // to be overridden as required
#else
#warning consider using C++ interface
#endif
%include "stdint.i"

%apply const char* { const byte*, const byte[ANY] }
%apply (const char *STRING, size_t LENGTH) { (const byte *STRING,
                                              size_t LENGTH) }

#if defined(SWIGPYTHON)

%header %{
#if PY_VERSION_HEX<0x030d0000
/* Tailored polyfill, for example no need to handle |n_bytes| == 0 here */
static Py_ssize_t PyLong_AsNativeBytes(PyObject* v, void* buffer,
                                       Py_ssize_t n_bytes, int flags)
{
    return _PyLong_AsByteArray((PyLongObject*)v,
                               (unsigned char*)buffer, n_bytes,
                               flags&1, (flags&4) == 0) < 0 ? -1 : n_bytes;
}
# define My_PYLONG_FLAGS (1 | 4 | 8)
#else
# define My_PYLONG_FLAGS (Py_ASNATIVEBYTES_LITTLE_ENDIAN | \
                          Py_ASNATIVEBYTES_UNSIGNED_BUFFER | \
                          Py_ASNATIVEBYTES_REJECT_NEGATIVE)
#endif
#if PY_VERSION_HEX<0x030e0000
static int PyLong_GetSign(PyObject *obj, int *sign)
{
    if (!PyLong_Check(obj))
        return -1;
    *sign = _PyLong_Sign(obj);
    return 0;
}
#endif
%}

// some sorcery to allow assignments as output, e.g.
//      hash = blst.encode_to_g1(b"foo")
%typemap(in, numinputs=0) OBJECT *OUTPUT($1_basetype temp) %{ $1 = &temp; %}
%typemap(argout) OBJECT *OUTPUT {
    PyObject *obj = SWIG_NewPointerObj(memcpy(malloc(sizeof($1_basetype)),
                                              $1,sizeof($1_basetype)),
                                       $descriptor, SWIG_POINTER_NEW);
    $result = SWIG_AppendOutput($result, obj);
}
%apply OBJECT *OUTPUT {
    blst_p1        *out, blst_p1        *out_pk, blst_p1        *out_sig,
    blst_p1_affine *out, blst_p1_affine *out_pk, blst_p1_affine *out_sig,
    blst_p2        *out, blst_p2        *out_pk, blst_p2        *out_sig,
    blst_p2_affine *out, blst_p2_affine *out_pk, blst_p2_affine *out_sig,
    blst_scalar    *out, blst_scalar    *out_SK,
    blst_fp12      *out
}

// accept 'bytes' and 'bytearray' as inputs...
%typemap(in) const byte* %{
    if ($input == Py_None) {
        $1 = NULL;
    } else if (PyBytes_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname'");

        $1 = ($1_ltype)buf;
    } else if (PyByteArray_Check($input)) {
        $1 = ($1_ltype)PyByteArray_AsString($input);
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting 'bytes' or 'bytearray'");
    }
%}
%typemap(freearg) const byte* ""

%typemap(in) const byte[ANY] %{
    if (PyBytes_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname'");

        if (nbytes != $1_dim0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname', "
                                                 "expecting $1_dim0 bytes");
        $1 = ($1_ltype)buf;
    } else if (PyByteArray_Check($input)) {
        if (PyByteArray_Size($input) != $1_dim0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname', "
                                                 "expecting $1_dim0 bytes");
        $1 = ($1_ltype)PyByteArray_AsString($input);
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting 'bytes' or 'bytearray'");
    }
%}
%typemap(freearg) const byte[ANY] ""

%typemap(in) (const byte *STRING, size_t LENGTH) %{
    if ($input == Py_None) {
        $1 = NULL;
        $2 = 0;
    } else if (PyBytes_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname'");

        $1 = ($1_ltype)buf;
        $2 = nbytes;
    } else if (PyByteArray_Check($input)) {
        $1 = ($1_ltype)PyByteArray_AsString($input);
        $2 = PyByteArray_Size($input);
#ifdef Py_USING_UNICODE
    } else if (PyUnicode_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;
        PyObject *obj = PyUnicode_AsUTF8String($input);

        if (obj == NULL || PyBytes_AsStringAndSize(obj, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname'");

        $1 = ($1_ltype)alloca($2 = nbytes);
        memcpy($1, buf, $2);
        Py_DECREF(obj);
#endif
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting 'bytes' or 'bytearray'");
    }
%}
%typemap(freearg) (const byte *STRING, size_t LENGTH) ""

%typemap(in) blst::bytes_t %{
    if ($input == Py_None) {
        $1.ptr = NULL;
        $1.len = 0;
    } else if (PyBytes_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname'");

        $1.ptr = (byte*)buf;
        $1.len = nbytes;
    } else if (PyByteArray_Check($input)) {
        $1.ptr = (byte*)PyByteArray_AsString($input);
        $1.len = PyByteArray_Size($input);
#ifdef Py_USING_UNICODE
    } else if (PyUnicode_Check($input)) {
        char *buf;
        Py_ssize_t nbytes;
        PyObject *obj = PyUnicode_AsUTF8String($input);

        if (obj == NULL || PyBytes_AsStringAndSize(obj, &buf, &nbytes) < 0)
            SWIG_exception_fail(SWIG_ValueError, "in method '$symname'");

        auto ptr = alloca(nbytes);
        memcpy(ptr, buf, nbytes);
        $1.ptr = (byte*)ptr;
        $1.len = nbytes;
        Py_DECREF(obj);
#endif
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting 'bytes' or 'bytearray'");
    }
%}
%typemap(freearg)   blst::bytes_t ""
%typemap(typecheck) blst::bytes_t ""

// let users use Python 'int', 'bytes' and 'bytearray' as scalars
%typemap(in) (const byte* scalar, size_t nbits) %{
    if (PyBytes_Check($input)) {
        char *scalar;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &scalar, &nbytes) < 0)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname'");

        $1 = ($1_ltype)scalar;
        $2 = 8 * nbytes;
    } else if (PyByteArray_Check($input)) {
        $1 = ($1_ltype)PyByteArray_AsString($input);
        $2 = 8 * PyByteArray_Size($input);
    } else if (PyLong_Check($input)) {
        size_t nbytes;

        $2 = _PyLong_NumBits($input);
        $1 = ($1_ltype)alloca(nbytes = ($2 + 7)/8);

        if (PyLong_AsNativeBytes($input, $1, nbytes, My_PYLONG_FLAGS) < 0)
            SWIG_exception_fail(SWIG_OverflowError, "in method '$symname'");
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting 'int', 'bytes' "
                                            "or 'bytearray'");
    }
%}

#ifdef __cplusplus
%typemap(in) (const POINT* points[], size_t npoints)
    (std::unique_ptr<$*1_ltype[]> points, size_t _global_npoints) %{
    if (PyList_Check($input)) {
        _global_npoints = PyList_Size($input);
        points = std::unique_ptr<$*1_ltype[]>(new $*1_ltype[_global_npoints]);
        PyObject* obj = PyList_GET_ITEM($input, 0);
        // check the type of the 1st element
        if (SWIG_ConvertPtr(obj, (void**)&points[0], $*1_descriptor, 0) != SWIG_OK)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                "expecting 'list' of '$*1_ltype'");
        for (size_t i = 1; i < _global_npoints; i++) {
            obj = PyList_GET_ITEM($input, i);
            points[i] = ($*1_ltype)SWIG_Python_GetSwigThis(obj)->ptr;
        }
        $1 = points.get();
        $2 = _global_npoints;
    } else if (PyBytes_Check($input)) {
        char *bytes;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &bytes, &nbytes) < 0)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname'");

        points = std::unique_ptr<$*1_ltype[]>(new $*1_ltype[2]);
        points[0] = ($*1_ltype)bytes;
        points[1] = nullptr;
        $1 = points.get();
        $2 = _global_npoints = nbytes / sizeof(points[0][0]);
    } else if (PyMemoryView_Check($input)) {    // output from to_affine()
        Py_buffer *buf = PyMemoryView_GET_BUFFER($input);

        if (!PyBytes_Check(buf->obj))
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                "expecting 'bytes' in "
                                                "'memoryview'  for points[]");
        points = std::unique_ptr<$*1_ltype[]>(new $*1_ltype[2]);
        points[0] = ($*1_ltype)buf->buf;
        points[1] = nullptr;
        $1 = points.get();
        $2 = _global_npoints = buf->len / sizeof(points[0][0]);
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting "
                                            "'list', 'bytes' or 'memoryview' "
                                            "for points[]");
    }
%}
%apply (const POINT* points[], size_t npoints) {
       (const blst::P1_Affine* const points[], size_t npoints),
       (const blst::P2_Affine* const points[], size_t npoints),
       (const blst::P1* const points[], size_t npoints),
       (const blst::P2* const points[], size_t npoints)
}

%typemap(in, numinputs=0) POINT points[] (PyObject *obj) ""
%typemap(check) POINT points[] {
    char *bytes;
    Py_ssize_t size = sizeof($1[0]) * _global_npoints;

    obj$argnum = PyBytes_FromStringAndSize(NULL, size);
    if (obj$argnum == NULL) SWIG_fail;
    PyBytes_AsStringAndSize(obj$argnum, &bytes, &size);
    $1 = ($1_ltype)bytes;
}
%typemap(argout) POINT points[] %{
    $result = PyMemoryView_FromObject(obj$argnum);
    if ($result != NULL) {
        // .itemsize to return size of point, and len() - amount of points
        PyMemoryView_GET_BUFFER($result)->itemsize  = sizeof($1[0]);
        PyMemoryView_GET_BUFFER($result)->shape[0] /= sizeof($1[0]);
    } else {
        Py_DECREF(obj$argnum);
    }
%}
%apply POINT points[] { blst_p1_affine dst[], blst_p2_affine dst[] }

%extend blst::P1_Affines {
    static PyObject* as_memory(blst_p1_affine dst[],
                               const blst::P1* const points[], size_t npoints)
    {   blst_p1s_to_affine(dst, (const blst_p1 *const*)points, npoints);
        return Py_None; // ignored by 'argout' typemap above
    }
}
%extend blst::P2_Affines {
    static PyObject* as_memory(blst_p2_affine dst[],
                               const blst::P2* const points[], size_t npoints)
    {   blst_p2s_to_affine(dst, (const blst_p2 *const*)points, npoints);
        return Py_None; // ignored by 'argout' typemap above
    }
}
%nodefault blst::P1_Affines;
%nodefault blst::P2_Affines;

%typemap(in) (const byte* const scalars[], size_t nbits)
    (std::unique_ptr<byte[]> bytes, byte *scalars[2]) %{
    if (PyList_Check($input)) {
        if ((size_t)PyList_Size($input) != _global_npoints)
            SWIG_exception_fail(SWIG_IndexError, "in method '$symname', 'list' "
                                                 "length mismatch for scalars[]");

        PyObject *obj = PyList_GET_ITEM($input, 0);
        if (PyLong_Check(obj)) {
            $2 = _PyLong_NumBits(obj);
            for (size_t i = 1; i < _global_npoints; i++) {
                size_t nbits;
                int sign;
                obj = PyList_GET_ITEM($input, i);
                if (PyLong_GetSign(obj, &sign) < 0 || sign < 0)
                    SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                        "expecting all 'long's");
                nbits = _PyLong_NumBits(obj);
                if (nbits > $2) $2 = nbits;
            }

            size_t nbytes = ($2 + 7)/8;
            bytes = std::unique_ptr<byte[]>(new byte[_global_npoints*nbytes]);
            byte* scalar = bytes.get();
            for (size_t i = 0; i < _global_npoints; i++, scalar += nbytes)
                PyLong_AsNativeBytes(PyList_GET_ITEM($input, i),
                                     scalar, nbytes, My_PYLONG_FLAGS);

            scalars[0] = bytes.get();
            scalars[1] = nullptr;
            $1 = scalars;
        } else {
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                "expecting 'list' of 'long's "
                                                "for scalars[]");
        }
    } else if (PyBytes_Check($input)) {
        char *bytes;
        Py_ssize_t nbytes;

        if (PyBytes_AsStringAndSize($input, &bytes, &nbytes) < 0)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname'");

        scalars[0] = ($*1_ltype)bytes;
        scalars[1] = nullptr;
        $1 = scalars;
        $2 = 8 * (nbytes / _global_npoints);
    } else if (PyByteArray_Check($input)) {
        scalars[0] = ($*1_ltype)PyByteArray_AsString($input);
        scalars[1] = nullptr;
        $1 = scalars;
        $2 = 8 * (PyByteArray_Size($input) / _global_npoints);
    } else if (PyMemoryView_Check($input)) {
        Py_buffer *buf = PyMemoryView_GET_BUFFER($input);

        if (!PyBytes_Check(buf->obj) && !PyByteArray_Check(buf->obj))
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                "expecting 'bytes' in "
                                                "'memoryview'  for points[]");
        scalars[0] = ($*1_ltype)buf->buf;
        scalars[1] = nullptr;
        $1 = scalars;
        $2 = 8 * (buf->len / _global_npoints);
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting "
                                            "'list', 'bytes', 'bytearray' "
                                            "or 'memoryview' for scalars[]");
    }
%}

%typemap(out) BLST_ERROR %{
    if ($1 != BLST_SUCCESS) {
        SWIG_exception(SWIG_ValueError, BLST_ERROR_str[$1]);
        SWIG_fail;
    }
    $result = SWIG_From_int($1);
%}

// return |this|
%typemap(out) SELF* OUTPUT %{ (void)$1; Py_INCREF($result = swig_obj[0]); %}
#endif

#elif defined(SWIGJAVA)

%header %{
#ifdef __cplusplus
# define JCALL(func, ...) jenv->func(__VA_ARGS__)
#else
# define JCALL(func, ...) (*jenv)->func(jenv, __VA_ARGS__)
#endif
%}

%include "enums.swg"
%include "arrays_java.i"
%javaconst(1);

#if SWIG_VERSION < 0x040000
%apply (char *STRING, size_t LENGTH) { (const byte *STRING, size_t LENGTH) }
#endif

%pragma(java) jniclassimports=%{
import java.io.*;
import java.nio.file.*;
%}
%pragma(java) jniclasscode=%{
    final static String libName = System.mapLibraryName("$module");
    final static String resName = System.getProperty("os.name").replaceFirst(" .*","")
                                + "/" + System.getProperty("os.arch")
                                + "/" + libName;
    static {
        Class<?> imClazz = $imclassname.class;
        InputStream res = imClazz.getResourceAsStream(
                        System.getProperty(imClazz.getPackageName() + ".jniResource", resName));
        if (res == null) {
            try {
                System.loadLibrary("$module");
            } catch (UnsatisfiedLinkError e) {
                String[] cmd = System.getProperty("sun.java.command").split("/");
                if (!"$imclassname".equals(cmd[cmd.length-1]))
                    // suppress exception if 'main' below is executed
                    throw new RuntimeException(e.getMessage());
            }
        } else {
            // unpack shared library into a temporary directory and load it
            try {
                Path tmpdir = Files.createTempDirectory("$module@");
                tmpdir.toFile().deleteOnExit();
                Path tmpdll = Paths.get(tmpdir.toString(), libName);
                tmpdll.toFile().deleteOnExit();
                Files.copy(res, tmpdll, StandardCopyOption.REPLACE_EXISTING);
                res.close();
                System.load(tmpdll.toString());
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    }
    public static void main(String argv[]) {
        System.out.println(resName);
    }
%}

#ifdef __cplusplus
// Extensive sorcery to shift memory management to JVM GC. General idea is
// to use Java long[] as opaque storage for blst data. Methods that return
// new objects allocate suitably sized long[] arrays from JVM heap,
// references to which are then assigned to |swigCPtr| on the Java side.
// And when passed back to JNI, |swigCPtr|s are dereferenced with
// GetLongArrayElements... And no destructors!
%nodefaultdtor;
%typemap(javafinalize)  SWIGTYPE ""
%typemap(javadestruct)  SWIGTYPE ""

%typemap(javabody)      SWIGTYPE %{
  private transient long[] swigCPtr;

  protected $javaclassname(long[] cPtr) { swigCPtr = cPtr; }

  protected static long[] getCPtr($javaclassname obj) {
    return obj != null ? obj.swigCPtr : null;
  }

  public $javaclassname dup() { return new $javaclassname(swigCPtr.clone()); }
%}
%ignore dup;
%typemap(javaconstruct) SWIGTYPE { this($imcall); }
%typemap(jni)           SWIGTYPE, SWIGTYPE&, SWIGTYPE* "jlongArray"
%typemap(jtype)         SWIGTYPE, SWIGTYPE&, SWIGTYPE* "long[]"
%typemap(javaout)       SWIGTYPE, SWIGTYPE&, SWIGTYPE* {
    return new $javaclassname($jnicall);
}
%typemap(in)            SWIGTYPE&, SWIGTYPE* %{
    $1 = ($1_ltype)JCALL(GetLongArrayElements, $input, 0);
%}
%typemap(in)      const SWIGTYPE&, const SWIGTYPE* %{
    $1 = $input ? ($1_ltype)JCALL(GetLongArrayElements, $input, 0) : NULL;
%}
%typemap(out)           SWIGTYPE&, SWIGTYPE* %{
    if ($1 != $null) {
        size_t sz = (sizeof($1_basetype) + sizeof(jlong) - 1)/sizeof(jlong);
        $result = JCALL(NewLongArray, sz);
        if ($result != $null)
            JCALL(SetLongArrayRegion, $result, 0, sz, (const jlong *)$1);
    }
%}
%typemap(out)           SWIGTYPE {
    size_t sz = (sizeof($1_basetype) + sizeof(jlong) - 1)/sizeof(jlong);
    $result = JCALL(NewLongArray, sz);
    if ($result != $null)
        JCALL(SetLongArrayRegion, $result, 0, sz, (const jlong *)&$1);
}
%typemap(newfree)       SWIGTYPE* "delete $1;"
%typemap(freearg)       SWIGTYPE&, SWIGTYPE* %{
    JCALL(ReleaseLongArrayElements, $input, (jlong *)$1, 0);
%}
%typemap(freearg) const SWIGTYPE&, const SWIGTYPE* %{
    if ($input) JCALL(ReleaseLongArrayElements, $input, (jlong *)$1, JNI_ABORT);
%}
%typemap(freearg) const std::string& ""

// I wish |jenv| was available in the constructor, so that NewLongArray
// could be called at once, without having to resort to matching
// %typemap(out)...
%extend blst::Pairing {
    Pairing(bool hash_or_encode, const std::string& DST)
    {   size_t sz = blst_pairing_sizeof();
        size_t SZ = (sz + DST.size() + sizeof(jlong) - 1)/sizeof(jlong);
        blst_pairing *ret = (blst_pairing *)malloc(SZ*sizeof(jlong));
        if (DST.size() != 0) {
            byte *dst = (byte *)ret + sz;
            memcpy(dst, DST.data(), DST.size());
            blst_pairing_init(ret, hash_or_encode, dst, DST.size());
        } else {
            blst_pairing_init(ret, hash_or_encode, NULL, 0);
        }
        return (Pairing *)ret;
    }
}
%typemap(out) blst::Pairing* {
    size_t sz = blst_pairing_sizeof();
    size_t SZ = (sz + arg2->size() + sizeof(jlong) - 1)/sizeof(jlong);
    $result = JCALL(NewLongArray, SZ);
    if ($result != $null)
        JCALL(SetLongArrayRegion, $result, 0, SZ, (const jlong *)$1);
}
%typemap(newfree) blst::Pairing* "free($1);"

%typemap(javaout) SELF* OUTPUT { $jnicall; return this; }
%typemap(out)     SELF* OUTPUT "(void)$1;"
%typemap(jni)     SELF* OUTPUT "void"
%typemap(jtype)   SELF* OUTPUT "void"
#endif

%typemap(throws) BLST_ERROR %{
    SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException,
                                  BLST_ERROR_str[$1]);
%}

// handle input const byte[] more efficiently...
%apply signed char[] { const byte* }
%typemap(in) const byte* %{
    $1 = $input ? ($1_ltype)JCALL(GetByteArrayElements, $input, 0) : NULL;
%}
%typemap(argout)  const byte* ""
%typemap(freearg) const byte* %{
    if ($input) JCALL(ReleaseByteArrayElements, $input, (jbyte *)$1, JNI_ABORT);
%}

%apply const byte* { const byte[ANY] }
%typemap(in) const byte[ANY] {
    size_t sz = JCALL(GetArrayLength, $input);
    if (sz != $1_dim0) {
        SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException,
                                      "BLST_ERROR: input size mismatch");
        return $null;
    }
    $1 = ($1_ltype)JCALL(GetByteArrayElements, $input, 0);
}

// let users use 'java.math.BigInteger' as scalars
%typemap(in) (const byte* scalar, size_t nbits) %{
    $2 = JCALL(GetArrayLength, $input);
    $1 = ($1_ltype)alloca($2);
    JCALL(GetByteArrayRegion, $input, 0, $2, (jbyte*)$1);
    if (*(jbyte*)$1 < 0) {
        SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException,
                                      "expecting unsigned value");
        return $null;
    }
    {   // BigInteger.toByteArray() emits big-endian, flip the order...
        size_t i, j;
        for(i=0, j=$2-1; i<$2/2; i++, j--) {
            $*1_ltype t=$1[i]; $1[i]=$1[j]; $1[j]=t;
        }
    }
    if ($1[$2-1] == 0)
        $2--;
    $2 *= 8;
%}
%typemap(jni)    (const byte* scalar, size_t nbits) "jbyteArray"
%typemap(jtype)  (const byte* scalar, size_t nbits) "byte[]"
%typemap(jstype) (const byte* scalar, size_t nbits) "java.math.BigInteger"
%typemap(javain) (const byte* scalar, size_t nbits) "$javainput.toByteArray()"

%typemap(jni)    (const byte *STRING, size_t LENGTH) "jbyteArray"
%typemap(jtype)  (const byte *STRING, size_t LENGTH) "byte[]"
%typemap(jstype) (const byte *STRING, size_t LENGTH) "byte[]"
%typemap(javain) (const byte *STRING, size_t LENGTH) "$javainput"
%typemap(freearg)(const byte *STRING, size_t LENGTH) ""

%typemap(jni)    blst::bytes_t "jbyteArray"
%typemap(jtype)  blst::bytes_t "byte[]"
%typemap(jstype) blst::bytes_t "byte[]"
%typemap(javain) blst::bytes_t "$javainput"
%typemap(freearg)blst::bytes_t ""
%typemap(in)     blst::bytes_t %{
    $1.ptr = (const byte*)JCALL(GetByteArrayElements, $input, 0);
    $1.len = JCALL(GetArrayLength, $input);
%}
%typemap(argout) blst::bytes_t  %{
    JCALL(ReleaseByteArrayElements, $input, (jbyte *)$1.ptr, JNI_ABORT);
%}

#elif defined(SWIGJAVASCRIPT) && defined(SWIG_JAVASCRIPT_V8)

%header %{
#if V8_MAJOR_VERSION >= 8
# define GetData() GetBackingStore()->Data()
#else
# define GetData() GetContents().Data()
#endif
%}

%typemap(throws) BLST_ERROR %{ SWIG_V8_Raise(BLST_ERROR_str[$1]); SWIG_fail; %}

%typemap(in) const byte* %{
    if ($input->IsArrayBufferView()) {
        auto av = v8::Local<v8::ArrayBufferView>::Cast($input);
        auto buf = av->Buffer();
        $1 = ($1_ltype)buf->GetData() + av->ByteOffset();
    } else if ($input->IsNull()) {
        $1 = nullptr;
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting <Buffer>");
    }
%}
%typemap(argout)  const byte* ""
%typemap(freearg) const byte* ""

%apply const byte* { const byte[ANY] }
%typemap(in) const byte[ANY] %{
    if ($input->IsArrayBufferView()) {
        auto av = v8::Local<v8::ArrayBufferView>::Cast($input);
        if (av->ByteLength() != $1_dim0)
            SWIG_exception_fail(SWIG_IndexError, "in method '$symname', "
                                                 "expecting $1_dim0 bytes");
        auto buf = av->Buffer();
        $1 = ($1_ltype)buf->GetData() + av->ByteOffset();
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting <Buffer>");
    }
%}

// let users use JavaScript <BigInt> and <Buffer> as scalars
%typemap(in) (const byte* scalar, size_t nbits) %{
    if ($input->IsArrayBufferView()) {
        auto av = v8::Local<v8::ArrayBufferView>::Cast($input);
        auto buf = av->Buffer();
        $1 = ($1_ltype)buf->GetData() + av->ByteOffset();
        $2 = 8*av->ByteLength();
#if V8_MAJOR_VERSION >=6 && V8_MINOR_VERSION >= 8
    } else if ($input->IsBigInt()) {
        auto bi = v8::Local<v8::BigInt>::Cast($input);
        int sign, word_count = bi->WordCount();
        uint64_t* words = (uint64_t*)alloca($2 = word_count*sizeof(uint64_t));

        bi->ToWordsArray(&sign, &word_count, words);
        if (sign)
            SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                                "expecting unsigned value");
        $1 = ($1_ltype)words;
        $2 *= 8;

        const union {
            long one;
            char little;
        } is_endian = { 1 };

        if (!is_endian.little) {
            byte* p = $1;
            for (int i = 0; i < word_count; i++) {
                uint64_t val = words[i];
                for (size_t j = 0; j < sizeof(val); j++, val >>= 8)
                    *p++ = (byte)val;
            }
        }
#endif
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting <Buffer> or <BigInt>");
    }
%}

%typemap(in) (const byte *STRING, size_t LENGTH) %{
    if ($input->IsArrayBufferView()) {
        auto av = v8::Local<v8::ArrayBufferView>::Cast($input);
        auto buf = av->Buffer();
        $1 = ($1_ltype)buf->GetData() + av->ByteOffset();
        $2 = av->ByteLength();
    } else if ($input->IsString()) {
        auto str = v8::Local<v8::String>::Cast($input);
        $2 = SWIGV8_UTF8_LENGTH(str);
        $1 = ($1_ltype)alloca($2);
        SWIGV8_WRITE_UTF8(str, (char *)$1, $2);
    } else if ($input->IsNull()) {
        $1 = nullptr;
        $2 = 0;
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting <Buffer> or <String>");
    }
%}
%typemap(freearg) (const byte *STRING, size_t LENGTH) ""

%typemap(in) blst::bytes_t %{
    if ($input->IsArrayBufferView()) {
        auto av = v8::Local<v8::ArrayBufferView>::Cast($input);
        auto buf = av->Buffer();
        $1.ptr = (byte*)buf->GetData() + av->ByteOffset();
        $1.len = av->ByteLength();
    } else if ($input->IsString()) {
        auto str = v8::Local<v8::String>::Cast($input);
        $1.len = SWIGV8_UTF8_LENGTH(str);
        $1.ptr = (byte*)alloca($1.len);
        SWIGV8_WRITE_UTF8(str, (char *)$1.ptr, $1.len);
    } else if ($input->IsNull()) {
        $1.ptr = nullptr;
        $1.len = 0;
    } else {
        SWIG_exception_fail(SWIG_TypeError, "in method '$symname', "
                                            "expecting <Buffer> or <String>");
    }
%}
%typemap(freearg) blst::bytes_t ""

// return |this|
%typemap(out) SELF* OUTPUT %{ (void)$1; $result = args.Holder(); %}

#elif defined(SWIGPERL)

// let users use byte[] as scalars
%apply (const char *STRING, size_t LENGTH) { (const byte* scalar, size_t nbits) }
%typemap(check) (const byte* scalar, size_t nbits) %{ $2 *= 8; %}

#ifdef __cplusplus
// return |this|
%typemap(out) SELF* OUTPUT %{ (void)$1; argvi++; %}
#endif

#endif  // SWIG<language>

// everybody has a way to bundle pointer and buffer size, but C:-(
%apply (const byte *STRING, size_t LENGTH) {
       (const byte *msg,    size_t msg_len),
       (const byte *DST,    size_t DST_len),
       (const byte *aug,    size_t aug_len),
       (const byte *IKM,    size_t IKM_len),
       (const byte *info,   size_t info_len),
       (const byte *salt,   size_t salt_len),
       (const byte *in,     size_t len)
}

// some sorcery to return byte[] from serialization methods
%typemap(in, numinputs=0) byte out[ANY] (byte temp[$1_dim0]) %{ $1 = temp; %}
%typemap(argout) byte out[ANY] {
#if defined(SWIGPYTHON)
    PyObject *obj = SWIG_FromCharPtrAndSize((char *)$1, $1_dim0);
    $result = SWIG_AppendOutput($result, obj);
#elif defined(SWIGJAVA)
    $result = JCALL(NewByteArray, $1_dim0);
    if ($result != $null) {
        JCALL(SetByteArrayRegion, $result, 0, $1_dim0, (const jbyte *)$1);
    }
#elif defined(SWIGJAVASCRIPT) && defined(SWIG_JAVASCRIPT_V8)
    auto ab = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), $1_dim0);
    memcpy(ab->GetData(), $1, $1_dim0);
    $result = v8::Uint8Array::New(ab, 0, $1_dim0);
#elif defined(SWIGPERL)
    $result = SWIG_FromCharPtrAndSize((char *)$1, $1_dim0); argvi++;
#else // TODO: figure out more language-specific ways to return multi-values...
    if ($result == NULL)
        $result = SWIG_FromCharPtrAndSize((char *)$1, $1_dim0);
#endif
}
%typemap(freearg) byte out[ANY] ""
#ifdef SWIGJAVA
%typemap(jni)     byte out[ANY] "jbyteArray"
%typemap(jtype)   byte out[ANY] "byte[]"
%typemap(jstype)  byte out[ANY] "byte[]"
%typemap(javaout) byte out[ANY] { return $jnicall; }
#endif
%apply byte out[ANY] {
    void to_bendian,    void blst_bendian_from_scalar,
    void to_lendian,    void blst_lendian_from_scalar,
    void serialize,     void blst_p1_serialize, void blst_p1_affine_serialize,
                        void blst_p2_serialize, void blst_p2_affine_serialize,
    void compress,      void blst_p1_compress,  void blst_p1_affine_compress,
                        void blst_p2_compress,  void blst_p2_affine_compress,
    void blst_sk_to_pk2_in_g1,  void blst_sign_pk2_in_g1,
    void blst_sk_to_pk2_in_g2,  void blst_sign_pk2_in_g2
}

#ifdef __cplusplus
%apply const std::string& { const std::string* }

#pragma SWIG nowarn=509,516

#if !defined(SWIGPYTHON)
%ignore P1_Affines;
%ignore P2_Affines;
#endif

%ignore nullptr;
%ignore None;
%ignore C_bytes;
%ignore bytes_t;
%feature("novaluewrapper") bytes_t;
%catches(BLST_ERROR) P1(const byte* in, size_t len);
%catches(BLST_ERROR) P1_Affine(const byte* in, size_t len);
%catches(BLST_ERROR) aggregate(const P1_Affine& in);

%catches(BLST_ERROR) P2(const byte* in, size_t len);
%catches(BLST_ERROR) P2_Affine(const byte* in, size_t len);
%catches(BLST_ERROR) aggregate(const P2_Affine& in);

%catches(BLST_ERROR) blst::Scalar::add;
%catches(BLST_ERROR) blst::Scalar::sub;
%catches(BLST_ERROR) blst::Scalar::mul;

// methods returning |this|
%apply SELF* OUTPUT {
    blst::P1* sign_with,    blst::P2* sign_with,
    blst::P1* hash_to,      blst::P2* hash_to,
    blst::P1* encode_to,    blst::P2* encode_to,
    blst::P1* mult,         blst::P2* mult,
    blst::P1* cneg,         blst::P2* cneg,
    blst::P1* neg,          blst::P2* neg,
    blst::P1* add,          blst::P2* add,
    blst::P1* dbl,          blst::P2* dbl,
    blst::PT* mul,          blst::PT* sqr,
    blst::PT* final_exp,
    blst::Scalar* from_bendian,
    blst::Scalar* from_lendian,
    blst::Scalar* add,
    blst::Scalar* sub,
    blst::Scalar* mul,
    blst::Scalar* inverse
}

typedef enum {
    BLST_SUCCESS = 0,
    BLST_BAD_ENCODING,
    BLST_POINT_NOT_ON_CURVE,
    BLST_POINT_NOT_IN_GROUP,
    BLST_AGGR_TYPE_MISMATCH,
    BLST_VERIFY_FAIL,
    BLST_PK_IS_INFINITY,
} BLST_ERROR;

%include "blst.hpp"

extern const blst::P1_Affine BLS12_381_G1;
extern const blst::P1_Affine BLS12_381_NEG_G1;
extern const blst::P2_Affine BLS12_381_G2;
extern const blst::P2_Affine BLS12_381_NEG_G2;

#else
%ignore blst_fr;
%ignore blst_fp;
%ignore blst_fp2;
%ignore blst_fp6;
%ignore blst_scalar_from_uint32;
%ignore blst_scalar_from_uint64;
%ignore blst_uint32_from_scalar;
%ignore blst_uint64_from_scalar;
%ignore blst_pairing_init;
%ignore blst_pairing_get_dst;

%include "blst.h"
%include "blst_aux.h"
%extend blst_pairing {
    blst_pairing(bool hash_or_encode, const byte *DST DEFNULL,
                                      size_t DST_len DEFNULL)
    {   void *ret = malloc(blst_pairing_sizeof());
        if (DST_len != 0) {
            void *dst = malloc(DST_len);
            memcpy(dst, DST, DST_len);
            blst_pairing_init(ret, hash_or_encode, dst, DST_len);
        } else {
            blst_pairing_init(ret, hash_or_encode, NULL, 0);
        }
        return ret;
    }
    ~blst_pairing()
    {   void *dst = (void *)blst_pairing_get_dst($self);
        if (dst != NULL) free(dst);
        free($self);
    }
}
#endif

%begin %{
#ifdef __cplusplus
# include <memory>
# include "blst.hpp"
using namespace blst;
#else
# include "blst.h"
#endif

static const char *const BLST_ERROR_str [] = {
    "BLST_ERROR: success",
    "BLST_ERROR: bad point encoding",
    "BLST_ERROR: point is not on curve",
    "BLST_ERROR: point is not in group",
    "BLST_ERROR: context type mismatch",
    "BLST_ERROR: verify failed",
    "BLST_ERROR: public key is infinite",
};

#define SWIG_PYTHON_STRICT_BYTE_CHAR

#if defined(__GNUC__)
# ifndef alloca
#  define alloca(s) __builtin_alloca(s)
# endif
#elif defined(__sun)
# include <alloca.h>
#elif defined(_WIN32)
# include <malloc.h>
# ifndef alloca
#  define alloca(s) _alloca(s)
# endif
#endif
%}

#if defined(SWIGPYTHON) || defined(SWIGPERL)
%include "cdata.i"
#endif

#if SWIG_VERSION < 0x040100 && defined(SWIGJAVASCRIPT)
%wrapper %{
#ifdef NODE_MODULE
# undef NODE_MODULE
# define NODE_MODULE NODE_MODULE_CONTEXT_AWARE
// actually error-prone and not exactly suitable for production, but
// sufficient for development purposes till SWIG 4.1.0 is released...
#endif
%}
#endif

#if SWIG_VERSION < 0x040100 && defined(SWIGJAVA)
/* SWIG versions prior 4.1 were crossing the MinGW's ways on the path
 * to JNI 'jlong' type */
%begin %{
#if defined(__MINGW32__) && defined(__int64)
# undef __int64
#endif
%}
#endif


================================================
FILE: bindings/blst_aux.h
================================================
/*
 * Copyright Supranational LLC
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef __BLST_AUX_H__
#define __BLST_AUX_H__
/*
 * This file lists interfaces that might be promoted to blst.h or removed,
 * depending on their proven/unproven worthiness.
 */

void blst_fr_ct_bfly(blst_fr *x0, blst_fr *x1, const blst_fr *twiddle);
void blst_fr_gs_bfly(blst_fr *x0, blst_fr *x1, const blst_fr *twiddle);
void blst_fr_to(blst_fr *ret, const blst_fr *a);
void blst_fr_from(blst_fr *ret, const blst_fr *a);
#ifdef BLST_FR_PENTAROOT
void blst_fr_pentaroot(blst_fr *ret, const blst_fr *a);
void blst_fr_pentapow(blst_fr *ret, const blst_fr *a);
#endif

void blst_fp_to(blst_fp *ret, const blst_fp *a);
void blst_fp_from(blst_fp *ret, const blst_fp *a);

bool blst_fp_is_square(const blst_fp *a);
bool blst_fp2_is_square(const blst_fp2 *a);

void blst_p1_from_jacobian(blst_p1 *out, const blst_p1 *in);
void blst_p2_from_jacobian(blst_p2 *out, const blst_p2 *in);

/*
 * Below functions produce both point and deserialized outcome of
 * SkToPk and Sign. However, deserialized outputs are pre-decorated
 * with sign and infinity bits. This means that you have to bring the
 * output into compliance prior returning to application. If you want
 * compressed point value, then do [equivalent of]
 *
 *  byte temp[96];
 *  blst_sk_to_pk2_in_g1(temp, out_pk, SK);
 *  temp[0] |= 0x80;
 *  memcpy(out, temp, 48);
 *
 * Otherwise do
 *
 *  blst_sk_to_pk2_in_g1(out, out_pk, SK);
 *  out[0] &= ~0x20;
 *
 * Either |out| or |out_<point>| can be NULL.
 */
void blst_sk_to_pk2_in_g1(byte out[96], blst_p1_affine *out_pk,
                          const blst_scalar *SK);
void blst_sign_pk2_in_g1(byte out[192], blst_p2_affine *out_sig,
                         const blst_p2 *hash, const blst_scalar *SK);
void blst_sk_to_pk2_in_g2(byte out[192], blst_p2_affine *out_pk,
                          const blst_scalar *SK);
void blst_sign_pk2_in_g2(byte out[96], blst_p1_affine *out_sig,
                         const blst_p1 *hash, const blst_scalar *SK);

#ifdef __BLST_RUST_BINDGEN__
typedef struct {} blst_uniq;
#else
typedef struct blst_opaque blst_uniq;
#endif

size_t blst_uniq_sizeof(size_t n_nodes);
void blst_uniq_init(blst_uniq *tree);
bool blst_uniq_test(blst_uniq *tree, const byte *msg, size_t len);

#ifdef expand_message_xmd
void expand_message_xmd(unsigned char *bytes, size_t len_in_bytes,
                        const unsigned char *aug, size_t aug_len,
                        const unsigned char *msg, size_t msg_len,
                        const unsigned char *DST, size_t DST_len);
#else
void blst_expand_message_xmd(byte *out, size_t out_len,
                             const byte *msg, size_t msg_len,
                             const byte *DST, size_t DST_len);
#endif

void blst_p1_unchecked_mult(blst_p1 *out, const blst_p1 *p, const byte *scalar,
                                                            size_t nbits);
void blst_p2_unchecked_mult(blst_p2 *out, const blst_p2 *p, const byte *scalar,
                                                            size_t nbits);

void blst_pairing_raw_aggregate(blst_pairing *ctx, const blst_p2_affine *q,
                                                   const blst_p1_affine *p);
blst_fp12 *blst_pairing_as_fp12(blst_pairing *ctx);
void blst_bendian_from_fp12(byte out[48*12], const blst_fp12 *a);

void blst_keygen_v3(blst_scalar *out_SK, const byte *IKM, size_t IKM_len,
                    const byte *info DEFNULL, size_t info_len DEFNULL);
void blst_keygen_v4_5(blst_scalar *out_SK, const byte *IKM, size_t IKM_len,
                      const byte *salt, size_t salt_len,
                      const byte *info DEFNULL, size_t info_len DEFNULL);
void blst_keygen_v5(blst_scalar *out_SK, const byte *IKM, size_t IKM_len,
                    const byte *salt, size_t salt_len,
                    const byte *info DEFNULL, size_t info_len DEFNULL);
void blst_derive_master_eip2333(blst_scalar *out_SK,
                                const byte *IKM, size_t IKM_len);
void blst_derive_child_eip2333(blst_scalar *out_SK, const blst_scalar *SK,
                               uint32_t child_index);

void blst_scalar_from_hexascii(blst_scalar *out, const byte *hex);
void blst_fr_from_hexascii(blst_fr *ret, const byte *hex);
void blst_fp_from_hexascii(blst_fp *ret, const byte *hex);

size_t blst_p1_sizeof(void);
size_t blst_p1_affine_sizeof(void);
size_t blst_p2_sizeof(void);
size_t blst_p2_affine_sizeof(void);
size_t blst_fp12_sizeof(void);

void blst_fp_from_le_bytes(blst_fp *ret, const byte *in, size_t len);
void blst_fp_from_be_bytes(blst_fp *ret, const byte *in, size_t len);

/*
 * Single-shot SHA-256 hash function.
 */
void blst_sha256(byte out[32], const byte *msg, size_t msg_len);
#endif


================================================
FILE: bindings/c#/poc.cs
================================================
using System;
using System.Text;
using supranational;

class PoC {
  private static void Main(string[] args)
  {
    var msg = Encoding.UTF8.GetBytes("assertion");
    var DST = "MY-DST";

    var SK = new blst.SecretKey();
    SK.keygen(Encoding.UTF8.GetBytes(new string('*', 32)));

    // generate public key and serialize it...
    var pk_for_wire = new blst.P1(SK).serialize();

    // sign |msg| and serialize the signature...
    var sig_for_wire = new blst.P2().hash_to(msg, DST, pk_for_wire)
                                    .sign_with(SK)
                                    .serialize();

    // now on "receiving" side, start with deserialization...
    var _sig = new blst.P2_Affine(sig_for_wire);
    var _pk = new blst.P1_Affine(pk_for_wire);
    if (!_pk.in_group())
        throw new blst.Exception(blst.ERROR.POINT_NOT_IN_GROUP);
    var ctx = new blst.Pairing(true, DST);
    var err = ctx.aggregate(_pk, _sig, msg, pk_for_wire);
    if (err != blst.ERROR.SUCCESS)
        throw new blst.Exception(err);
    ctx.commit();
    if (!ctx.finalverify())
        throw new blst.Exception(blst.ERROR.VERIFY_FAIL);
    Console.WriteLine("OK");

    // exercise .as_fp12 by performing equivalent of ctx.finalverify above
    var C1 = new blst.PT(_sig);
    var C2 = ctx.as_fp12();
    if (!blst.PT.finalverify(C1, C2))
        throw new blst.Exception(blst.ERROR.VERIFY_FAIL);

    // test integers as scalar multiplicands
    var p = blst.G1();
    var q = p.dup().dbl().dbl().add(p);
    if (!p.mult(5).is_equal(q))
       throw new ApplicationException("disaster");
    if (!blst.G1().mult(-5).is_equal(q.neg()))
       throw new ApplicationException("disaster");

    // low-order sanity check
    var p11 = new blst.P1(fromHexString("80803f0d09fec09a95f2ee7495323c15c162270c7cceaffa8566e941c66bcf206e72955d58b3b32e564de3209d672ca5"));
    if (p11.in_group())
       throw new ApplicationException("disaster");
    if (!p11.mult(11).is_inf())
       throw new ApplicationException("disaster");
  }

  private static int fromHexChar(char c)
  {
    if      (c>='0' && c<='9')  return c - '0';
    else if (c>='a' && c<='f')  return c - 'a' + 10;
    else if (c>='A' && c<='F')  return c - 'A' + 10;
    throw new ArgumentOutOfRangeException("non-hex character");
  }

  private static byte[] fromHexString(string str)
  {
    if (str.Length%2 != 0)
        throw new ArgumentException("odd number of characters in hex string");

    char[] hex = str.ToCharArray();
    byte[] ret = new byte[hex.Length/2];

    for (int i=0; i<hex.Length; i+=2)
        ret[i/2] = (byte)(fromHexChar(hex[i]) << 4 | fromHexChar(hex[i+1]));

    return ret;
  }
}


================================================
FILE: bindings/c#/poc.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <NoWarn>CS8981</NoWarn>
  </PropertyGroup>

</Project>


================================================
FILE: bindings/c#/run.me
================================================
#!/usr/bin/env python3
# Copyright Supranational LLC
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import os
import re
import sys
import glob
import subprocess

top = """
using System;
using System.Text;
using System.Numerics;
using System.Runtime.InteropServices;
using size_t = System.UIntPtr;

#if NET5_0_OR_GREATER
using System.Runtime.Loader;
using System.Reflection;
using System.IO;
#endif

namespace supranational { public static class blst {

#if NET5_0_OR_GREATER
private static readonly string dll;

static blst()
{
    if (String.IsNullOrEmpty(dll)) {
        var name = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "blst.dll"
                 : RuntimeInformation.IsOSPlatform(OSPlatform.OSX)     ? "libblst.dll.dylib"
                 : "libblst.dll.so";

        var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        var arch = RuntimeInformation.ProcessArchitecture switch {
            Architecture.X64   => "x64",
            Architecture.Arm64 => "arm64",
            _ => "unsupported"
        };

#if NET8_0_OR_GREATER
        // RuntimeInformation.RuntimeIdentifier changed between .NET 7 and 8
        // and only aligns to the nuget layout in 8+
        var rid = RuntimeInformation.RuntimeIdentifier;
#else
        // Mimic pre-8 RuntimeInformation.RuntimeIdentifier as
        // "win-x64", "linux-x64", "linux-arm64", "osx-x64", etc.
        var os = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win"
               : RuntimeInformation.IsOSPlatform(OSPlatform.OSX)     ? "osx"
               : RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) ? "freebsd"
               : "linux";
        var rid = $"{os}-{arch}";
#endif

        // first look for the file in the standard locations for a nuget installed native lib
        dll = Path.Combine(dir, "runtimes", rid, "native", name);

        if (!File.Exists(dll))
            dll = Path.Combine(dir, arch, name); // try the original non-standard location

        if (!File.Exists(dll))
            dll = Path.Combine(Environment.CurrentDirectory, name);

        if (File.Exists(dll)) {
            AssemblyLoadContext.Default.ResolvingUnmanagedDll += (asm, needs) =>
                (needs == "blst.dll" ? NativeLibrary.Load(dll) : IntPtr.Zero);
        }
    }
}
#endif

public enum ERROR {
    SUCCESS = 0,
    BAD_ENCODING,
    POINT_NOT_ON_CURVE,
    POINT_NOT_IN_GROUP,
    AGGR_TYPE_MISMATCH,
    VERIFY_FAIL,
    PK_IS_INFINITY,
    BAD_SCALAR,
}

public class Exception : ApplicationException {
    private readonly ERROR code;

    public Exception(ERROR err) { code = err; }
    public override string Message
    {   get
        {   switch(code) {
            case ERROR.BAD_ENCODING:        return "bad encoding";
            case ERROR.POINT_NOT_ON_CURVE:  return "point not on curve";
            case ERROR.POINT_NOT_IN_GROUP:  return "point not in group";
            case ERROR.AGGR_TYPE_MISMATCH:  return "aggregate type mismatch";
            case ERROR.VERIFY_FAIL:         return "verify failure";
            case ERROR.PK_IS_INFINITY:      return "public key is infinity";
            case ERROR.BAD_SCALAR:          return "bad scalar";
            default:                        return null;
            }
        }
    }
}

public enum ByteOrder {
    BigEndian,
    LittleEndian,
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                   [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v3([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                      [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v4_5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                        [In] byte[] salt, size_t salt_len,
                                        [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                      [In] byte[] salt, size_t salt_len,
                                      [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_master_eip2333([Out] byte[] key,
                                              [In] byte[] IKM, size_t IKM_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_child_eip2333([Out] byte[] key,
                                             [In] byte[] master, uint child_index);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_bendian([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_bendian_from_scalar([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_check([In] byte[] key);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_lendian([Out] byte[] key, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_lendian_from_scalar([Out] byte[] key, [In] byte[] inp);

public struct SecretKey {
    internal byte[] key;

    //public SecretKey() { key = new byte[32]; }
    public SecretKey(byte[] IKM, string info)
    {   key = new byte[32]; keygen(IKM, info);   }
    public SecretKey(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
    {   key = new byte[32];
        switch(order) {
        case ByteOrder.BigEndian:       from_bendian(inp);  break;
        case ByteOrder.LittleEndian:    from_lendian(inp);  break;
        }
    }

    public void keygen(byte[] IKM, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen(key, IKM, (size_t)IKM.Length,
                         info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v3(byte[] IKM, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v3(key, IKM, (size_t)IKM.Length,
                            info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v4_5(byte[] IKM, string salt, string info="")
    {   if (key == null) key = new byte[32];
        byte[] salt_bytes = Encoding.UTF8.GetBytes(salt);
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v4_5(key, IKM, (size_t)IKM.Length,
                              salt_bytes, (size_t)salt_bytes.Length,
                              info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v5(byte[] IKM, byte[] salt, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v5(key, IKM, (size_t)IKM.Length,
                            salt, (size_t)salt.Length,
                            info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v5(byte[] IKM, string salt, string info="")
    {   keygen_v5(IKM, Encoding.UTF8.GetBytes(salt), info);   }
    public void derive_master_eip2333(byte[] IKM)
    {   if (key == null) key = new byte[32];
        blst_derive_master_eip2333(key, IKM, (size_t)IKM.Length);
    }
    public SecretKey(SecretKey master, uint child_index)
    {   key = new byte[32];
        blst_derive_child_eip2333(key, master.key, child_index);
    }

    public void from_bendian(byte[] inp)
    {   if (inp.Length != 32)
            throw new Exception(ERROR.BAD_ENCODING);
        if (key == null) key = new byte[32];
        blst_scalar_from_bendian(key, inp);
        if (!blst_sk_check(key))
            throw new Exception(ERROR.BAD_ENCODING);
    }
    public void from_lendian(byte[] inp)
    {   if (inp.Length != 32)
            throw new Exception(ERROR.BAD_ENCODING);
        if (key == null) key = new byte[32];
        blst_scalar_from_lendian(key, inp);
        if (!blst_sk_check(key))
            throw new Exception(ERROR.BAD_ENCODING);
    }

    public byte[] to_bendian()
    {   byte[] ret = new byte[32];
        blst_bendian_from_scalar(ret, key);
        return ret;
    }
    public byte[] to_lendian()
    {   byte[] ret = new byte[32];
        blst_lendian_from_scalar(ret, key);
        return ret;
    }
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_be_bytes([Out] byte[] ret, [In] byte[] inp,
                                                               size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_le_bytes([Out] byte[] ret, [In] byte[] inp,
                                                               size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_add_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_sub_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_mul_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_sk_inverse([Out] byte[] ret, [In] byte[] a);

public struct Scalar {
    internal byte[] val;

    //public Scalar() { val = new byte[32]; }
    public Scalar(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
    {   val = new byte[32];
        switch(order) {
        case ByteOrder.BigEndian:       from_bendian(inp);  break;
        case ByteOrder.LittleEndian:    from_lendian(inp);  break;
        }
    }
    private Scalar(bool _)      { val = new byte[32];               }
    private Scalar(Scalar orig) { val = (byte[])orig.val.Clone();   }

    public Scalar dup()         { return new Scalar(this);          }

    public void from_bendian(byte[] inp)
    {   if (val == null) val = new byte[32];
        blst_scalar_from_be_bytes(val, inp, (size_t)inp.Length);
    }
    public void from_lendian(byte[] inp)
    {   if (val == null) val = new byte[32];
        blst_scalar_from_le_bytes(val, inp, (size_t)inp.Length);
    }

    public byte[] to_bendian()
    {   byte[] ret = new byte[32];
        blst_bendian_from_scalar(ret, val);
        return ret;
    }
    public byte[] to_lendian()
    {   byte[] ret = new byte[32];
        blst_lendian_from_scalar(ret, val);
        return ret;
    }

    public Scalar add(SecretKey a)
    {   if (!blst_sk_add_n_check(val, val, a.key))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar add(Scalar a)
    {   if (!blst_sk_add_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar sub(Scalar a)
    {   if (!blst_sk_sub_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar mul(Scalar a)
    {   if (!blst_sk_mul_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar inverse()
    {   blst_sk_inverse(val, val); return this;   }

    public static Scalar operator+(Scalar a, Scalar b)
    {   return a.dup().add(b);   }
    public static Scalar operator-(Scalar a, Scalar b)
    {   return a.dup().sub(b);   }
    public static Scalar operator*(Scalar a, Scalar b)
    {   return a.dup().mul(b);   }
    public static Scalar operator/(Scalar a, Scalar b)
    {   return b.dup().inverse().mul(a);   }
}

private const int P1_COMPRESSED_SZ = 384/8;
private const int P2_COMPRESSED_SZ = 2*P1_COMPRESSED_SZ;
"""
middle = """
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_p1_affine_sizeof();

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_p1_deserialize([Out] long[] ret, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_serialize([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_compress([Out] byte[] ret, [In] long[] inp);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_to_affine([Out] long[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_on_curve([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_in_g1([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_inf([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_equal([In] long[] a, [In] long[] b);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_p1_generator();

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_core_verify_pk_in_g2([In] long[] pk, [In] long[] sig,
                                              bool hash_or_encode,
                                              [In] byte[] msg, size_t msg_len,
                                              [In] byte[] dst, size_t dst_len,
                                              [In] byte[] aug, size_t aug_len);

public struct P1_Affine {
    internal readonly long[] point;

    private static readonly int sz = (int)blst_p1_affine_sizeof()/sizeof(long);

    //public P1_Affine()            { point = new long[sz]; }
    private P1_Affine(bool _)       { point = new long[sz]; }
    private P1_Affine(P1_Affine p)  { point = (long[])p.point.Clone(); }

    public P1_Affine(byte[] inp) : this(true)
    {   int len = inp.Length;
        if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ
                                                      : 2*P1_COMPRESSED_SZ))
            throw new Exception(ERROR.BAD_ENCODING);
        ERROR err = blst_p1_deserialize(point, inp);
        if (err != ERROR.SUCCESS)
            throw new Exception(err);
    }
    public P1_Affine(P1 jacobian) : this(true)
    {   blst_p1_to_affine(point, jacobian.point);   }

    public P1_Affine dup()      { return new P1_Affine(this);   }
    public P1 to_jacobian()     { return new P1(this);          }
    public byte[] serialize()
    {   byte[] ret = new byte[2*P1_COMPRESSED_SZ];
        blst_p1_affine_serialize(ret, point);
        return ret;
    }
    public byte[] compress()
    {   byte[] ret = new byte[P1_COMPRESSED_SZ];
        blst_p1_affine_compress(ret, point);
        return ret;
    }

    public bool on_curve()      { return blst_p1_affine_on_curve(point);    }
    public bool in_group()      { return blst_p1_affine_in_g1(point);       }
    public bool is_inf()        { return blst_p1_affine_is_inf(point);      }
    public bool is_equal(P1_Affine p)
    {   return blst_p1_affine_is_equal(point, p.point);   }

    ERROR core_verify(P2_Affine pk, bool hash_or_encode,
                      byte[] msg, string DST = "", byte[] aug = null)
    {   byte[] dst = Encoding.UTF8.GetBytes(DST);
        return blst_core_verify_pk_in_g2(pk.point, point,
                                         hash_or_encode,
                                         msg, (size_t)msg.Length,
                                         dst, (size_t)dst.Length,
                                         aug, (size_t)(aug!=null ? aug.Length : 0));
    }

    public static P1_Affine generator()
    {   var ret = new P1_Affine(true);
        Marshal.Copy(blst_p1_generator(), ret.point, 0, ret.point.Length);
        return ret;
    }
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_p1_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_serialize([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_compress([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_from_affine([Out] long[] ret, [In] long[] inp);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_on_curve([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_in_g1([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_is_inf([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_is_equal([In] long[] a, [In] long[] b);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_sk_to_pk_in_g1([Out] long[] ret, [In] byte[] SK);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_encode_to_g1([Out] long[] ret, [In] byte[] msg, size_t msg_len,
                                         [In] byte[] dst, size_t dst_len,
                                         [In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_hash_to_g1([Out] long[] ret, [In] byte[] msg, size_t msg_len,
                                       [In] byte[] dst, size_t dst_len,
                                       [In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_sign_pk_in_g2([Out] long[] ret, [In] long[] hash, [In] byte[] SK);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_mult([Out] long[] ret, [In] long[] a,
                                    [In] byte[] scalar, size_t nbits);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_cneg([Out] long[] ret, bool cbit);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_add_or_double([Out] long[] ret, [In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_p1_add_or_double_affine([Out] long[] ret, [In] long[] a,
                                                    [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_double([Out] long[] ret, [In] long[] a);

public struct P1 {
    internal long[] point;

    private static readonly int sz = (int)blst_p1_sizeof()/sizeof(long);

    //public P1()           { point = new long[sz]; }
    private P1(bool _)      { point = new long[sz]; }
    private P1(P1 p)        { point = (long[])p.point.Clone(); }
    private long[] self()
    {   if (point==null) { point = new long[sz]; } return point;   }

    public P1(SecretKey sk) : this(true)
    {   blst_sk_to_pk_in_g1(point, sk.key);   }
    public P1(byte[] inp) : this(true)
    {   int len = inp.Length;
        if (len == 0 || len != ((inp[0]&0x80) == 0x80 ? P1_COMPRESSED_SZ
                                                      : 2*P1_COMPRESSED_SZ))
            throw new Exception(ERROR.BAD_ENCODING);
        ERROR err = blst_p1_deserialize(point, inp);
        if (err != ERROR.SUCCESS)
            throw new Exception(err);
        blst_p1_from_affine(point, point);
    }
    public P1(P1_Affine affine) : this(true)
    {   blst_p1_from_affine(point, affine.point);   }

    public P1 dup()                 { return new P1(this);                  }
    public P1_Affine to_affine()    { return new P1_Affine(this);           }
    public byte[] serialize()
    {   byte[] ret = new byte[2*P1_COMPRESSED_SZ];
        blst_p1_serialize(ret, point);
        return ret;
    }
    public byte[] compress()
    {   byte[] ret = new byte[P1_COMPRESSED_SZ];
        blst_p1_compress(ret, point);
        return ret;
    }

    public bool on_curve()      { return blst_p1_on_curve(point);           }
    public bool in_group()      { return blst_p1_in_g1(point);              }
    public bool is_inf()        { return blst_p1_is_inf(point);             }
    public bool is_equal(P1 p)  { return blst_p1_is_equal(point, p.point);  }

    public P1 hash_to(byte[] msg, string DST="", byte[] aug=null)
    {   byte[] dst = Encoding.UTF8.GetBytes(DST);
        blst_hash_to_g1(self(), msg, (size_t)msg.Length,
                                dst, (size_t)dst.Length,
                                aug, (size_t)(aug!=null ? aug.Length : 0));
        return this;
    }
    public P1 encode_to(byte[] msg, string DST="", byte[] aug=null)
    {   byte[] dst = Encoding.UTF8.GetBytes(DST);
        blst_encode_to_g1(self(), msg, (size_t)msg.Length,
                                  dst, (size_t)dst.Length,
                                  aug, (size_t)(aug!=null ? aug.Length : 0));
        return this;
    }

    public P1 sign_with(SecretKey sk)
    {   blst_sign_pk_in_g2(point, point, sk.key); return this;   }
    public P1 sign_with(Scalar scalar)
    {   blst_sign_pk_in_g2(point, point, scalar.val); return this;   }

    public void aggregate(P1_Affine inp)
    {   if (blst_p1_affine_in_g1(inp.point))
            blst_p1_add_or_double_affine(point, point, inp.point);
        else
            throw new Exception(ERROR.POINT_NOT_IN_GROUP);
    }

    public P1 mult(byte[] scalar)
    {   blst_p1_mult(point, point, scalar, (size_t)(scalar.Length*8));
        return this;
    }
    public P1 mult(Scalar scalar)
    {   blst_p1_mult(point, point, scalar.val, (size_t)255);
        return this;
    }
    public P1 mult(BigInteger scalar)
    {   byte[] val;
        if (scalar.Sign < 0) {
            val = BigInteger.Negate(scalar).ToByteArray();
            blst_p1_cneg(point, true);
        } else {
            val = scalar.ToByteArray();
        }
        int len = val.Length;
        if (val[len-1]==0) len--;
        blst_p1_mult(point, point, val, (size_t)(len*8));
        return this;
    }
    public P1 cneg(bool flag)   { blst_p1_cneg(point, flag); return this;   }
    public P1 neg()             { blst_p1_cneg(point, true); return this;   }
    public P1 add(P1 a)
    {   blst_p1_add_or_double(point, point, a.point); return this;          }
    public P1 add(P1_Affine a)
    {   blst_p1_add_or_double_affine(point, point, a.point); return this;   }
    public P1 dbl()
    {   blst_p1_double(point, point); return this;                          }

    public static P1 generator()
    {   var ret = new P1(true);
        Marshal.Copy(blst_p1_generator(), ret.point, 0, ret.point.Length);
        return ret;
    }
}

public static P1 G1() { return P1.generator(); }

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_aggregated_in_g1([Out] long[] fp12, [In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_aggregate_pk_in_g1([In, Out] long[] fp12,
                                [In] long[] pk, [In] long[] sig,
                                [In] byte[] msg, size_t msg_len,
                                [In] byte[] aug, size_t aug_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_mul_n_aggregate_pk_in_g1([In, Out] long[] fp12,
                                [In] long[] pk, [In] long[] sig,
                                [In] byte[] scalar, size_t nbits,
                                [In] byte[] msg, size_t msg_len,
                                [In] byte[] aug, size_t aug_len);
"""
bottom = """
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_fp12_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_miller_loop([Out] long[] fp12, [In] long[] q,
                                                       [In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_is_one([In] long[] fp12);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_is_equal([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_fp12_sqr([Out] long[] ret, [In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_fp12_mul([Out] long[] ret, [In] long[] a,
                                                   [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_final_exp([Out] long[] ret, [In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_finalverify([In] long[] a, [In] long[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_fp12_one();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_fp12_in_group([In] long[] a);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_bendian_from_fp12([Out] byte[] ret, [In] long[] a);

public struct PT {
    internal readonly long[] fp12;

    private static readonly int sz = (int)blst_fp12_sizeof()/sizeof(long);

    internal PT(bool _)     { fp12 = new long[sz]; }
    private PT(PT orig)     { fp12 = (long[])orig.fp12.Clone(); }

    public PT(P1_Affine p) : this(true)
    {   blst_aggregated_in_g1(fp12, p.point);   }
    public PT(P1 p) : this(true)
    {   blst_aggregated_in_g1(fp12, (new P1_Affine(p)).point);   }
    public PT(P2_Affine q) : this(true)
    {   blst_aggregated_in_g2(fp12, q.point);   }
    public PT(P2 q) : this(true)
    {   blst_aggregated_in_g2(fp12, (new P2_Affine(q)).point);   }
    public PT(P2_Affine q, P1_Affine p) : this(true)
    {   blst_miller_loop(fp12, q.point, p.point);   }
    public PT(P1_Affine p, P2_Affine q) : this(q, p) {}
    public PT(P2 q, P1 p) : this(true)
    {   blst_miller_loop(fp12, (new P2_Affine(q)).point,
                               (new P1_Affine(p)).point);
    }
    public PT(P1 p, P2 q) : this(q, p) {}

    public PT dup()         { return new PT(this); }
    public bool is_one()    { return blst_fp12_is_one(fp12); }
    public bool is_equal(PT p)
    {   return blst_fp12_is_equal(fp12, p.fp12);   }
    public PT sqr()         { blst_fp12_sqr(fp12, fp12);         return this; }
    public PT mul(PT p)     { blst_fp12_mul(fp12, fp12, p.fp12); return this; }
    public PT final_exp()   { blst_final_exp(fp12, fp12);        return this; }
    public bool in_group()  { return blst_fp12_in_group(fp12); }
    public byte[] to_bendian()
    {   byte[] ret = new byte[12*P1_COMPRESSED_SZ];
        blst_bendian_from_fp12(ret, fp12);
        return ret;
    }

    public static bool finalverify(PT gt1, PT gt2)
    {   return blst_fp12_finalverify(gt1.fp12, gt2.fp12);   }

    public static PT one()
    {   var ret = new PT(true);
        Marshal.Copy(blst_fp12_one(), ret.fp12, 0, ret.fp12.Length);
        return ret;
    }
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_pairing_sizeof();
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_pairing_init([In, Out] long[] ctx, bool hash_or_encode,
                                             [In] ref long dst, size_t dst_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_pairing_commit([In, Out] long[] ctx);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_pairing_merge([In, Out] long[] ctx, [In] long[] ctx1);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_pairing_finalverify([In] long[] ctx, [In] long[] sig);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_pairing_raw_aggregate([In, Out] long[] ctx, [In] long[] q,
                                                      [In] long[] p);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_pairing_as_fp12([In] long[] ctx);

public struct Pairing {
    private readonly long[] ctx;

    private static readonly int sz = (int)blst_pairing_sizeof()/sizeof(long);

    public Pairing(bool hash_or_encode=false, string DST="")
    {
        byte[] dst = Encoding.UTF8.GetBytes(DST);
        int dst_len = dst.Length;
        int add_len = dst_len!=0 ? (dst_len+sizeof(long)-1)/sizeof(long) : 1;
        Array.Resize(ref dst, add_len*sizeof(long));

        ctx = new long[sz+add_len];

        for (int i=0; i<add_len; i++)
            ctx[sz+i] = BitConverter.ToInt64(dst, i*sizeof(long));

        GCHandle h = GCHandle.Alloc(ctx, GCHandleType.Pinned);
        blst_pairing_init(ctx, hash_or_encode, ref ctx[sz], (size_t)dst_len);
        h.Free();
    }

    public ERROR aggregate(P1_Affine pk, Nullable<P2_Affine> sig,
                                         byte[] msg, byte[] aug=null)
    {   return blst_pairing_aggregate_pk_in_g1(ctx, pk.point,
                                sig.HasValue ? sig.Value.point : null,
                                msg, (size_t)msg.Length,
                                aug, (size_t)(aug!=null ? aug.Length : 0));
    }
    public ERROR aggregate(P2_Affine pk, Nullable<P1_Affine> sig,
                                         byte[] msg, byte[] aug=null)
    {   return blst_pairing_aggregate_pk_in_g2(ctx, pk.point,
                                sig.HasValue ? sig.Value.point : null,
                                msg, (size_t)msg.Length,
                                aug, (size_t)(aug!=null ? aug.Length : 0));
    }
    public ERROR mul_n_aggregate(P2_Affine pk, P1_Affine sig,
                                               byte[] scalar, int nbits,
                                               byte[] msg, byte[] aug=null)
    {   return blst_pairing_mul_n_aggregate_pk_in_g2(ctx, pk.point, sig.point,
                                scalar, (size_t)nbits,
                                msg, (size_t)msg.Length,
                                aug, (size_t)(aug!=null ? aug.Length : 0));
    }
    public ERROR mul_n_aggregate(P1_Affine pk, P2_Affine sig,
                                               byte[] scalar, int nbits,
                                               byte[] msg, byte[] aug=null)
    {   return blst_pairing_mul_n_aggregate_pk_in_g1(ctx, pk.point, sig.point,
                                scalar, (size_t)nbits,
                                msg, (size_t)msg.Length,
                                aug, (size_t)(aug!=null ? aug.Length : 0));
    }

    public void commit()    { blst_pairing_commit(ctx); }
    public void merge(Pairing a)
    {   var err = blst_pairing_merge(ctx, a.ctx);
        if (err != ERROR.SUCCESS)
            throw new Exception(err);
    }
    public bool finalverify(PT sig=new PT())
    {   return blst_pairing_finalverify(ctx, sig.fp12);   }

    public void raw_aggregate(P2_Affine q, P1_Affine p)
    {   blst_pairing_raw_aggregate(ctx, q.point, p.point);   }
    public void raw_aggregate(P1_Affine p, P2_Affine q)
    {   raw_aggregate(q, p);   }
    public void raw_aggregate(P2 q, P1 p)
    {   blst_pairing_raw_aggregate(ctx, (new P2_Affine(q)).point,
                                        (new P1_Affine(p)).point);
    }
    public void raw_aggregate(P1 p, P2 q)
    {   raw_aggregate(q, p);   }
    public PT as_fp12()
    {   var ret = new PT(true);
        GCHandle h = GCHandle.Alloc(ctx, GCHandleType.Pinned);
        Marshal.Copy(blst_pairing_as_fp12(ctx), ret.fp12, 0, ret.fp12.Length);
        h.Free();
        return ret;
    }
}
}}"""

here = re.split(r'[/\\](?=[^/\\]*$)', sys.argv[0])
if len(here) > 1:
    os.chdir(here[0])


def xchg_1vs2(matchobj):
    if matchobj.group(2) == '1':
        return matchobj.group(1) + '2'
    else:
        return matchobj.group(1) + '1'


def newer(files):
    if len(files) == 1:
        return True
    rh = files[-1]
    if not os.path.exists(rh):
        return True
    for lh in files[:-1]:
        if os.stat(lh).st_ctime > os.stat(rh).st_ctime:
            return True
    return False


fname = "supranational.blst.cs"
if newer([here[-1], fname]):
    fd = open(fname, "w")
    print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
    print("// DO NOT EDIT THIS FILE!!!",                         file=fd)
    print("// The file is auto-generated by " + here[-1],        file=fd)
    print("//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", file=fd)
    print("\n\n", file=fd)
    print(top,    file=fd)
    print(middle, file=fd)
    print(re.sub(r'((?<!f)[pgPG])([12])', xchg_1vs2, middle), file=fd)
    print(bottom, file=fd)
    fd.close()

try:  # mono-devel on Linux ["-language:5" corresponds to latest ECMA/ISO]
    subprocess.check_call(["mcs", "-langversion:5", "-optimize+",
                                  "poc.cs", fname, "-r:System.Numerics.dll"])
    if newer(["../blst.h"] + glob.glob("libblst.dll.*")):
        print("building libblst.dll...") or sys.stdout.flush()
        subprocess.check_call(["../../build.sh", "-dll"] + sys.argv[1:])
    subprocess.check_call(["mono", "poc.exe"])
    sys.exit(0)
except OSError as e:
    if e.errno != 2:    # not "no such file or directory"
        raise e

try:  # Visual Studio Developer Command Prompt
    subprocess.check_call(["csc", "-langversion:5", "-optimize+",
                                  "poc.cs", fname, "-r:System.Numerics.dll"])
    if newer([os.path.normpath("../blst.h"), "blst.dll"]):
        print("building blst.dll...") or sys.stdout.flush()
        subprocess.check_call([os.path.normpath("../../build.bat"), "-shared"]
                              + sys.argv[1:])
    subprocess.check_call(os.path.normpath("./poc.exe"))
    sys.exit(0)
except OSError as e:
    if e.errno != 2:    # not "no such file or directory"
        raise e

# env = os.environ.copy()
# env["PATH"] = os.getcwd() + os.path.pathsep + env["PATH"]
# env["DYLD_FALLBACK_LIBRARY_PATH"] = os.getcwd()
# env["LD_LIBRARY_PATH"] = os.getcwd()
# subprocess.check_call(["dotnet", "run"], env=env)


================================================
FILE: bindings/c#/supranational.blst.cs
================================================
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// DO NOT EDIT THIS FILE!!!
// The file is auto-generated by run.me
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!




using System;
using System.Text;
using System.Numerics;
using System.Runtime.InteropServices;
using size_t = System.UIntPtr;

#if NET5_0_OR_GREATER
using System.Runtime.Loader;
using System.Reflection;
using System.IO;
#endif

namespace supranational { public static class blst {

#if NET5_0_OR_GREATER
private static readonly string dll;

static blst()
{
    if (String.IsNullOrEmpty(dll)) {
        var name = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "blst.dll"
                 : RuntimeInformation.IsOSPlatform(OSPlatform.OSX)     ? "libblst.dll.dylib"
                 : "libblst.dll.so";

        var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        var arch = RuntimeInformation.ProcessArchitecture switch {
            Architecture.X64   => "x64",
            Architecture.Arm64 => "arm64",
            _ => "unsupported"
        };

#if NET8_0_OR_GREATER
        // RuntimeInformation.RuntimeIdentifier changed between .NET 7 and 8
        // and only aligns to the nuget layout in 8+
        var rid = RuntimeInformation.RuntimeIdentifier;
#else
        // Mimic pre-8 RuntimeInformation.RuntimeIdentifier as
        // "win-x64", "linux-x64", "linux-arm64", "osx-x64", etc.
        var os = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win"
               : RuntimeInformation.IsOSPlatform(OSPlatform.OSX)     ? "osx"
               : RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) ? "freebsd"
               : "linux";
        var rid = $"{os}-{arch}";
#endif

        // first look for the file in the standard locations for a nuget installed native lib
        dll = Path.Combine(dir, "runtimes", rid, "native", name);

        if (!File.Exists(dll))
            dll = Path.Combine(dir, arch, name); // try the original non-standard location

        if (!File.Exists(dll))
            dll = Path.Combine(Environment.CurrentDirectory, name);

        if (File.Exists(dll)) {
            AssemblyLoadContext.Default.ResolvingUnmanagedDll += (asm, needs) =>
                (needs == "blst.dll" ? NativeLibrary.Load(dll) : IntPtr.Zero);
        }
    }
}
#endif

public enum ERROR {
    SUCCESS = 0,
    BAD_ENCODING,
    POINT_NOT_ON_CURVE,
    POINT_NOT_IN_GROUP,
    AGGR_TYPE_MISMATCH,
    VERIFY_FAIL,
    PK_IS_INFINITY,
    BAD_SCALAR,
}

public class Exception : ApplicationException {
    private readonly ERROR code;

    public Exception(ERROR err) { code = err; }
    public override string Message
    {   get
        {   switch(code) {
            case ERROR.BAD_ENCODING:        return "bad encoding";
            case ERROR.POINT_NOT_ON_CURVE:  return "point not on curve";
            case ERROR.POINT_NOT_IN_GROUP:  return "point not in group";
            case ERROR.AGGR_TYPE_MISMATCH:  return "aggregate type mismatch";
            case ERROR.VERIFY_FAIL:         return "verify failure";
            case ERROR.PK_IS_INFINITY:      return "public key is infinity";
            case ERROR.BAD_SCALAR:          return "bad scalar";
            default:                        return null;
            }
        }
    }
}

public enum ByteOrder {
    BigEndian,
    LittleEndian,
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                   [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v3([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                      [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v4_5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                        [In] byte[] salt, size_t salt_len,
                                        [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern
void blst_keygen_v5([Out] byte[] key, [In] byte[] IKM, size_t IKM_len,
                                      [In] byte[] salt, size_t salt_len,
                                      [In] byte[] info, size_t info_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_master_eip2333([Out] byte[] key,
                                              [In] byte[] IKM, size_t IKM_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_derive_child_eip2333([Out] byte[] key,
                                             [In] byte[] master, uint child_index);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_bendian([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_bendian_from_scalar([Out] byte[] ret, [In] byte[] key);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_check([In] byte[] key);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_lendian([Out] byte[] key, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_lendian_from_scalar([Out] byte[] key, [In] byte[] inp);

public struct SecretKey {
    internal byte[] key;

    //public SecretKey() { key = new byte[32]; }
    public SecretKey(byte[] IKM, string info)
    {   key = new byte[32]; keygen(IKM, info);   }
    public SecretKey(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
    {   key = new byte[32];
        switch(order) {
        case ByteOrder.BigEndian:       from_bendian(inp);  break;
        case ByteOrder.LittleEndian:    from_lendian(inp);  break;
        }
    }

    public void keygen(byte[] IKM, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen(key, IKM, (size_t)IKM.Length,
                         info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v3(byte[] IKM, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v3(key, IKM, (size_t)IKM.Length,
                            info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v4_5(byte[] IKM, string salt, string info="")
    {   if (key == null) key = new byte[32];
        byte[] salt_bytes = Encoding.UTF8.GetBytes(salt);
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v4_5(key, IKM, (size_t)IKM.Length,
                              salt_bytes, (size_t)salt_bytes.Length,
                              info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v5(byte[] IKM, byte[] salt, string info="")
    {   if (key == null) key = new byte[32];
        byte[] info_bytes = Encoding.UTF8.GetBytes(info);
        blst_keygen_v5(key, IKM, (size_t)IKM.Length,
                            salt, (size_t)salt.Length,
                            info_bytes, (size_t)info_bytes.Length);
    }
    public void keygen_v5(byte[] IKM, string salt, string info="")
    {   keygen_v5(IKM, Encoding.UTF8.GetBytes(salt), info);   }
    public void derive_master_eip2333(byte[] IKM)
    {   if (key == null) key = new byte[32];
        blst_derive_master_eip2333(key, IKM, (size_t)IKM.Length);
    }
    public SecretKey(SecretKey master, uint child_index)
    {   key = new byte[32];
        blst_derive_child_eip2333(key, master.key, child_index);
    }

    public void from_bendian(byte[] inp)
    {   if (inp.Length != 32)
            throw new Exception(ERROR.BAD_ENCODING);
        if (key == null) key = new byte[32];
        blst_scalar_from_bendian(key, inp);
        if (!blst_sk_check(key))
            throw new Exception(ERROR.BAD_ENCODING);
    }
    public void from_lendian(byte[] inp)
    {   if (inp.Length != 32)
            throw new Exception(ERROR.BAD_ENCODING);
        if (key == null) key = new byte[32];
        blst_scalar_from_lendian(key, inp);
        if (!blst_sk_check(key))
            throw new Exception(ERROR.BAD_ENCODING);
    }

    public byte[] to_bendian()
    {   byte[] ret = new byte[32];
        blst_bendian_from_scalar(ret, key);
        return ret;
    }
    public byte[] to_lendian()
    {   byte[] ret = new byte[32];
        blst_lendian_from_scalar(ret, key);
        return ret;
    }
}

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_be_bytes([Out] byte[] ret, [In] byte[] inp,
                                                               size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_scalar_from_le_bytes([Out] byte[] ret, [In] byte[] inp,
                                                               size_t inp_len);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_add_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_sub_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_sk_mul_n_check([Out] byte[] ret, [In] byte[] a,
                                                         [In] byte[] b);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_sk_inverse([Out] byte[] ret, [In] byte[] a);

public struct Scalar {
    internal byte[] val;

    //public Scalar() { val = new byte[32]; }
    public Scalar(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
    {   val = new byte[32];
        switch(order) {
        case ByteOrder.BigEndian:       from_bendian(inp);  break;
        case ByteOrder.LittleEndian:    from_lendian(inp);  break;
        }
    }
    private Scalar(bool _)      { val = new byte[32];               }
    private Scalar(Scalar orig) { val = (byte[])orig.val.Clone();   }

    public Scalar dup()         { return new Scalar(this);          }

    public void from_bendian(byte[] inp)
    {   if (val == null) val = new byte[32];
        blst_scalar_from_be_bytes(val, inp, (size_t)inp.Length);
    }
    public void from_lendian(byte[] inp)
    {   if (val == null) val = new byte[32];
        blst_scalar_from_le_bytes(val, inp, (size_t)inp.Length);
    }

    public byte[] to_bendian()
    {   byte[] ret = new byte[32];
        blst_bendian_from_scalar(ret, val);
        return ret;
    }
    public byte[] to_lendian()
    {   byte[] ret = new byte[32];
        blst_lendian_from_scalar(ret, val);
        return ret;
    }

    public Scalar add(SecretKey a)
    {   if (!blst_sk_add_n_check(val, val, a.key))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar add(Scalar a)
    {   if (!blst_sk_add_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar sub(Scalar a)
    {   if (!blst_sk_sub_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar mul(Scalar a)
    {   if (!blst_sk_mul_n_check(val, val, a.val))
            throw new Exception(ERROR.BAD_SCALAR);
        return this;
    }
    public Scalar inverse()
    {   blst_sk_inverse(val, val); return this;   }

    public static Scalar operator+(Scalar a, Scalar b)
    {   return a.dup().add(b);   }
    public static Scalar operator-(Scalar a, Scalar b)
    {   return a.dup().sub(b);   }
    public static Scalar operator*(Scalar a, Scalar b)
    {   return a.dup().mul(b);   }
    public static Scalar operator/(Scalar a, Scalar b)
    {   return b.dup().inverse().mul(a);   }
}

private const int P1_COMPRESSED_SZ = 384/8;
private const int P2_COMPRESSED_SZ = 2*P1_COMPRESSED_SZ;


[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern size_t blst_p1_affine_sizeof();

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_p1_deserialize([Out] long[] ret, [In] byte[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_serialize([Out] byte[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_affine_compress([Out] byte[] ret, [In] long[] inp);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void blst_p1_to_affine([Out] long[] ret, [In] long[] inp);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_on_curve([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_in_g1([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_inf([In] long[] point);
[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool blst_p1_affine_is_equal([In] long[] a, [In] long[] b);

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr blst_p1_generator();

[DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
static extern ERROR blst_core_verify_pk_in_g2([In] long[] pk, [In] long[] sig,
                                              bool hash_or_encode,
                                              [In] byte[] msg, size_t ms
Download .txt
gitextract_z39wz_mc/

├── .gitattributes
├── .github/
│   └── workflows/
│       ├── ci.yml
│       ├── codeql-analysis.yml
│       └── golang-lint.yml
├── .gitignore
├── .golangci.yml
├── .lgtm.yml
├── .travis.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── bindings/
│   ├── blst.h
│   ├── blst.hpp
│   ├── blst.swg
│   ├── blst_aux.h
│   ├── c#/
│   │   ├── poc.cs
│   │   ├── poc.csproj
│   │   ├── run.me
│   │   └── supranational.blst.cs
│   ├── go/
│   │   ├── README.md
│   │   ├── blst.go
│   │   ├── blst.tgo
│   │   ├── blst_htoc_test.go
│   │   ├── blst_miller_loop_test.go
│   │   ├── blst_minpk.tgo
│   │   ├── blst_minpk_test.go
│   │   ├── blst_minsig_test.go
│   │   ├── blst_misc.tgo
│   │   ├── blst_px.tgo
│   │   ├── blst_wasm.go
│   │   ├── cgo_assembly.S
│   │   ├── cgo_server.c
│   │   ├── generate.py
│   │   └── rb_tree.go
│   ├── rust/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── benches/
│   │   │   └── blst_benches.rs
│   │   ├── build.rs
│   │   ├── publish.sh
│   │   ├── rustfmt.toml
│   │   └── src/
│   │       ├── bindings.rs
│   │       ├── lib.rs
│   │       ├── pippenger-no_std.rs
│   │       ├── pippenger-test_mod.rs
│   │       └── pippenger.rs
│   ├── vectors/
│   │   └── hash_to_curve/
│   │       ├── BLS12381G1_XMD_SHA-256_SSWU_NU_.json
│   │       ├── BLS12381G1_XMD_SHA-256_SSWU_RO_.json
│   │       ├── BLS12381G2_XMD_SHA-256_SSWU_NU_.json
│   │       ├── BLS12381G2_XMD_SHA-256_SSWU_RO_.json
│   │       ├── README
│   │       ├── expand_message_xmd_SHA256_256.json
│   │       └── expand_message_xmd_SHA256_38.json
│   └── zig/
│       ├── README.md
│       ├── blst.zig
│       ├── c.zig
│       ├── generate.py
│       └── tests.zig
├── build/
│   ├── assembly.S
│   ├── bindings_trim.pl
│   ├── cheri/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_384-armv8.S
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── div3w-armv8.S
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   └── sha256-armv8.S
│   ├── coff/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── elf/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── mach-o/
│   │   ├── add_mod_256-armv8.S
│   │   ├── add_mod_256-x86_64.s
│   │   ├── add_mod_384-armv8.S
│   │   ├── add_mod_384-x86_64.s
│   │   ├── add_mod_384x384-x86_64.s
│   │   ├── ct_inverse_mod_256-armv8.S
│   │   ├── ct_inverse_mod_256-x86_64.s
│   │   ├── ct_inverse_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-armv8.S
│   │   ├── ct_is_square_mod_384-x86_64.s
│   │   ├── ctq_inverse_mod_384-x86_64.s
│   │   ├── ctx_inverse_mod_384-x86_64.s
│   │   ├── div3w-armv8.S
│   │   ├── div3w-x86_64.s
│   │   ├── mul_mont_256-armv8.S
│   │   ├── mul_mont_384-armv8.S
│   │   ├── mulq_mont_256-x86_64.s
│   │   ├── mulq_mont_384-x86_64.s
│   │   ├── mulx_mont_256-x86_64.s
│   │   ├── mulx_mont_384-x86_64.s
│   │   ├── sha256-armv8.S
│   │   ├── sha256-portable-x86_64.s
│   │   └── sha256-x86_64.s
│   ├── refresh.sh
│   ├── srcroot.go
│   └── win64/
│       ├── add_mod_256-armv8.asm
│       ├── add_mod_256-x86_64.asm
│       ├── add_mod_384-armv8.asm
│       ├── add_mod_384-x86_64.asm
│       ├── add_mod_384x384-x86_64.asm
│       ├── blst.def
│       ├── ct_inverse_mod_256-armv8.asm
│       ├── ct_inverse_mod_256-x86_64.asm
│       ├── ct_inverse_mod_384-armv8.asm
│       ├── ct_is_square_mod_384-armv8.asm
│       ├── ct_is_square_mod_384-x86_64.asm
│       ├── ctq_inverse_mod_384-x86_64.asm
│       ├── ctx_inverse_mod_384-x86_64.asm
│       ├── div3w-armv8.asm
│       ├── div3w-x86_64.asm
│       ├── dll.c
│       ├── mul_mont_256-armv8.asm
│       ├── mul_mont_384-armv8.asm
│       ├── mulq_mont_256-x86_64.asm
│       ├── mulq_mont_384-x86_64.asm
│       ├── mulx_mont_256-x86_64.asm
│       ├── mulx_mont_384-x86_64.asm
│       ├── sha256-armv8.asm
│       └── sha256-x86_64.asm
├── build.bat
├── build.sh
├── build.zig
├── build.zig.zon
└── src/
    ├── aggregate.c
    ├── asm/
    │   ├── add_mod_256-armv8.pl
    │   ├── add_mod_256-x86_64.pl
    │   ├── add_mod_384-armv8.pl
    │   ├── add_mod_384-x86_64.pl
    │   ├── add_mod_384x384-x86_64.pl
    │   ├── arm-xlate.pl
    │   ├── ct_inverse_mod_256-armv8.pl
    │   ├── ct_inverse_mod_256-x86_64.pl
    │   ├── ct_inverse_mod_384-armv8.pl
    │   ├── ct_is_square_mod_384-armv8.pl
    │   ├── ct_is_square_mod_384-x86_64.pl
    │   ├── ctq_inverse_mod_384-x86_64.pl
    │   ├── ctx_inverse_mod_384-x86_64.pl
    │   ├── div3w-armv8.pl
    │   ├── div3w-x86_64.pl
    │   ├── mul_mont_256-armv8.pl
    │   ├── mul_mont_384-armv8.pl
    │   ├── mulq_mont_256-x86_64.pl
    │   ├── mulq_mont_384-x86_64.pl
    │   ├── mulx_mont_256-x86_64.pl
    │   ├── mulx_mont_384-x86_64.pl
    │   ├── sha256-armv8.pl
    │   ├── sha256-portable-x86_64.pl
    │   ├── sha256-x86_64.pl
    │   └── x86_64-xlate.pl
    ├── blst_t.hpp
    ├── bulk_addition.c
    ├── bytes.h
    ├── client_min_pk.c
    ├── client_min_sig.c
    ├── consts.c
    ├── consts.h
    ├── cpuid.c
    ├── e1.c
    ├── e2.c
    ├── ec_mult.h
    ├── ec_ops.h
    ├── errors.h
    ├── exp.c
    ├── exports.c
    ├── fields.h
    ├── fp12_tower.c
    ├── hash_to_field.c
    ├── keygen.c
    ├── map_to_g1.c
    ├── map_to_g2.c
    ├── multi_scalar.c
    ├── no_asm.h
    ├── pairing.c
    ├── pentaroot-addchain.h
    ├── pentaroot.c
    ├── point.h
    ├── rb_tree.c
    ├── recip-addchain.h
    ├── recip.c
    ├── server.c
    ├── sha256.h
    ├── sqrt-addchain.h
    ├── sqrt.c
    ├── vect.c
    └── vect.h
Download .txt
SYMBOL INDEX (1673 symbols across 47 files)

FILE: bindings/blst.h
  type __SIZE_TYPE__ (line 10) | typedef __SIZE_TYPE__ size_t;
  type __UINT8_TYPE__ (line 17) | typedef __UINT8_TYPE__  uint8_t;
  type __UINT32_TYPE__ (line 18) | typedef __UINT32_TYPE__ uint32_t;
  type __UINT64_TYPE__ (line 19) | typedef __UINT64_TYPE__ uint64_t;
  type _Bool (line 28) | typedef _Bool bool;
  type BLST_ERROR (line 47) | typedef enum {
  type byte (line 58) | typedef uint8_t byte;
  type limb_t (line 59) | typedef uint64_t limb_t;
  type blst_scalar (line 61) | typedef struct { byte b[256/8]; } blst_scalar;
  type blst_fr (line 62) | typedef struct { limb_t l[256/8/sizeof(limb_t)]; } blst_fr;
  type blst_fp (line 63) | typedef struct { limb_t l[384/8/sizeof(limb_t)]; } blst_fp;
  type blst_fp2 (line 65) | typedef struct { blst_fp fp[2]; } blst_fp2;
  type blst_fp6 (line 66) | typedef struct { blst_fp2 fp2[3]; } blst_fp6;
  type blst_fp12 (line 67) | typedef struct { blst_fp6 fp6[2]; } blst_fp12;
  type blst_p1 (line 169) | typedef struct { blst_fp x, y, z; } blst_p1;
  type blst_p1_affine (line 170) | typedef struct { blst_fp x, y; } blst_p1_affine;
  type blst_p2 (line 196) | typedef struct { blst_fp2 x, y, z; } blst_p2;
  type blst_p2_affine (line 197) | typedef struct { blst_fp2 x, y; } blst_p2_affine;
  type limb_t (line 356) | typedef limb_t blst_pairing;
  type blst_pairing (line 358) | typedef struct {} blst_pairing;
  type blst_pairing (line 360) | typedef struct blst_opaque blst_pairing;

FILE: bindings/blst.hpp
  type blst (line 19) | namespace blst {
    type bytes_t (line 32) | struct bytes_t {
      method bytes_t (line 36) | bytes_t() = default;
      method bytes_t (line 37) | bytes_t(const byte* p, size_t l) : ptr{p}, len{l} {}
      method bytes_t (line 39) | bytes_t(const C<T>& c)
      method bytes_t (line 46) | bytes_t(const C<T, N>& c)
    class P1_Affine (line 54) | class P1_Affine
      method P1_Affine (line 192) | P1_Affine(const blst_p1_affine *cptr) { point = *cptr; }
      method P1_Affine (line 194) | P1_Affine() { memset(&point, 0, sizeof(point)); }
      method P1_Affine (line 196) | P1_Affine(const byte *in)
      method P1_Affine (line 202) | P1_Affine(const byte *in, size_t len)
      method P1_Affine (line 211) | P1_Affine dup() const { return *this; }
      method serialize (line 213) | void serialize(byte out[96]) const
      method compress (line 215) | void compress(byte out[48]) const
      method on_curve (line 217) | bool on_curve() const { return blst_p1_affine_on_curve(&point); }
      method in_group (line 218) | bool in_group() const { return blst_p1_affine_in_g1(&point);    }
      method is_inf (line 219) | bool is_inf() const   { return blst_p1_affine_is_inf(&point);   }
      method is_equal (line 220) | bool is_equal(const P1_Affine& p) const
      method BLST_ERROR (line 228) | BLST_ERROR core_verify(const P2_Affine& pk, bool hash_or_encode,
      method P1_Affine (line 234) | static P1_Affine generator()
    class P1 (line 55) | class P1
      method P1 (line 251) | P1(const blst_p1 *cptr) { point = *cptr; }
      method P1 (line 253) | P1() { memset(&point, 0, sizeof(point)); }
      method P1 (line 254) | P1(const SecretKey& sk) { blst_sk_to_pk_in_g1(&point, &sk.key); }
      method P1 (line 256) | P1(const byte *in)
      method P1 (line 264) | P1(const byte *in, size_t len)
      method P1 (line 273) | P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); }
      method P1 (line 275) | P1 dup() const                      { return *this; }
      method P1_Affine (line 276) | P1_Affine to_affine() const         { return P1_Affine(*this);      ...
      method serialize (line 277) | void serialize(byte out[96]) const  { blst_p1_serialize(out, &point)...
      method compress (line 278) | void compress(byte out[48]) const   { blst_p1_compress(out, &point);...
      method on_curve (line 279) | bool on_curve() const               { return blst_p1_on_curve(&point...
      method in_group (line 280) | bool in_group() const               { return blst_p1_in_g1(&point); ...
      method is_inf (line 281) | bool is_inf() const                 { return blst_p1_is_inf(&point);...
      method is_equal (line 282) | bool is_equal(const P1& p) const
      method aggregate (line 284) | void aggregate(const P1_Affine& in)
      method P1 (line 290) | P1* sign_with(const SecretKey& sk)
      method P1 (line 292) | P1* sign_with(const Scalar& scalar)
      method P1 (line 294) | P1* hash_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 300) | P1* encode_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 307) | P1* hash_to(const byte* msg, size_t msg_len,
      method P1 (line 314) | P1* encode_to(const byte* msg, size_t msg_len,
      method P1 (line 322) | P1* mult(const byte* scalar, size_t nbits)
      method P1 (line 324) | P1* mult(const Scalar& scalar)
      method P1 (line 326) | P1* cneg(bool flag)
      method P1 (line 328) | P1* neg()
      method P1 (line 330) | P1* add(const P1& a)
      method P1 (line 332) | P1* add(const P1_Affine &a)
      method P1 (line 334) | P1* dbl()
      method P1 (line 337) | static P1 add(const P1& a, const P1& b)
      method P1 (line 339) | static P1 add(const P1& a, const P1_Affine& b)
      method P1 (line 341) | static P1 dbl(const P1& a)
      method P1 (line 344) | static P1 generator()
    class P2_Affine (line 56) | class P2_Affine
      method P2_Affine (line 494) | P2_Affine(const blst_p2_affine *cptr) { point = *cptr; }
      method P2_Affine (line 496) | P2_Affine() { memset(&point, 0, sizeof(point)); }
      method P2_Affine (line 498) | P2_Affine(const byte *in)
      method P2_Affine (line 504) | P2_Affine(const byte *in, size_t len)
      method P2_Affine (line 513) | P2_Affine dup() const { return *this; }
      method serialize (line 515) | void serialize(byte out[192]) const
      method compress (line 517) | void compress(byte out[96]) const
      method on_curve (line 519) | bool on_curve() const { return blst_p2_affine_on_curve(&point); }
      method in_group (line 520) | bool in_group() const { return blst_p2_affine_in_g2(&point);    }
      method is_inf (line 521) | bool is_inf() const   { return blst_p2_affine_is_inf(&point);   }
      method is_equal (line 522) | bool is_equal(const P2_Affine& p) const
      method BLST_ERROR (line 530) | BLST_ERROR core_verify(const P1_Affine& pk, bool hash_or_encode,
      method P2_Affine (line 536) | static P2_Affine generator()
    class P2 (line 57) | class P2
      method P2 (line 553) | P2(const blst_p2 *cptr) { point = *cptr; }
      method P2 (line 555) | P2() { memset(&point, 0, sizeof(point)); }
      method P2 (line 556) | P2(const SecretKey& sk) { blst_sk_to_pk_in_g2(&point, &sk.key); }
      method P2 (line 558) | P2(const byte *in)
      method P2 (line 566) | P2(const byte *in, size_t len)
      method P2 (line 575) | P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); }
      method P2 (line 577) | P2 dup() const                      { return *this; }
      method P2_Affine (line 578) | P2_Affine to_affine() const         { return P2_Affine(*this);      ...
      method serialize (line 579) | void serialize(byte out[192]) const { blst_p2_serialize(out, &point)...
      method compress (line 580) | void compress(byte out[96]) const   { blst_p2_compress(out, &point);...
      method on_curve (line 581) | bool on_curve() const               { return blst_p2_on_curve(&point...
      method in_group (line 582) | bool in_group() const               { return blst_p2_in_g2(&point); ...
      method is_inf (line 583) | bool is_inf() const                 { return blst_p2_is_inf(&point);...
      method is_equal (line 584) | bool is_equal(const P2& p) const
      method aggregate (line 586) | void aggregate(const P2_Affine& in)
      method P2 (line 592) | P2* sign_with(const SecretKey& sk)
      method P2 (line 594) | P2* sign_with(const Scalar& scalar)
      method P2 (line 596) | P2* hash_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 602) | P2* encode_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 609) | P2* hash_to(const byte* msg, size_t msg_len,
      method P2 (line 616) | P2* encode_to(const byte* msg, size_t msg_len,
      method P2 (line 625) | P2* mult(const byte* scalar, size_t nbits)
      method P2 (line 627) | P2* mult(const Scalar& scalar)
      method P2 (line 629) | P2* cneg(bool flag)
      method P2 (line 631) | P2* neg()
      method P2 (line 633) | P2* add(const P2& a)
      method P2 (line 635) | P2* add(const P2_Affine &a)
      method P2 (line 637) | P2* dbl()
      method P2 (line 640) | static P2 add(const P2& a, const P2& b)
      method P2 (line 642) | static P2 add(const P2& a, const P2_Affine& b)
      method P2 (line 644) | static P2 dbl(const P2& a)
      method P2 (line 647) | static P2 generator()
    class Pairing (line 58) | class Pairing
      method init (line 869) | void init(bool hash_or_encode, const byte* DST, size_t DST_len)
      method Pairing (line 883) | Pairing(bool hash_or_encode, const std::string& DST)
      method Pairing (line 887) | Pairing(bool hash_or_encode, const byte* DST, size_t DST_len)
      method BLST_ERROR (line 892) | BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 897) | BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 902) | BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 908) | BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 915) | BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 921) | BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 927) | BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 934) | BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method commit (line 942) | void commit()
      method BLST_ERROR (line 944) | BLST_ERROR merge(const Pairing* ctx)
      method finalverify (line 946) | bool finalverify(const PT* sig = nullptr) const
      method raw_aggregate (line 950) | void raw_aggregate(const P2_Affine* q, const P1_Affine* p)
      method PT (line 952) | PT as_fp12()
    function byte (line 60) | inline const byte *C_bytes(const void *ptr)
    type SecretKey (line 72) | struct SecretKey {
      method keygen (line 82) | void keygen(const byte* IKM, size_t IKM_len,
      method keygen_v3 (line 85) | void keygen_v3(const byte* IKM, size_t IKM_len,
      method keygen_v4_5 (line 88) | void keygen_v4_5(const byte* IKM, size_t IKM_len,
      method keygen_v5 (line 94) | void keygen_v5(const byte* IKM, size_t IKM_len,
      method keygen (line 101) | void keygen(bytes_t IKM, const std::string& info = "")
      method keygen_v3 (line 103) | void keygen_v3(bytes_t IKM, const std::string& info = "")
      method keygen_v4_5 (line 105) | void keygen_v4_5(bytes_t IKM, bytes_t salt, const std::string& info ...
      method keygen_v5 (line 107) | void keygen_v5(bytes_t IKM, bytes_t salt, const std::string& info = "")
      method derive_master_eip2333 (line 109) | void derive_master_eip2333(const byte* IKM, size_t IKM_len)
      method derive_child_eip2333 (line 111) | void derive_child_eip2333(const SecretKey& SK, unsigned int child_in...
      method from_bendian (line 114) | void from_bendian(const byte in[32]) { blst_scalar_from_bendian(&key...
      method from_lendian (line 115) | void from_lendian(const byte in[32]) { blst_scalar_from_lendian(&key...
      method to_bendian (line 117) | void to_bendian(byte out[32]) const
      method to_lendian (line 119) | void to_lendian(byte out[32]) const
    class Scalar (line 123) | class Scalar {
      method Scalar (line 128) | Scalar() { memset(&val, 0, sizeof(val)); }
      method Scalar (line 129) | Scalar(const byte* scalar, size_t nbits)
      method Scalar (line 132) | Scalar(const byte *msg, size_t msg_len, const std::string& DST)
      method Scalar (line 135) | Scalar* hash_to(const byte *msg, size_t msg_len, const std::string& ...
      method Scalar (line 143) | Scalar(bytes_t msg, const std::string& DST)
      method Scalar (line 145) | Scalar* hash_to(bytes_t msg, const std::string& DST = "")
      method Scalar (line 148) | Scalar dup() const { return *this; }
      method Scalar (line 149) | Scalar* from_bendian(const byte *msg, size_t msg_len)
      method Scalar (line 151) | Scalar* from_lendian(const byte *msg, size_t msg_len)
      method to_bendian (line 153) | void to_bendian(byte out[32]) const
      method to_lendian (line 155) | void to_lendian(byte out[32]) const
      method Scalar (line 158) | Scalar* add(const Scalar& a)
      method Scalar (line 163) | Scalar* add(const SecretKey& a)
      method Scalar (line 168) | Scalar* sub(const Scalar& a)
      method Scalar (line 173) | Scalar* mul(const Scalar& a)
      method Scalar (line 178) | Scalar* inverse()
    class P1_Affine (line 188) | class P1_Affine {
      method P1_Affine (line 192) | P1_Affine(const blst_p1_affine *cptr) { point = *cptr; }
      method P1_Affine (line 194) | P1_Affine() { memset(&point, 0, sizeof(point)); }
      method P1_Affine (line 196) | P1_Affine(const byte *in)
      method P1_Affine (line 202) | P1_Affine(const byte *in, size_t len)
      method P1_Affine (line 211) | P1_Affine dup() const { return *this; }
      method serialize (line 213) | void serialize(byte out[96]) const
      method compress (line 215) | void compress(byte out[48]) const
      method on_curve (line 217) | bool on_curve() const { return blst_p1_affine_on_curve(&point); }
      method in_group (line 218) | bool in_group() const { return blst_p1_affine_in_g1(&point);    }
      method is_inf (line 219) | bool is_inf() const   { return blst_p1_affine_is_inf(&point);   }
      method is_equal (line 220) | bool is_equal(const P1_Affine& p) const
      method BLST_ERROR (line 228) | BLST_ERROR core_verify(const P2_Affine& pk, bool hash_or_encode,
      method P1_Affine (line 234) | static P1_Affine generator()
    class P1 (line 247) | class P1 {
      method P1 (line 251) | P1(const blst_p1 *cptr) { point = *cptr; }
      method P1 (line 253) | P1() { memset(&point, 0, sizeof(point)); }
      method P1 (line 254) | P1(const SecretKey& sk) { blst_sk_to_pk_in_g1(&point, &sk.key); }
      method P1 (line 256) | P1(const byte *in)
      method P1 (line 264) | P1(const byte *in, size_t len)
      method P1 (line 273) | P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); }
      method P1 (line 275) | P1 dup() const                      { return *this; }
      method P1_Affine (line 276) | P1_Affine to_affine() const         { return P1_Affine(*this);      ...
      method serialize (line 277) | void serialize(byte out[96]) const  { blst_p1_serialize(out, &point)...
      method compress (line 278) | void compress(byte out[48]) const   { blst_p1_compress(out, &point);...
      method on_curve (line 279) | bool on_curve() const               { return blst_p1_on_curve(&point...
      method in_group (line 280) | bool in_group() const               { return blst_p1_in_g1(&point); ...
      method is_inf (line 281) | bool is_inf() const                 { return blst_p1_is_inf(&point);...
      method is_equal (line 282) | bool is_equal(const P1& p) const
      method aggregate (line 284) | void aggregate(const P1_Affine& in)
      method P1 (line 290) | P1* sign_with(const SecretKey& sk)
      method P1 (line 292) | P1* sign_with(const Scalar& scalar)
      method P1 (line 294) | P1* hash_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 300) | P1* encode_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 307) | P1* hash_to(const byte* msg, size_t msg_len,
      method P1 (line 314) | P1* encode_to(const byte* msg, size_t msg_len,
      method P1 (line 322) | P1* mult(const byte* scalar, size_t nbits)
      method P1 (line 324) | P1* mult(const Scalar& scalar)
      method P1 (line 326) | P1* cneg(bool flag)
      method P1 (line 328) | P1* neg()
      method P1 (line 330) | P1* add(const P1& a)
      method P1 (line 332) | P1* add(const P1_Affine &a)
      method P1 (line 334) | P1* dbl()
      method P1 (line 337) | static P1 add(const P1& a, const P1& b)
      method P1 (line 339) | static P1 add(const P1& a, const P1_Affine& b)
      method P1 (line 341) | static P1 dbl(const P1& a)
      method P1 (line 344) | static P1 generator()
    class P1_Affines (line 354) | class P1_Affines {
      type p1_affine_no_init (line 356) | struct p1_affine_no_init {
        method p1_affine_no_init (line 358) | p1_affine_no_init() { }
      method P1_Affines (line 368) | P1_Affines() {}
      method P1_Affines (line 369) | P1_Affines(size_t wbits, const P1_Affine* const points[], size_t npo...
      method P1_Affines (line 377) | P1_Affines(size_t wbits, const P1_Affine points[], size_t npoints)
      method P1_Affines (line 381) | P1_Affines(size_t wbits, const std::vector<P1_Affine>& points)
      method P1_Affines (line 384) | P1_Affines(size_t wbits, const P1* const points[], size_t npoints)
      method P1_Affines (line 396) | P1_Affines(size_t wbits, const P1 points[], size_t npoints)
      method P1_Affines (line 400) | P1_Affines(size_t wbits, const std::vector<P1>& points)
      method P1_Affines (line 403) | P1_Affines(const P1* const points[], size_t npoints)
      method P1_Affines (line 411) | P1_Affines(const P1 points[], size_t npoints)
      method P1_Affines (line 415) | P1_Affines(const std::vector<P1>& points)
      method P1 (line 418) | P1 mult(const byte* const scalars[], size_t nbits) const
      method from (line 436) | static std::vector<P1_Affine> from(const P1* const points[], size_t ...
      method from (line 444) | static std::vector<P1_Affine> from(const P1 points[], size_t npoints)
      method from (line 448) | static std::vector<P1_Affine> from(const std::vector<P1>& points)
      method P1 (line 452) | static P1 mult_pippenger(const P1_Affine* const points[], size_t npo...
      method P1 (line 463) | static P1 mult_pippenger(const P1_Affine points[], size_t npoints,
      method P1 (line 468) | static P1 mult_pippenger(const std::vector<P1_Affine>& points,
      method P1 (line 473) | static P1 add(const P1_Affine* const points[], size_t npoints)
      method P1 (line 481) | static P1 add(const P1_Affine points[], size_t npoints)
      method P1 (line 485) | static P1 add(const std::vector<P1_Affine>& points)
    class P2_Affine (line 490) | class P2_Affine {
      method P2_Affine (line 494) | P2_Affine(const blst_p2_affine *cptr) { point = *cptr; }
      method P2_Affine (line 496) | P2_Affine() { memset(&point, 0, sizeof(point)); }
      method P2_Affine (line 498) | P2_Affine(const byte *in)
      method P2_Affine (line 504) | P2_Affine(const byte *in, size_t len)
      method P2_Affine (line 513) | P2_Affine dup() const { return *this; }
      method serialize (line 515) | void serialize(byte out[192]) const
      method compress (line 517) | void compress(byte out[96]) const
      method on_curve (line 519) | bool on_curve() const { return blst_p2_affine_on_curve(&point); }
      method in_group (line 520) | bool in_group() const { return blst_p2_affine_in_g2(&point);    }
      method is_inf (line 521) | bool is_inf() const   { return blst_p2_affine_is_inf(&point);   }
      method is_equal (line 522) | bool is_equal(const P2_Affine& p) const
      method BLST_ERROR (line 530) | BLST_ERROR core_verify(const P1_Affine& pk, bool hash_or_encode,
      method P2_Affine (line 536) | static P2_Affine generator()
    class P2 (line 549) | class P2 {
      method P2 (line 553) | P2(const blst_p2 *cptr) { point = *cptr; }
      method P2 (line 555) | P2() { memset(&point, 0, sizeof(point)); }
      method P2 (line 556) | P2(const SecretKey& sk) { blst_sk_to_pk_in_g2(&point, &sk.key); }
      method P2 (line 558) | P2(const byte *in)
      method P2 (line 566) | P2(const byte *in, size_t len)
      method P2 (line 575) | P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); }
      method P2 (line 577) | P2 dup() const                      { return *this; }
      method P2_Affine (line 578) | P2_Affine to_affine() const         { return P2_Affine(*this);      ...
      method serialize (line 579) | void serialize(byte out[192]) const { blst_p2_serialize(out, &point)...
      method compress (line 580) | void compress(byte out[96]) const   { blst_p2_compress(out, &point);...
      method on_curve (line 581) | bool on_curve() const               { return blst_p2_on_curve(&point...
      method in_group (line 582) | bool in_group() const               { return blst_p2_in_g2(&point); ...
      method is_inf (line 583) | bool is_inf() const                 { return blst_p2_is_inf(&point);...
      method is_equal (line 584) | bool is_equal(const P2& p) const
      method aggregate (line 586) | void aggregate(const P2_Affine& in)
      method P2 (line 592) | P2* sign_with(const SecretKey& sk)
      method P2 (line 594) | P2* sign_with(const Scalar& scalar)
      method P2 (line 596) | P2* hash_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 602) | P2* encode_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 609) | P2* hash_to(const byte* msg, size_t msg_len,
      method P2 (line 616) | P2* encode_to(const byte* msg, size_t msg_len,
      method P2 (line 625) | P2* mult(const byte* scalar, size_t nbits)
      method P2 (line 627) | P2* mult(const Scalar& scalar)
      method P2 (line 629) | P2* cneg(bool flag)
      method P2 (line 631) | P2* neg()
      method P2 (line 633) | P2* add(const P2& a)
      method P2 (line 635) | P2* add(const P2_Affine &a)
      method P2 (line 637) | P2* dbl()
      method P2 (line 640) | static P2 add(const P2& a, const P2& b)
      method P2 (line 642) | static P2 add(const P2& a, const P2_Affine& b)
      method P2 (line 644) | static P2 dbl(const P2& a)
      method P2 (line 647) | static P2 generator()
    class P2_Affines (line 657) | class P2_Affines {
      type p2_affine_no_init (line 659) | struct p2_affine_no_init {
        method p2_affine_no_init (line 661) | p2_affine_no_init() { }
      method P2_Affines (line 671) | P2_Affines() {}
      method P2_Affines (line 672) | P2_Affines(size_t wbits, const P2_Affine* const points[], size_t npo...
      method P2_Affines (line 680) | P2_Affines(size_t wbits, const P2_Affine points[], size_t npoints)
      method P2_Affines (line 684) | P2_Affines(size_t wbits, const std::vector<P2_Affine>& points)
      method P2_Affines (line 687) | P2_Affines(size_t wbits, const P2* const points[], size_t npoints)
      method P2_Affines (line 699) | P2_Affines(size_t wbits, const P2 points[], size_t npoints)
      method P2_Affines (line 703) | P2_Affines(size_t wbits, const std::vector<P2>& points)
      method P2_Affines (line 706) | P2_Affines(const P2* const points[], size_t npoints)
      method P2_Affines (line 714) | P2_Affines(const P2 points[], size_t npoints)
      method P2_Affines (line 718) | P2_Affines(const std::vector<P2>& points)
      method P2 (line 721) | P2 mult(const byte* const scalars[], size_t nbits) const
      method from (line 739) | static std::vector<P2_Affine> from(const P2* const points[], size_t ...
      method from (line 747) | static std::vector<P2_Affine> from(const P2 points[], size_t npoints)
      method from (line 751) | static std::vector<P2_Affine> from(const std::vector<P2>& points)
      method P2 (line 755) | static P2 mult_pippenger(const P2_Affine* const points[], size_t npo...
      method P2 (line 766) | static P2 mult_pippenger(const P2_Affine points[], size_t npoints,
      method P2 (line 771) | static P2 mult_pippenger(const std::vector<P2_Affine>& points,
      method P2 (line 776) | static P2 add(const P2_Affine* const points[], size_t npoints)
      method P2 (line 784) | static P2 add(const P2_Affine points[], size_t npoints)
      method P2 (line 788) | static P2 add(const std::vector<P2_Affine>& points)
    function P1 (line 798) | inline P1 P1_Affine::to_jacobian() const { P1 ret(*this); return ret; }
      method P1 (line 251) | P1(const blst_p1 *cptr) { point = *cptr; }
      method P1 (line 253) | P1() { memset(&point, 0, sizeof(point)); }
      method P1 (line 254) | P1(const SecretKey& sk) { blst_sk_to_pk_in_g1(&point, &sk.key); }
      method P1 (line 256) | P1(const byte *in)
      method P1 (line 264) | P1(const byte *in, size_t len)
      method P1 (line 273) | P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); }
      method P1 (line 275) | P1 dup() const                      { return *this; }
      method P1_Affine (line 276) | P1_Affine to_affine() const         { return P1_Affine(*this);      ...
      method serialize (line 277) | void serialize(byte out[96]) const  { blst_p1_serialize(out, &point)...
      method compress (line 278) | void compress(byte out[48]) const   { blst_p1_compress(out, &point);...
      method on_curve (line 279) | bool on_curve() const               { return blst_p1_on_curve(&point...
      method in_group (line 280) | bool in_group() const               { return blst_p1_in_g1(&point); ...
      method is_inf (line 281) | bool is_inf() const                 { return blst_p1_is_inf(&point);...
      method is_equal (line 282) | bool is_equal(const P1& p) const
      method aggregate (line 284) | void aggregate(const P1_Affine& in)
      method P1 (line 290) | P1* sign_with(const SecretKey& sk)
      method P1 (line 292) | P1* sign_with(const Scalar& scalar)
      method P1 (line 294) | P1* hash_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 300) | P1* encode_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 307) | P1* hash_to(const byte* msg, size_t msg_len,
      method P1 (line 314) | P1* encode_to(const byte* msg, size_t msg_len,
      method P1 (line 322) | P1* mult(const byte* scalar, size_t nbits)
      method P1 (line 324) | P1* mult(const Scalar& scalar)
      method P1 (line 326) | P1* cneg(bool flag)
      method P1 (line 328) | P1* neg()
      method P1 (line 330) | P1* add(const P1& a)
      method P1 (line 332) | P1* add(const P1_Affine &a)
      method P1 (line 334) | P1* dbl()
      method P1 (line 337) | static P1 add(const P1& a, const P1& b)
      method P1 (line 339) | static P1 add(const P1& a, const P1_Affine& b)
      method P1 (line 341) | static P1 dbl(const P1& a)
      method P1 (line 344) | static P1 generator()
    function P2 (line 799) | inline P2 P2_Affine::to_jacobian() const { P2 ret(*this); return ret; }
      method P2 (line 553) | P2(const blst_p2 *cptr) { point = *cptr; }
      method P2 (line 555) | P2() { memset(&point, 0, sizeof(point)); }
      method P2 (line 556) | P2(const SecretKey& sk) { blst_sk_to_pk_in_g2(&point, &sk.key); }
      method P2 (line 558) | P2(const byte *in)
      method P2 (line 566) | P2(const byte *in, size_t len)
      method P2 (line 575) | P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); }
      method P2 (line 577) | P2 dup() const                      { return *this; }
      method P2_Affine (line 578) | P2_Affine to_affine() const         { return P2_Affine(*this);      ...
      method serialize (line 579) | void serialize(byte out[192]) const { blst_p2_serialize(out, &point)...
      method compress (line 580) | void compress(byte out[96]) const   { blst_p2_compress(out, &point);...
      method on_curve (line 581) | bool on_curve() const               { return blst_p2_on_curve(&point...
      method in_group (line 582) | bool in_group() const               { return blst_p2_in_g2(&point); ...
      method is_inf (line 583) | bool is_inf() const                 { return blst_p2_is_inf(&point);...
      method is_equal (line 584) | bool is_equal(const P2& p) const
      method aggregate (line 586) | void aggregate(const P2_Affine& in)
      method P2 (line 592) | P2* sign_with(const SecretKey& sk)
      method P2 (line 594) | P2* sign_with(const Scalar& scalar)
      method P2 (line 596) | P2* hash_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 602) | P2* encode_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 609) | P2* hash_to(const byte* msg, size_t msg_len,
      method P2 (line 616) | P2* encode_to(const byte* msg, size_t msg_len,
      method P2 (line 625) | P2* mult(const byte* scalar, size_t nbits)
      method P2 (line 627) | P2* mult(const Scalar& scalar)
      method P2 (line 629) | P2* cneg(bool flag)
      method P2 (line 631) | P2* neg()
      method P2 (line 633) | P2* add(const P2& a)
      method P2 (line 635) | P2* add(const P2_Affine &a)
      method P2 (line 637) | P2* dbl()
      method P2 (line 640) | static P2 add(const P2& a, const P2& b)
      method P2 (line 642) | static P2 add(const P2& a, const P2_Affine& b)
      method P2 (line 644) | static P2 dbl(const P2& a)
      method P2 (line 647) | static P2 generator()
    function P1 (line 801) | inline P1 G1() { return P1::generator();  }
      method P1 (line 251) | P1(const blst_p1 *cptr) { point = *cptr; }
      method P1 (line 253) | P1() { memset(&point, 0, sizeof(point)); }
      method P1 (line 254) | P1(const SecretKey& sk) { blst_sk_to_pk_in_g1(&point, &sk.key); }
      method P1 (line 256) | P1(const byte *in)
      method P1 (line 264) | P1(const byte *in, size_t len)
      method P1 (line 273) | P1(const P1_Affine& affine) { blst_p1_from_affine(&point, affine); }
      method P1 (line 275) | P1 dup() const                      { return *this; }
      method P1_Affine (line 276) | P1_Affine to_affine() const         { return P1_Affine(*this);      ...
      method serialize (line 277) | void serialize(byte out[96]) const  { blst_p1_serialize(out, &point)...
      method compress (line 278) | void compress(byte out[48]) const   { blst_p1_compress(out, &point);...
      method on_curve (line 279) | bool on_curve() const               { return blst_p1_on_curve(&point...
      method in_group (line 280) | bool in_group() const               { return blst_p1_in_g1(&point); ...
      method is_inf (line 281) | bool is_inf() const                 { return blst_p1_is_inf(&point);...
      method is_equal (line 282) | bool is_equal(const P1& p) const
      method aggregate (line 284) | void aggregate(const P1_Affine& in)
      method P1 (line 290) | P1* sign_with(const SecretKey& sk)
      method P1 (line 292) | P1* sign_with(const Scalar& scalar)
      method P1 (line 294) | P1* hash_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 300) | P1* encode_to(bytes_t msg, const std::string& DST = "",
      method P1 (line 307) | P1* hash_to(const byte* msg, size_t msg_len,
      method P1 (line 314) | P1* encode_to(const byte* msg, size_t msg_len,
      method P1 (line 322) | P1* mult(const byte* scalar, size_t nbits)
      method P1 (line 324) | P1* mult(const Scalar& scalar)
      method P1 (line 326) | P1* cneg(bool flag)
      method P1 (line 328) | P1* neg()
      method P1 (line 330) | P1* add(const P1& a)
      method P1 (line 332) | P1* add(const P1_Affine &a)
      method P1 (line 334) | P1* dbl()
      method P1 (line 337) | static P1 add(const P1& a, const P1& b)
      method P1 (line 339) | static P1 add(const P1& a, const P1_Affine& b)
      method P1 (line 341) | static P1 dbl(const P1& a)
      method P1 (line 344) | static P1 generator()
    function P2 (line 802) | inline P2 G2() { return P2::generator();  }
      method P2 (line 553) | P2(const blst_p2 *cptr) { point = *cptr; }
      method P2 (line 555) | P2() { memset(&point, 0, sizeof(point)); }
      method P2 (line 556) | P2(const SecretKey& sk) { blst_sk_to_pk_in_g2(&point, &sk.key); }
      method P2 (line 558) | P2(const byte *in)
      method P2 (line 566) | P2(const byte *in, size_t len)
      method P2 (line 575) | P2(const P2_Affine& affine) { blst_p2_from_affine(&point, affine); }
      method P2 (line 577) | P2 dup() const                      { return *this; }
      method P2_Affine (line 578) | P2_Affine to_affine() const         { return P2_Affine(*this);      ...
      method serialize (line 579) | void serialize(byte out[192]) const { blst_p2_serialize(out, &point)...
      method compress (line 580) | void compress(byte out[96]) const   { blst_p2_compress(out, &point);...
      method on_curve (line 581) | bool on_curve() const               { return blst_p2_on_curve(&point...
      method in_group (line 582) | bool in_group() const               { return blst_p2_in_g2(&point); ...
      method is_inf (line 583) | bool is_inf() const                 { return blst_p2_is_inf(&point);...
      method is_equal (line 584) | bool is_equal(const P2& p) const
      method aggregate (line 586) | void aggregate(const P2_Affine& in)
      method P2 (line 592) | P2* sign_with(const SecretKey& sk)
      method P2 (line 594) | P2* sign_with(const Scalar& scalar)
      method P2 (line 596) | P2* hash_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 602) | P2* encode_to(bytes_t msg, const std::string& DST = "",
      method P2 (line 609) | P2* hash_to(const byte* msg, size_t msg_len,
      method P2 (line 616) | P2* encode_to(const byte* msg, size_t msg_len,
      method P2 (line 625) | P2* mult(const byte* scalar, size_t nbits)
      method P2 (line 627) | P2* mult(const Scalar& scalar)
      method P2 (line 629) | P2* cneg(bool flag)
      method P2 (line 631) | P2* neg()
      method P2 (line 633) | P2* add(const P2& a)
      method P2 (line 635) | P2* add(const P2_Affine &a)
      method P2 (line 637) | P2* dbl()
      method P2 (line 640) | static P2 add(const P2& a, const P2& b)
      method P2 (line 642) | static P2 add(const P2& a, const P2_Affine& b)
      method P2 (line 644) | static P2 dbl(const P2& a)
      method P2 (line 647) | static P2 generator()
    function BLST_ERROR (line 805) | inline BLST_ERROR P1_Affine::core_verify(const P2_Affine& pk,
    function BLST_ERROR (line 815) | inline BLST_ERROR P2_Affine::core_verify(const P1_Affine& pk,
    class PT (line 827) | class PT {
      method PT (line 831) | PT(const blst_fp12 *v)  { value = *v; }
      method PT (line 833) | PT(const P1_Affine& p)  { blst_aggregated_in_g1(&value, p); }
      method PT (line 834) | PT(const P2_Affine& q)  { blst_aggregated_in_g2(&value, q); }
      method PT (line 835) | PT(const P2_Affine& q, const P1_Affine& p)
      method PT (line 837) | PT(const P1_Affine& p, const P2_Affine& q) : PT(q, p) {}
      method PT (line 838) | PT(const P2& q, const P1& p)
      method PT (line 840) | PT(const P1& p, const P2& q) : PT(q, p) {}
      method PT (line 842) | PT dup() const          { return *this; }
      method is_one (line 843) | bool is_one() const     { return blst_fp12_is_one(&value); }
      method is_equal (line 844) | bool is_equal(const PT& p) const
      method PT (line 846) | PT* sqr()               { blst_fp12_sqr(&value, &value);    return t...
      method PT (line 847) | PT* mul(const PT& p)    { blst_fp12_mul(&value, &value, p); return t...
      method PT (line 848) | PT* final_exp()         { blst_final_exp(&value, &value);   return t...
      method in_group (line 849) | bool in_group() const   { return blst_fp12_in_group(&value); }
      method to_bendian (line 850) | void to_bendian(byte out[48*12]) const
      method finalverify (line 853) | static bool finalverify(const PT& gt1, const PT& gt2)
      method PT (line 855) | static PT one() { return PT(blst_fp12_one()); }
    class Pairing (line 862) | class Pairing {
      method init (line 869) | void init(bool hash_or_encode, const byte* DST, size_t DST_len)
      method Pairing (line 883) | Pairing(bool hash_or_encode, const std::string& DST)
      method Pairing (line 887) | Pairing(bool hash_or_encode, const byte* DST, size_t DST_len)
      method BLST_ERROR (line 892) | BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 897) | BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 902) | BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 908) | BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 915) | BLST_ERROR aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 921) | BLST_ERROR aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method BLST_ERROR (line 927) | BLST_ERROR mul_n_aggregate(const P1_Affine* pk, const P2_Affine* sig,
      method BLST_ERROR (line 934) | BLST_ERROR mul_n_aggregate(const P2_Affine* pk, const P1_Affine* sig,
      method commit (line 942) | void commit()
      method BLST_ERROR (line 944) | BLST_ERROR merge(const Pairing* ctx)
      method finalverify (line 946) | bool finalverify(const PT* sig = nullptr) const
      method raw_aggregate (line 950) | void raw_aggregate(const P2_Affine* q, const P1_Affine* p)
      method PT (line 952) | PT as_fp12()

FILE: bindings/blst_aux.h
  type blst_uniq (line 60) | typedef struct {} blst_uniq;
  type blst_uniq (line 62) | typedef struct blst_opaque blst_uniq;

FILE: bindings/c#/poc.cs
  class PoC (line 5) | class PoC {
    method Main (line 6) | private static void Main(string[] args)
    method fromHexChar (line 58) | private static int fromHexChar(char c)
    method fromHexString (line 66) | private static byte[] fromHexString(string str)

FILE: bindings/c#/supranational.blst.cs
  class blst (line 21) | public static class blst {
    method blst (line 26) | static blst()
    type ERROR (line 71) | public enum ERROR {
    class Exception (line 82) | public class Exception : ApplicationException {
      method Exception (line 85) | public Exception(ERROR err) { code = err; }
    type ByteOrder (line 102) | public enum ByteOrder {
    method blst_keygen (line 107) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_keygen_v3 (line 111) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_keygen_v4_5 (line 115) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_keygen_v5 (line 120) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_derive_master_eip2333 (line 125) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_derive_child_eip2333 (line 128) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_scalar_from_bendian (line 132) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_bendian_from_scalar (line 134) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_check (line 136) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_scalar_from_lendian (line 139) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_lendian_from_scalar (line 141) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type SecretKey (line 144) | public struct SecretKey {
      method SecretKey (line 148) | public SecretKey(byte[] IKM, string info)
      method SecretKey (line 150) | public SecretKey(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
      method keygen (line 158) | public void keygen(byte[] IKM, string info="")
      method keygen_v3 (line 164) | public void keygen_v3(byte[] IKM, string info="")
      method keygen_v4_5 (line 170) | public void keygen_v4_5(byte[] IKM, string salt, string info="")
      method keygen_v5 (line 178) | public void keygen_v5(byte[] IKM, byte[] salt, string info="")
      method keygen_v5 (line 185) | public void keygen_v5(byte[] IKM, string salt, string info="")
      method derive_master_eip2333 (line 187) | public void derive_master_eip2333(byte[] IKM)
      method SecretKey (line 191) | public SecretKey(SecretKey master, uint child_index)
      method from_bendian (line 196) | public void from_bendian(byte[] inp)
      method from_lendian (line 204) | public void from_lendian(byte[] inp)
      method to_bendian (line 213) | public byte[] to_bendian()
      method to_lendian (line 218) | public byte[] to_lendian()
    method blst_scalar_from_be_bytes (line 225) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_scalar_from_le_bytes (line 228) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_add_n_check (line 231) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_sub_n_check (line 234) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_mul_n_check (line 237) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_inverse (line 240) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type Scalar (line 243) | public struct Scalar {
      method Scalar (line 247) | public Scalar(byte[] inp, ByteOrder order=ByteOrder.BigEndian)
      method Scalar (line 254) | private Scalar(bool _)      { val = new byte[32];               }
      method Scalar (line 255) | private Scalar(Scalar orig) { val = (byte[])orig.val.Clone();   }
      method dup (line 257) | public Scalar dup()         { return new Scalar(this);          }
      method from_bendian (line 259) | public void from_bendian(byte[] inp)
      method from_lendian (line 263) | public void from_lendian(byte[] inp)
      method to_bendian (line 268) | public byte[] to_bendian()
      method to_lendian (line 273) | public byte[] to_lendian()
      method add (line 279) | public Scalar add(SecretKey a)
      method add (line 284) | public Scalar add(Scalar a)
      method sub (line 289) | public Scalar sub(Scalar a)
      method mul (line 294) | public Scalar mul(Scalar a)
      method inverse (line 299) | public Scalar inverse()
    method blst_p1_affine_sizeof (line 316) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_deserialize (line 319) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_serialize (line 321) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_compress (line 323) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_to_affine (line 326) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_on_curve (line 328) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_in_g1 (line 330) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_is_inf (line 332) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_affine_is_equal (line 334) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_generator (line 337) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_core_verify_pk_in_g2 (line 340) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type P1_Affine (line 347) | public struct P1_Affine {
      method P1_Affine (line 353) | private P1_Affine(bool _)       { point = new long[sz]; }
      method P1_Affine (line 354) | private P1_Affine(P1_Affine p)  { point = (long[])p.point.Clone(); }
      method P1_Affine (line 356) | public P1_Affine(byte[] inp) : this(true)
      method P1_Affine (line 365) | public P1_Affine(P1 jacobian) : this(true)
      method dup (line 368) | public P1_Affine dup()      { return new P1_Affine(this);   }
      method to_jacobian (line 369) | public P1 to_jacobian()     { return new P1(this);          }
      method serialize (line 370) | public byte[] serialize()
      method compress (line 375) | public byte[] compress()
      method on_curve (line 381) | public bool on_curve()      { return blst_p1_affine_on_curve(point);...
      method in_group (line 382) | public bool in_group()      { return blst_p1_affine_in_g1(point);   ...
      method is_inf (line 383) | public bool is_inf()        { return blst_p1_affine_is_inf(point);  ...
      method is_equal (line 384) | public bool is_equal(P1_Affine p)
      method core_verify (line 387) | ERROR core_verify(P2_Affine pk, bool hash_or_encode,
      method generator (line 397) | public static P1_Affine generator()
    method blst_p1_sizeof (line 404) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_serialize (line 406) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_compress (line 408) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_from_affine (line 410) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_on_curve (line 413) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_in_g1 (line 415) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_is_inf (line 417) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_is_equal (line 419) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_to_pk_in_g1 (line 422) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_encode_to_g1 (line 424) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_hash_to_g1 (line 429) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sign_pk_in_g2 (line 434) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_mult (line 438) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_cneg (line 442) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_add_or_double (line 444) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_add_or_double_affine (line 447) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p1_double (line 451) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type P1 (line 454) | public struct P1 {
      method P1 (line 460) | private P1(bool _)      { point = new long[sz]; }
      method P1 (line 461) | private P1(P1 p)        { point = (long[])p.point.Clone(); }
      method self (line 462) | private long[] self()
      method P1 (line 465) | public P1(SecretKey sk) : this(true)
      method P1 (line 467) | public P1(byte[] inp) : this(true)
      method P1 (line 477) | public P1(P1_Affine affine) : this(true)
      method dup (line 480) | public P1 dup()                 { return new P1(this);              ...
      method to_affine (line 481) | public P1_Affine to_affine()    { return new P1_Affine(this);       ...
      method serialize (line 482) | public byte[] serialize()
      method compress (line 487) | public byte[] compress()
      method on_curve (line 493) | public bool on_curve()      { return blst_p1_on_curve(point);       ...
      method in_group (line 494) | public bool in_group()      { return blst_p1_in_g1(point);          ...
      method is_inf (line 495) | public bool is_inf()        { return blst_p1_is_inf(point);         ...
      method is_equal (line 496) | public bool is_equal(P1 p)  { return blst_p1_is_equal(point, p.point...
      method hash_to (line 498) | public P1 hash_to(byte[] msg, string DST="", byte[] aug=null)
      method encode_to (line 505) | public P1 encode_to(byte[] msg, string DST="", byte[] aug=null)
      method sign_with (line 513) | public P1 sign_with(SecretKey sk)
      method sign_with (line 515) | public P1 sign_with(Scalar scalar)
      method aggregate (line 518) | public void aggregate(P1_Affine inp)
      method mult (line 525) | public P1 mult(byte[] scalar)
      method mult (line 529) | public P1 mult(Scalar scalar)
      method mult (line 533) | public P1 mult(BigInteger scalar)
      method cneg (line 546) | public P1 cneg(bool flag)   { blst_p1_cneg(point, flag); return this...
      method neg (line 547) | public P1 neg()             { blst_p1_cneg(point, true); return this...
      method add (line 548) | public P1 add(P1 a)
      method add (line 550) | public P1 add(P1_Affine a)
      method dbl (line 552) | public P1 dbl()
      method generator (line 555) | public static P1 generator()
    method G1 (line 562) | public static P1 G1() { return P1.generator(); }
    method blst_aggregated_in_g1 (line 564) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_aggregate_pk_in_g1 (line 566) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_mul_n_aggregate_pk_in_g1 (line 571) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_sizeof (line 579) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_deserialize (line 582) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_serialize (line 584) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_compress (line 586) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_to_affine (line 589) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_on_curve (line 591) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_in_g2 (line 593) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_is_inf (line 595) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_affine_is_equal (line 597) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_generator (line 600) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_core_verify_pk_in_g1 (line 603) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type P2_Affine (line 610) | public struct P2_Affine {
      method P2_Affine (line 616) | private P2_Affine(bool _)       { point = new long[sz]; }
      method P2_Affine (line 617) | private P2_Affine(P2_Affine p)  { point = (long[])p.point.Clone(); }
      method P2_Affine (line 619) | public P2_Affine(byte[] inp) : this(true)
      method P2_Affine (line 628) | public P2_Affine(P2 jacobian) : this(true)
      method dup (line 631) | public P2_Affine dup()      { return new P2_Affine(this);   }
      method to_jacobian (line 632) | public P2 to_jacobian()     { return new P2(this);          }
      method serialize (line 633) | public byte[] serialize()
      method compress (line 638) | public byte[] compress()
      method on_curve (line 644) | public bool on_curve()      { return blst_p2_affine_on_curve(point);...
      method in_group (line 645) | public bool in_group()      { return blst_p2_affine_in_g2(point);   ...
      method is_inf (line 646) | public bool is_inf()        { return blst_p2_affine_is_inf(point);  ...
      method is_equal (line 647) | public bool is_equal(P2_Affine p)
      method core_verify (line 650) | ERROR core_verify(P1_Affine pk, bool hash_or_encode,
      method generator (line 660) | public static P2_Affine generator()
    method blst_p2_sizeof (line 667) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_serialize (line 669) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_compress (line 671) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_from_affine (line 673) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_on_curve (line 676) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_in_g2 (line 678) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_is_inf (line 680) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_is_equal (line 682) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sk_to_pk_in_g2 (line 685) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_encode_to_g2 (line 687) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_hash_to_g2 (line 692) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_sign_pk_in_g1 (line 697) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_mult (line 701) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_cneg (line 705) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_add_or_double (line 707) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_add_or_double_affine (line 710) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_p2_double (line 714) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type P2 (line 717) | public struct P2 {
      method P2 (line 723) | private P2(bool _)      { point = new long[sz]; }
      method P2 (line 724) | private P2(P2 p)        { point = (long[])p.point.Clone(); }
      method self (line 725) | private long[] self()
      method P2 (line 728) | public P2(SecretKey sk) : this(true)
      method P2 (line 730) | public P2(byte[] inp) : this(true)
      method P2 (line 740) | public P2(P2_Affine affine) : this(true)
      method dup (line 743) | public P2 dup()                 { return new P2(this);              ...
      method to_affine (line 744) | public P2_Affine to_affine()    { return new P2_Affine(this);       ...
      method serialize (line 745) | public byte[] serialize()
      method compress (line 750) | public byte[] compress()
      method on_curve (line 756) | public bool on_curve()      { return blst_p2_on_curve(point);       ...
      method in_group (line 757) | public bool in_group()      { return blst_p2_in_g2(point);          ...
      method is_inf (line 758) | public bool is_inf()        { return blst_p2_is_inf(point);         ...
      method is_equal (line 759) | public bool is_equal(P2 p)  { return blst_p2_is_equal(point, p.point...
      method hash_to (line 761) | public P2 hash_to(byte[] msg, string DST="", byte[] aug=null)
      method encode_to (line 768) | public P2 encode_to(byte[] msg, string DST="", byte[] aug=null)
      method sign_with (line 776) | public P2 sign_with(SecretKey sk)
      method sign_with (line 778) | public P2 sign_with(Scalar scalar)
      method aggregate (line 781) | public void aggregate(P2_Affine inp)
      method mult (line 788) | public P2 mult(byte[] scalar)
      method mult (line 792) | public P2 mult(Scalar scalar)
      method mult (line 796) | public P2 mult(BigInteger scalar)
      method cneg (line 809) | public P2 cneg(bool flag)   { blst_p2_cneg(point, flag); return this...
      method neg (line 810) | public P2 neg()             { blst_p2_cneg(point, true); return this...
      method add (line 811) | public P2 add(P2 a)
      method add (line 813) | public P2 add(P2_Affine a)
      method dbl (line 815) | public P2 dbl()
      method generator (line 818) | public static P2 generator()
    method G2 (line 825) | public static P2 G2() { return P2.generator(); }
    method blst_aggregated_in_g2 (line 827) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_aggregate_pk_in_g2 (line 829) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_mul_n_aggregate_pk_in_g2 (line 834) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_sizeof (line 842) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_miller_loop (line 844) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_is_one (line 847) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_is_equal (line 849) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_sqr (line 851) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_mul (line 853) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_final_exp (line 856) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_finalverify (line 858) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_one (line 860) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_fp12_in_group (line 862) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_bendian_from_fp12 (line 864) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type PT (line 867) | public struct PT {
      method PT (line 872) | internal PT(bool _)     { fp12 = new long[sz]; }
      method PT (line 873) | private PT(PT orig)     { fp12 = (long[])orig.fp12.Clone(); }
      method PT (line 875) | public PT(P1_Affine p) : this(true)
      method PT (line 877) | public PT(P1 p) : this(true)
      method PT (line 879) | public PT(P2_Affine q) : this(true)
      method PT (line 881) | public PT(P2 q) : this(true)
      method PT (line 883) | public PT(P2_Affine q, P1_Affine p) : this(true)
      method PT (line 885) | public PT(P1_Affine p, P2_Affine q) : this(q, p) {}
      method PT (line 886) | public PT(P2 q, P1 p) : this(true)
      method PT (line 890) | public PT(P1 p, P2 q) : this(q, p) {}
      method dup (line 892) | public PT dup()         { return new PT(this); }
      method is_one (line 893) | public bool is_one()    { return blst_fp12_is_one(fp12); }
      method is_equal (line 894) | public bool is_equal(PT p)
      method sqr (line 896) | public PT sqr()         { blst_fp12_sqr(fp12, fp12);         return ...
      method mul (line 897) | public PT mul(PT p)     { blst_fp12_mul(fp12, fp12, p.fp12); return ...
      method final_exp (line 898) | public PT final_exp()   { blst_final_exp(fp12, fp12);        return ...
      method in_group (line 899) | public bool in_group()  { return blst_fp12_in_group(fp12); }
      method to_bendian (line 900) | public byte[] to_bendian()
      method finalverify (line 906) | public static bool finalverify(PT gt1, PT gt2)
      method one (line 909) | public static PT one()
    method blst_pairing_sizeof (line 916) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_init (line 918) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_commit (line 922) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_merge (line 924) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_finalverify (line 926) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_raw_aggregate (line 928) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    method blst_pairing_as_fp12 (line 932) | [DllImport("blst.dll", CallingConvention = CallingConvention.Cdecl)]
    type Pairing (line 935) | public struct Pairing {
      method Pairing (line 940) | public Pairing(bool hash_or_encode=false, string DST="")
      method aggregate (line 957) | public ERROR aggregate(P1_Affine pk, Nullable<P2_Affine> sig,
      method aggregate (line 964) | public ERROR aggregate(P2_Affine pk, Nullable<P1_Affine> sig,
      method mul_n_aggregate (line 971) | public ERROR mul_n_aggregate(P2_Affine pk, P1_Affine sig,
      method mul_n_aggregate (line 979) | public ERROR mul_n_aggregate(P1_Affine pk, P2_Affine sig,
      method commit (line 988) | public void commit()    { blst_pairing_commit(ctx); }
      method merge (line 989) | public void merge(Pairing a)
      method finalverify (line 994) | public bool finalverify(PT sig=new PT())
      method raw_aggregate (line 997) | public void raw_aggregate(P2_Affine q, P1_Affine p)
      method raw_aggregate (line 999) | public void raw_aggregate(P1_Affine p, P2_Affine q)
      method raw_aggregate (line 1001) | public void raw_aggregate(P2 q, P1 p)
      method raw_aggregate (line 1005) | public void raw_aggregate(P1 p, P2 q)
      method as_fp12 (line 1007) | public PT as_fp12()

FILE: bindings/go/blst.go
  constant BLST_SCALAR_BYTES (line 165) | BLST_SCALAR_BYTES = 256 / 8
  constant BLST_FP_BYTES (line 166) | BLST_FP_BYTES = 384 / 8
  constant BLST_P1_COMPRESS_BYTES (line 167) | BLST_P1_COMPRESS_BYTES = BLST_FP_BYTES
  constant BLST_P1_SERIALIZE_BYTES (line 168) | BLST_P1_SERIALIZE_BYTES = BLST_FP_BYTES * 2
  constant BLST_P2_COMPRESS_BYTES (line 169) | BLST_P2_COMPRESS_BYTES = BLST_FP_BYTES * 2
  constant BLST_P2_SERIALIZE_BYTES (line 170) | BLST_P2_SERIALIZE_BYTES = BLST_FP_BYTES * 4
  type Scalar (line 172) | type Scalar struct
    method MulAssign (line 3336) | func (a *Scalar) MulAssign(b *Scalar) (*Scalar, bool) {
    method Mul (line 3340) | func (a *Scalar) Mul(b *Scalar) (*Scalar, bool) {
    method AddAssign (line 3345) | func (a *Scalar) AddAssign(b *Scalar) (*Scalar, bool) {
    method Add (line 3349) | func (a *Scalar) Add(b *Scalar) (*Scalar, bool) {
    method SubAssign (line 3354) | func (a *Scalar) SubAssign(b *Scalar) (*Scalar, bool) {
    method Sub (line 3358) | func (a *Scalar) Sub(b *Scalar) (*Scalar, bool) {
    method Inverse (line 3363) | func (a *Scalar) Inverse() *Scalar {
    method Serialize (line 3374) | func (s *Scalar) Serialize() []byte {
    method Deserialize (line 3380) | func (s *Scalar) Deserialize(in []byte) *Scalar {
    method Valid (line 3388) | func (s *Scalar) Valid() bool {
    method HashTo (line 3392) | func (s *Scalar) HashTo(msg []byte, dst []byte) bool {
    method ToLEndian (line 3416) | func (fr *Scalar) ToLEndian() []byte {
    method FromLEndian (line 3428) | func (fr *Scalar) FromLEndian(arr []byte) *Scalar {
    method ToBEndian (line 3449) | func (fr *Scalar) ToBEndian() []byte {
    method FromBEndian (line 3461) | func (fr *Scalar) FromBEndian(arr []byte) *Scalar {
    method Print (line 3486) | func (s *Scalar) Print(name string) {
    method Equals (line 3534) | func (s1 *Scalar) Equals(s2 *Scalar) bool {
  type Fp (line 173) | type Fp struct
    method ToLEndian (line 3422) | func (fp *Fp) ToLEndian() []byte {
    method FromLEndian (line 3437) | func (fp *Fp) FromLEndian(arr []byte) *Fp {
    method ToBEndian (line 3455) | func (fp *Fp) ToBEndian() []byte {
    method FromBEndian (line 3470) | func (fp *Fp) FromBEndian(arr []byte) *Fp {
    method Equals (line 3538) | func (e1 *Fp) Equals(e2 *Fp) bool {
  type Fp2 (line 174) | type Fp2 struct
    method Print (line 3507) | func (f *Fp2) Print(name string) {
    method Equals (line 3542) | func (e1 *Fp2) Equals(e2 *Fp2) bool {
  type Fp12 (line 176) | type Fp12 struct
    method MulAssign (line 449) | func (pt *Fp12) MulAssign(p *Fp12) {
    method FinalExp (line 453) | func (pt *Fp12) FinalExp() {
    method InGroup (line 457) | func (pt *Fp12) InGroup() bool {
    method ToBendian (line 461) | func (pt *Fp12) ToBendian() []byte {
    method Equals (line 467) | func (pt1 *Fp12) Equals(pt2 *Fp12) bool {
    method asPtr (line 471) | func (pt *Fp12) asPtr() *C.blst_fp12 {
  type P1 (line 177) | type P1 struct
    method Serialize (line 1814) | func (p1 *P1) Serialize() []byte {
    method Compress (line 1819) | func (p1 *P1) Compress() []byte {
    method MultAssign (line 1825) | func (p1 *P1) MultAssign(scalarIf interface{}, optional ...int) *P1 {
    method Mult (line 1845) | func (p1 *P1) Mult(scalarIf interface{}, optional ...int) *P1 {
    method AddAssign (line 1850) | func (p1 *P1) AddAssign(pointIf interface{}) *P1 {
    method Add (line 1862) | func (p1 *P1) Add(pointIf interface{}) *P1 {
    method SubAssign (line 1867) | func (p1 *P1) SubAssign(pointIf interface{}) *P1 {
    method Sub (line 1884) | func (p1 *P1) Sub(pointIf interface{}) *P1 {
    method MultNAccumulate (line 1896) | func (acc *P1) MultNAccumulate(pointIf interface{}, scalarIf interface{},
    method ToAffine (line 1935) | func (p *P1) ToAffine() *P1Affine {
    method FromAffine (line 1941) | func (p *P1) FromAffine(pa *P1Affine) {
    method Print (line 3501) | func (p *P1) Print(name string) {
    method Equals (line 3558) | func (e1 *P1) Equals(e2 *P1) bool {
  type P2 (line 178) | type P2 struct
    method Serialize (line 2627) | func (p2 *P2) Serialize() []byte {
    method Compress (line 2632) | func (p2 *P2) Compress() []byte {
    method MultAssign (line 2638) | func (p2 *P2) MultAssign(scalarIf interface{}, optional ...int) *P2 {
    method Mult (line 2658) | func (p2 *P2) Mult(scalarIf interface{}, optional ...int) *P2 {
    method AddAssign (line 2663) | func (p2 *P2) AddAssign(pointIf interface{}) *P2 {
    method Add (line 2675) | func (p2 *P2) Add(pointIf interface{}) *P2 {
    method SubAssign (line 2680) | func (p2 *P2) SubAssign(pointIf interface{}) *P2 {
    method Sub (line 2697) | func (p2 *P2) Sub(pointIf interface{}) *P2 {
    method MultNAccumulate (line 2709) | func (acc *P2) MultNAccumulate(pointIf interface{}, scalarIf interface{},
    method ToAffine (line 2748) | func (p *P2) ToAffine() *P2Affine {
    method FromAffine (line 2754) | func (p *P2) FromAffine(pa *P2Affine) {
    method Print (line 3524) | func (p *P2) Print(name string) {
    method Equals (line 3574) | func (e1 *P2) Equals(e2 *P2) bool {
  type P1Affine (line 179) | type P1Affine struct
    method From (line 495) | func (pk *P1Affine) From(s *Scalar) *P1Affine {
    method KeyValidate (line 500) | func (pk *P1Affine) KeyValidate() bool {
    method SigValidate (line 1108) | func (sig *P1Affine) SigValidate(sigInfcheck bool) bool {
    method Sign (line 1116) | func (sig *P1Affine) Sign(sk *SecretKey, msg []byte, dst []byte,
    method Verify (line 1143) | func (sig *P1Affine) Verify(sigGroupcheck bool, pk *P2Affine, pkValida...
    method VerifyCompressed (line 1157) | func (dummy *P1Affine) VerifyCompressed(sig []byte, sigGroupcheck bool,
    method AggregateVerify (line 1171) | func (sig *P1Affine) AggregateVerify(sigGroupcheck bool,
    method AggregateVerifyCompressed (line 1203) | func (*P1Affine) AggregateVerifyCompressed(sig []byte, sigGroupcheck b...
    method FastAggregateVerify (line 1389) | func (sig *P1Affine) FastAggregateVerify(sigGroupcheck bool,
    method MultipleAggregateVerify (line 1409) | func (*P1Affine) MultipleAggregateVerify(sigs []*P1Affine,
    method Serialize (line 1727) | func (p1 *P1Affine) Serialize() []byte {
    method Deserialize (line 1733) | func (p1 *P1Affine) Deserialize(in []byte) *P1Affine {
    method Compress (line 1742) | func (p1 *P1Affine) Compress() []byte {
    method Uncompress (line 1748) | func (p1 *P1Affine) Uncompress(in []byte) *P1Affine {
    method InG1 (line 1758) | func (p1 *P1Affine) InG1() bool {
    method BatchUncompress (line 1762) | func (*P1Affine) BatchUncompress(in [][]byte) []*P1Affine {
    method Print (line 3491) | func (p *P1Affine) Print(name string) {
    method Equals (line 3546) | func (e1 *P1Affine) Equals(e2 *P1Affine) bool {
    method asPtr (line 3550) | func (pt *P1Affine) asPtr() *C.blst_p1_affine {
  type P2Affine (line 180) | type P2Affine struct
    method SigValidate (line 508) | func (sig *P2Affine) SigValidate(sigInfcheck bool) bool {
    method Sign (line 516) | func (sig *P2Affine) Sign(sk *SecretKey, msg []byte, dst []byte,
    method Verify (line 543) | func (sig *P2Affine) Verify(sigGroupcheck bool, pk *P1Affine, pkValida...
    method VerifyCompressed (line 557) | func (dummy *P2Affine) VerifyCompressed(sig []byte, sigGroupcheck bool,
    method AggregateVerify (line 571) | func (sig *P2Affine) AggregateVerify(sigGroupcheck bool,
    method AggregateVerifyCompressed (line 603) | func (*P2Affine) AggregateVerifyCompressed(sig []byte, sigGroupcheck b...
    method FastAggregateVerify (line 789) | func (sig *P2Affine) FastAggregateVerify(sigGroupcheck bool,
    method MultipleAggregateVerify (line 809) | func (*P2Affine) MultipleAggregateVerify(sigs []*P2Affine,
    method From (line 1095) | func (pk *P2Affine) From(s *Scalar) *P2Affine {
    method KeyValidate (line 1100) | func (pk *P2Affine) KeyValidate() bool {
    method Serialize (line 2540) | func (p2 *P2Affine) Serialize() []byte {
    method Deserialize (line 2546) | func (p2 *P2Affine) Deserialize(in []byte) *P2Affine {
    method Compress (line 2555) | func (p2 *P2Affine) Compress() []byte {
    method Uncompress (line 2561) | func (p2 *P2Affine) Uncompress(in []byte) *P2Affine {
    method InG2 (line 2571) | func (p2 *P2Affine) InG2() bool {
    method BatchUncompress (line 2575) | func (*P2Affine) BatchUncompress(in [][]byte) []*P2Affine {
    method Print (line 3516) | func (p *P2Affine) Print(name string) {
    method Equals (line 3562) | func (e1 *P2Affine) Equals(e2 *P2Affine) bool {
    method asPtr (line 3566) | func (pt *P2Affine) asPtr() *C.blst_p2_affine {
  type P1s (line 184) | type P1s
    method ToAffine (line 1994) | func (points P1s) ToAffine(optional ...P1Affines) P1Affines {
    method Add (line 2088) | func (points P1s) Add() *P1 {
    method Mult (line 2408) | func (points P1s) Mult(scalarsIf interface{}, nbits int) *P1 {
  type P2s (line 185) | type P2s
    method ToAffine (line 2807) | func (points P2s) ToAffine(optional ...P2Affines) P2Affines {
    method Add (line 2901) | func (points P2s) Add() *P2 {
    method Mult (line 3221) | func (points P2s) Mult(scalarsIf interface{}, nbits int) *P2 {
  type P1Affines (line 186) | type P1Affines
    method Add (line 2053) | func (points P1Affines) Add() *P1 {
    method Mult (line 2404) | func (points P1Affines) Mult(scalarsIf interface{}, nbits int) *P1 {
    method Validate (line 2496) | func (points P1Affines) Validate() bool {
  type P2Affines (line 187) | type P2Affines
    method Add (line 2866) | func (points P2Affines) Add() *P2 {
    method Mult (line 3217) | func (points P2Affines) Mult(scalarsIf interface{}, nbits int) *P2 {
    method Validate (line 3309) | func (points P2Affines) Validate() bool {
  function initMaxProcs (line 195) | func initMaxProcs() int {
  function SetMaxProcs (line 209) | func SetMaxProcs(procs int) {
  function numThreads (line 216) | func numThreads(maxThreads int) int {
  method Zeroize (line 238) | func (sk *SecretKey) Zeroize() {
  function KeyGen (line 243) | func KeyGen(ikm []byte, optional ...[]byte) *SecretKey {
  function KeyGenV3 (line 260) | func KeyGenV3(ikm []byte, optional ...[]byte) *SecretKey {
  function KeyGenV45 (line 277) | func KeyGenV45(ikm []byte, salt []byte, optional ...[]byte) *SecretKey {
  function KeyGenV5 (line 295) | func KeyGenV5(ikm []byte, salt []byte, optional ...[]byte) *SecretKey {
  function DeriveMasterEip2333 (line 317) | func DeriveMasterEip2333(ikm []byte) *SecretKey {
  method DeriveChildEip2333 (line 329) | func (master *SecretKey) DeriveChildEip2333(child_index uint32) *SecretK...
  function pairingSizeOf (line 339) | func pairingSizeOf(DST_len C.size_t) int {
  function PairingCtx (line 343) | func PairingCtx(hash_or_encode bool, DST []byte) Pairing {
  function PairingCommit (line 350) | func PairingCommit(ctx Pairing) {
  function PairingMerge (line 354) | func PairingMerge(ctx Pairing, ctx1 Pairing) int {
  function PairingFinalVerify (line 359) | func PairingFinalVerify(ctx Pairing, optional ...*Fp12) bool {
  function PairingRawAggregate (line 367) | func PairingRawAggregate(ctx Pairing, q *P2Affine, p *P1Affine) {
  function PairingAsFp12 (line 371) | func PairingAsFp12(ctx Pairing) *Fp12 {
  function Fp12One (line 377) | func Fp12One() Fp12 {
  function Fp12FinalVerify (line 381) | func Fp12FinalVerify(pt1 *Fp12, pt2 *Fp12) bool {
  function Fp12MillerLoop (line 385) | func Fp12MillerLoop(q *P2Affine, p *P1Affine) *Fp12 {
  function Fp12MillerLoopN (line 391) | func Fp12MillerLoopN(qs []P2Affine, ps []P1Affine) *Fp12 {
  function ptrOrNil (line 479) | func ptrOrNil(bytes []byte) *C.byte {
  type sigGetterP2 (line 539) | type sigGetterP2
  type pkGetterP1 (line 540) | type pkGetterP1
  function coreAggregateVerifyPkInG1 (line 650) | func coreAggregateVerifyPkInG1(sigFn sigGetterP2, sigGroupcheck bool,
  function CoreVerifyPkInG1 (line 759) | func CoreVerifyPkInG1(pk *P1Affine, sig *P2Affine, hash_or_encode bool,
  type mulAggGetterPkInG1 (line 840) | type mulAggGetterPkInG1
  function multipleAggregateVerifyPkInG1 (line 843) | func multipleAggregateVerifyPkInG1(paramsFn mulAggGetterPkInG1,
  type aggGetterP2 (line 929) | type aggGetterP2
  type P2Aggregate (line 930) | type P2Aggregate struct
    method Aggregate (line 935) | func (agg *P2Aggregate) Aggregate(elmts []*P2Affine,
    method AggregateWithRandomness (line 944) | func (agg *P2Aggregate) AggregateWithRandomness(pointsIf interface{},
    method AggregateCompressed (line 954) | func (agg *P2Aggregate) AggregateCompressed(elmts [][]byte,
    method AddAggregate (line 969) | func (agg *P2Aggregate) AddAggregate(other *P2Aggregate) {
    method Add (line 979) | func (agg *P2Aggregate) Add(elmt *P2Affine, groupcheck bool) bool {
    method ToAffine (line 992) | func (agg *P2Aggregate) ToAffine() *P2Affine {
    method coreAggregate (line 999) | func (agg *P2Aggregate) coreAggregate(getter aggGetterP2, groupcheck b...
  type sigGetterP1 (line 1139) | type sigGetterP1
  type pkGetterP2 (line 1140) | type pkGetterP2
  function coreAggregateVerifyPkInG2 (line 1250) | func coreAggregateVerifyPkInG2(sigFn sigGetterP1, sigGroupcheck bool,
  function CoreVerifyPkInG2 (line 1359) | func CoreVerifyPkInG2(pk *P2Affine, sig *P1Affine, hash_or_encode bool,
  type mulAggGetterPkInG2 (line 1440) | type mulAggGetterPkInG2
  function multipleAggregateVerifyPkInG2 (line 1443) | func multipleAggregateVerifyPkInG2(paramsFn mulAggGetterPkInG2,
  type aggGetterP1 (line 1529) | type aggGetterP1
  type P1Aggregate (line 1530) | type P1Aggregate struct
    method Aggregate (line 1535) | func (agg *P1Aggregate) Aggregate(elmts []*P1Affine,
    method AggregateWithRandomness (line 1544) | func (agg *P1Aggregate) AggregateWithRandomness(pointsIf interface{},
    method AggregateCompressed (line 1554) | func (agg *P1Aggregate) AggregateCompressed(elmts [][]byte,
    method AddAggregate (line 1569) | func (agg *P1Aggregate) AddAggregate(other *P1Aggregate) {
    method Add (line 1579) | func (agg *P1Aggregate) Add(elmt *P1Affine, groupcheck bool) bool {
    method ToAffine (line 1592) | func (agg *P1Aggregate) ToAffine() *P1Affine {
    method coreAggregate (line 1599) | func (agg *P1Aggregate) coreAggregate(getter aggGetterP1, groupcheck b...
  function PairingAggregatePkInG1 (line 1686) | func PairingAggregatePkInG1(ctx Pairing, PK *P1Affine, pkValidate bool,
  function PairingMulNAggregatePkInG1 (line 1703) | func PairingMulNAggregatePkInG1(ctx Pairing, PK *P1Affine, pkValidate bool,
  function P1Generator (line 1889) | func P1Generator() *P1 {
  function HashToG1 (line 1946) | func HashToG1(msg []byte, dst []byte,
  function EncodeToG1 (line 1961) | func EncodeToG1(msg []byte, dst []byte,
  function P1sToAffine (line 1980) | func P1sToAffine(points []*P1, optional ...int) P1Affines {
  function P1AffinesAdd (line 2039) | func P1AffinesAdd(points []*P1Affine, optional ...int) *P1 {
  function P1AffinesMult (line 2096) | func P1AffinesMult(pointsIf interface{}, scalarsIf interface{}, nbits in...
  function P1AffinesValidate (line 2416) | func P1AffinesValidate(pointsIf interface{}) bool {
  function PairingAggregatePkInG2 (line 2499) | func PairingAggregatePkInG2(ctx Pairing, PK *P2Affine, pkValidate bool,
  function PairingMulNAggregatePkInG2 (line 2516) | func PairingMulNAggregatePkInG2(ctx Pairing, PK *P2Affine, pkValidate bool,
  function P2Generator (line 2702) | func P2Generator() *P2 {
  function HashToG2 (line 2759) | func HashToG2(msg []byte, dst []byte,
  function EncodeToG2 (line 2774) | func EncodeToG2(msg []byte, dst []byte,
  function P2sToAffine (line 2793) | func P2sToAffine(points []*P2, optional ...int) P2Affines {
  function P2AffinesAdd (line 2852) | func P2AffinesAdd(points []*P2Affine, optional ...int) *P2 {
  function P2AffinesMult (line 2909) | func P2AffinesMult(pointsIf interface{}, scalarsIf interface{}, nbits in...
  function P2AffinesValidate (line 3229) | func P2AffinesValidate(pointsIf interface{}) bool {
  function parseOpts (line 3314) | func parseOpts(optional ...interface{}) (augSingle []byte, aug [][]byte,
  function HashToScalar (line 3401) | func HashToScalar(msg []byte, dst []byte) *Scalar {
  function PrintBytes (line 3482) | func PrintBytes(val []byte, name string) {
  function expandMessageXmd (line 3580) | func expandMessageXmd(msg []byte, dst []byte, len_in_bytes int) []byte {
  function breakdown (line 3589) | func breakdown(nbits, window, ncpus int) (nx int, ny int, wnd int) {
  function pippenger_window_size (line 3620) | func pippenger_window_size(npoints int) int {

FILE: bindings/go/blst_htoc_test.go
  function decodeP1 (line 20) | func decodeP1(m map[string]interface{}) *P1Affine {
  function readAll (line 36) | func readAll(file *os.File) ([]byte, error) {
  function jsonG1HashToCurve (line 57) | func jsonG1HashToCurve(t *testing.T, fname string) {
  function TestG1HashToCurve (line 103) | func TestG1HashToCurve(t *testing.T) {
  function decodeP2 (line 109) | func decodeP2(m map[string]interface{}) *P2Affine {
  function jsonG2HashToCurve (line 137) | func jsonG2HashToCurve(t *testing.T, fname string) {
  function TestG2HashToCurve (line 183) | func TestG2HashToCurve(t *testing.T) {
  function jsonExpandMessageXmd (line 189) | func jsonExpandMessageXmd(t *testing.T, fname string) {
  function TestExpandMessageXmd (line 236) | func TestExpandMessageXmd(t *testing.T) {

FILE: bindings/go/blst_miller_loop_test.go
  function TestMillerLoopN (line 8) | func TestMillerLoopN(t *testing.T) {

FILE: bindings/go/blst_minpk_test.go
  function init (line 26) | func init() {
  function TestInfinityMinPk (line 31) | func TestInfinityMinPk(t *testing.T) {
  function TestSerdesMinPk (line 38) | func TestSerdesMinPk(t *testing.T) {
  function TestSignVerifyMinPk (line 84) | func TestSignVerifyMinPk(t *testing.T) {
  function TestSignVerifyAugMinPk (line 159) | func TestSignVerifyAugMinPk(t *testing.T) {
  function TestSignVerifyEncodeMinPk (line 179) | func TestSignVerifyEncodeMinPk(t *testing.T) {
  function TestSignVerifyAggregateMinPk (line 196) | func TestSignVerifyAggregateMinPk(t *testing.T) {
  function TestSignMultipleVerifyAggregateMinPk (line 250) | func TestSignMultipleVerifyAggregateMinPk(t *testing.T) {
  function TestBatchUncompressMinPk (line 330) | func TestBatchUncompressMinPk(t *testing.T) {
  function BenchmarkCoreSignMinPk (line 353) | func BenchmarkCoreSignMinPk(b *testing.B) {
  function BenchmarkCoreVerifyMinPk (line 368) | func BenchmarkCoreVerifyMinPk(b *testing.B) {
  function BenchmarkCoreVerifyAggregateMinPk (line 389) | func BenchmarkCoreVerifyAggregateMinPk(b *testing.B) {
  function BenchmarkVerifyAggregateUncompressedMinPk (line 417) | func BenchmarkVerifyAggregateUncompressedMinPk(b *testing.B) {
  function BenchmarkCoreAggregateMinPk (line 444) | func BenchmarkCoreAggregateMinPk(b *testing.B) {
  function genRandomKeyMinPk (line 469) | func genRandomKeyMinPk() *SecretKey {
  function generateBatchTestDataMinPk (line 480) | func generateBatchTestDataMinPk(size int) (msgs []Message,
  function generateBatchTestDataUncompressedMinPk (line 507) | func generateBatchTestDataUncompressedMinPk(size int) (sks []*SecretKey,
  function BenchmarkBatchUncompressMinPk (line 529) | func BenchmarkBatchUncompressMinPk(b *testing.B) {
  function TestSignVerifyAggregateValidatesInfinitePubkeyMinPk (line 562) | func TestSignVerifyAggregateValidatesInfinitePubkeyMinPk(t *testing.T) {
  function TestEmptyMessageMinPk (line 608) | func TestEmptyMessageMinPk(t *testing.T) {
  function TestEmptySignatureMinPk (line 623) | func TestEmptySignatureMinPk(t *testing.T) {
  function TestMultiScalarP1 (line 637) | func TestMultiScalarP1(t *testing.T) {
  function BenchmarkMultiScalarP1 (line 667) | func BenchmarkMultiScalarP1(b *testing.B) {
  function BenchmarkToP1Affines (line 694) | func BenchmarkToP1Affines(b *testing.B) {

FILE: bindings/go/blst_minsig_test.go
  function init (line 30) | func init() {
  function TestInfinityMinSig (line 35) | func TestInfinityMinSig(t *testing.T) {
  function TestSerdesMinSig (line 42) | func TestSerdesMinSig(t *testing.T) {
  function TestSignVerifyMinSig (line 88) | func TestSignVerifyMinSig(t *testing.T) {
  function TestSignVerifyAugMinSig (line 163) | func TestSignVerifyAugMinSig(t *testing.T) {
  function TestSignVerifyEncodeMinSig (line 183) | func TestSignVerifyEncodeMinSig(t *testing.T) {
  function TestSignVerifyAggregateMinSig (line 200) | func TestSignVerifyAggregateMinSig(t *testing.T) {
  function TestSignMultipleVerifyAggregateMinSig (line 254) | func TestSignMultipleVerifyAggregateMinSig(t *testing.T) {
  function TestBatchUncompressMinSig (line 334) | func TestBatchUncompressMinSig(t *testing.T) {
  function BenchmarkCoreSignMinSig (line 357) | func BenchmarkCoreSignMinSig(b *testing.B) {
  function BenchmarkCoreVerifyMinSig (line 372) | func BenchmarkCoreVerifyMinSig(b *testing.B) {
  function BenchmarkCoreVerifyAggregateMinSig (line 393) | func BenchmarkCoreVerifyAggregateMinSig(b *testing.B) {
  function BenchmarkVerifyAggregateUncompressedMinSig (line 421) | func BenchmarkVerifyAggregateUncompressedMinSig(b *testing.B) {
  function BenchmarkCoreAggregateMinSig (line 448) | func BenchmarkCoreAggregateMinSig(b *testing.B) {
  function genRandomKeyMinSig (line 473) | func genRandomKeyMinSig() *SecretKey {
  function generateBatchTestDataMinSig (line 484) | func generateBatchTestDataMinSig(size int) (msgs []Message,
  function generateBatchTestDataUncompressedMinSig (line 511) | func generateBatchTestDataUncompressedMinSig(size int) (sks []*SecretKey,
  function BenchmarkBatchUncompressMinSig (line 533) | func BenchmarkBatchUncompressMinSig(b *testing.B) {
  function TestSignVerifyAggregateValidatesInfinitePubkeyMinSig (line 566) | func TestSignVerifyAggregateValidatesInfinitePubkeyMinSig(t *testing.T) {
  function TestEmptyMessageMinSig (line 612) | func TestEmptyMessageMinSig(t *testing.T) {
  function TestEmptySignatureMinSig (line 627) | func TestEmptySignatureMinSig(t *testing.T) {
  function TestMultiScalarP2 (line 641) | func TestMultiScalarP2(t *testing.T) {
  function BenchmarkMultiScalarP2 (line 671) | func BenchmarkMultiScalarP2(b *testing.B) {
  function BenchmarkToP2Affines (line 698) | func BenchmarkToP2Affines(b *testing.B) {

FILE: bindings/go/generate.py
  function concatFile (line 34) | def concatFile(fout, fin, removeImports):
  function remap (line 43) | def remap(fout, fin, mapping, dont_touch, removeImports):

FILE: bindings/go/rb_tree.go
  constant red (line 21) | red, black bool = true, false
  type node (line 23) | type node struct
  type rbTree (line 29) | type rbTree struct
    method insert (line 35) | func (tree *rbTree) insert(data *[]byte) bool {
  function Uniq (line 134) | func Uniq(msgs []Message) bool {

FILE: bindings/rust/benches/blst_benches.rs
  type BenchData (line 14) | struct BenchData {
  function gen_bench_data (line 22) | fn gen_bench_data(rng: &mut rand_chacha::ChaCha20Rng) -> BenchData {
  function gen_bench_data_for_msg (line 30) | fn gen_bench_data_for_msg(
  function bench_verify_multi_aggregate (line 55) | fn bench_verify_multi_aggregate(c: &mut Criterion) {
  function bench_fast_aggregate_verify (line 150) | fn bench_fast_aggregate_verify(c: &mut Criterion) {
  function bench_aggregate_verify (line 221) | fn bench_aggregate_verify(c: &mut Criterion) {
  function bench_aggregate (line 275) | fn bench_aggregate(c: &mut Criterion) {
  function bench_single_message (line 318) | fn bench_single_message(c: &mut Criterion) {
  function bench_serdes (line 336) | fn bench_serdes(c: &mut Criterion) {
  function bench_keys (line 442) | fn bench_keys(c: &mut Criterion) {

FILE: bindings/rust/build.rs
  function assembly (line 8) | fn assembly(
  function main (line 33) | fn main() {

FILE: bindings/rust/src/bindings.rs
  type BLST_ERROR (line 5) | pub enum BLST_ERROR {
  type byte (line 15) | pub type byte = u8;
  type limb_t (line 16) | pub type limb_t = u64;
  type blst_scalar (line 20) | pub struct blst_scalar {
  function bindgen_test_layout_blst_scalar (line 24) | fn bindgen_test_layout_blst_scalar() {
  type blst_fr (line 50) | pub struct blst_fr {
  function bindgen_test_layout_blst_fr (line 54) | fn bindgen_test_layout_blst_fr() {
  type blst_fp (line 80) | pub struct blst_fp {
  function bindgen_test_layout_blst_fp (line 84) | fn bindgen_test_layout_blst_fp() {
  type blst_fp2 (line 110) | pub struct blst_fp2 {
  function bindgen_test_layout_blst_fp2 (line 114) | fn bindgen_test_layout_blst_fp2() {
  type blst_fp6 (line 140) | pub struct blst_fp6 {
  function bindgen_test_layout_blst_fp6 (line 144) | fn bindgen_test_layout_blst_fp6() {
  type blst_fp12 (line 170) | pub struct blst_fp12 {
  function bindgen_test_layout_blst_fp12 (line 174) | fn bindgen_test_layout_blst_fp12() {
  function blst_scalar_from_uint32 (line 199) | pub fn blst_scalar_from_uint32(out: *mut blst_scalar, a: *const u32);
  function blst_uint32_from_scalar (line 202) | pub fn blst_uint32_from_scalar(out: *mut u32, a: *const blst_scalar);
  function blst_scalar_from_uint64 (line 205) | pub fn blst_scalar_from_uint64(out: *mut blst_scalar, a: *const u64);
  function blst_uint64_from_scalar (line 208) | pub fn blst_uint64_from_scalar(out: *mut u64, a: *const blst_scalar);
  function blst_scalar_from_bendian (line 211) | pub fn blst_scalar_from_bendian(out: *mut blst_scalar, a: *const byte);
  function blst_bendian_from_scalar (line 214) | pub fn blst_bendian_from_scalar(out: *mut byte, a: *const blst_scalar);
  function blst_scalar_from_lendian (line 217) | pub fn blst_scalar_from_lendian(out: *mut blst_scalar, a: *const byte);
  function blst_lendian_from_scalar (line 220) | pub fn blst_lendian_from_scalar(out: *mut byte, a: *const blst_scalar);
  function blst_scalar_fr_check (line 223) | pub fn blst_scalar_fr_check(a: *const blst_scalar) -> bool;
  function blst_sk_check (line 226) | pub fn blst_sk_check(a: *const blst_scalar) -> bool;
  function blst_sk_add_n_check (line 229) | pub fn blst_sk_add_n_check(
  function blst_sk_sub_n_check (line 236) | pub fn blst_sk_sub_n_check(
  function blst_sk_mul_n_check (line 243) | pub fn blst_sk_mul_n_check(
  function blst_sk_inverse (line 250) | pub fn blst_sk_inverse(out: *mut blst_scalar, a: *const blst_scalar);
  function blst_scalar_from_le_bytes (line 253) | pub fn blst_scalar_from_le_bytes(out: *mut blst_scalar, in_: *const byte...
  function blst_scalar_from_be_bytes (line 256) | pub fn blst_scalar_from_be_bytes(out: *mut blst_scalar, in_: *const byte...
  function blst_fr_add (line 259) | pub fn blst_fr_add(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_...
  function blst_fr_sub (line 262) | pub fn blst_fr_sub(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_...
  function blst_fr_mul_by_3 (line 265) | pub fn blst_fr_mul_by_3(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fr_lshift (line 268) | pub fn blst_fr_lshift(ret: *mut blst_fr, a: *const blst_fr, count: usize);
  function blst_fr_rshift (line 271) | pub fn blst_fr_rshift(ret: *mut blst_fr, a: *const blst_fr, count: usize);
  function blst_fr_mul (line 274) | pub fn blst_fr_mul(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_...
  function blst_fr_sqr (line 277) | pub fn blst_fr_sqr(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fr_cneg (line 280) | pub fn blst_fr_cneg(ret: *mut blst_fr, a: *const blst_fr, flag: bool);
  function blst_fr_eucl_inverse (line 283) | pub fn blst_fr_eucl_inverse(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fr_inverse (line 286) | pub fn blst_fr_inverse(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fr_from_uint64 (line 289) | pub fn blst_fr_from_uint64(ret: *mut blst_fr, a: *const u64);
  function blst_uint64_from_fr (line 292) | pub fn blst_uint64_from_fr(ret: *mut u64, a: *const blst_fr);
  function blst_fr_from_scalar (line 295) | pub fn blst_fr_from_scalar(ret: *mut blst_fr, a: *const blst_scalar);
  function blst_scalar_from_fr (line 298) | pub fn blst_scalar_from_fr(ret: *mut blst_scalar, a: *const blst_fr);
  function blst_fp_add (line 301) | pub fn blst_fp_add(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_...
  function blst_fp_sub (line 304) | pub fn blst_fp_sub(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_...
  function blst_fp_mul_by_3 (line 307) | pub fn blst_fp_mul_by_3(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_mul_by_8 (line 310) | pub fn blst_fp_mul_by_8(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_lshift (line 313) | pub fn blst_fp_lshift(ret: *mut blst_fp, a: *const blst_fp, count: usize);
  function blst_fp_mul (line 316) | pub fn blst_fp_mul(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_...
  function blst_fp_sqr (line 319) | pub fn blst_fp_sqr(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_cneg (line 322) | pub fn blst_fp_cneg(ret: *mut blst_fp, a: *const blst_fp, flag: bool);
  function blst_fp_eucl_inverse (line 325) | pub fn blst_fp_eucl_inverse(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_inverse (line 328) | pub fn blst_fp_inverse(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_sqrt (line 331) | pub fn blst_fp_sqrt(ret: *mut blst_fp, a: *const blst_fp) -> bool;
  function blst_fp_from_uint32 (line 334) | pub fn blst_fp_from_uint32(ret: *mut blst_fp, a: *const u32);
  function blst_uint32_from_fp (line 337) | pub fn blst_uint32_from_fp(ret: *mut u32, a: *const blst_fp);
  function blst_fp_from_uint64 (line 340) | pub fn blst_fp_from_uint64(ret: *mut blst_fp, a: *const u64);
  function blst_uint64_from_fp (line 343) | pub fn blst_uint64_from_fp(ret: *mut u64, a: *const blst_fp);
  function blst_fp_from_bendian (line 346) | pub fn blst_fp_from_bendian(ret: *mut blst_fp, a: *const byte);
  function blst_bendian_from_fp (line 349) | pub fn blst_bendian_from_fp(ret: *mut byte, a: *const blst_fp);
  function blst_fp_from_lendian (line 352) | pub fn blst_fp_from_lendian(ret: *mut blst_fp, a: *const byte);
  function blst_lendian_from_fp (line 355) | pub fn blst_lendian_from_fp(ret: *mut byte, a: *const blst_fp);
  function blst_fp2_add (line 358) | pub fn blst_fp2_add(ret: *mut blst_fp2, a: *const blst_fp2, b: *const bl...
  function blst_fp2_sub (line 361) | pub fn blst_fp2_sub(ret: *mut blst_fp2, a: *const blst_fp2, b: *const bl...
  function blst_fp2_mul_by_3 (line 364) | pub fn blst_fp2_mul_by_3(ret: *mut blst_fp2, a: *const blst_fp2);
  function blst_fp2_mul_by_8 (line 367) | pub fn blst_fp2_mul_by_8(ret: *mut blst_fp2, a: *const blst_fp2);
  function blst_fp2_lshift (line 370) | pub fn blst_fp2_lshift(ret: *mut blst_fp2, a: *const blst_fp2, count: us...
  function blst_fp2_mul (line 373) | pub fn blst_fp2_mul(ret: *mut blst_fp2, a: *const blst_fp2, b: *const bl...
  function blst_fp2_sqr (line 376) | pub fn blst_fp2_sqr(ret: *mut blst_fp2, a: *const blst_fp2);
  function blst_fp2_cneg (line 379) | pub fn blst_fp2_cneg(ret: *mut blst_fp2, a: *const blst_fp2, flag: bool);
  function blst_fp2_eucl_inverse (line 382) | pub fn blst_fp2_eucl_inverse(ret: *mut blst_fp2, a: *const blst_fp2);
  function blst_fp2_inverse (line 385) | pub fn blst_fp2_inverse(ret: *mut blst_fp2, a: *const blst_fp2);
  function blst_fp2_sqrt (line 388) | pub fn blst_fp2_sqrt(ret: *mut blst_fp2, a: *const blst_fp2) -> bool;
  function blst_fp12_sqr (line 391) | pub fn blst_fp12_sqr(ret: *mut blst_fp12, a: *const blst_fp12);
  function blst_fp12_cyclotomic_sqr (line 394) | pub fn blst_fp12_cyclotomic_sqr(ret: *mut blst_fp12, a: *const blst_fp12);
  function blst_fp12_mul (line 397) | pub fn blst_fp12_mul(ret: *mut blst_fp12, a: *const blst_fp12, b: *const...
  function blst_fp12_mul_by_xy00z0 (line 400) | pub fn blst_fp12_mul_by_xy00z0(
  function blst_fp12_conjugate (line 407) | pub fn blst_fp12_conjugate(a: *mut blst_fp12);
  function blst_fp12_inverse (line 410) | pub fn blst_fp12_inverse(ret: *mut blst_fp12, a: *const blst_fp12);
  function blst_fp12_frobenius_map (line 413) | pub fn blst_fp12_frobenius_map(ret: *mut blst_fp12, a: *const blst_fp12,...
  function blst_fp12_is_equal (line 416) | pub fn blst_fp12_is_equal(a: *const blst_fp12, b: *const blst_fp12) -> b...
  function blst_fp12_is_one (line 419) | pub fn blst_fp12_is_one(a: *const blst_fp12) -> bool;
  function blst_fp12_in_group (line 422) | pub fn blst_fp12_in_group(a: *const blst_fp12) -> bool;
  function blst_fp12_one (line 425) | pub fn blst_fp12_one() -> *const blst_fp12;
  type blst_p1 (line 429) | pub struct blst_p1 {
  function bindgen_test_layout_blst_p1 (line 435) | fn bindgen_test_layout_blst_p1() {
  type blst_p1_affine (line 481) | pub struct blst_p1_affine {
  function bindgen_test_layout_blst_p1_affine (line 486) | fn bindgen_test_layout_blst_p1_affine() {
  function blst_p1_add (line 521) | pub fn blst_p1_add(out: *mut blst_p1, a: *const blst_p1, b: *const blst_...
  function blst_p1_add_or_double (line 524) | pub fn blst_p1_add_or_double(out: *mut blst_p1, a: *const blst_p1, b: *c...
  function blst_p1_add_affine (line 527) | pub fn blst_p1_add_affine(out: *mut blst_p1, a: *const blst_p1, b: *cons...
  function blst_p1_add_or_double_affine (line 530) | pub fn blst_p1_add_or_double_affine(
  function blst_p1_double (line 537) | pub fn blst_p1_double(out: *mut blst_p1, a: *const blst_p1);
  function blst_p1_mult (line 540) | pub fn blst_p1_mult(out: *mut blst_p1, p: *const blst_p1, scalar: *const...
  function blst_p1_cneg (line 543) | pub fn blst_p1_cneg(p: *mut blst_p1, cbit: bool);
  function blst_p1_to_affine (line 546) | pub fn blst_p1_to_affine(out: *mut blst_p1_affine, in_: *const blst_p1);
  function blst_p1_from_affine (line 549) | pub fn blst_p1_from_affine(out: *mut blst_p1, in_: *const blst_p1_affine);
  function blst_p1_on_curve (line 552) | pub fn blst_p1_on_curve(p: *const blst_p1) -> bool;
  function blst_p1_in_g1 (line 555) | pub fn blst_p1_in_g1(p: *const blst_p1) -> bool;
  function blst_p1_is_equal (line 558) | pub fn blst_p1_is_equal(a: *const blst_p1, b: *const blst_p1) -> bool;
  function blst_p1_is_inf (line 561) | pub fn blst_p1_is_inf(a: *const blst_p1) -> bool;
  function blst_p1_generator (line 564) | pub fn blst_p1_generator() -> *const blst_p1;
  function blst_p1_affine_on_curve (line 567) | pub fn blst_p1_affine_on_curve(p: *const blst_p1_affine) -> bool;
  function blst_p1_affine_in_g1 (line 570) | pub fn blst_p1_affine_in_g1(p: *const blst_p1_affine) -> bool;
  function blst_p1_affine_is_equal (line 573) | pub fn blst_p1_affine_is_equal(a: *const blst_p1_affine, b: *const blst_...
  function blst_p1_affine_is_inf (line 576) | pub fn blst_p1_affine_is_inf(a: *const blst_p1_affine) -> bool;
  function blst_p1_affine_generator (line 579) | pub fn blst_p1_affine_generator() -> *const blst_p1_affine;
  type blst_p2 (line 583) | pub struct blst_p2 {
  function bindgen_test_layout_blst_p2 (line 589) | fn bindgen_test_layout_blst_p2() {
  type blst_p2_affine (line 635) | pub struct blst_p2_affine {
  function bindgen_test_layout_blst_p2_affine (line 640) | fn bindgen_test_layout_blst_p2_affine() {
  function blst_p2_add (line 675) | pub fn blst_p2_add(out: *mut blst_p2, a: *const blst_p2, b: *const blst_...
  function blst_p2_add_or_double (line 678) | pub fn blst_p2_add_or_double(out: *mut blst_p2, a: *const blst_p2, b: *c...
  function blst_p2_add_affine (line 681) | pub fn blst_p2_add_affine(out: *mut blst_p2, a: *const blst_p2, b: *cons...
  function blst_p2_add_or_double_affine (line 684) | pub fn blst_p2_add_or_double_affine(
  function blst_p2_double (line 691) | pub fn blst_p2_double(out: *mut blst_p2, a: *const blst_p2);
  function blst_p2_mult (line 694) | pub fn blst_p2_mult(out: *mut blst_p2, p: *const blst_p2, scalar: *const...
  function blst_p2_cneg (line 697) | pub fn blst_p2_cneg(p: *mut blst_p2, cbit: bool);
  function blst_p2_to_affine (line 700) | pub fn blst_p2_to_affine(out: *mut blst_p2_affine, in_: *const blst_p2);
  function blst_p2_from_affine (line 703) | pub fn blst_p2_from_affine(out: *mut blst_p2, in_: *const blst_p2_affine);
  function blst_p2_on_curve (line 706) | pub fn blst_p2_on_curve(p: *const blst_p2) -> bool;
  function blst_p2_in_g2 (line 709) | pub fn blst_p2_in_g2(p: *const blst_p2) -> bool;
  function blst_p2_is_equal (line 712) | pub fn blst_p2_is_equal(a: *const blst_p2, b: *const blst_p2) -> bool;
  function blst_p2_is_inf (line 715) | pub fn blst_p2_is_inf(a: *const blst_p2) -> bool;
  function blst_p2_generator (line 718) | pub fn blst_p2_generator() -> *const blst_p2;
  function blst_p2_affine_on_curve (line 721) | pub fn blst_p2_affine_on_curve(p: *const blst_p2_affine) -> bool;
  function blst_p2_affine_in_g2 (line 724) | pub fn blst_p2_affine_in_g2(p: *const blst_p2_affine) -> bool;
  function blst_p2_affine_is_equal (line 727) | pub fn blst_p2_affine_is_equal(a: *const blst_p2_affine, b: *const blst_...
  function blst_p2_affine_is_inf (line 730) | pub fn blst_p2_affine_is_inf(a: *const blst_p2_affine) -> bool;
  function blst_p2_affine_generator (line 733) | pub fn blst_p2_affine_generator() -> *const blst_p2_affine;
  function blst_p1s_to_affine (line 736) | pub fn blst_p1s_to_affine(
  function blst_p1s_add (line 743) | pub fn blst_p1s_add(ret: *mut blst_p1, points: *const *const blst_p1_aff...
  function blst_p1s_mult_wbits_precompute_sizeof (line 746) | pub fn blst_p1s_mult_wbits_precompute_sizeof(wbits: usize, npoints: usiz...
  function blst_p1s_mult_wbits_precompute (line 749) | pub fn blst_p1s_mult_wbits_precompute(
  function blst_p1s_mult_wbits_scratch_sizeof (line 757) | pub fn blst_p1s_mult_wbits_scratch_sizeof(npoints: usize) -> usize;
  function blst_p1s_mult_wbits (line 760) | pub fn blst_p1s_mult_wbits(
  function blst_p1s_mult_pippenger_scratch_sizeof (line 771) | pub fn blst_p1s_mult_pippenger_scratch_sizeof(npoints: usize) -> usize;
  function blst_p1s_mult_pippenger (line 774) | pub fn blst_p1s_mult_pippenger(
  function blst_p1s_tile_pippenger (line 784) | pub fn blst_p1s_tile_pippenger(
  function blst_p2s_to_affine (line 796) | pub fn blst_p2s_to_affine(
  function blst_p2s_add (line 803) | pub fn blst_p2s_add(ret: *mut blst_p2, points: *const *const blst_p2_aff...
  function blst_p2s_mult_wbits_precompute_sizeof (line 806) | pub fn blst_p2s_mult_wbits_precompute_sizeof(wbits: usize, npoints: usiz...
  function blst_p2s_mult_wbits_precompute (line 809) | pub fn blst_p2s_mult_wbits_precompute(
  function blst_p2s_mult_wbits_scratch_sizeof (line 817) | pub fn blst_p2s_mult_wbits_scratch_sizeof(npoints: usize) -> usize;
  function blst_p2s_mult_wbits (line 820) | pub fn blst_p2s_mult_wbits(
  function blst_p2s_mult_pippenger_scratch_sizeof (line 831) | pub fn blst_p2s_mult_pippenger_scratch_sizeof(npoints: usize) -> usize;
  function blst_p2s_mult_pippenger (line 834) | pub fn blst_p2s_mult_pippenger(
  function blst_p2s_tile_pippenger (line 844) | pub fn blst_p2s_tile_pippenger(
  function blst_map_to_g1 (line 856) | pub fn blst_map_to_g1(out: *mut blst_p1, u: *const blst_fp, v: *const bl...
  function blst_map_to_g2 (line 859) | pub fn blst_map_to_g2(out: *mut blst_p2, u: *const blst_fp2, v: *const b...
  function blst_encode_to_g1 (line 862) | pub fn blst_encode_to_g1(
  function blst_hash_to_g1 (line 873) | pub fn blst_hash_to_g1(
  function blst_encode_to_g2 (line 884) | pub fn blst_encode_to_g2(
  function blst_hash_to_g2 (line 895) | pub fn blst_hash_to_g2(
  function blst_p1_serialize (line 906) | pub fn blst_p1_serialize(out: *mut byte, in_: *const blst_p1);
  function blst_p1_compress (line 909) | pub fn blst_p1_compress(out: *mut byte, in_: *const blst_p1);
  function blst_p1_affine_serialize (line 912) | pub fn blst_p1_affine_serialize(out: *mut byte, in_: *const blst_p1_affi...
  function blst_p1_affine_compress (line 915) | pub fn blst_p1_affine_compress(out: *mut byte, in_: *const blst_p1_affine);
  function blst_p1_uncompress (line 918) | pub fn blst_p1_uncompress(out: *mut blst_p1_affine, in_: *const byte) ->...
  function blst_p1_deserialize (line 921) | pub fn blst_p1_deserialize(out: *mut blst_p1_affine, in_: *const byte) -...
  function blst_p2_serialize (line 924) | pub fn blst_p2_serialize(out: *mut byte, in_: *const blst_p2);
  function blst_p2_compress (line 927) | pub fn blst_p2_compress(out: *mut byte, in_: *const blst_p2);
  function blst_p2_affine_serialize (line 930) | pub fn blst_p2_affine_serialize(out: *mut byte, in_: *const blst_p2_affi...
  function blst_p2_affine_compress (line 933) | pub fn blst_p2_affine_compress(out: *mut byte, in_: *const blst_p2_affine);
  function blst_p2_uncompress (line 936) | pub fn blst_p2_uncompress(out: *mut blst_p2_affine, in_: *const byte) ->...
  function blst_p2_deserialize (line 939) | pub fn blst_p2_deserialize(out: *mut blst_p2_affine, in_: *const byte) -...
  function blst_keygen (line 942) | pub fn blst_keygen(
  function blst_sk_to_pk_in_g1 (line 951) | pub fn blst_sk_to_pk_in_g1(out_pk: *mut blst_p1, SK: *const blst_scalar);
  function blst_sign_pk_in_g1 (line 954) | pub fn blst_sign_pk_in_g1(out_sig: *mut blst_p2, hash: *const blst_p2, S...
  function blst_sk_to_pk_in_g2 (line 957) | pub fn blst_sk_to_pk_in_g2(out_pk: *mut blst_p2, SK: *const blst_scalar);
  function blst_sign_pk_in_g2 (line 960) | pub fn blst_sign_pk_in_g2(out_sig: *mut blst_p1, hash: *const blst_p1, S...
  function blst_miller_loop (line 963) | pub fn blst_miller_loop(
  function blst_miller_loop_n (line 970) | pub fn blst_miller_loop_n(
  function blst_final_exp (line 978) | pub fn blst_final_exp(ret: *mut blst_fp12, f: *const blst_fp12);
  function blst_precompute_lines (line 981) | pub fn blst_precompute_lines(Qlines: *mut blst_fp6, Q: *const blst_p2_af...
  function blst_miller_loop_lines (line 984) | pub fn blst_miller_loop_lines(
  function blst_fp12_finalverify (line 991) | pub fn blst_fp12_finalverify(gt1: *const blst_fp12, gt2: *const blst_fp1...
  type blst_pairing (line 996) | pub struct blst_pairing {
  function bindgen_test_layout_blst_pairing (line 1000) | fn bindgen_test_layout_blst_pairing() {
  function blst_pairing_sizeof (line 1013) | pub fn blst_pairing_sizeof() -> usize;
  function blst_pairing_init (line 1016) | pub fn blst_pairing_init(
  function blst_pairing_get_dst (line 1024) | pub fn blst_pairing_get_dst(ctx: *const blst_pairing) -> *const byte;
  function blst_pairing_commit (line 1027) | pub fn blst_pairing_commit(ctx: *mut blst_pairing);
  function blst_pairing_aggregate_pk_in_g2 (line 1030) | pub fn blst_pairing_aggregate_pk_in_g2(
  function blst_pairing_chk_n_aggr_pk_in_g2 (line 1041) | pub fn blst_pairing_chk_n_aggr_pk_in_g2(
  function blst_pairing_mul_n_aggregate_pk_in_g2 (line 1054) | pub fn blst_pairing_mul_n_aggregate_pk_in_g2(
  function blst_pairing_chk_n_mul_n_aggr_pk_in_g2 (line 1067) | pub fn blst_pairing_chk_n_mul_n_aggr_pk_in_g2(
  function blst_pairing_aggregate_pk_in_g1 (line 1082) | pub fn blst_pairing_aggregate_pk_in_g1(
  function blst_pairing_chk_n_aggr_pk_in_g1 (line 1093) | pub fn blst_pairing_chk_n_aggr_pk_in_g1(
  function blst_pairing_mul_n_aggregate_pk_in_g1 (line 1106) | pub fn blst_pairing_mul_n_aggregate_pk_in_g1(
  function blst_pairing_chk_n_mul_n_aggr_pk_in_g1 (line 1119) | pub fn blst_pairing_chk_n_mul_n_aggr_pk_in_g1(
  function blst_pairing_merge (line 1134) | pub fn blst_pairing_merge(ctx: *mut blst_pairing, ctx1: *const blst_pair...
  function blst_pairing_finalverify (line 1137) | pub fn blst_pairing_finalverify(ctx: *const blst_pairing, gtsig: *const ...
  function blst_aggregate_in_g1 (line 1140) | pub fn blst_aggregate_in_g1(
  function blst_aggregate_in_g2 (line 1147) | pub fn blst_aggregate_in_g2(
  function blst_aggregated_in_g1 (line 1154) | pub fn blst_aggregated_in_g1(out: *mut blst_fp12, signature: *const blst...
  function blst_aggregated_in_g2 (line 1157) | pub fn blst_aggregated_in_g2(out: *mut blst_fp12, signature: *const blst...
  function blst_core_verify_pk_in_g1 (line 1160) | pub fn blst_core_verify_pk_in_g1(
  function blst_core_verify_pk_in_g2 (line 1173) | pub fn blst_core_verify_pk_in_g2(
  function blst_fr_ct_bfly (line 1198) | pub fn blst_fr_ct_bfly(x0: *mut blst_fr, x1: *mut blst_fr, twiddle: *con...
  function blst_fr_gs_bfly (line 1201) | pub fn blst_fr_gs_bfly(x0: *mut blst_fr, x1: *mut blst_fr, twiddle: *con...
  function blst_fr_to (line 1204) | pub fn blst_fr_to(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fr_from (line 1207) | pub fn blst_fr_from(ret: *mut blst_fr, a: *const blst_fr);
  function blst_fp_to (line 1210) | pub fn blst_fp_to(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_from (line 1213) | pub fn blst_fp_from(ret: *mut blst_fp, a: *const blst_fp);
  function blst_fp_is_square (line 1216) | pub fn blst_fp_is_square(a: *const blst_fp) -> bool;
  function blst_fp2_is_square (line 1219) | pub fn blst_fp2_is_square(a: *const blst_fp2) -> bool;
  function blst_p1_from_jacobian (line 1222) | pub fn blst_p1_from_jacobian(out: *mut blst_p1, in_: *const blst_p1);
  function blst_p2_from_jacobian (line 1225) | pub fn blst_p2_from_jacobian(out: *mut blst_p2, in_: *const blst_p2);
  function blst_sk_to_pk2_in_g1 (line 1228) | pub fn blst_sk_to_pk2_in_g1(
  function blst_sign_pk2_in_g1 (line 1235) | pub fn blst_sign_pk2_in_g1(
  function blst_sk_to_pk2_in_g2 (line 1243) | pub fn blst_sk_to_pk2_in_g2(
  function blst_sign_pk2_in_g2 (line 1250) | pub fn blst_sign_pk2_in_g2(
  type blst_uniq (line 1260) | pub struct blst_uniq {
  function bindgen_test_layout_blst_uniq (line 1264) | fn bindgen_test_layout_blst_uniq() {
  function blst_uniq_sizeof (line 1277) | pub fn blst_uniq_sizeof(n_nodes: usize) -> usize;
  function blst_uniq_init (line 1280) | pub fn blst_uniq_init(tree: *mut blst_uniq);
  function blst_uniq_test (line 1283) | pub fn blst_uniq_test(tree: *mut blst_uniq, msg: *const byte, len: usize...
  function blst_expand_message_xmd (line 1286) | pub fn blst_expand_message_xmd(
  function blst_p1_unchecked_mult (line 1296) | pub fn blst_p1_unchecked_mult(
  function blst_p2_unchecked_mult (line 1304) | pub fn blst_p2_unchecked_mult(
  function blst_pairing_raw_aggregate (line 1312) | pub fn blst_pairing_raw_aggregate(
  function blst_pairing_as_fp12 (line 1319) | pub fn blst_pairing_as_fp12(ctx: *mut blst_pairing) -> *mut blst_fp12;
  function blst_bendian_from_fp12 (line 1322) | pub fn blst_bendian_from_fp12(out: *mut byte, a: *const blst_fp12);
  function blst_keygen_v3 (line 1325) | pub fn blst_keygen_v3(
  function blst_keygen_v4_5 (line 1334) | pub fn blst_keygen_v4_5(
  function blst_keygen_v5 (line 1345) | pub fn blst_keygen_v5(
  function blst_derive_master_eip2333 (line 1356) | pub fn blst_derive_master_eip2333(out_SK: *mut blst_scalar, IKM: *const ...
  function blst_derive_child_eip2333 (line 1359) | pub fn blst_derive_child_eip2333(
  function blst_scalar_from_hexascii (line 1366) | pub fn blst_scalar_from_hexascii(out: *mut blst_scalar, hex: *const byte);
  function blst_fr_from_hexascii (line 1369) | pub fn blst_fr_from_hexascii(ret: *mut blst_fr, hex: *const byte);
  function blst_fp_from_hexascii (line 1372) | pub fn blst_fp_from_hexascii(ret: *mut blst_fp, hex: *const byte);
  function blst_p1_sizeof (line 1375) | pub fn blst_p1_sizeof() -> usize;
  function blst_p1_affine_sizeof (line 1378) | pub fn blst_p1_affine_sizeof() -> usize;
  function blst_p2_sizeof (line 1381) | pub fn blst_p2_sizeof() -> usize;
  function blst_p2_affine_sizeof (line 1384) | pub fn blst_p2_affine_sizeof() -> usize;
  function blst_fp12_sizeof (line 1387) | pub fn blst_fp12_sizeof() -> usize;
  function blst_fp_from_le_bytes (line 1390) | pub fn blst_fp_from_le_bytes(ret: *mut blst_fp, in_: *const byte, len: u...
  function blst_fp_from_be_bytes (line 1393) | pub fn blst_fp_from_be_bytes(ret: *mut blst_fp, in_: *const byte, len: u...
  function blst_sha256 (line 1396) | pub fn blst_sha256(out: *mut byte, msg: *const byte, msg_len: usize);
  function bindgen_test_normal_types (line 1399) | fn bindgen_test_normal_types() {

FILE: bindings/rust/src/lib.rs
  type ThreadPoolExt (line 28) | trait ThreadPoolExt {
    method joined_execute (line 29) | fn joined_execute<'any, F>(&self, job: F)
    method joined_execute (line 54) | fn joined_execute<'scope, F>(&self, job: F)
    method joined_execute (line 84) | fn joined_execute<'scope, F>(&self, job: F)
  function da_pool (line 40) | pub fn da_pool() -> ThreadPool {
  type Thunk (line 51) | type Thunk<'any> = Box<dyn FnOnce() + Send + 'any>;
  type EmptyPool (line 71) | pub struct EmptyPool {}
    method max_count (line 78) | pub fn max_count(&self) -> usize {
  function da_pool (line 73) | pub fn da_pool() -> EmptyPool {
  method eq (line 96) | fn eq(&self, other: &Self) -> bool {
  method eq (line 102) | fn eq(&self, other: &Self) -> bool {
  method eq (line 108) | fn eq(&self, other: &Self) -> bool {
  method eq (line 114) | fn eq(&self, other: &Self) -> bool {
  method default (line 120) | fn default() -> Self {
  method eq (line 126) | fn eq(&self, other: &Self) -> bool {
  type Output (line 132) | type Output = Self;
  method mul (line 134) | fn mul(self, other: Self) -> Self {
  method mul_assign (line 144) | fn mul_assign(&mut self, other: Self) {
  method miller_loop (line 150) | pub fn miller_loop(q: &blst_p2_affine, p: &blst_p1_affine) -> Self {
  method miller_loop_n (line 159) | pub fn miller_loop_n(q: &[blst_p2_affine], p: &[blst_p1_affine]) -> Self {
  method miller_loop_n (line 174) | pub fn miller_loop_n(q: &[blst_p2_affine], p: &[blst_p1_affine]) -> Self {
  method final_exp (line 233) | pub fn final_exp(&self) -> Self {
  method in_group (line 241) | pub fn in_group(&self) -> bool {
  method finalverify (line 245) | pub fn finalverify(a: &Self, b: &Self) -> bool {
  method to_bendian (line 249) | pub fn to_bendian(&self) -> [u8; 48 * 12] {
  method hash_to (line 259) | pub fn hash_to(msg: &[u8], dst: &[u8]) -> Option<Self> {
  type Pairing (line 281) | pub struct Pairing {
    method new (line 286) | pub fn new(hash_or_encode: bool, dst: &[u8]) -> Self {
    method init (line 295) | pub fn init(&mut self, hash_or_encode: bool, dst: &[u8]) {
    method ctx (line 305) | fn ctx(&mut self) -> *mut blst_pairing {
    method const_ctx (line 308) | fn const_ctx(&self) -> *const blst_pairing {
    method aggregate (line 312) | pub fn aggregate(
    method mul_n_aggregate (line 367) | pub fn mul_n_aggregate(
    method aggregated (line 427) | pub fn aggregated(gtsig: &mut blst_fp12, sig: &dyn Any) {
    method commit (line 447) | pub fn commit(&mut self) {
    method merge (line 451) | pub fn merge(&mut self, ctx1: &Self) -> BLST_ERROR {
    method finalverify (line 455) | pub fn finalverify(&self, gtsig: Option<&blst_fp12>) -> bool {
    method raw_aggregate (line 467) | pub fn raw_aggregate(&mut self, q: &blst_p2_affine, p: &blst_p1_affine) {
    method as_fp12 (line 471) | pub fn as_fp12(&mut self) -> blst_fp12 {
  function uniq (line 476) | pub fn uniq(msgs: &[&[u8]]) -> bool {
  function print_bytes (line 500) | pub fn print_bytes(bytes: &[u8], name: &str) {
  type MultiPoint (line 2286) | pub trait MultiPoint {
    method mult (line 2289) | fn mult(&self, scalars: &[u8], nbits: usize) -> Self::Output;
    method add (line 2290) | fn add(&self) -> Self::Output;
    method validate (line 2291) | fn validate(&self) -> Result<(), BLST_ERROR> {
  function miller_loop_n (line 2309) | fn miller_loop_n() {
  function inverse (line 2362) | fn inverse() {

FILE: bindings/rust/src/pippenger.rs
  type tile (line 10) | struct tile {
  type Cell (line 21) | struct Cell<T: ?Sized> {
  function as_ptr (line 26) | pub fn as_ptr(&self) -> *mut T {
  function num_bits (line 497) | fn num_bits(l: usize) -> usize {
  function breakdown (line 501) | fn breakdown(
  function pippenger_window_size (line 538) | fn pippenger_window_size(npoints: usize) -> usize {

FILE: bindings/zig/generate.py
  function xchg_1vs2 (line 396) | def xchg_1vs2(matchobj):
  function newer (line 414) | def newer(*files):

FILE: build/srcroot.go
  function init (line 10) | func init() {

FILE: build/win64/dll.c
  function BOOL (line 31) | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser...

FILE: src/aggregate.c
  type AggregatedSignature (line 43) | typedef union { POINTonE1 e1; POINTonE2 e2; } AggregatedSignature;
  type PAIRING (line 44) | typedef struct {
  function blst_pairing_sizeof (line 65) | size_t blst_pairing_sizeof(void)
  function blst_pairing_init (line 68) | void blst_pairing_init(PAIRING *ctx, int hash_or_encode,
  function BLST_ERROR (line 98) | static BLST_ERROR PAIRING_Aggregate_PK_in_G2(PAIRING *ctx,
  function BLST_ERROR (line 192) | BLST_ERROR blst_pairing_aggregate_pk_in_g2(PAIRING *ctx,
  function BLST_ERROR (line 201) | BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g2(PAIRING *ctx,
  function BLST_ERROR (line 214) | BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g2(PAIRING *ctx,
  function BLST_ERROR (line 225) | BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g2(PAIRING *ctx,
  function BLST_ERROR (line 241) | static BLST_ERROR PAIRING_Aggregate_PK_in_G1(PAIRING *ctx,
  function BLST_ERROR (line 341) | BLST_ERROR blst_pairing_aggregate_pk_in_g1(PAIRING *ctx,
  function BLST_ERROR (line 350) | BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g1(PAIRING *ctx,
  function BLST_ERROR (line 363) | BLST_ERROR blst_pairing_chk_n_aggr_pk_in_g1(PAIRING *ctx,
  function BLST_ERROR (line 374) | BLST_ERROR blst_pairing_chk_n_mul_n_aggr_pk_in_g1(PAIRING *ctx,
  function PAIRING_Commit (line 390) | static void PAIRING_Commit(PAIRING *ctx)
  function blst_pairing_commit (line 407) | void blst_pairing_commit(PAIRING *ctx)
  function BLST_ERROR (line 410) | BLST_ERROR blst_pairing_merge(PAIRING *ctx, const PAIRING *ctx1)
  function bool_t (line 460) | static bool_t PAIRING_FinalVerify(const PAIRING *ctx, const vec384fp12 G...
  function blst_pairing_finalverify (line 503) | int blst_pairing_finalverify(const PAIRING *ctx, const vec384fp12 GTsig)
  function blst_fp12_finalverify (line 506) | int blst_fp12_finalverify(const vec384fp12 GT1, const vec384fp12 GT2)
  function blst_pairing_raw_aggregate (line 520) | void blst_pairing_raw_aggregate(PAIRING *ctx, const POINTonE2_affine *q,
  function vec384fp12 (line 545) | vec384fp12 *blst_pairing_as_fp12(PAIRING *ctx)
  function BLST_ERROR (line 559) | BLST_ERROR blst_aggregate_in_g1(POINTonE1 *out, const POINTonE1 *in,
  function BLST_ERROR (line 589) | BLST_ERROR blst_aggregate_in_g2(POINTonE2 *out, const POINTonE2 *in,
  function blst_aggregated_in_g1 (line 619) | void blst_aggregated_in_g1(vec384fp12 ret, const POINTonE1_affine *sig)
  function blst_aggregated_in_g2 (line 622) | void blst_aggregated_in_g2(vec384fp12 ret, const POINTonE2_affine *sig)
  function BLST_ERROR (line 625) | BLST_ERROR blst_core_verify_pk_in_g1(const POINTonE1_affine *pk,
  function BLST_ERROR (line 650) | BLST_ERROR blst_core_verify_pk_in_g2(const POINTonE2_affine *pk,

FILE: src/blst_t.hpp
  function vec_left_align (line 33) | static inline void vec_left_align(limb_t *out, const limb_t *inp, size_t N)
  class blst_384_t (line 56) | class blst_384_t {
    method limb_t (line 62) | inline limb_t& operator[](size_t i)             { return val[i]; }
    method limb_t (line 63) | inline const limb_t& operator[](size_t i) const { return val[i]; }
    method bit_length (line 68) | static constexpr size_t bit_length() { return N; }
    method blst_384_t (line 73) | inline blst_384_t() {}
    method blst_384_t (line 74) | inline blst_384_t(const vec384 p, bool align = false)
    method blst_384_t (line 81) | inline blst_384_t(uint64_t a)
    method blst_384_t (line 87) | inline blst_384_t(int a) : blst_384_t((uint64_t)a) {}
    method blst_384_t (line 94) | constexpr blst_384_t(limb_t a0, Ts... arr)
    method blst_384_t (line 116) | constexpr blst_384_t(limb_t a0, Ts... arr) : val{a0, arr...} {}
    method to_scalar (line 119) | inline void to_scalar(pow_t& scalar) const
    method blst_384_t (line 136) | static inline const blst_384_t& one()
    method blst_384_t (line 139) | static inline blst_384_t one(bool or_zero)
    method blst_384_t (line 148) | inline blst_384_t& to()
    method blst_384_t (line 150) | inline blst_384_t& from()
    method store (line 153) | inline void store(limb_t *p) const
    method blst_384_t (line 156) | inline blst_384_t& operator+=(const blst_384_t& b)
    method blst_384_t (line 158) | inline blst_384_t operator+(const blst_384_t& a, const blst_384_t& b)
    method blst_384_t (line 165) | inline blst_384_t& operator<<=(unsigned l)
    method blst_384_t (line 167) | inline blst_384_t operator<<(const blst_384_t& a, unsigned l)
    method blst_384_t (line 174) | inline blst_384_t& operator>>=(unsigned r)
    method blst_384_t (line 176) | inline blst_384_t operator>>(const blst_384_t& a, unsigned r)
    method blst_384_t (line 183) | inline blst_384_t& operator-=(const blst_384_t& b)
    method blst_384_t (line 185) | inline blst_384_t operator-(const blst_384_t& a, const blst_384_t& b)
    method blst_384_t (line 192) | inline blst_384_t& cneg(bool flag)
    method blst_384_t (line 194) | inline blst_384_t cneg(const blst_384_t& a, bool flag)
    method blst_384_t (line 200) | inline blst_384_t operator-(const blst_384_t& a)
    method blst_384_t (line 207) | inline blst_384_t& operator*=(const blst_384_t& a)
    method blst_384_t (line 213) | inline blst_384_t operator*(const blst_384_t& a, const blst_384_t& b)
    method blst_384_t (line 222) | inline blst_384_t operator^(const blst_384_t& a, unsigned p)
    method blst_384_t (line 247) | inline blst_384_t& operator^=(unsigned p)
    method blst_384_t (line 257) | inline blst_384_t operator()(unsigned p)
    method blst_384_t (line 259) | inline blst_384_t sqr(const blst_384_t& a)
    method is_one (line 262) | inline bool is_one() const
    method is_zero (line 265) | inline int is_zero() const
    method zero (line 268) | inline void zero()
    method blst_384_t (line 271) | inline blst_384_t czero(const blst_384_t& a, int set_z)
    method blst_384_t (line 278) | static inline blst_384_t csel(const blst_384_t& a, const blst_384_t& b,
    method blst_384_t (line 285) | blst_384_t reciprocal() const
    method blst_384_t (line 296) | inline blst_384_t operator/(unsigned one, const blst_384_t& a)
    method blst_384_t (line 302) | inline blst_384_t operator/(const blst_384_t& a, const blst_384_t& b)
    method blst_384_t (line 304) | inline blst_384_t& operator/=(const blst_384_t& a)
    method blst_384_t (line 307) | inline blst_384_t(const char *hexascii)
    method OStream (line 316) | OStream& operator<<(OStream& os, const blst_384_t& obj)
  class blst_256_t (line 334) | class blst_256_t {
    method limb_t (line 339) | inline limb_t& operator[](size_t i)             { return val[i]; }
    method limb_t (line 340) | inline const limb_t& operator[](size_t i) const { return val[i]; }
    method bit_length (line 345) | static constexpr size_t bit_length() { return N; }
    method blst_256_t (line 350) | inline blst_256_t() {}
    method blst_256_t (line 351) | inline blst_256_t(const vec256 p, bool align = false)
    method blst_256_t (line 358) | inline blst_256_t(uint64_t a)
    method blst_256_t (line 364) | inline blst_256_t(int a) : blst_256_t((uint64_t)a) {}
    method blst_256_t (line 371) | constexpr blst_256_t(limb_t a0, Ts... arr)
    method blst_256_t (line 389) | constexpr blst_256_t(limb_t a0, Ts... arr) : val{a0, arr...} {}
    method to_scalar (line 392) | inline void to_scalar(pow_t& scalar) const
    method blst_256_t (line 409) | static inline const blst_256_t& one()
    method blst_256_t (line 412) | static inline blst_256_t one(bool or_zero)
    method blst_256_t (line 421) | inline blst_256_t& to()
    method blst_256_t (line 423) | inline blst_256_t& to(const uint64_t a[2*n])
    method blst_256_t (line 431) | blst_256_t& to(const unsigned char* bytes, size_t n, bool le = false)
    method blst_256_t (line 464) | inline blst_256_t& from()
    method blst_256_t (line 466) | inline blst_256_t& from(const uint64_t a[2*n])
    method blst_256_t (line 473) | inline blst_256_t& from(const unsigned char *bytes, size_t n, bool le ...
    method store (line 494) | inline void store(limb_t *p) const
    method blst_256_t (line 497) | inline blst_256_t& operator+=(const blst_256_t& b)
    method blst_256_t (line 499) | inline blst_256_t operator+(const blst_256_t& a, const blst_256_t& b)
    method blst_256_t (line 506) | inline blst_256_t& operator<<=(unsigned l)
    method blst_256_t (line 508) | inline blst_256_t operator<<(const blst_256_t& a, unsigned l)
    method blst_256_t (line 515) | inline blst_256_t& operator>>=(unsigned r)
    method blst_256_t (line 517) | inline blst_256_t operator>>(const blst_256_t& a, unsigned r)
    method blst_256_t (line 524) | inline blst_256_t& operator-=(const blst_256_t& b)
    method blst_256_t (line 526) | inline blst_256_t operator-(const blst_256_t& a, const blst_256_t& b)
    method blst_256_t (line 533) | inline blst_256_t& cneg(bool flag)
    method blst_256_t (line 535) | inline blst_256_t cneg(const blst_256_t& a, bool flag)
    method blst_256_t (line 541) | inline blst_256_t operator-(const blst_256_t& a)
    method blst_256_t (line 548) | inline blst_256_t& operator*=(const blst_256_t& a)
    method blst_256_t (line 554) | inline blst_256_t operator*(const blst_256_t& a, const blst_256_t& b)
    method blst_256_t (line 563) | inline blst_256_t operator^(const blst_256_t& a, unsigned p)
    method blst_256_t (line 588) | inline blst_256_t& operator^=(unsigned p)
    method blst_256_t (line 598) | inline blst_256_t operator()(unsigned p)
    method blst_256_t (line 600) | inline blst_256_t sqr(const blst_256_t& a)
    method is_one (line 603) | inline bool is_one() const
    method is_zero (line 606) | inline int is_zero() const
    method zero (line 609) | inline void zero()
    method blst_256_t (line 612) | inline blst_256_t czero(const blst_256_t& a, int set_z)
    method blst_256_t (line 619) | static inline blst_256_t csel(const blst_256_t& a, const blst_256_t& b,
    method blst_256_t (line 626) | blst_256_t reciprocal() const
    method blst_256_t (line 637) | inline blst_256_t operator/(int one, const blst_256_t& a)
    method blst_256_t (line 643) | inline blst_256_t operator/(const blst_256_t& a, const blst_256_t& b)
    method blst_256_t (line 645) | inline blst_256_t& operator/=(const blst_256_t& a)
    method blst_256_t (line 648) | inline blst_256_t(const char *hexascii)
    method OStream (line 657) | OStream& operator<<(OStream& os, const blst_256_t& obj)

FILE: src/bytes.h
  function bytes_zero (line 9) | static inline void bytes_zero(unsigned char *a, size_t num)
  function limbs_from_be_bytes (line 17) | static inline void limbs_from_be_bytes(limb_t *restrict ret,
  function be_bytes_from_limbs (line 35) | static inline void be_bytes_from_limbs(unsigned char *out, const limb_t ...
  function limbs_from_le_bytes (line 46) | static inline void limbs_from_le_bytes(limb_t *restrict ret,
  function le_bytes_from_limbs (line 64) | static inline void le_bytes_from_limbs(unsigned char *out, const limb_t ...
  function hex_from_nibble (line 90) | static inline char hex_from_nibble(unsigned char nibble)
  function nibble_from_hex (line 96) | static unsigned char nibble_from_hex(char c)
  function bytes_from_hexascii (line 112) | static void bytes_from_hexascii(unsigned char *ret, size_t sz, const cha...
  function limbs_from_hexascii (line 132) | static void limbs_from_hexascii(limb_t *ret, size_t sz, const char *hex)

FILE: src/consts.h
  type radix384 (line 13) | typedef union { vec384 p12[12]; vec384x p2; vec384 p; } radix384;

FILE: src/cpuid.c
  function __cpuidex (line 15) | static void __cpuidex(int info[4], int func, int sub)
  function __blst_cpuid (line 32) | __attribute__((constructor))
  function __blst_cpuid (line 62) | __attribute__((constructor))
  function __blst_cpuid (line 77) | __attribute__((constructor))
  function __blst_cpuid (line 85) | __attribute__((constructor))
  function __blst_cpuid (line 99) | __attribute__((constructor))
  function BOOL (line 121) | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)

FILE: src/e1.c
  function mul_by_b_onE1 (line 48) | static inline void mul_by_b_onE1(vec384 out, const vec384 in)
  function mul_by_4b_onE1 (line 51) | static inline void mul_by_4b_onE1(vec384 out, const vec384 in)
  function POINTonE1_cneg (line 54) | static void POINTonE1_cneg(POINTonE1 *p, bool_t cbit)
  function blst_p1_cneg (line 57) | void blst_p1_cneg(POINTonE1 *a, int cbit)
  function POINTonE1_from_Jacobian (line 60) | static void POINTonE1_from_Jacobian(POINTonE1 *out, const POINTonE1 *in)
  function blst_p1_from_jacobian (line 77) | void blst_p1_from_jacobian(POINTonE1 *out, const POINTonE1 *a)
  function POINTonE1_to_affine (line 80) | static void POINTonE1_to_affine(POINTonE1_affine *out, const POINTonE1 *in)
  function blst_p1_to_affine (line 91) | void blst_p1_to_affine(POINTonE1_affine *out, const POINTonE1 *a)
  function blst_p1_from_affine (line 94) | void blst_p1_from_affine(POINTonE1 *out, const POINTonE1_affine *a)
  function bool_t (line 101) | static bool_t POINTonE1_affine_on_curve(const POINTonE1_affine *p)
  function blst_p1_affine_on_curve (line 114) | int blst_p1_affine_on_curve(const POINTonE1_affine *p)
  function bool_t (line 117) | static bool_t POINTonE1_on_curve(const POINTonE1 *p)
  function blst_p1_on_curve (line 136) | int blst_p1_on_curve(const POINTonE1 *p)
  function limb_t (line 139) | static limb_t POINTonE1_affine_Serialize_BE(unsigned char out[96],
  function blst_p1_affine_serialize (line 153) | void blst_p1_affine_serialize(unsigned char out[96],
  function limb_t (line 164) | static limb_t POINTonE1_Serialize_BE(unsigned char out[96],
  function POINTonE1_Serialize (line 177) | static void POINTonE1_Serialize(unsigned char out[96], const POINTonE1 *in)
  function blst_p1_serialize (line 187) | void blst_p1_serialize(unsigned char out[96], const POINTonE1 *in)
  function limb_t (line 190) | static limb_t POINTonE1_affine_Compress_BE(unsigned char out[48],
  function blst_p1_affine_compress (line 201) | void blst_p1_affine_compress(unsigned char out[48], const POINTonE1_affi...
  function limb_t (line 212) | static limb_t POINTonE1_Compress_BE(unsigned char out[48],
  function blst_p1_compress (line 225) | void blst_p1_compress(unsigned char out[48], const POINTonE1 *in)
  function limb_t (line 236) | static limb_t POINTonE1_Uncompress_BE(POINTonE1_affine *out,
  function BLST_ERROR (line 261) | static BLST_ERROR POINTonE1_Uncompress_Z(POINTonE1_affine *out,
  function BLST_ERROR (line 293) | BLST_ERROR blst_p1_uncompress(POINTonE1_affine *out, const unsigned char...
  function BLST_ERROR (line 296) | static BLST_ERROR POINTonE1_Deserialize_BE(POINTonE1_affine *out,
  function BLST_ERROR (line 328) | static BLST_ERROR POINTonE1_Deserialize_Z(POINTonE1_affine *out,
  function BLST_ERROR (line 349) | BLST_ERROR blst_p1_deserialize(POINTonE1_affine *out,
  function blst_p1_add (line 361) | void blst_p1_add(POINTonE1 *out, const POINTonE1 *a, const POINTonE1 *b)
  function blst_p1_add_or_double (line 364) | void blst_p1_add_or_double(POINTonE1 *out, const POINTonE1 *a,
  function blst_p1_add_affine (line 368) | void blst_p1_add_affine(POINTonE1 *out, const POINTonE1 *a,
  function blst_p1_add_or_double_affine (line 372) | void blst_p1_add_or_double_affine(POINTonE1 *out, const POINTonE1 *a,
  function blst_p1_double (line 376) | void blst_p1_double(POINTonE1 *out, const POINTonE1 *a)
  function blst_p1_is_equal (line 379) | int blst_p1_is_equal(const POINTonE1 *a, const POINTonE1 *b)
  function sigma (line 405) | static void sigma(POINTonE1 *out, const POINTonE1 *in)
  function POINTonE1_mult_glv (line 412) | static void POINTonE1_mult_glv(POINTonE1 *out, const POINTonE1 *in,
  function POINTonE1_sign (line 444) | static void POINTonE1_sign(POINTonE1 *out, const POINTonE1 *in, const po...
  function blst_sk_to_pk_in_g1 (line 469) | void blst_sk_to_pk_in_g1(POINTonE1 *out, const pow256 SK)
  function blst_sign_pk_in_g2 (line 472) | void blst_sign_pk_in_g2(POINTonE1 *out, const POINTonE1 *msg, const pow2...
  function blst_sk_to_pk2_in_g1 (line 475) | void blst_sk_to_pk2_in_g1(unsigned char out[96], POINTonE1_affine *PK,
  function blst_sign_pk2_in_g2 (line 490) | void blst_sign_pk2_in_g2(unsigned char out[96], POINTonE1_affine *sig,
  function blst_p1_mult (line 505) | void blst_p1_mult(POINTonE1 *out, const POINTonE1 *a,
  function blst_p1_unchecked_mult (line 535) | void blst_p1_unchecked_mult(POINTonE1 *out, const POINTonE1 *a,
  function blst_p1_affine_is_equal (line 544) | int blst_p1_affine_is_equal(const POINTonE1_affine *a,
  function blst_p1_is_inf (line 548) | int blst_p1_is_inf(const POINTonE1 *p)
  function POINTonE1 (line 551) | const POINTonE1 *blst_p1_generator(void)
  function blst_p1_affine_is_inf (line 554) | int blst_p1_affine_is_inf(const POINTonE1_affine *p)
  function POINTonE1_affine (line 557) | const POINTonE1_affine *blst_p1_affine_generator(void)
  function blst_p1_sizeof (line 560) | size_t blst_p1_sizeof(void)
  function blst_p1_affine_sizeof (line 563) | size_t blst_p1_affine_sizeof(void)

FILE: src/e2.c
  function mul_by_b_onE2 (line 75) | static void mul_by_b_onE2(vec384x out, const vec384x in)
  function mul_by_4b_onE2 (line 83) | static void mul_by_4b_onE2(vec384x out, const vec384x in)
  function POINTonE2_cneg (line 91) | static void POINTonE2_cneg(POINTonE2 *p, bool_t cbit)
  function blst_p2_cneg (line 94) | void blst_p2_cneg(POINTonE2 *a, int cbit)
  function POINTonE2_from_Jacobian (line 97) | static void POINTonE2_from_Jacobian(POINTonE2 *out, const POINTonE2 *in)
  function blst_p2_from_jacobian (line 114) | void blst_p2_from_jacobian(POINTonE2 *out, const POINTonE2 *a)
  function POINTonE2_to_affine (line 117) | static void POINTonE2_to_affine(POINTonE2_affine *out, const POINTonE2 *in)
  function blst_p2_to_affine (line 128) | void blst_p2_to_affine(POINTonE2_affine *out, const POINTonE2 *a)
  function blst_p2_from_affine (line 131) | void blst_p2_from_affine(POINTonE2 *out, const POINTonE2_affine *a)
  function bool_t (line 138) | static bool_t POINTonE2_affine_on_curve(const POINTonE2_affine *p)
  function blst_p2_affine_on_curve (line 151) | int blst_p2_affine_on_curve(const POINTonE2_affine *p)
  function bool_t (line 154) | static bool_t POINTonE2_on_curve(const POINTonE2 *p)
  function blst_p2_on_curve (line 173) | int blst_p2_on_curve(const POINTonE2 *p)
  function limb_t (line 176) | static limb_t POINTonE2_affine_Serialize_BE(unsigned char out[192],
  function blst_p2_affine_serialize (line 194) | void blst_p2_affine_serialize(unsigned char out[192],
  function limb_t (line 205) | static limb_t POINTonE2_Serialize_BE(unsigned char out[192],
  function POINTonE2_Serialize (line 218) | static void POINTonE2_Serialize(unsigned char out[192], const POINTonE2 ...
  function blst_p2_serialize (line 228) | void blst_p2_serialize(unsigned char out[192], const POINTonE2 *in)
  function limb_t (line 231) | static limb_t POINTonE2_affine_Compress_BE(unsigned char out[96],
  function blst_p2_affine_compress (line 244) | void blst_p2_affine_compress(unsigned char out[96], const POINTonE2_affi...
  function limb_t (line 255) | static limb_t POINTonE2_Compress_BE(unsigned char out[96],
  function blst_p2_compress (line 268) | void blst_p2_compress(unsigned char out[96], const POINTonE2 *in)
  function limb_t (line 279) | static limb_t POINTonE2_Uncompress_BE(POINTonE2_affine *out,
  function BLST_ERROR (line 312) | static BLST_ERROR POINTonE2_Uncompress_Z(POINTonE2_affine *out,
  function BLST_ERROR (line 342) | BLST_ERROR blst_p2_uncompress(POINTonE2_affine *out, const unsigned char...
  function BLST_ERROR (line 345) | static BLST_ERROR POINTonE2_Deserialize_BE(POINTonE2_affine *out,
  function BLST_ERROR (line 387) | static BLST_ERROR POINTonE2_Deserialize_Z(POINTonE2_affine *out,
  function BLST_ERROR (line 408) | BLST_ERROR blst_p2_deserialize(POINTonE2_affine *out,
  function blst_p2_add (line 420) | void blst_p2_add(POINTonE2 *out, const POINTonE2 *a, const POINTonE2 *b)
  function blst_p2_add_or_double (line 423) | void blst_p2_add_or_double(POINTonE2 *out, const POINTonE2 *a,
  function blst_p2_add_affine (line 427) | void blst_p2_add_affine(POINTonE2 *out, const POINTonE2 *a,
  function blst_p2_add_or_double_affine (line 431) | void blst_p2_add_or_double_affine(POINTonE2 *out, const POINTonE2 *a,
  function blst_p2_double (line 435) | void blst_p2_double(POINTonE2 *out, const POINTonE2 *a)
  function blst_p2_is_equal (line 438) | int blst_p2_is_equal(const POINTonE2 *a, const POINTonE2 *b)
  function DECLARE_PRIVATE_POINTXZ (line 446) | POINT_AFFINE_MULT_SCALAR_IMPL(POINTonE2)
  function POINTonE2_sign (line 518) | static void POINTonE2_sign(POINTonE2 *out, const POINTonE2 *in, const po...
  function blst_sk_to_pk_in_g2 (line 543) | void blst_sk_to_pk_in_g2(POINTonE2 *out, const pow256 SK)
  function blst_sign_pk_in_g1 (line 546) | void blst_sign_pk_in_g1(POINTonE2 *out, const POINTonE2 *msg, const pow2...
  function blst_sk_to_pk2_in_g2 (line 549) | void blst_sk_to_pk2_in_g2(unsigned char out[192], POINTonE2_affine *PK,
  function blst_sign_pk2_in_g1 (line 564) | void blst_sign_pk2_in_g1(unsigned char out[192], POINTonE2_affine *sig,
  function blst_p2_mult (line 579) | void blst_p2_mult(POINTonE2 *out, const POINTonE2 *a,
  function blst_p2_unchecked_mult (line 609) | void blst_p2_unchecked_mult(POINTonE2 *out, const POINTonE2 *a,
  function blst_p2_affine_is_equal (line 618) | int blst_p2_affine_is_equal(const POINTonE2_affine *a,
  function blst_p2_is_inf (line 622) | int blst_p2_is_inf(const POINTonE2 *p)
  function POINTonE2 (line 625) | const POINTonE2 *blst_p2_generator(void)
  function blst_p2_affine_is_inf (line 628) | int blst_p2_affine_is_inf(const POINTonE2_affine *p)
  function POINTonE2_affine (line 631) | const POINTonE2_affine *blst_p2_affine_generator(void)
  function blst_p2_sizeof (line 634) | size_t blst_p2_sizeof(void)
  function blst_p2_affine_sizeof (line 637) | size_t blst_p2_affine_sizeof(void)

FILE: src/ec_mult.h
  function limb_t (line 12) | static limb_t get_wval(const byte *d, size_t off, size_t bits)
  function limb_t (line 23) | static limb_t get_wval_limb(const byte *d, size_t off, size_t bits)
  function limb_t (line 46) | static limb_t booth_encode(limb_t wval, size_t sz)

FILE: src/errors.h
  type BLST_ERROR (line 9) | typedef enum {

FILE: src/exp.c
  function exp_mont_384 (line 12) | static void exp_mont_384(vec384 out, const vec384 inp, const byte *pow,
  function exp_mont_384x (line 42) | static void exp_mont_384x(vec384x out, const vec384x inp, const byte *pow,

FILE: src/exports.c
  function blst_fr_add (line 24) | void blst_fr_add(vec256 ret, const vec256 a, const vec256 b)
  function blst_fr_sub (line 27) | void blst_fr_sub(vec256 ret, const vec256 a, const vec256 b)
  function blst_fr_mul_by_3 (line 30) | void blst_fr_mul_by_3(vec256 ret, const vec256 a)
  function blst_fr_lshift (line 33) | void blst_fr_lshift(vec256 ret, const vec256 a, size_t count)
  function blst_fr_rshift (line 36) | void blst_fr_rshift(vec256 ret, const vec256 a, size_t count)
  function blst_fr_mul (line 39) | void blst_fr_mul(vec256 ret, const vec256 a, const vec256 b)
  function blst_fr_ct_bfly (line 42) | void blst_fr_ct_bfly(vec256 x0, vec256 x1, const vec256 twiddle)
  function blst_fr_gs_bfly (line 51) | void blst_fr_gs_bfly(vec256 x0, vec256 x1, const vec256 twiddle)
  function blst_fr_sqr (line 60) | void blst_fr_sqr(vec256 ret, const vec256 a)
  function blst_fr_cneg (line 63) | void blst_fr_cneg(vec256 ret, const vec256 a, int flag)
  function blst_fr_to (line 66) | void blst_fr_to(vec256 ret, const vec256 a)
  function blst_fr_from (line 69) | void blst_fr_from(vec256 ret, const vec256 a)
  function blst_fr_from_scalar (line 72) | void blst_fr_from_scalar(vec256 ret, const pow256 a)
  function blst_scalar_from_fr (line 90) | void blst_scalar_from_fr(pow256 ret, const vec256 a)
  function blst_scalar_fr_check (line 107) | int blst_scalar_fr_check(const pow256 a)
  function blst_sk_check (line 112) | int blst_sk_check(const pow256 a)
  function blst_sk_add_n_check (line 115) | int blst_sk_add_n_check(pow256 ret, const pow256 a, const pow256 b)
  function blst_sk_sub_n_check (line 118) | int blst_sk_sub_n_check(pow256 ret, const pow256 a, const pow256 b)
  function blst_sk_mul_n_check (line 121) | int blst_sk_mul_n_check(pow256 ret, const pow256 a, const pow256 b)
  function blst_sk_inverse (line 145) | void blst_sk_inverse(pow256 ret, const pow256 a)
  function blst_fp_add (line 172) | void blst_fp_add(vec384 ret, const vec384 a, const vec384 b)
  function blst_fp_sub (line 175) | void blst_fp_sub(vec384 ret, const vec384 a, const vec384 b)
  function blst_fp_mul_by_3 (line 178) | void blst_fp_mul_by_3(vec384 ret, const vec384 a)
  function blst_fp_mul_by_8 (line 181) | void blst_fp_mul_by_8(vec384 ret, const vec384 a)
  function blst_fp_lshift (line 184) | void blst_fp_lshift(vec384 ret, const vec384 a, size_t count)
  function blst_fp_mul (line 187) | void blst_fp_mul(vec384 ret, const vec384 a, const vec384 b)
  function blst_fp_sqr (line 190) | void blst_fp_sqr(vec384 ret, const vec384 a)
  function blst_fp_cneg (line 193) | void blst_fp_cneg(vec384 ret, const vec384 a, int flag)
  function blst_fp_to (line 196) | void blst_fp_to(vec384 ret, const vec384 a)
  function blst_fp_from (line 199) | void blst_fp_from(vec384 ret, const vec384 a)
  function blst_fp_from_uint32 (line 205) | void blst_fp_from_uint32(vec384 ret, const unsigned int a[12])
  function blst_uint32_from_fp (line 216) | void blst_uint32_from_fp(unsigned int ret[12], const vec384 a)
  function blst_fp_from_uint64 (line 233) | void blst_fp_from_uint64(vec384 ret, const unsigned long long a[6])
  function blst_uint64_from_fp (line 252) | void blst_uint64_from_fp(unsigned long long ret[6], const vec384 a)
  function blst_fp_from_bendian (line 271) | void blst_fp_from_bendian(vec384 ret, const unsigned char a[48])
  function blst_bendian_from_fp (line 279) | void blst_bendian_from_fp(unsigned char ret[48], const vec384 a)
  function blst_fp_from_lendian (line 287) | void blst_fp_from_lendian(vec384 ret, const unsigned char a[48])
  function blst_lendian_from_fp (line 295) | void blst_lendian_from_fp(unsigned char ret[48], const vec384 a)
  function blst_fp2_add (line 306) | void blst_fp2_add(vec384x ret, const vec384x a, const vec384x b)
  function blst_fp2_sub (line 309) | void blst_fp2_sub(vec384x ret, const vec384x a, const vec384x b)
  function blst_fp2_mul_by_3 (line 312) | void blst_fp2_mul_by_3(vec384x ret, const vec384x a)
  function blst_fp2_mul_by_8 (line 315) | void blst_fp2_mul_by_8(vec384x ret, const vec384x a)
  function blst_fp2_lshift (line 318) | void blst_fp2_lshift(vec384x ret, const vec384x a, size_t count)
  function blst_fp2_mul (line 321) | void blst_fp2_mul(vec384x ret, const vec384x a, const vec384x b)
  function blst_fp2_sqr (line 324) | void blst_fp2_sqr(vec384x ret, const vec384x a)
  function blst_fp2_cneg (line 327) | void blst_fp2_cneg(vec384x ret, const vec384x a, int flag)
  function blst_scalar_from_uint32 (line 333) | void blst_scalar_from_uint32(pow256 ret, const unsigned int a[8])
  function blst_uint32_from_scalar (line 353) | void blst_uint32_from_scalar(unsigned int ret[8], const pow256 a)
  function blst_scalar_from_uint64 (line 373) | void blst_scalar_from_uint64(pow256 ret, const unsigned long long a[4])
  function blst_uint64_from_scalar (line 397) | void blst_uint64_from_scalar(unsigned long long ret[4], const pow256 a)
  function blst_scalar_from_bendian (line 421) | void blst_scalar_from_bendian(pow256 ret, const unsigned char a[32])
  function blst_bendian_from_scalar (line 429) | void blst_bendian_from_scalar(unsigned char ret[32], const pow256 a)
  function blst_scalar_from_lendian (line 437) | void blst_scalar_from_lendian(pow256 ret, const unsigned char a[32])
  function blst_lendian_from_scalar (line 448) | void blst_lendian_from_scalar(unsigned char ret[32], const pow256 a)
  function blst_fr_from_uint64 (line 459) | void blst_fr_from_uint64(vec256 ret, const unsigned long long a[4])
  function blst_uint64_from_fr (line 478) | void blst_uint64_from_fr(unsigned long long ret[4], const vec256 a)
  function blst_scalar_from_le_bytes (line 498) | int blst_scalar_from_le_bytes(pow256 out, const unsigned char *bytes, si...
  function blst_scalar_from_be_bytes (line 526) | int blst_scalar_from_be_bytes(pow256 out, const unsigned char *bytes, si...
  function blst_fp_from_le_bytes (line 553) | void blst_fp_from_le_bytes(vec384 out, const unsigned char *bytes, size_...
  function blst_fp_from_be_bytes (line 572) | void blst_fp_from_be_bytes(vec384 out, const unsigned char *bytes, size_...
  function blst_sha256 (line 595) | void blst_sha256(unsigned char md[32], const void *msg, size_t len)
  function blst_scalar_from_hexascii (line 607) | void blst_scalar_from_hexascii(pow256 ret, const char *hex)
  function blst_fr_from_hexascii (line 610) | void blst_fr_from_hexascii(vec256 ret, const char *hex)
  function blst_fp_from_hexascii (line 616) | void blst_fp_from_hexascii(vec384 ret, const char *hex)

FILE: src/fields.h
  function add_fp (line 15) | static inline void add_fp(vec384 ret, const vec384 a, const vec384 b)
  function sub_fp (line 18) | static inline void sub_fp(vec384 ret, const vec384 a, const vec384 b)
  function mul_by_3_fp (line 21) | static inline void mul_by_3_fp(vec384 ret, const vec384 a)
  function mul_by_8_fp (line 24) | static inline void mul_by_8_fp(vec384 ret, const vec384 a)
  function lshift_fp (line 27) | static inline void lshift_fp(vec384 ret, const vec384 a, size_t count)
  function rshift_fp (line 30) | static inline void rshift_fp(vec384 ret, const vec384 a, size_t count)
  function div_by_2_fp (line 33) | static inline void div_by_2_fp(vec384 ret, const vec384 a)
  function mul_fp (line 36) | static inline void mul_fp(vec384 ret, const vec384 a, const vec384 b)
  function sqr_fp (line 39) | static inline void sqr_fp(vec384 ret, const vec384 a)
  function cneg_fp (line 42) | static inline void cneg_fp(vec384 ret, const vec384 a, bool_t flag)
  function from_fp (line 45) | static inline void from_fp(vec384 ret, const vec384 a)
  function redc_fp (line 48) | static inline void redc_fp(vec384 ret, const vec768 a)
  function add_fp2 (line 54) | static inline void add_fp2(vec384x ret, const vec384x a, const vec384x b)
  function sub_fp2 (line 57) | static inline void sub_fp2(vec384x ret, const vec384x a, const vec384x b)
  function mul_by_3_fp2 (line 60) | static inline void mul_by_3_fp2(vec384x ret, const vec384x a)
  function mul_by_8_fp2 (line 63) | static inline void mul_by_8_fp2(vec384x ret, const vec384x a)
  function lshift_fp2 (line 66) | static inline void lshift_fp2(vec384x ret, const vec384x a, size_t count)
  function mul_fp2 (line 72) | static inline void mul_fp2(vec384x ret, const vec384x a, const vec384x b)
  function sqr_fp2 (line 75) | static inline void sqr_fp2(vec384x ret, const vec384x a)
  function cneg_fp2 (line 78) | static inline void cneg_fp2(vec384x ret, const vec384x a, bool_t flag)
  type vec384x (line 99) | typedef vec384x   vec384fp2;
  type vec384fp2 (line 100) | typedef vec384fp2 vec384fp6[3];
  type vec384fp6 (line 101) | typedef vec384fp6 vec384fp12[2];

FILE: src/fp12_tower.c
  function mul_by_u_plus_1_fp2 (line 15) | static inline void mul_by_u_plus_1_fp2(vec384x ret, const vec384x a)
  type vec768 (line 27) | typedef vec768 vec768x[2];
  function add_fp2x2 (line 29) | static inline void add_fp2x2(vec768x ret, const vec768x a, const vec768x b)
  function sub_fp2x2 (line 35) | static inline void sub_fp2x2(vec768x ret, const vec768x a, const vec768x b)
  function mul_by_u_plus_1_fp2x2 (line 41) | static inline void mul_by_u_plus_1_fp2x2(vec768x ret, const vec768x a)
  function redc_fp2x2 (line 48) | static inline void redc_fp2x2(vec384x ret, const vec768x a)
  function mul_fp2x2 (line 54) | static void mul_fp2x2(vec768x ret, const vec384x a, const vec384x b)
  function sqr_fp2x2 (line 75) | static void sqr_fp2x2(vec768x ret, const vec384x a)
  type vec768x (line 97) | typedef vec768x vec768fp6[3];
  function sub_fp6x2 (line 99) | static inline void sub_fp6x2(vec768fp6 ret, const vec768fp6 a,
  function mul_fp6x2 (line 107) | static void mul_fp6x2(vec768fp6 ret, const vec384fp6 a, const vec384fp6 b)
  function redc_fp6x2 (line 146) | static inline void redc_fp6x2(vec384fp6 ret, const vec768fp6 a)
  function mul_fp6 (line 153) | static void mul_fp6(vec384fp6 ret, const vec384fp6 a, const vec384fp6 b)
  function sqr_fp6 (line 161) | static void sqr_fp6(vec384fp6 ret, const vec384fp6 a)
  function mul_fp6 (line 197) | static void mul_fp6(vec384fp6 ret, const vec384fp6 a, const vec384fp6 b)
  function sqr_fp6 (line 237) | static void sqr_fp6(vec384fp6 ret, const vec384fp6 a)
  function add_fp6 (line 271) | static void add_fp6(vec384fp6 ret, const vec384fp6 a, const vec384fp6 b)
  function sub_fp6 (line 278) | static void sub_fp6(vec384fp6 ret, const vec384fp6 a, const vec384fp6 b)
  function neg_fp6 (line 285) | static void neg_fp6(vec384fp6 ret, const vec384fp6 a)
  function mul_by_v_fp6 (line 294) | static void mul_by_v_fp6(vec384fp6 ret, const vec384fp6 a)
  function mul_fp12 (line 309) | static void mul_fp12(vec384fp12 ret, const vec384fp12 a, const vec384fp1...
  function mul_by_0y0_fp6x2 (line 334) | static inline void mul_by_0y0_fp6x2(vec768fp6 ret, const vec384fp6 a,
  function mul_by_xy0_fp6x2 (line 343) | static void mul_by_xy0_fp6x2(vec768fp6 ret, const vec384fp6 a,
  function mul_by_xy00z0_fp12 (line 372) | static void mul_by_xy00z0_fp12(vec384fp12 ret, const vec384fp12 a,
  function mul_fp12 (line 399) | static void mul_fp12(vec384fp12 ret, const vec384fp12 a, const vec384fp1...
  function mul_by_0y0_fp6 (line 426) | static inline void mul_by_0y0_fp6(vec384fp6 ret, const vec384fp6 a,
  function mul_by_xy0_fp6 (line 437) | static void mul_by_xy0_fp6(vec384fp6 ret, const vec384fp6 a, const vec38...
  function mul_by_xy00z0_fp12 (line 466) | static void mul_by_xy00z0_fp12(vec384fp12 ret, const vec384fp12 a,
  function sqr_fp12 (line 496) | static void sqr_fp12(vec384fp12 ret, const vec384fp12 a)
  function conjugate_fp12 (line 530) | static void conjugate_fp12(vec384fp12 a)
  function inverse_fp6 (line 533) | static void inverse_fp6(vec384fp6 ret, const vec384fp6 a)
  function inverse_fp12 (line 569) | static void inverse_fp12(vec384fp12 ret, const vec384fp12 a)
  type vec384x (line 592) | typedef vec384x vec384fp4[2];
  function sqr_fp4 (line 595) | static void sqr_fp4(vec384fp4 ret, const vec384x a0, const vec384x a1)
  function sqr_fp4 (line 613) | static void sqr_fp4(vec384fp4 ret, const vec384x a0, const vec384x a1)
  function cyclotomic_sqr_fp12 (line 630) | static void cyclotomic_sqr_fp12(vec384fp12 ret, const vec384fp12 a)
  function frobenius_map_fp2 (line 667) | static inline void frobenius_map_fp2(vec384x ret, const vec384x a, size_...
  function frobenius_map_fp6 (line 673) | static void frobenius_map_fp6(vec384fp6 ret, const vec384fp6 a, size_t n)
  function frobenius_map_fp12 (line 706) | static void frobenius_map_fp12(vec384fp12 ret, const vec384fp12 a, size_...
  function blst_fp12_sqr (line 738) | void blst_fp12_sqr(vec384fp12 ret, const vec384fp12 a)
  function blst_fp12_cyclotomic_sqr (line 741) | void blst_fp12_cyclotomic_sqr(vec384fp12 ret, const vec384fp12 a)
  function blst_fp12_mul (line 744) | void blst_fp12_mul(vec384fp12 ret, const vec384fp12 a, const vec384fp12 b)
  function blst_fp12_mul_by_xy00z0 (line 747) | void blst_fp12_mul_by_xy00z0(vec384fp12 ret, const vec384fp12 a,
  function blst_fp12_conjugate (line 751) | void blst_fp12_conjugate(vec384fp12 a)
  function blst_fp12_inverse (line 754) | void blst_fp12_inverse(vec384fp12 ret, const vec384fp12 a)
  function blst_fp12_frobenius_map (line 758) | void blst_fp12_frobenius_map(vec384fp12 ret, const vec384fp12 a, size_t n)
  function blst_fp12_is_equal (line 761) | int blst_fp12_is_equal(const vec384fp12 a, const vec384fp12 b)
  function blst_fp12_is_one (line 764) | int blst_fp12_is_one(const vec384fp12 a)
  function vec384fp12 (line 770) | const vec384fp12 *blst_fp12_one(void)
  function blst_bendian_from_fp12 (line 773) | void blst_bendian_from_fp12(unsigned char ret[48*12], const vec384fp12 a)
  function blst_fp12_sizeof (line 788) | size_t blst_fp12_sizeof(void)

FILE: src/hash_to_field.c
  function sha256_init_Zpad (line 22) | static void sha256_init_Zpad(SHA256_CTX *ctx)
  function vec_xor (line 37) | static void vec_xor(void *restrict ret, const void *restrict a,
  function expand_message_xmd (line 51) | static void expand_message_xmd(unsigned char *bytes, size_t len_in_bytes,
  function hash_to_field (line 120) | static void hash_to_field(vec384 elems[], size_t nelems,
  function blst_expand_message_xmd (line 156) | void blst_expand_message_xmd(unsigned char *bytes, size_t len_in_bytes,

FILE: src/keygen.c
  type HMAC_SHA256_CTX (line 11) | typedef struct {
  function HMAC_init (line 18) | static void HMAC_init(HMAC_SHA256_CTX *ctx, const void *K, size_t K_len)
  function HMAC_update (line 59) | static void HMAC_update(HMAC_SHA256_CTX *ctx, const unsigned char *inp,
  function HMAC_final (line 63) | static void HMAC_final(unsigned char md[32], HMAC_SHA256_CTX *ctx)
  function HKDF_Extract (line 71) | static void HKDF_Extract(unsigned char PRK[32],
  function HKDF_Expand (line 92) | static void HKDF_Expand(unsigned char *OKM, size_t L,
  function keygen (line 135) | static void keygen(pow256 SK, const void *IKM, size_t IKM_len,
  function blst_keygen (line 214) | void blst_keygen(pow256 SK, const void *IKM, size_t IKM_len,
  function blst_keygen_v3 (line 218) | void blst_keygen_v3(pow256 SK, const void *IKM, size_t IKM_len,
  function blst_keygen_v4_5 (line 222) | void blst_keygen_v4_5(pow256 SK, const void *IKM, size_t IKM_len,
  function blst_keygen_v5 (line 227) | void blst_keygen_v5(pow256 SK, const void *IKM, size_t IKM_len,
  function blst_derive_master_eip2333 (line 235) | void blst_derive_master_eip2333(pow256 SK, const void *seed, size_t seed...
  function parent_SK_to_lamport_PK (line 238) | static void parent_SK_to_lamport_PK(pow256 PK, const pow256 parent_SK,
  function blst_derive_child_eip2333 (line 313) | void blst_derive_child_eip2333(pow256 SK, const pow256 parent_SK,

FILE: src/map_to_g1.c
  function map_fp_times_Zz (line 28) | static void map_fp_times_Zz(vec384 map[], const vec384 isogeny_map[],
  function map_fp (line 35) | static void map_fp(vec384 acc, const vec384 x, const vec384 map[], size_...
  function isogeny_map_to_E1 (line 43) | static void isogeny_map_to_E1(POINTonE1 *out, const POINTonE1 *p)
  function map_to_isogenous_E1 (line 285) | static void map_to_isogenous_E1(POINTonE1 *p, const vec384 u)
  function POINTonE1_add_n_dbl (line 384) | static void POINTonE1_add_n_dbl(POINTonE1 *out, const POINTonE1 *p, size...
  function POINTonE1_times_minus_z (line 391) | static void POINTonE1_times_minus_z(POINTonE1 *out, const POINTonE1 *in)
  function map_to_g1 (line 404) | static void map_to_g1(POINTonE1 *out, const vec384 u, const vec384 v)
  function blst_map_to_g1 (line 422) | void blst_map_to_g1(POINTonE1 *out, const vec384 u, const vec384 v)
  function Encode_to_G1 (line 425) | static void Encode_to_G1(POINTonE1 *p, const unsigned char *msg, size_t ...
  function blst_encode_to_g1 (line 435) | void blst_encode_to_g1(POINTonE1 *p, const unsigned char *msg, size_t ms...
  function Hash_to_G1 (line 440) | static void Hash_to_G1(POINTonE1 *p, const unsigned char *msg, size_t ms...
  function blst_hash_to_g1 (line 450) | void blst_hash_to_g1(POINTonE1 *p, const unsigned char *msg, size_t msg_...
  function POINTonE1_times_zz_minus_1_div_by_3 (line 459) | static void POINTonE1_times_zz_minus_1_div_by_3(POINTonE1 *out,
  function POINTonE1_dbl_n_add (line 475) | static void POINTonE1_dbl_n_add(POINTonE1 *out, size_t n, const POINTonE...
  function POINTonE1_times_zz_minus_1_div_by_3 (line 482) | static void POINTonE1_times_zz_minus_1_div_by_3(POINTonE1 *out,
  function bool_t (line 512) | static bool_t POINTonE1_in_G1(const POINTonE1 *P)
  function bool_t (line 531) | static bool_t POINTonE1_in_G1(const POINTonE1 *P)
  function blst_p1_in_g1 (line 547) | int blst_p1_in_g1(const POINTonE1 *p)
  function blst_p1_affine_in_g1 (line 550) | int blst_p1_affine_in_g1(const POINTonE1_affine *p)

FILE: src/map_to_g2.c
  function map_fp2_times_Zz (line 28) | static void map_fp2_times_Zz(vec384x map[], const vec384x isogeny_map[],
  function map_fp2 (line 35) | static void map_fp2(vec384x acc, const vec384x x, const vec384x map[], s...
  function isogeny_map_to_E2 (line 43) | static void isogeny_map_to_E2(POINTonE2 *out, const POINTonE2 *p)
  function map_to_isogenous_E2 (line 173) | static void map_to_isogenous_E2(POINTonE2 *p, const vec384x u)
  function clear_cofactor (line 301) | static void clear_cofactor(POINTonE2 *out, const POINTonE2 *p)
  function POINTonE2_add_n_dbl (line 308) | static void POINTonE2_add_n_dbl(POINTonE2 *out, const POINTonE2 *p, size...
  function POINTonE2_times_minus_z (line 315) | static void POINTonE2_times_minus_z(POINTonE2 *out, const POINTonE2 *in)
  function clear_cofactor (line 327) | static void clear_cofactor(POINTonE2 *out, const POINTonE2 *p)
  function map_to_g2 (line 355) | static void map_to_g2(POINTonE2 *out, const vec384x u, const vec384x v)
  function blst_map_to_g2 (line 370) | void blst_map_to_g2(POINTonE2 *out, const vec384x u, const vec384x v)
  function Encode_to_G2 (line 373) | static void Encode_to_G2(POINTonE2 *p, const unsigned char *msg, size_t ...
  function blst_encode_to_g2 (line 383) | void blst_encode_to_g2(POINTonE2 *p, const unsigned char *msg, size_t ms...
  function Hash_to_G2 (line 388) | static void Hash_to_G2(POINTonE2 *p, const unsigned char *msg, size_t ms...
  function blst_hash_to_g2 (line 398) | void blst_hash_to_g2(POINTonE2 *p, const unsigned char *msg, size_t msg_...
  function bool_t (line 403) | static bool_t POINTonE2_in_G2(const POINTonE2 *P)
  function blst_p2_in_g2 (line 432) | int blst_p2_in_g2(const POINTonE2 *p)
  function blst_p2_affine_in_g2 (line 435) | int blst_p2_affine_in_g2(const POINTonE2_affine *p)

FILE: src/multi_scalar.c
  function pippenger_window_size (line 303) | static size_t pippenger_window_size(size_t npoints)

FILE: src/no_asm.h
  type llimb_t (line 8) | typedef unsigned long long llimb_t;
  function mul_mont_n (line 29) | static void mul_mont_n(limb_t ret[], const limb_t a[], const limb_t b[],
  function add_mod_n (line 104) | static void add_mod_n(limb_t ret[], const limb_t a[], const limb_t b[],
  function sub_mod_n (line 139) | static void sub_mod_n(limb_t ret[], const limb_t a[], const limb_t b[],
  function mul_by_3_mod_n (line 171) | static void mul_by_3_mod_n(limb_t ret[], const limb_t a[], const limb_t ...
  function lshift_mod_n (line 224) | static void lshift_mod_n(limb_t ret[], const limb_t a[], size_t count,
  function cneg_mod_n (line 264) | static void cneg_mod_n(limb_t ret[], const limb_t a[], bool_t flag,
  function limb_t (line 293) | static limb_t check_mod_n(const byte a[], const limb_t p[], size_t n)
  function limb_t (line 317) | static limb_t add_n_check_mod_n(byte ret[], const byte a[], const byte b[],
  function limb_t (line 341) | static limb_t sub_n_check_mod_n(byte ret[], const byte a[], const byte b[],
  function from_mont_n (line 365) | static void from_mont_n(limb_t ret[], const limb_t a[],
  function redc_mont_n (line 408) | static void redc_mont_n(limb_t ret[], const limb_t a[],
  function rshift_mod_n (line 457) | static void rshift_mod_n(limb_t ret[], const limb_t a[], size_t count,
  function limb_t (line 501) | static limb_t sgn0_pty_mod_n(const limb_t a[], const limb_t p[], size_t n)
  function limb_t (line 526) | inline limb_t sgn0_pty_mod_384(const vec384 a, const vec384 p)
  function limb_t (line 529) | inline limb_t sgn0_pty_mont_384(const vec384 a, const vec384 p, limb_t n0)
  function limb_t (line 538) | inline limb_t sgn0_pty_mod_384x(const vec384x a, const vec384 p)
  function limb_t (line 556) | inline limb_t sgn0_pty_mont_384x(const vec384x a, const vec384 p, limb_t...
  function mul_mont_384x (line 566) | void mul_mont_384x(vec384x ret, const vec384x a, const vec384x b,
  function mul_mont_nonred_n (line 586) | static void mul_mont_nonred_n(limb_t ret[], const limb_t a[], const limb...
  function sqr_n_mul_mont_383 (line 627) | void sqr_n_mul_mont_383(vec384 ret, const vec384 a, size_t count,
  function sqr_mont_382x (line 638) | void sqr_mont_382x(vec384x ret, const vec384x a,
  function num_bits (line 696) | static size_t num_bits(limb_t l)
  function limb_t (line 734) | __attribute__((optnone))
  function ab_approximation_n (line 746) | static void ab_approximation_n(limb_t a_[2], const limb_t a[],
  type factors (line 770) | typedef struct { limb_t f0, g0, f1, g1; } factors;
  function inner_loop_n (line 772) | static void inner_loop_n(factors *fg, const limb_t a_[2], const limb_t b...
  function limb_t (line 829) | static limb_t cneg_n(limb_t ret[], const limb_t a[], limb_t neg, size_t n)
  function limb_t (line 845) | static limb_t add_n(limb_t ret[], const limb_t a[], limb_t b[], size_t n)
  function limb_t (line 861) | static limb_t umul_n(limb_t ret[], const limb_t a[], limb_t b, size_t n)
  function limb_t (line 877) | static limb_t smul_n_shift_n(limb_t ret[], const limb_t a[], limb_t *f_,
  function limb_t (line 920) | static limb_t smul_2n(limb_t ret[], const limb_t u[], limb_t f,
  function ct_inverse_mod_n (line 944) | static void ct_inverse_mod_n(limb_t ret[], const limb_t inp[],
  function limb_t (line 999) | static limb_t legendre_loop_n(limb_t L, factors *fg, const limb_t a_[2],
  function bool_t (line 1062) | static bool_t ct_is_sqr_mod_n(const limb_t inp[], const limb_t mod[], si...
  function limb_t (line 1112) | limb_t div_3_limbs(const limb_t div_top[2], limb_t d_lo, limb_t d_hi)
  function limb_t (line 1155) | static limb_t quot_rem_n(limb_t *div_rem, const limb_t *divisor,
  function limb_t (line 1191) | inline limb_t quot_rem_128(limb_t *div_rem, const limb_t *divisor,
  function limb_t (line 1195) | inline limb_t quot_rem_64(limb_t *div_rem, const limb_t *divisor,
  function vec_prefetch (line 1211) | inline void vec_prefetch(const void *ptr, size_t len)
  function blst_sha256_block_data_order (line 1225) | void blst_sha256_block_data_order(unsigned int *v, const void *inp,
  function blst_sha256_hcopy (line 1316) | void blst_sha256_hcopy(unsigned int dst[8], const unsigned int src[8])
  function blst_sha256_emit (line 1324) | void blst_sha256_emit(unsigned char md[32], const unsigned int h[8])
  function blst_sha256_bcopy (line 1337) | void blst_sha256_bcopy(void *dst_, const void *src_, size_t len)

FILE: src/pairing.c
  function line_add (line 14) | static void line_add(vec384fp6 line, POINTonE2 *T, const POINTonE2 *R,
  function line_dbl (line 78) | static void line_dbl(vec384fp6 line, POINTonE2 *T, const POINTonE2 *Q)
  function line_by_Px2 (line 128) | static void line_by_Px2(vec384fp6 line, const POINTonE1_affine *Px2)
  function add_n_dbl (line 138) | static void add_n_dbl(vec384fp12 ret, POINTonE2 *T, const POINTonE2_affi...
  function miller_loop (line 150) | static void miller_loop(vec384fp12 ret, const POINTonE2 *Q, const POINTo...
  function start_dbl_n (line 181) | static void start_dbl_n(vec384fp12 ret, POINTonE2 T[],
  function add_n_dbl_n (line 199) | static void add_n_dbl_n(vec384fp12 ret, POINTonE2 T[],
  function miller_loop_n (line 220) | static void miller_loop_n(vec384fp12 ret, const POINTonE2_affine Q[],
  function pre_add_n_dbl (line 263) | static void pre_add_n_dbl(vec384fp6 lines[], POINTonE2 *T,
  function precompute_lines (line 272) | static void precompute_lines(vec384fp6 Qlines[68], const POINTonE2_affin...
  function post_line_by_Px2 (line 287) | static void post_line_by_Px2(vec384fp6 out, const vec384fp6 in,
  function post_add_n_dbl (line 299) | static void post_add_n_dbl(vec384fp12 ret, const vec384fp6 lines[],
  function miller_loop_lines (line 313) | static void miller_loop_lines(vec384fp12 ret, const vec384fp6 Qlines[68],
  function miller_loop_alt (line 338) | static void miller_loop_alt(vec384fp12 ret, const POINTonE2_affine *Q,
  function mul_n_sqr (line 348) | static void mul_n_sqr(vec384fp12 ret, const vec384fp12 a, size_t n)
  function raise_to_z_div_by_2 (line 355) | static void raise_to_z_div_by_2(vec384fp12 ret, const vec384fp12 a)
  function final_exp (line 371) | static void final_exp(vec384fp12 ret, const vec384fp12 f)
  function blst_miller_loop (line 406) | void blst_miller_loop(vec384fp12 ret, const POINTonE2_affine *Q,
  function blst_miller_loop_n (line 416) | void blst_miller_loop_n(vec384fp12 out, const POINTonE2_affine *const Qs[],
  function blst_final_exp (line 461) | void blst_final_exp(vec384fp12 ret, const vec384fp12 f)
  function blst_precompute_lines (line 464) | void blst_precompute_lines(vec384fp6 Qlines[68], const POINTonE2_affine *Q)
  function blst_miller_loop_lines (line 467) | void blst_miller_loop_lines(vec384fp12 ret, const vec384fp6 Qlines[68],
  function bool_t (line 471) | static bool_t is_cyclotomic(const vec384fp12 f)
  function blst_fp12_in_group (line 482) | int blst_fp12_in_group(const vec384fp12 f)

FILE: src/pentaroot.c
  function mul_fr (line 9) | static inline void mul_fr(vec256 ret, const vec256 a, const vec256 b)
  function sqr_fr (line 12) | static inline void sqr_fr(vec256 ret, const vec256 a)
  function blst_fr_pentaroot (line 16) | void blst_fr_pentaroot(vec256 out, const vec256 inp)
  function sqr_n_mul_fr (line 40) | static inline void sqr_n_mul_fr(vec256 out, const vec256 a, size_t count,
  function sqr_n_mul_fr (line 44) | static void sqr_n_mul_fr(vec256 out, const vec256 a, size_t count,
  function blst_fr_pentaroot (line 60) | void blst_fr_pentaroot(vec256 out, const vec256 inp)
  function blst_fr_pentapow (line 69) | void blst_fr_pentapow(vec256 out, const vec256 inp)

FILE: src/rb_tree.c
  type node (line 15) | struct node {
  type rb_tree (line 21) | struct rb_tree {
  function bytes_compare (line 27) | static long bytes_compare(const unsigned char *ptr0, size_t len0,
  function rb_tree_insert (line 45) | static int rb_tree_insert(struct rb_tree *tree, const void *data, size_t...
  function blst_uniq_sizeof (line 135) | size_t blst_uniq_sizeof(size_t n_nodes)
  function blst_uniq_init (line 138) | void blst_uniq_init(struct rb_tree *tree)
  function blst_uniq_test (line 144) | int blst_uniq_test(struct rb_tree *tree, const void *data, size_t len)

FILE: src/recip.c
  function flt_reciprocal_fp (line 16) | static void flt_reciprocal_fp(vec384 out, const vec384 inp)
  function flt_reciprocal_fp (line 32) | static void flt_reciprocal_fp(vec384 out, const vec384 inp)
  function flt_reciprocal_fp2 (line 42) | static void flt_reciprocal_fp2(vec384x out, const vec384x inp)
  function reciprocal_fp (line 58) | static void reciprocal_fp(vec384 out, const vec384 inp)
  function blst_fp_inverse (line 84) | void blst_fp_inverse(vec384 out, const vec384 inp)
  function blst_fp_eucl_inverse (line 87) | void blst_fp_eucl_inverse(vec384 ret, const vec384 a)
  function reciprocal_fp2 (line 90) | static void reciprocal_fp2(vec384x out, const vec384x inp)
  function blst_fp2_inverse (line 106) | void blst_fp2_inverse(vec384x out, const vec384x inp)
  function blst_fp2_eucl_inverse (line 109) | void blst_fp2_eucl_inverse(vec384x out, const vec384x inp)
  function reciprocal_fr (line 112) | static void reciprocal_fr(vec256 out, const vec256 inp)
  function blst_fr_inverse (line 125) | void blst_fr_inverse(vec256 out, const vec256 inp)
  function blst_fr_eucl_inverse (line 128) | void blst_fr_eucl_inverse(vec256 out, const vec256 inp)

FILE: src/sha256.h
  type SHA256_CTX (line 32) | typedef struct {
  function sha256_init_h (line 40) | static void sha256_init_h(unsigned int h[8])
  function sha256_init (line 52) | static void sha256_init(SHA256_CTX *ctx)
  function sha256_update (line 60) | static void sha256_update(SHA256_CTX *ctx, const void *_inp, size_t len)
  function sha256_emit (line 104) | static void sha256_emit(unsigned char md[32], const unsigned int h[8])
  function sha256_final (line 119) | static void sha256_final(unsigned char md[32], SHA256_CTX *ctx)

FILE: src/sqrt.c
  function recip_sqrt_fp_3mod4 (line 10) | static void recip_sqrt_fp_3mod4(vec384 out, const vec384 inp)
  function sqr_n_mul_fp (line 28) | static inline void sqr_n_mul_fp(vec384 out, const vec384 a, size_t count,
  function sqr_n_mul_fp (line 32) | static void sqr_n_mul_fp(vec384 out, const vec384 a, size_t count,
  function recip_sqrt_fp_3mod4 (line 48) | static void recip_sqrt_fp_3mod4(vec384 out, const vec384 inp)
  function bool_t (line 59) | static bool_t recip_sqrt_fp(vec384 out, const vec384 inp)
  function bool_t (line 74) | static bool_t sqrt_fp(vec384 out, const vec384 inp)
  function blst_fp_sqrt (line 89) | int blst_fp_sqrt(vec384 out, const vec384 inp)
  function blst_fp_is_square (line 92) | int blst_fp_is_square(const vec384 inp)
  function bool_t (line 97) | static bool_t sqrt_align_fp2(vec384x out, const vec384x ret,
  function bool_t (line 167) | static bool_t recip_sqrt_fp2(vec384x out, const vec384x inp,
  function bool_t (line 218) | static bool_t sqrt_fp2(vec384x out, const vec384x inp)
  function blst_fp2_sqrt (line 249) | int blst_fp2_sqrt(vec384x out, const vec384x inp)
  function blst_fp2_is_square (line 252) | int blst_fp2_is_square(const vec384x inp)

FILE: src/vect.c
  function lshift_mod_384 (line 21) | inline void lshift_mod_384(vec384 ret, const vec384 a, size_t n,
  function mul_by_8_mod_384 (line 30) | inline void mul_by_8_mod_384(vec384 ret, const vec384 a, const vec384 mod)
  function mul_by_3_mod_384 (line 35) | inline void mul_by_3_mod_384(vec384 ret, const vec384 a, const vec384 mod)
  function mul_by_3_mod_384x (line 45) | inline void mul_by_3_mod_384x(vec384x ret, const vec384x a, const vec384...
  function mul_by_8_mod_384x (line 53) | inline void mul_by_8_mod_384x(vec384x ret, const vec384x a, const vec384...
  function mul_by_1_plus_i_mod_384x (line 61) | inline void mul_by_1_plus_i_mod_384x(vec384x ret, const vec384x a,
  function add_mod_384x (line 73) | inline void add_mod_384x(vec384x ret, const vec384x a, const vec384x b,
  function sub_mod_384x (line 82) | inline void sub_mod_384x(vec384x ret, const vec384x a, const vec384x b,
  function lshift_mod_384x (line 91) | inline void lshift_mod_384x(vec384x ret, const vec384x a, size_t n,
  function mul_mont_384x (line 100) | void mul_mont_384x(vec384x ret, const vec384x a, const vec384x b,
  function sqr_mont_384x (line 123) | void sqr_mont_384x(vec384x ret, const vec384x a, const vec384 mod, limb_...
  function div_by_zz (line 144) | static void div_by_zz(limb_t val[])
  function div_by_z (line 163) | static void div_by_z(limb_t val[])

FILE: src/vect.h
  type limb_t (line 14) | typedef unsigned long long limb_t;
  type limb_t (line 18) | typedef unsigned __int64 limb_t;
  type limb_t (line 22) | typedef unsigned int limb_t;
  type limb_t (line 29) | typedef unsigned long limb_t;
  type limb_t (line 50) | typedef limb_t vec256[NLIMBS(256)];
  type limb_t (line 51) | typedef limb_t vec512[NLIMBS(512)];
  type limb_t (line 52) | typedef limb_t vec384[NLIMBS(384)];
  type limb_t (line 53) | typedef limb_t vec768[NLIMBS(768)];
  type vec384 (line 54) | typedef vec384 vec384x[2];
  type byte (line 56) | typedef unsigned char byte;
  type byte (line 61) | typedef byte pow256[256/8];
  type limb_t (line 67) | typedef limb_t bool_t;
  type __UINTPTR_TYPE__ (line 182) | typedef __UINTPTR_TYPE__ uptr_t;
  function bool_t (line 217) | static inline bool_t is_bit_set(const byte *v, size_t i)
  function bool_t (line 224) | static inline bool_t byte_is_zero(unsigned char c)
  function bool_t (line 231) | static inline bool_t bytes_are_zero(const unsigned char *a, size_t num)
  function vec_cswap (line 242) | static inline void vec_cswap(void *restrict a, void *restrict b, size_t ...
  function vec_select (line 269) | static inline void vec_select(void *ret, const void *a, const void *b,
  function bool_t (line 300) | static inline bool_t is_zero(limb_t l)
  function bool_t (line 307) | static inline bool_t vec_is_zero(const void *a, size_t num)
  function bool_t (line 327) | static inline bool_t vec_is_equal(const void *a, const void *b, size_t num)
  function cneg_mod_384x (line 348) | static inline void cneg_mod_384x(vec384x ret, const vec384x a, bool_t flag,
  function vec_copy (line 355) | static inline void vec_copy(void *restrict ret, const void *a, size_t num)
  function vec_zero (line 367) | static inline void vec_zero(void *ret, size_t num)
  function vec_czero (line 382) | static inline void vec_czero(void *ret, size_t num, bool_t cbit)
Condensed preview — 229 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,262K chars).
[
  {
    "path": ".gitattributes",
    "chars": 83,
    "preview": "*.pl linguist-language=assembly\n*.h linguist-language=c\n*.tgo linguist-language=go\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 9500,
    "preview": "name: build\n\non:\n  push:\n    branches:\n    - '**'\n  workflow_dispatch:\n    branches:\n    - '**'\n  pull_request:\n    bran"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 1230,
    "preview": "name: \"CodeQL\"\n\non:\n  push:\n    branches:\n      - '**'\n    paths:\n      - 'src/*'\n      - 'bindings/c#/*'\n      - '.gith"
  },
  {
    "path": ".github/workflows/golang-lint.yml",
    "chars": 2026,
    "preview": "name: golang-lint\n\non:\n  push:\n    branches:\n      - '**'\n    paths:\n      - 'bindings/go/*.go'\n      - '.github/workflo"
  },
  {
    "path": ".gitignore",
    "chars": 696,
    "preview": "# Prerequisites\n*.d\n\n# Object files\n*.o\n*.ko\n*.obj\n*.elf\n\n# Linker output\n*.ilk\n*.map\n*.exp\n\n# Precompiled Headers\n*.gch"
  },
  {
    "path": ".golangci.yml",
    "chars": 2481,
    "preview": "version: \"2\"\nlinters:\n  default: all\n  disable:\n    # just whining\n    - copyloopvar                       # go>=1.22\n  "
  },
  {
    "path": ".lgtm.yml",
    "chars": 373,
    "preview": "queries:\n  - include: \"*\"\n  - exclude: cpp/unused-static-function\n  - exclude: cpp/include-non-header\n  - exclude: cs/ca"
  },
  {
    "path": ".travis.yml",
    "chars": 1789,
    "preview": "branches:\n    only:\n      - /.*/\n\nlanguage: rust\n\ngit:\n    quiet: true\n\nos:\n    - linux\n\narch:\n    - arm64\n    - s390x\n\n"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 15681,
    "preview": "[![Actions status](https://github.com/supranational/blst/workflows/build/badge.svg)](https://github.com/supranational/bl"
  },
  {
    "path": "SECURITY.md",
    "chars": 428,
    "preview": "# Security Policy\n\n## Reporting a Vulnerability\n\nTo report security issues please send an e-mail to hello@supranational."
  },
  {
    "path": "bindings/blst.h",
    "chars": 23486,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/blst.hpp",
    "chars": 37562,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/blst.swg",
    "chars": 34154,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/blst_aux.h",
    "chars": 4847,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/c#/poc.cs",
    "chars": 2662,
    "preview": "using System;\nusing System.Text;\nusing supranational;\n\nclass PoC {\n  private static void Main(string[] args)\n  {\n    var"
  },
  {
    "path": "bindings/c#/poc.csproj",
    "chars": 191,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</Targe"
  },
  {
    "path": "bindings/c#/run.me",
    "chars": 35137,
    "preview": "#!/usr/bin/env python3\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for d"
  },
  {
    "path": "bindings/c#/supranational.blst.cs",
    "chars": 44635,
    "preview": "//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// DO NOT EDIT THIS FILE!!!\n// The file is auto-generated by run.me\n"
  },
  {
    "path": "bindings/go/README.md",
    "chars": 6449,
    "preview": "# blst [![Lint Status](https://github.com/supranational/blst/workflows/golang-lint/badge.svg)](https://github.com/supran"
  },
  {
    "path": "bindings/go/blst.go",
    "chars": 85190,
    "preview": "// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// DO NOT MODIFY THIS FILE!!\n// The file is generated from *.tgo by "
  },
  {
    "path": "bindings/go/blst.tgo",
    "chars": 14546,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/go/blst_htoc_test.go",
    "chars": 5339,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/go/blst_miller_loop_test.go",
    "chars": 814,
    "preview": "package blst\n\nimport (\n    \"crypto/rand\"\n    \"testing\"\n)\n\nfunc TestMillerLoopN(t *testing.T) {\n    t.Parallel()\n    cons"
  },
  {
    "path": "bindings/go/blst_minpk.tgo",
    "chars": 18104,
    "preview": "\nimport (\n    \"runtime\"\n    \"sync\"\n    \"sync/atomic\"\n)\n\n//\n// PublicKey\n//\n\nfunc (pk *P1Affine) From(s *Scalar) *P1Affin"
  },
  {
    "path": "bindings/go/blst_minpk_test.go",
    "chars": 22999,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/go/blst_minsig_test.go",
    "chars": 23335,
    "preview": "// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// DO NOT EDIT THIS FILE!!\n// The file is generated from blst_minpk_"
  },
  {
    "path": "bindings/go/blst_misc.tgo",
    "chars": 7549,
    "preview": "\nimport \"fmt\"\n\n//\n// Parse out optional arguments for sign and verify.\n//  augSingle []byte - augmentation bytes for agg"
  },
  {
    "path": "bindings/go/blst_px.tgo",
    "chars": 22920,
    "preview": "func PairingAggregatePkInG1(ctx Pairing, PK *P1Affine, pkValidate bool,\n                            sig *P2Affine, sigGr"
  },
  {
    "path": "bindings/go/blst_wasm.go",
    "chars": 38,
    "preview": "//go:build wasm\npackage not_supported\n"
  },
  {
    "path": "bindings/go/cgo_assembly.S",
    "chars": 22,
    "preview": "#include \"assembly.S\"\n"
  },
  {
    "path": "bindings/go/cgo_server.c",
    "chars": 20,
    "preview": "#include \"server.c\"\n"
  },
  {
    "path": "bindings/go/generate.py",
    "chars": 3692,
    "preview": "#!/usr/bin/env python3\n\nimport os\nimport sys\nimport re\nimport subprocess\n\nhere = re.split(r'/(?=[^/]*$)', sys.argv[0])\ni"
  },
  {
    "path": "bindings/go/rb_tree.go",
    "chars": 3480,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "bindings/rust/Cargo.toml",
    "chars": 1975,
    "preview": "[package]\nname = \"blst\"\nversion = \"0.3.16\"\nauthors = [\"sean-sn <sean@supranational.net>\"]\nedition = \"2018\"\nlicense = \"Ap"
  },
  {
    "path": "bindings/rust/README.md",
    "chars": 3348,
    "preview": "# blst [![Crates.io](https://img.shields.io/crates/v/blst.svg)](https://crates.io/crates/blst)\n\nThe `blst` crate provide"
  },
  {
    "path": "bindings/rust/benches/blst_benches.rs",
    "chars": 13865,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/rust/build.rs",
    "chars": 8943,
    "preview": "#![allow(unused_imports)]\n\nextern crate cc;\n\nuse std::env;\nuse std::path::{Path, PathBuf};\n\nfn assembly(\n    file_vec: &"
  },
  {
    "path": "bindings/rust/publish.sh",
    "chars": 247,
    "preview": "#!/bin/sh\n\nHERE=`dirname $0`\ncd \"${HERE}\"\n\nif [ ! -d blst ]; then\n    trap '[ -h blst ] && rm -f blst' 0 2\n    ln -s ../"
  },
  {
    "path": "bindings/rust/rustfmt.toml",
    "chars": 15,
    "preview": "max_width = 80\n"
  },
  {
    "path": "bindings/rust/src/bindings.rs",
    "chars": 37392,
    "preview": "/* automatically generated by rust-bindgen 0.65.1 */\n\n#[repr(u32)]\n#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]\npu"
  },
  {
    "path": "bindings/rust/src/lib.rs",
    "chars": 79770,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/rust/src/pippenger-no_std.rs",
    "chars": 5019,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/rust/src/pippenger-test_mod.rs",
    "chars": 2992,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/rust/src/pippenger.rs",
    "chars": 18678,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "bindings/vectors/hash_to_curve/BLS12381G1_XMD_SHA-256_SSWU_NU_.json",
    "chars": 4430,
    "preview": "{\n  \"L\": \"0x40\",\n  \"Z\": \"0xb\",\n  \"ciphersuite\": \"BLS12381G1_XMD:SHA-256_SSWU_NU_\",\n  \"curve\": \"BLS12-381 G1\",\n  \"dst\": \""
  },
  {
    "path": "bindings/vectors/hash_to_curve/BLS12381G1_XMD_SHA-256_SSWU_RO_.json",
    "chars": 6244,
    "preview": "{\n  \"L\": \"0x40\",\n  \"Z\": \"0xb\",\n  \"ciphersuite\": \"BLS12381G1_XMD:SHA-256_SSWU_RO_\",\n  \"curve\": \"BLS12-381 G1\",\n  \"dst\": \""
  },
  {
    "path": "bindings/vectors/hash_to_curve/BLS12381G2_XMD_SHA-256_SSWU_NU_.json",
    "chars": 7099,
    "preview": "{\n  \"L\": \"0x40\",\n  \"Z\": \"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa"
  },
  {
    "path": "bindings/vectors/hash_to_curve/BLS12381G2_XMD_SHA-256_SSWU_RO_.json",
    "chars": 10398,
    "preview": "{\n  \"L\": \"0x40\",\n  \"Z\": \"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa"
  },
  {
    "path": "bindings/vectors/hash_to_curve/README",
    "chars": 210,
    "preview": "These files are downloaded from https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/tree/master/poc/vectors, commit 6d"
  },
  {
    "path": "bindings/vectors/hash_to_curve/expand_message_xmd_SHA256_256.json",
    "chars": 9947,
    "preview": "{\n  \"DST\": \"QUUX-V01-CS02-with-expander-SHA256-128-long-DST-111111111111111111111111111111111111111111111111111111111111"
  },
  {
    "path": "bindings/vectors/hash_to_curve/expand_message_xmd_SHA256_38.json",
    "chars": 9969,
    "preview": "{\n  \"DST\": \"QUUX-V01-CS02-with-expander-SHA256-128\",\n  \"hash\": \"SHA256\",\n  \"k\": 128,\n  \"name\": \"expand_message_xmd\",\n  \""
  },
  {
    "path": "bindings/zig/README.md",
    "chars": 846,
    "preview": "# blst for [Zig](https://ziglang.org/)\n\nThe object-oriented interface is modeled after [C++ interface](../blst.hpp), but"
  },
  {
    "path": "bindings/zig/blst.zig",
    "chars": 19768,
    "preview": "//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n// DO NOT EDIT THIS FILE!!!\n// The file is auto-generated by generat"
  },
  {
    "path": "bindings/zig/c.zig",
    "chars": 33914,
    "preview": "// automatically generated with 'zig translate-c'\nconst BLST_SUCCESS: c_int = 0;\nconst BLST_BAD_ENCODING: c_int = 1;\ncon"
  },
  {
    "path": "bindings/zig/generate.py",
    "chars": 15698,
    "preview": "#!/usr/bin/env python3\n\nimport os, re, sys, subprocess\n\ntop_zig = \"\"\"\n// Copyright Supranational LLC\n// SPDX-License-Ide"
  },
  {
    "path": "bindings/zig/tests.zig",
    "chars": 3293,
    "preview": "const std = @import(\"std\");\nconst blst = @import(\"blst\");\n\ntest \"sign/verify\" {\n    const password = [_]u8{'*'} ** 32;\n\n"
  },
  {
    "path": "build/assembly.S",
    "chars": 5892,
    "preview": "#if defined(__x86_64) || defined(__x86_64__)\n# if defined(__ELF__)\n#  if defined(__BLST_PORTABLE__)\n#   include \"elf/sha"
  },
  {
    "path": "build/bindings_trim.pl",
    "chars": 1103,
    "preview": "#!/usr/bin/env perl\n\n# read whole file\nwhile(<>) { push @file, $_; }\n\n# traverse and remove auto-generated PartialEq for"
  },
  {
    "path": "build/cheri/add_mod_256-armv8.S",
    "chars": 6083,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/add_mod_384-armv8.S",
    "chars": 20980,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/ct_inverse_mod_256-armv8.S",
    "chars": 20019,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/ct_inverse_mod_384-armv8.S",
    "chars": 19631,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/ct_is_square_mod_384-armv8.S",
    "chars": 8169,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/div3w-armv8.S",
    "chars": 2247,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/mul_mont_256-armv8.S",
    "chars": 9042,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/mul_mont_384-armv8.S",
    "chars": 45503,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/cheri/sha256-armv8.S",
    "chars": 23602,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/coff/add_mod_256-armv8.S",
    "chars": 5212,
    "preview": ".text\n\n.globl\tadd_mod_256\n\n.def\tadd_mod_256;\n.type\t32;\n.endef\n.p2align\t5\nadd_mod_256:\n\thint\t#34\n\tldp\tx8,x9,[x1]\n\tldp\tx12"
  },
  {
    "path": "build/coff/add_mod_256-x86_64.s",
    "chars": 16767,
    "preview": ".text\t\n\n.globl\tadd_mod_256\n\n.def\tadd_mod_256;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nadd_mod_256:\n\t.byte\t0xf3,0x0f,0x1e,0xf"
  },
  {
    "path": "build/coff/add_mod_384-armv8.S",
    "chars": 18954,
    "preview": ".text\n\n.globl\tadd_mod_384\n\n.def\tadd_mod_384;\n.type\t32;\n.endef\n.p2align\t5\nadd_mod_384:\n\thint\t#25\n\tstp\tx29,x30,[sp,#-6*__S"
  },
  {
    "path": "build/coff/add_mod_384-x86_64.s",
    "chars": 47137,
    "preview": ".text\t\n\n.globl\tadd_mod_384\n\n.def\tadd_mod_384;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nadd_mod_384:\n\t.byte\t0xf3,0x0f,0x1e,0xf"
  },
  {
    "path": "build/coff/add_mod_384x384-x86_64.s",
    "chars": 5533,
    "preview": ".text\t\n\n.globl\tadd_mod_384x384\n\n.def\tadd_mod_384x384;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nadd_mod_384x384:\n\t.byte\t0xf3,0"
  },
  {
    "path": "build/coff/ct_inverse_mod_256-armv8.S",
    "chars": 19274,
    "preview": ".text\n\n.globl\tct_inverse_mod_256\n\n.def\tct_inverse_mod_256;\n.type\t32;\n.endef\n.p2align\t5\nct_inverse_mod_256:\n\thint\t#25\n\tst"
  },
  {
    "path": "build/coff/ct_inverse_mod_256-x86_64.s",
    "chars": 19476,
    "preview": ".text\t\n\n.globl\tct_inverse_mod_256\n\n.def\tct_inverse_mod_256;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nct_inverse_mod_256:\n\t.by"
  },
  {
    "path": "build/coff/ct_inverse_mod_384-armv8.S",
    "chars": 18940,
    "preview": ".text\n\n.globl\tct_inverse_mod_384\n\n.def\tct_inverse_mod_384;\n.type\t32;\n.endef\n.p2align\t5\nct_inverse_mod_384:\n\thint\t#25\n\tst"
  },
  {
    "path": "build/coff/ct_is_square_mod_384-armv8.S",
    "chars": 7510,
    "preview": ".text\n\n.globl\tct_is_square_mod_384\n\n.def\tct_is_square_mod_384;\n.type\t32;\n.endef\n.p2align\t5\nct_is_square_mod_384:\n\thint\t#"
  },
  {
    "path": "build/coff/ct_is_square_mod_384-x86_64.s",
    "chars": 8187,
    "preview": ".text\t\n\n.globl\tct_is_square_mod_384\n\n.def\tct_is_square_mod_384;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nct_is_square_mod_384"
  },
  {
    "path": "build/coff/ctq_inverse_mod_384-x86_64.s",
    "chars": 20517,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tct_inverse_mod_384\n\n.def\tct_inverse_mod_384;\t.scl 2;\t.type 32;\t.endef\n.p2alig"
  },
  {
    "path": "build/coff/ctx_inverse_mod_384-x86_64.s",
    "chars": 27407,
    "preview": ".text\t\n\n.globl\tctx_inverse_mod_384\n\n.def\tctx_inverse_mod_384;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nctx_inverse_mod_384:\n\t"
  },
  {
    "path": "build/coff/div3w-armv8.S",
    "chars": 1709,
    "preview": ".text\n\n.globl\tdiv_3_limbs\n\n.def\tdiv_3_limbs;\n.type\t32;\n.endef\n.p2align\t5\ndiv_3_limbs:\n\thint\t#34\n\tldp\tx4,x5,[x0]\t// load "
  },
  {
    "path": "build/coff/div3w-x86_64.s",
    "chars": 4487,
    "preview": ".text\t\n\n.globl\tdiv_3_limbs\n\n.def\tdiv_3_limbs;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\ndiv_3_limbs:\n\t.byte\t0xf3,0x0f,0x1e,0xf"
  },
  {
    "path": "build/coff/mul_mont_256-armv8.S",
    "chars": 8309,
    "preview": ".text\n\n.globl\tmul_mont_sparse_256\n\n.def\tmul_mont_sparse_256;\n.type\t32;\n.endef\n.p2align\t5\nmul_mont_sparse_256:\n\thint\t#34\n"
  },
  {
    "path": "build/coff/mul_mont_384-armv8.S",
    "chars": 43628,
    "preview": ".text\n\n.globl\tadd_mod_384x384\n\n.def\tadd_mod_384x384;\n.type\t32;\n.endef\n.p2align\t5\nadd_mod_384x384:\n\thint\t#25\n\tstp\tx29,x30"
  },
  {
    "path": "build/coff/mulq_mont_256-x86_64.s",
    "chars": 14121,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tmul_mont_sparse_256\n\n.def\tmul_mont_sparse_256;\t.scl 2;\t.type 32;\t.endef\n.p2al"
  },
  {
    "path": "build/coff/mulq_mont_384-x86_64.s",
    "chars": 66153,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n\n\n\n\n\n\n.def\t__subq_mod_384x384;\t.scl 3;\t.type 32;\t.endef\n.p2align\t5\n__subq_mod_384x38"
  },
  {
    "path": "build/coff/mulx_mont_256-x86_64.s",
    "chars": 13302,
    "preview": ".text\t\n\n.globl\tmulx_mont_sparse_256\n\n.def\tmulx_mont_sparse_256;\t.scl 2;\t.type 32;\t.endef\n.p2align\t5\nmulx_mont_sparse_256"
  },
  {
    "path": "build/coff/mulx_mont_384-x86_64.s",
    "chars": 60704,
    "preview": ".text\t\n\n\n\n\n\n\n\n.def\t__subx_mod_384x384;\t.scl 3;\t.type 32;\t.endef\n.p2align\t5\n__subx_mod_384x384:\n\t.byte\t0xf3,0x0f,0x1e,0xf"
  },
  {
    "path": "build/coff/sha256-armv8.S",
    "chars": 22767,
    "preview": "//\n// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Li"
  },
  {
    "path": "build/coff/sha256-portable-x86_64.s",
    "chars": 26835,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tblst_sha256_block_data_order\n.def\tblst_sha256_block_data_order;\t.scl 2;\t.type"
  },
  {
    "path": "build/coff/sha256-x86_64.s",
    "chars": 29801,
    "preview": ".comm\t__blst_platform_cap,4\n\n.section\t.rdata\n.p2align\t6\n\nK256:\n.long\t0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5\n.long\t0"
  },
  {
    "path": "build/elf/add_mod_256-armv8.S",
    "chars": 6083,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/add_mod_256-x86_64.s",
    "chars": 10183,
    "preview": ".text\t\n\n.globl\tadd_mod_256\n.hidden\tadd_mod_256\n.type\tadd_mod_256,@function\n.align\t32\nadd_mod_256:\n.cfi_startproc\n\t.byte\t"
  },
  {
    "path": "build/elf/add_mod_384-armv8.S",
    "chars": 20903,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/add_mod_384-x86_64.s",
    "chars": 37778,
    "preview": ".text\t\n\n.globl\tadd_mod_384\n.hidden\tadd_mod_384\n.type\tadd_mod_384,@function\n.align\t32\nadd_mod_384:\n.cfi_startproc\n\t.byte\t"
  },
  {
    "path": "build/elf/add_mod_384x384-x86_64.s",
    "chars": 4310,
    "preview": ".text\t\n\n.globl\tadd_mod_384x384\n.hidden\tadd_mod_384x384\n.type\tadd_mod_384x384,@function\n.align\t32\nadd_mod_384x384:\n.cfi_s"
  },
  {
    "path": "build/elf/ct_inverse_mod_256-armv8.S",
    "chars": 20005,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/ct_inverse_mod_256-x86_64.s",
    "chars": 19261,
    "preview": ".text\t\n\n.globl\tct_inverse_mod_256\n.hidden\tct_inverse_mod_256\n.type\tct_inverse_mod_256,@function\n.align\t32\nct_inverse_mod"
  },
  {
    "path": "build/elf/ct_inverse_mod_384-armv8.S",
    "chars": 19616,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/ct_is_square_mod_384-armv8.S",
    "chars": 8157,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/ct_is_square_mod_384-x86_64.s",
    "chars": 7851,
    "preview": ".text\t\n\n.globl\tct_is_square_mod_384\n.hidden\tct_is_square_mod_384\n.type\tct_is_square_mod_384,@function\n.align\t32\nct_is_sq"
  },
  {
    "path": "build/elf/ctq_inverse_mod_384-x86_64.s",
    "chars": 20226,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tct_inverse_mod_384\n.hidden\tct_inverse_mod_384\n.type\tct_inverse_mod_384,@funct"
  },
  {
    "path": "build/elf/ctx_inverse_mod_384-x86_64.s",
    "chars": 27224,
    "preview": ".text\t\n\n.globl\tctx_inverse_mod_384\n.hidden\tctx_inverse_mod_384\n.type\tctx_inverse_mod_384,@function\n.align\t32\nctx_inverse"
  },
  {
    "path": "build/elf/div3w-armv8.S",
    "chars": 2247,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/div3w-x86_64.s",
    "chars": 2133,
    "preview": ".text\t\n\n.globl\tdiv_3_limbs\n.hidden\tdiv_3_limbs\n.type\tdiv_3_limbs,@function\n.align\t32\ndiv_3_limbs:\n.cfi_startproc\n\t.byte\t"
  },
  {
    "path": "build/elf/mul_mont_256-armv8.S",
    "chars": 9025,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/mul_mont_384-armv8.S",
    "chars": 45302,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/mulq_mont_256-x86_64.s",
    "chars": 11593,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tmul_mont_sparse_256\n.hidden\tmul_mont_sparse_256\n.type\tmul_mont_sparse_256,@fu"
  },
  {
    "path": "build/elf/mulq_mont_384-x86_64.s",
    "chars": 56936,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n\n\n\n\n\n\n.type\t__subq_mod_384x384,@function\n.align\t32\n__subq_mod_384x384:\n.cfi_startpro"
  },
  {
    "path": "build/elf/mulx_mont_256-x86_64.s",
    "chars": 10722,
    "preview": ".text\t\n\n.globl\tmulx_mont_sparse_256\n.hidden\tmulx_mont_sparse_256\n.type\tmulx_mont_sparse_256,@function\n.align\t32\nmulx_mon"
  },
  {
    "path": "build/elf/mulx_mont_384-x86_64.s",
    "chars": 51371,
    "preview": ".text\t\n\n\n\n\n\n\n\n.type\t__subx_mod_384x384,@function\n.align\t32\n__subx_mod_384x384:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,0xfa"
  },
  {
    "path": "build/elf/sha256-armv8.S",
    "chars": 23557,
    "preview": "#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT==2\n# define PACI_HINT 27\n# define AUTI_HINT 31\n#else"
  },
  {
    "path": "build/elf/sha256-portable-x86_64.s",
    "chars": 26196,
    "preview": ".comm\t__blst_platform_cap,4\n.text\t\n\n.globl\tblst_sha256_block_data_order\n.type\tblst_sha256_block_data_order,@function\n.al"
  },
  {
    "path": "build/elf/sha256-x86_64.s",
    "chars": 27458,
    "preview": ".comm\t__blst_platform_cap,4\n\n.section\t.rodata\n.align\t64\n.type\tK256,@object\nK256:\n.long\t0x428a2f98,0x71374491,0xb5c0fbcf,"
  },
  {
    "path": "build/mach-o/add_mod_256-armv8.S",
    "chars": 5154,
    "preview": ".text\n\n.globl\t_add_mod_256\n.private_extern\t_add_mod_256\n\n.align\t5\n_add_mod_256:\n\thint\t#34\n\tldp\tx8,x9,[x1]\n\tldp\tx12,x13,["
  },
  {
    "path": "build/mach-o/add_mod_256-x86_64.s",
    "chars": 9416,
    "preview": ".text\t\n\n.globl\t_add_mod_256\n.private_extern\t_add_mod_256\n\n.p2align\t5\n_add_mod_256:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,"
  },
  {
    "path": "build/mach-o/add_mod_384-armv8.S",
    "chars": 18640,
    "preview": ".text\n\n.globl\t_add_mod_384\n.private_extern\t_add_mod_384\n\n.align\t5\n_add_mod_384:\n\thint\t#25\n\tstp\tx29,x30,[sp,#-6*__SIZEOF_"
  },
  {
    "path": "build/mach-o/add_mod_384-x86_64.s",
    "chars": 35958,
    "preview": ".text\t\n\n.globl\t_add_mod_384\n.private_extern\t_add_mod_384\n\n.p2align\t5\n_add_mod_384:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,"
  },
  {
    "path": "build/mach-o/add_mod_384x384-x86_64.s",
    "chars": 4003,
    "preview": ".text\t\n\n.globl\t_add_mod_384x384\n.private_extern\t_add_mod_384x384\n\n.p2align\t5\n_add_mod_384x384:\n.cfi_startproc\n\t.byte\t0xf"
  },
  {
    "path": "build/mach-o/ct_inverse_mod_256-armv8.S",
    "chars": 18994,
    "preview": ".text\n\n.globl\t_ct_inverse_mod_256\n.private_extern\t_ct_inverse_mod_256\n\n.align\t5\n_ct_inverse_mod_256:\n\thint\t#25\n\tstp\tx29,"
  },
  {
    "path": "build/mach-o/ct_inverse_mod_256-x86_64.s",
    "chars": 18511,
    "preview": ".text\t\n\n.globl\t_ct_inverse_mod_256\n.private_extern\t_ct_inverse_mod_256\n\n.p2align\t5\n_ct_inverse_mod_256:\n.cfi_startproc\n\t"
  },
  {
    "path": "build/mach-o/ct_inverse_mod_384-armv8.S",
    "chars": 18714,
    "preview": ".text\n\n.globl\t_ct_inverse_mod_384\n.private_extern\t_ct_inverse_mod_384\n\n.align\t5\n_ct_inverse_mod_384:\n\thint\t#25\n\tstp\tx29,"
  },
  {
    "path": "build/mach-o/ct_is_square_mod_384-armv8.S",
    "chars": 7319,
    "preview": ".text\n\n.globl\t_ct_is_square_mod_384\n.private_extern\t_ct_is_square_mod_384\n\n.align\t5\n_ct_is_square_mod_384:\n\thint\t#25\n\tst"
  },
  {
    "path": "build/mach-o/ct_is_square_mod_384-x86_64.s",
    "chars": 7264,
    "preview": ".text\t\n\n.globl\t_ct_is_square_mod_384\n.private_extern\t_ct_is_square_mod_384\n\n.p2align\t5\n_ct_is_square_mod_384:\n.cfi_start"
  },
  {
    "path": "build/mach-o/ctq_inverse_mod_384-x86_64.s",
    "chars": 19586,
    "preview": ".comm\t___blst_platform_cap,4\n.text\t\n\n.globl\t_ct_inverse_mod_384\n.private_extern\t_ct_inverse_mod_384\n\n.p2align\t5\n_ct_inve"
  },
  {
    "path": "build/mach-o/ctx_inverse_mod_384-x86_64.s",
    "chars": 26413,
    "preview": ".text\t\n\n.globl\t_ctx_inverse_mod_384\n.private_extern\t_ctx_inverse_mod_384\n\n.p2align\t5\n_ctx_inverse_mod_384:\n.cfi_startpro"
  },
  {
    "path": "build/mach-o/div3w-armv8.S",
    "chars": 1689,
    "preview": ".text\n\n.globl\t_div_3_limbs\n.private_extern\t_div_3_limbs\n\n.align\t5\n_div_3_limbs:\n\thint\t#34\n\tldp\tx4,x5,[x0]\t// load R\n\teor"
  },
  {
    "path": "build/mach-o/div3w-x86_64.s",
    "chars": 1801,
    "preview": ".text\t\n\n.globl\t_div_3_limbs\n.private_extern\t_div_3_limbs\n\n.p2align\t5\n_div_3_limbs:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,"
  },
  {
    "path": "build/mach-o/mul_mont_256-armv8.S",
    "chars": 8241,
    "preview": ".text\n\n.globl\t_mul_mont_sparse_256\n.private_extern\t_mul_mont_sparse_256\n\n.align\t5\n_mul_mont_sparse_256:\n\thint\t#34\n\tstp\tx"
  },
  {
    "path": "build/mach-o/mul_mont_384-armv8.S",
    "chars": 43131,
    "preview": ".text\n\n.globl\t_add_mod_384x384\n.private_extern\t_add_mod_384x384\n\n.align\t5\n_add_mod_384x384:\n\thint\t#25\n\tstp\tx29,x30,[sp,#"
  },
  {
    "path": "build/mach-o/mulq_mont_256-x86_64.s",
    "chars": 10997,
    "preview": ".comm\t___blst_platform_cap,4\n.text\t\n\n.globl\t_mul_mont_sparse_256\n.private_extern\t_mul_mont_sparse_256\n\n.p2align\t5\n_mul_m"
  },
  {
    "path": "build/mach-o/mulq_mont_384-x86_64.s",
    "chars": 55381,
    "preview": ".comm\t___blst_platform_cap,4\n.text\t\n\n\n\n\n\n\n\n\n.p2align\t5\n__subq_mod_384x384:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,0xfa\n\n\tm"
  },
  {
    "path": "build/mach-o/mulx_mont_256-x86_64.s",
    "chars": 10109,
    "preview": ".text\t\n\n.globl\t_mulx_mont_sparse_256\n.private_extern\t_mulx_mont_sparse_256\n\n.p2align\t5\n_mulx_mont_sparse_256:\n.cfi_start"
  },
  {
    "path": "build/mach-o/mulx_mont_384-x86_64.s",
    "chars": 49755,
    "preview": ".text\t\n\n\n\n\n\n\n\n\n.p2align\t5\n__subx_mod_384x384:\n.cfi_startproc\n\t.byte\t0xf3,0x0f,0x1e,0xfa\n\n\tmovq\t0(%rsi),%r8\n\tmovq\t8(%rsi)"
  },
  {
    "path": "build/mach-o/sha256-armv8.S",
    "chars": 22727,
    "preview": "//\n// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Li"
  },
  {
    "path": "build/mach-o/sha256-portable-x86_64.s",
    "chars": 25704,
    "preview": ".comm\t___blst_platform_cap,4\n.text\t\n\n.globl\t_blst_sha256_block_data_order\n\n.p2align\t4\n_blst_sha256_block_data_order:\n.cf"
  },
  {
    "path": "build/mach-o/sha256-x86_64.s",
    "chars": 26858,
    "preview": ".comm\t___blst_platform_cap,4\n\n.section\t__TEXT,__const\n.p2align\t6\n\nK256:\n.long\t0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba"
  },
  {
    "path": "build/refresh.sh",
    "chars": 1330,
    "preview": "#!/bin/sh\n\nHERE=`dirname $0`\ncd \"${HERE}\"\n\nPERL=${PERL:-perl}\n\nfor pl in ../src/asm/*-x86_64.pl; do\n    s=`basename $pl "
  },
  {
    "path": "build/srcroot.go",
    "chars": 202,
    "preview": "package blst\n\nimport (\n    \"path/filepath\"\n    \"runtime\"\n)\n\nvar SrcRoot string\n\nfunc init() {\n    if _, self, _, ok := r"
  },
  {
    "path": "build/win64/add_mod_256-armv8.asm",
    "chars": 5115,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|add_mod_256|[FUNC]\n\tA"
  },
  {
    "path": "build/win64/add_mod_256-x86_64.asm",
    "chars": 17800,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tadd_mod_256\n\n\nALIGN\t32\nadd_mod_256\tPROC PUBLIC\n\tDB\t243,15,30,250"
  },
  {
    "path": "build/win64/add_mod_384-armv8.asm",
    "chars": 18277,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|add_mod_384|[FUNC]\n\tA"
  },
  {
    "path": "build/win64/add_mod_384-x86_64.asm",
    "chars": 50986,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tadd_mod_384\n\n\nALIGN\t32\nadd_mod_384\tPROC PUBLIC\n\tDB\t243,15,30,250"
  },
  {
    "path": "build/win64/add_mod_384x384-x86_64.asm",
    "chars": 6280,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tadd_mod_384x384\n\n\nALIGN\t32\nadd_mod_384x384\tPROC PUBLIC\n\tDB\t243,1"
  },
  {
    "path": "build/win64/blst.def",
    "chars": 4636,
    "preview": "LIBRARY blst\n\nEXPORTS\n\tblst_scalar_from_uint32\n\tblst_uint32_from_scalar\n\tblst_scalar_from_uint64\n\tblst_uint64_from_scala"
  },
  {
    "path": "build/win64/ct_inverse_mod_256-armv8.asm",
    "chars": 14368,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|ct_inverse_mod_256|[F"
  },
  {
    "path": "build/win64/ct_inverse_mod_256-x86_64.asm",
    "chars": 20503,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tct_inverse_mod_256\n\n\nALIGN\t32\nct_inverse_mod_256\tPROC PUBLIC\n\tDB"
  },
  {
    "path": "build/win64/ct_inverse_mod_384-armv8.asm",
    "chars": 14721,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|ct_inverse_mod_384|[F"
  },
  {
    "path": "build/win64/ct_is_square_mod_384-armv8.asm",
    "chars": 5857,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|ct_is_square_mod_384|"
  },
  {
    "path": "build/win64/ct_is_square_mod_384-x86_64.asm",
    "chars": 8100,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tct_is_square_mod_384\n\n\nALIGN\t32\nct_is_square_mod_384\tPROC PUBLIC"
  },
  {
    "path": "build/win64/ctq_inverse_mod_384-x86_64.asm",
    "chars": 21610,
    "preview": "OPTION\tDOTNAME\nEXTERN\tct_inverse_mod_384$1:NEAR\n_DATA\tSEGMENT\nCOMM\t__blst_platform_cap:DWORD:1\n_DATA\tENDS\n.text$\tSEGMENT"
  },
  {
    "path": "build/win64/ctx_inverse_mod_384-x86_64.asm",
    "chars": 29625,
    "preview": "OPTION\tDOTNAME\nPUBLIC\tct_inverse_mod_384$1\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tctx_inverse_mod_384\n\n\nALIGN\t32\nctx_i"
  },
  {
    "path": "build/win64/div3w-armv8.asm",
    "chars": 1083,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|div_3_limbs|[FUNC]\n\tA"
  },
  {
    "path": "build/win64/div3w-x86_64.asm",
    "chars": 4795,
    "preview": "OPTION\tDOTNAME\n.text$\tSEGMENT ALIGN(256) 'CODE'\n\nPUBLIC\tdiv_3_limbs\n\n\nALIGN\t32\ndiv_3_limbs\tPROC PUBLIC\n\tDB\t243,15,30,250"
  },
  {
    "path": "build/win64/dll.c",
    "chars": 665,
    "preview": "#include <windows.h>\n\n#if defined(_MSC_VER)\n/*\n * Even though we don't have memcpy/memset anywhere, MSVC compiler\n * gen"
  },
  {
    "path": "build/win64/mul_mont_256-armv8.asm",
    "chars": 7112,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|mul_mont_sparse_256|["
  },
  {
    "path": "build/win64/mul_mont_384-armv8.asm",
    "chars": 41283,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\tAREA\t|.text|,CODE,ALIGN=8,ARM64\n\n\n\n\tEXPORT\t|add_mod_384x384|[FUNC"
  },
  {
    "path": "build/win64/mulq_mont_256-x86_64.asm",
    "chars": 14320,
    "preview": "OPTION\tDOTNAME\nEXTERN\tmul_mont_sparse_256$1:NEAR\nEXTERN\tsqr_mont_sparse_256$1:NEAR\nEXTERN\tfrom_mont_256$1:NEAR\nEXTERN\tre"
  },
  {
    "path": "build/win64/mulq_mont_384-x86_64.asm",
    "chars": 68211,
    "preview": "OPTION\tDOTNAME\nEXTERN\tmul_mont_384x$1:NEAR\nEXTERN\tsqr_mont_384x$1:NEAR\nEXTERN\tmul_382x$1:NEAR\nEXTERN\tsqr_382x$1:NEAR\nEXT"
  },
  {
    "path": "build/win64/mulx_mont_256-x86_64.asm",
    "chars": 13805,
    "preview": "OPTION\tDOTNAME\nPUBLIC\tmul_mont_sparse_256$1\nPUBLIC\tsqr_mont_sparse_256$1\nPUBLIC\tfrom_mont_256$1\nPUBLIC\tredc_mont_256$1\n."
  },
  {
    "path": "build/win64/mulx_mont_384-x86_64.asm",
    "chars": 65206,
    "preview": "OPTION\tDOTNAME\nPUBLIC\tmul_mont_384x$1\nPUBLIC\tsqr_mont_384x$1\nPUBLIC\tmul_382x$1\nPUBLIC\tsqr_382x$1\nPUBLIC\tmul_384$1\nPUBLIC"
  },
  {
    "path": "build/win64/sha256-armv8.asm",
    "chars": 20123,
    "preview": " GBLA __SIZEOF_POINTER__\n__SIZEOF_POINTER__ SETA 64/8\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\tCOMMON\t|__blst_platform_cap|,4\n\tAREA\t|.text|,COD"
  },
  {
    "path": "build/win64/sha256-x86_64.asm",
    "chars": 28167,
    "preview": "OPTION\tDOTNAME\n_DATA\tSEGMENT\nCOMM\t__blst_platform_cap:DWORD:1\n\n_DATA\tENDS\n.rdata\tSEGMENT READONLY ALIGN(256)\nALIGN\t64\n\nK"
  },
  {
    "path": "build.bat",
    "chars": 2073,
    "preview": "@echo off\nSETLOCAL\nset PATH=%windir%\\system32;%PATH% &:: override msys if it's on the PATH\nset TOP=%~dp0\nset CFLAGS=/nol"
  },
  {
    "path": "build.sh",
    "chars": 4358,
    "preview": "#!/bin/sh\nset -e\n#\n# The script allows to override 'CC', 'CFLAGS' and 'flavour' at command\n# line, as well as specify ad"
  },
  {
    "path": "build.zig",
    "chars": 1511,
    "preview": "const std = @import(\"std\");\n\npub fn build(b: *std.Build) void {\n    const target = b.standardTargetOptions(.{});\n    con"
  },
  {
    "path": "build.zig.zon",
    "chars": 250,
    "preview": ".{\n    .name = .blst,\n    .version = \"0.3.16\",\n    .minimum_zig_version = \"0.14.0\",\n    .paths = .{\n        \"build.zig\","
  },
  {
    "path": "src/aggregate.c",
    "chars": 24213,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/asm/add_mod_256-armv8.pl",
    "chars": 8305,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/add_mod_256-x86_64.pl",
    "chars": 11662,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/add_mod_384-armv8.pl",
    "chars": 21240,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/add_mod_384-x86_64.pl",
    "chars": 31296,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/add_mod_384x384-x86_64.pl",
    "chars": 5630,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/arm-xlate.pl",
    "chars": 12602,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ct_inverse_mod_256-armv8.pl",
    "chars": 17270,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ct_inverse_mod_256-x86_64.pl",
    "chars": 20553,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ct_inverse_mod_384-armv8.pl",
    "chars": 19721,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ct_is_square_mod_384-armv8.pl",
    "chars": 11483,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ct_is_square_mod_384-x86_64.pl",
    "chars": 11485,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ctq_inverse_mod_384-x86_64.pl",
    "chars": 22868,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/ctx_inverse_mod_384-x86_64.pl",
    "chars": 26153,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/div3w-armv8.pl",
    "chars": 2867,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/div3w-x86_64.pl",
    "chars": 5380,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mul_mont_256-armv8.pl",
    "chars": 9890,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mul_mont_384-armv8.pl",
    "chars": 51139,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mulq_mont_256-x86_64.pl",
    "chars": 10269,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mulq_mont_384-x86_64.pl",
    "chars": 57446,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mulx_mont_256-x86_64.pl",
    "chars": 11057,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/mulx_mont_384-x86_64.pl",
    "chars": 54079,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/sha256-armv8.pl",
    "chars": 13727,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/sha256-portable-x86_64.pl",
    "chars": 7425,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/sha256-x86_64.pl",
    "chars": 19254,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/asm/x86_64-xlate.pl",
    "chars": 61338,
    "preview": "#!/usr/bin/env perl\n#\n# Copyright Supranational LLC\n# Licensed under the Apache License, Version 2.0, see LICENSE for de"
  },
  {
    "path": "src/blst_t.hpp",
    "chars": 20772,
    "preview": "// Copyright Supranational LLC\n// Licensed under the Apache License, Version 2.0, see LICENSE for details.\n// SPDX-Licen"
  },
  {
    "path": "src/bulk_addition.c",
    "chars": 5841,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/bytes.h",
    "chars": 3862,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/client_min_pk.c",
    "chars": 369,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/client_min_sig.c",
    "chars": 369,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/consts.c",
    "chars": 1342,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  },
  {
    "path": "src/consts.h",
    "chars": 1152,
    "preview": "/*\n * Copyright Supranational LLC\n * Licensed under the Apache License, Version 2.0, see LICENSE for details.\n * SPDX-Li"
  }
]

// ... and 29 more files (download for full content)

About this extraction

This page contains the full source code of the supranational/blst GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 229 files (3.7 MB), approximately 968.7k tokens, and a symbol index with 1673 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!