mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 06:55:50 +00:00
Compare commits
24 Commits
vlntb/tagg
...
bthomee/se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
292ba1c44c | ||
|
|
252d9f2464 | ||
|
|
656b53cb08 | ||
|
|
b33b506b90 | ||
|
|
f399749ee2 | ||
|
|
2ed4047840 | ||
|
|
4e25dc9291 | ||
|
|
a18b30b765 | ||
|
|
856470203a | ||
|
|
b124c9f7e3 | ||
|
|
b550dc00ed | ||
|
|
21c02232a5 | ||
|
|
a791c03dc1 | ||
|
|
800a315383 | ||
|
|
8449c6c365 | ||
|
|
58e03190ac | ||
|
|
fb74dc28e1 | ||
|
|
e4dccfd49b | ||
|
|
57f4b4eb7f | ||
|
|
adbeb94c2b | ||
|
|
a3d4be4eaf | ||
|
|
6ff495fd9b | ||
|
|
ad37461ab2 | ||
|
|
d9c27da529 |
3
.github/scripts/rename/copyright.sh
vendored
3
.github/scripts/rename/copyright.sh
vendored
@@ -70,9 +70,6 @@ fi
|
||||
if ! grep -q 'Dev Null' src/test/app/tx/apply_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/tx/apply_test.cpp)" > src/test/app/tx/apply_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/app/NetworkOPs_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/NetworkOPs_test.cpp)" > src/test/app/NetworkOPs_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/rpc/ManifestRPC_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ManifestRPC_test.cpp)" > src/test/rpc/ManifestRPC_test.cpp
|
||||
fi
|
||||
|
||||
246
.github/scripts/strategy-matrix/generate.py
vendored
246
.github/scripts/strategy-matrix/generate.py
vendored
@@ -2,11 +2,12 @@
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
THIS_DIR = Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
architecture: list[dict]
|
||||
@@ -14,7 +15,8 @@ class Config:
|
||||
build_type: list[str]
|
||||
cmake_args: list[str]
|
||||
|
||||
'''
|
||||
|
||||
"""
|
||||
Generate a strategy matrix for GitHub Actions CI.
|
||||
|
||||
On each PR commit we will build a selection of Debian, RHEL, Ubuntu, MacOS, and
|
||||
@@ -27,19 +29,23 @@ We will further set additional CMake arguments as follows:
|
||||
- All release builds will have the `assert` option.
|
||||
- Certain Debian Bookworm configurations will change the reference fee, enable
|
||||
codecov, and enable voidstar in PRs.
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
configurations = []
|
||||
for architecture, os, build_type, cmake_args in itertools.product(config.architecture, config.os, config.build_type, config.cmake_args):
|
||||
for architecture, os, build_type, cmake_args in itertools.product(
|
||||
config.architecture, config.os, config.build_type, config.cmake_args
|
||||
):
|
||||
# The default CMake target is 'all' for Linux and MacOS and 'install'
|
||||
# for Windows, but it can get overridden for certain configurations.
|
||||
cmake_target = 'install' if os["distro_name"] == 'windows' else 'all'
|
||||
cmake_target = "install" if os["distro_name"] == "windows" else "all"
|
||||
|
||||
# We build and test all configurations by default, except for Windows in
|
||||
# Debug, because it is too slow, as well as when code coverage is
|
||||
# enabled as that mode already runs the tests.
|
||||
build_only = False
|
||||
if os['distro_name'] == 'windows' and build_type == 'Debug':
|
||||
if os["distro_name"] == "windows" and build_type == "Debug":
|
||||
build_only = True
|
||||
|
||||
# Only generate a subset of configurations in PRs.
|
||||
@@ -54,21 +60,46 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
# - Bookworm using Clang 17: Release and no Unity on linux/amd64,
|
||||
# set the reference fee to 1000.
|
||||
# - Bookworm using Clang 20: Debug and Unity on linux/amd64.
|
||||
if os['distro_name'] == 'debian':
|
||||
if os["distro_name"] == "debian":
|
||||
skip = True
|
||||
if os['distro_version'] == 'bookworm':
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}'
|
||||
if os["distro_version"] == "bookworm":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
|
||||
and build_type == "Release"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64':
|
||||
cmake_args = f'-Dvoidstar=ON {cmake_args}'
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
cmake_args = f"-Dvoidstar=ON {cmake_args}"
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-17' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
cmake_args = f'-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}'
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17"
|
||||
and build_type == "Release"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
@@ -76,13 +107,23 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
# RHEL:
|
||||
# - 9 using GCC 12: Debug and Unity on linux/amd64.
|
||||
# - 10 using Clang: Release and no Unity on linux/amd64.
|
||||
if os['distro_name'] == 'rhel':
|
||||
if os["distro_name"] == "rhel":
|
||||
skip = True
|
||||
if os['distro_version'] == '9':
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
if os["distro_version"] == "9":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
elif os['distro_version'] == '10':
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
elif os["distro_version"] == "10":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any"
|
||||
and build_type == "Release"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
@@ -92,104 +133,169 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
# - Noble using GCC 14: Release and Unity on linux/amd64.
|
||||
# - Noble using Clang 18: Debug and no Unity on linux/amd64.
|
||||
# - Noble using Clang 19: Release and Unity on linux/arm64.
|
||||
if os['distro_name'] == 'ubuntu':
|
||||
if os["distro_name"] == "ubuntu":
|
||||
skip = True
|
||||
if os['distro_version'] == 'jammy':
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64':
|
||||
if os["distro_version"] == "jammy":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
elif os['distro_version'] == 'noble':
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-14' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
elif os["distro_version"] == "noble":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
|
||||
and build_type == "Release"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-18' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-19' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64':
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19"
|
||||
and build_type == "Release"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
|
||||
# MacOS:
|
||||
# - Debug and no Unity on macos/arm64.
|
||||
if os['distro_name'] == 'macos' and not (build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'macos/arm64'):
|
||||
if os["distro_name"] == "macos" and not (
|
||||
build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "macos/arm64"
|
||||
):
|
||||
continue
|
||||
|
||||
# Windows:
|
||||
# - Release and Unity on windows/amd64.
|
||||
if os['distro_name'] == 'windows' and not (build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'windows/amd64'):
|
||||
if os["distro_name"] == "windows" and not (
|
||||
build_type == "Release"
|
||||
and "-Dunity=ON" in cmake_args
|
||||
and architecture["platform"] == "windows/amd64"
|
||||
):
|
||||
continue
|
||||
|
||||
|
||||
# Additional CMake arguments.
|
||||
cmake_args = f'{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON'
|
||||
if not f'{os['compiler_name']}-{os['compiler_version']}' in ['gcc-12', 'clang-16']:
|
||||
cmake_args = f'{cmake_args} -Dwextra=ON'
|
||||
if build_type == 'Release':
|
||||
cmake_args = f'{cmake_args} -Dassert=ON'
|
||||
cmake_args = f"{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON"
|
||||
if not f"{os['compiler_name']}-{os['compiler_version']}" in [
|
||||
"gcc-12",
|
||||
"clang-16",
|
||||
]:
|
||||
cmake_args = f"{cmake_args} -Dwextra=ON"
|
||||
if build_type == "Release":
|
||||
cmake_args = f"{cmake_args} -Dassert=ON"
|
||||
|
||||
# We skip all RHEL on arm64 due to a build failure that needs further
|
||||
# investigation.
|
||||
if os['distro_name'] == 'rhel' and architecture['platform'] == 'linux/arm64':
|
||||
if os["distro_name"] == "rhel" and architecture["platform"] == "linux/arm64":
|
||||
continue
|
||||
|
||||
# We skip all clang 20+ on arm64 due to Boost build error.
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' in ['clang-20', 'clang-21'] and architecture['platform'] == 'linux/arm64':
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}"
|
||||
in ["clang-20", "clang-21"]
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
continue
|
||||
|
||||
# Enable code coverage for Debian Bookworm using GCC 15 in Debug and no
|
||||
# Unity on linux/amd64
|
||||
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
|
||||
cmake_args = f'-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}'
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
|
||||
and build_type == "Debug"
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}"
|
||||
|
||||
# Generate a unique name for the configuration, e.g. macos-arm64-debug
|
||||
# or debian-bookworm-gcc-12-amd64-release-unity.
|
||||
config_name = os['distro_name']
|
||||
if (n := os['distro_version']) != '':
|
||||
config_name += f'-{n}'
|
||||
if (n := os['compiler_name']) != '':
|
||||
config_name += f'-{n}'
|
||||
if (n := os['compiler_version']) != '':
|
||||
config_name += f'-{n}'
|
||||
config_name += f'-{architecture['platform'][architecture['platform'].find('/')+1:]}'
|
||||
config_name += f'-{build_type.lower()}'
|
||||
if '-Dunity=ON' in cmake_args:
|
||||
config_name += '-unity'
|
||||
config_name = os["distro_name"]
|
||||
if (n := os["distro_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_name"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
config_name += (
|
||||
f"-{architecture['platform'][architecture['platform'].find('/') + 1 :]}"
|
||||
)
|
||||
config_name += f"-{build_type.lower()}"
|
||||
if "-Dunity=ON" in cmake_args:
|
||||
config_name += "-unity"
|
||||
|
||||
# Add the configuration to the list, with the most unique fields first,
|
||||
# so that they are easier to identify in the GitHub Actions UI, as long
|
||||
# names get truncated.
|
||||
configurations.append({
|
||||
'config_name': config_name,
|
||||
'cmake_args': cmake_args,
|
||||
'cmake_target': cmake_target,
|
||||
'build_only': build_only,
|
||||
'build_type': build_type,
|
||||
'os': os,
|
||||
'architecture': architecture,
|
||||
})
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name,
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
}
|
||||
)
|
||||
|
||||
return configurations
|
||||
|
||||
|
||||
def read_config(file: Path) -> Config:
|
||||
config = json.loads(file.read_text())
|
||||
if config['architecture'] is None or config['os'] is None or config['build_type'] is None or config['cmake_args'] is None:
|
||||
raise Exception('Invalid configuration file.')
|
||||
if (
|
||||
config["architecture"] is None
|
||||
or config["os"] is None
|
||||
or config["build_type"] is None
|
||||
or config["cmake_args"] is None
|
||||
):
|
||||
raise Exception("Invalid configuration file.")
|
||||
|
||||
return Config(**config)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-a', '--all', help='Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).', action="store_true")
|
||||
parser.add_argument('-c', '--config', help='Path to the JSON file containing the strategy matrix configurations.', required=False, type=Path)
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--all",
|
||||
help="Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
help="Path to the JSON file containing the strategy matrix configurations.",
|
||||
required=False,
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
matrix = []
|
||||
if args.config is None or args.config == '':
|
||||
matrix += generate_strategy_matrix(args.all, read_config(THIS_DIR / "linux.json"))
|
||||
matrix += generate_strategy_matrix(args.all, read_config(THIS_DIR / "macos.json"))
|
||||
matrix += generate_strategy_matrix(args.all, read_config(THIS_DIR / "windows.json"))
|
||||
if args.config is None or args.config == "":
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "linux.json")
|
||||
)
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "macos.json")
|
||||
)
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "windows.json")
|
||||
)
|
||||
else:
|
||||
matrix += generate_strategy_matrix(args.all, read_config(args.config))
|
||||
|
||||
# Generate the strategy matrix.
|
||||
print(f'matrix={json.dumps({"include": matrix})}')
|
||||
print(f"matrix={json.dumps({'include': matrix})}")
|
||||
|
||||
2
.github/workflows/on-pr.yml
vendored
2
.github/workflows/on-pr.yml
vendored
@@ -122,7 +122,7 @@ jobs:
|
||||
needs:
|
||||
- should-run
|
||||
- build-test
|
||||
if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
|
||||
if: ${{ needs.should-run.outputs.go == 'true' && (startsWith(github.base_ref, 'release') || github.base_ref == 'master') }}
|
||||
uses: ./.github/workflows/reusable-notify-clio.yml
|
||||
secrets:
|
||||
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
||||
|
||||
6
.github/workflows/on-trigger.yml
vendored
6
.github/workflows/on-trigger.yml
vendored
@@ -14,9 +14,7 @@ on:
|
||||
- "master"
|
||||
paths:
|
||||
# These paths are unique to `on-trigger.yml`.
|
||||
- ".github/workflows/reusable-check-missing-commits.yml"
|
||||
- ".github/workflows/on-trigger.yml"
|
||||
- ".github/workflows/publish-docs.yml"
|
||||
|
||||
# Keep the paths below in sync with those in `on-pr.yml`.
|
||||
- ".github/actions/build-deps/**"
|
||||
@@ -63,10 +61,6 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-missing-commits:
|
||||
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }}
|
||||
uses: ./.github/workflows/reusable-check-missing-commits.yml
|
||||
|
||||
build-test:
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
--target "${CMAKE_TARGET}"
|
||||
|
||||
- name: Upload rippled artifact (Linux)
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }}
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
env:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# This workflow checks that all commits in the "master" branch are also in the
|
||||
# "release" and "develop" branches, and that all commits in the "release" branch
|
||||
# are also in the "develop" branch.
|
||||
name: Check for missing commits
|
||||
|
||||
# This workflow can only be triggered by other workflows.
|
||||
on: workflow_call
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-missing-commits
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check for missing commits
|
||||
env:
|
||||
MESSAGE: |
|
||||
|
||||
If you are reading this, then the commits indicated above are missing
|
||||
from the "develop" and/or "release" branch. Do a reverse-merge as soon
|
||||
as possible. See CONTRIBUTING.md for instructions.
|
||||
run: |
|
||||
set -o pipefail
|
||||
# Branches are ordered by how "canonical" they are. Every commit in one
|
||||
# branch should be in all the branches behind it.
|
||||
order=(master release develop)
|
||||
branches=()
|
||||
for branch in "${order[@]}"; do
|
||||
# Check that the branches exist so that this job will work on forked
|
||||
# repos, which don't necessarily have master and release branches.
|
||||
echo "Checking if ${branch} exists."
|
||||
if git ls-remote --exit-code --heads origin \
|
||||
refs/heads/${branch} > /dev/null; then
|
||||
branches+=(origin/${branch})
|
||||
fi
|
||||
done
|
||||
|
||||
prior=()
|
||||
for branch in "${branches[@]}"; do
|
||||
if [[ ${#prior[@]} -ne 0 ]]; then
|
||||
echo "Checking ${prior[@]} for commits missing from ${branch}."
|
||||
git log --oneline --no-merges "${prior[@]}" \
|
||||
^$branch | tee -a "missing-commits.txt"
|
||||
echo
|
||||
fi
|
||||
prior+=("${branch}")
|
||||
done
|
||||
|
||||
if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then
|
||||
echo "${MESSAGE}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -31,6 +31,11 @@ repos:
|
||||
hooks:
|
||||
- id: prettier
|
||||
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 25.11.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
exclude: |
|
||||
(?x)^(
|
||||
external/.*|
|
||||
|
||||
43
BUILD.md
43
BUILD.md
@@ -88,6 +88,13 @@ These instructions assume a basic familiarity with Conan and CMake. If you are
|
||||
unfamiliar with Conan, then please read [this crash course](./docs/build/conan.md) or the official
|
||||
[Getting Started][3] walkthrough.
|
||||
|
||||
#### Conan lockfile
|
||||
|
||||
To achieve reproducible dependencies, we use a [Conan lockfile](https://docs.conan.io/2/tutorial/versioning/lockfiles.html),
|
||||
which has to be updated every time dependencies change.
|
||||
|
||||
Please see the [instructions on how to regenerate the lockfile](conan/lockfile/README.md).
|
||||
|
||||
#### Default profile
|
||||
|
||||
We recommend that you import the provided `conan/profiles/default` profile:
|
||||
@@ -138,10 +145,14 @@ cd external
|
||||
git init
|
||||
git remote add origin git@github.com:XRPLF/conan-center-index.git
|
||||
git sparse-checkout init
|
||||
git sparse-checkout set recipes/snappy
|
||||
git sparse-checkout set recipes/ed25519
|
||||
git sparse-checkout add recipes/secp256k1
|
||||
git sparse-checkout add recipes/snappy
|
||||
git sparse-checkout add recipes/soci
|
||||
git fetch origin master
|
||||
git checkout master
|
||||
conan export --version 2015.03 recipes/ed25519/all
|
||||
conan export --version 0.7.0 recipes/secp256k1/all
|
||||
conan export --version 1.1.10 recipes/snappy/all
|
||||
conan export --version 4.0.3 recipes/soci/all
|
||||
rm -rf .git
|
||||
@@ -155,7 +166,8 @@ the new recipe will be automatically pulled from the official Conan Center.
|
||||
|
||||
> [!NOTE]
|
||||
> You might need to add `--lockfile=""` to your `conan install` command
|
||||
> to avoid automatic use of the existing `conan.lock` file when you run `conan export` manually on your machine
|
||||
> to avoid automatic use of the existing `conan.lock` file when you run
|
||||
> `conan export` manually on your machine
|
||||
|
||||
### Conan profile tweaks
|
||||
|
||||
@@ -450,33 +462,6 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
|
||||
The location of `rippled` binary in your build directory depends on your
|
||||
CMake generator. Pass `--help` to see the rest of the command line options.
|
||||
|
||||
#### Conan lockfile
|
||||
|
||||
To achieve reproducible dependencies, we use [Conan lockfile](https://docs.conan.io/2/tutorial/versioning/lockfiles.html).
|
||||
|
||||
The `conan.lock` file in the repository contains a "snapshot" of the current dependencies.
|
||||
It is implicitly used when running `conan` commands, you don't need to specify it.
|
||||
|
||||
You have to update this file every time you add a new dependency or change a revision or version of an existing dependency.
|
||||
|
||||
> [!NOTE]
|
||||
> Conan uses local cache by default when creating a lockfile.
|
||||
>
|
||||
> To ensure, that lockfile creation works the same way on all developer machines, you should clear the local cache before creating a new lockfile.
|
||||
|
||||
To create a new lockfile, run the following commands in the repository root:
|
||||
|
||||
```bash
|
||||
conan remove '*' --confirm
|
||||
rm conan.lock
|
||||
# This ensure that xrplf remote is the first to be consulted
|
||||
conan remote add --force --index 0 xrplf https://conan.ripplex.io
|
||||
conan lock create . -o '&:jemalloc=True' -o '&:rocksdb=True'
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If some dependencies are exclusive for some OS, you may need to run the last command for them adding `--profile:all <PROFILE>`.
|
||||
|
||||
## Coverage report
|
||||
|
||||
The coverage report is intended for developers using compilers GCC
|
||||
|
||||
@@ -89,15 +89,7 @@ find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
|
||||
)
|
||||
set(SECP256K1_INSTALL TRUE)
|
||||
set(SECP256K1_BUILD_BENCHMARK FALSE)
|
||||
set(SECP256K1_BUILD_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_CTIME_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_EXAMPLES FALSE)
|
||||
add_subdirectory(external/secp256k1)
|
||||
add_library(secp256k1::secp256k1 ALIAS secp256k1)
|
||||
add_subdirectory(external/ed25519-donna)
|
||||
|
||||
add_subdirectory(external/antithesis-sdk)
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
@@ -117,8 +109,10 @@ if(rocksdb)
|
||||
target_link_libraries(xrpl_libs INTERFACE RocksDB::rocksdb)
|
||||
endif()
|
||||
|
||||
find_package(nudb REQUIRED)
|
||||
find_package(date REQUIRED)
|
||||
find_package(ed25519 REQUIRED)
|
||||
find_package(nudb REQUIRED)
|
||||
find_package(secp256k1 REQUIRED)
|
||||
find_package(xxHash REQUIRED)
|
||||
|
||||
target_link_libraries(xrpl_libs INTERFACE
|
||||
|
||||
28
conan.lock
28
conan.lock
@@ -6,32 +6,35 @@
|
||||
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1756234266.869",
|
||||
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1756234262.318",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1756234314.246",
|
||||
"secp256k1/0.7.0#9210e4c655d0a665400378a663960d17%1764261276.764",
|
||||
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1762797952.535",
|
||||
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
|
||||
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
|
||||
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1764175362.029",
|
||||
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456",
|
||||
"openssl/3.5.4#a1d5835cc6ed5c5b8f3cd5b9b5d24205%1760106486.594",
|
||||
"nudb/2.0.9#fb8dfd1a5557f5e0528114c2da17721e%1763150366.909",
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
|
||||
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",
|
||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1756230911.03",
|
||||
"libarchive/3.8.1#5cf685686322e906cb42706ab7e099a8%1756234256.696",
|
||||
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1764175360.142",
|
||||
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
|
||||
"grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1756234248.958",
|
||||
"ed25519/2015.03#17c1f1910e769f368025267a53c23c13%1764259445.491",
|
||||
"doctest/2.4.12#eb9fb352fb2fdfc8abb17ec270945165%1762797941.757",
|
||||
"date/3.0.4#f74bbba5a08fa388256688743136cb6f%1756234217.493",
|
||||
"c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1756234217.915",
|
||||
"bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1756234261.716",
|
||||
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1763584497.32",
|
||||
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1764175359.429",
|
||||
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1764175359.429",
|
||||
"boost/1.88.0#8852c0b72ce8271fb8ff7c53456d4983%1756223752.326",
|
||||
"abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1756234220.907"
|
||||
"abseil/20230802.1#90ba607d4ee8fb5fb157c3db540671fc%1764175359.429"
|
||||
],
|
||||
"build_requires": [
|
||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
|
||||
"strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1756234281.733",
|
||||
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
|
||||
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456",
|
||||
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1756234232.901",
|
||||
"msys2/cci.latest#5b73b10144f73cc5bfe0572ed9be39e1%1751977009.857",
|
||||
"m4/1.4.19#f119296e5c4772b3bb7ab060ae8f417b%1760707875.678",
|
||||
"cmake/3.31.8#dde3bde00bb843687e55aea5afa0e220%1756234232.89",
|
||||
"m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846",
|
||||
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1764175359.44",
|
||||
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1764175359.429",
|
||||
"b2/5.3.3#107c15377719889654eb9a162a673975%1756234226.28",
|
||||
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
|
||||
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86"
|
||||
@@ -48,14 +51,11 @@
|
||||
"boost/1.83.0": [
|
||||
"boost/1.88.0"
|
||||
],
|
||||
"sqlite3/[>=3.44 <4]": [
|
||||
"sqlite3/3.44.2": [
|
||||
"sqlite3/3.49.1"
|
||||
],
|
||||
"lz4/[>=1.9.4 <2]": [
|
||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504"
|
||||
],
|
||||
"sqlite3/3.44.2": [
|
||||
"sqlite3/3.49.1"
|
||||
]
|
||||
},
|
||||
"config_requires": []
|
||||
|
||||
12
conan/lockfile/README.md
Normal file
12
conan/lockfile/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Conan lockfile
|
||||
|
||||
To achieve reproducible dependencies, we use a [Conan lockfile](https://docs.conan.io/2/tutorial/versioning/lockfiles.html).
|
||||
|
||||
The `conan.lock` file in the repository contains a "snapshot" of the current
|
||||
dependencies. It is implicitly used when running `conan` commands, so you don't
|
||||
need to specify it.
|
||||
|
||||
You have to update this file every time you add a new dependency or change a
|
||||
revision or version of an existing dependency.
|
||||
|
||||
To update a lockfile, run from the repository root: `./conan/lockfile/regenerate.sh`
|
||||
8
conan/lockfile/linux.profile
Normal file
8
conan/lockfile/linux.profile
Normal file
@@ -0,0 +1,8 @@
|
||||
[settings]
|
||||
arch=x86_64
|
||||
build_type=Release
|
||||
compiler=gcc
|
||||
compiler.cppstd=20
|
||||
compiler.libcxx=libstdc++11
|
||||
compiler.version=13
|
||||
os=Linux
|
||||
8
conan/lockfile/macos.profile
Normal file
8
conan/lockfile/macos.profile
Normal file
@@ -0,0 +1,8 @@
|
||||
[settings]
|
||||
arch=armv8
|
||||
build_type=Release
|
||||
compiler=apple-clang
|
||||
compiler.cppstd=20
|
||||
compiler.libcxx=libc++
|
||||
compiler.version=17.0
|
||||
os=Macos
|
||||
36
conan/lockfile/regenerate.sh
Executable file
36
conan/lockfile/regenerate.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
trap "rm -rf $TEMP_DIR" EXIT
|
||||
|
||||
echo "Using temporary CONAN_HOME: $TEMP_DIR"
|
||||
|
||||
# We use a temporary Conan home to avoid polluting the user's existing Conan
|
||||
# configuration and to not use local cache (which leads to non-reproducible lockfiles).
|
||||
export CONAN_HOME="$TEMP_DIR"
|
||||
|
||||
# Ensure that the xrplf remote is the first to be consulted, so any recipes we
|
||||
# patched are used. We also add it there to not created huge diff when the
|
||||
# official Conan Center Index is updated.
|
||||
conan remote add --force --index 0 xrplf https://conan.ripplex.io
|
||||
|
||||
# Delete any existing lockfile.
|
||||
rm -f conan.lock
|
||||
|
||||
# Create a new lockfile that is compatible with Linux, macOS, and Windows. The
|
||||
# first create command will create a new lockfile, while the subsequent create
|
||||
# commands will merge any additional dependencies into the created lockfile.
|
||||
conan lock create . \
|
||||
--options '&:jemalloc=True' \
|
||||
--options '&:rocksdb=True' \
|
||||
--profile:all=conan/lockfile/linux.profile
|
||||
conan lock create . \
|
||||
--options '&:jemalloc=True' \
|
||||
--options '&:rocksdb=True' \
|
||||
--profile:all=conan/lockfile/macos.profile
|
||||
conan lock create . \
|
||||
--options '&:jemalloc=True' \
|
||||
--options '&:rocksdb=True' \
|
||||
--profile:all=conan/lockfile/windows.profile
|
||||
9
conan/lockfile/windows.profile
Normal file
9
conan/lockfile/windows.profile
Normal file
@@ -0,0 +1,9 @@
|
||||
[settings]
|
||||
arch=x86_64
|
||||
build_type=Release
|
||||
compiler=msvc
|
||||
compiler.cppstd=20
|
||||
compiler.runtime=dynamic
|
||||
compiler.runtime_type=Release
|
||||
compiler.version=194
|
||||
os=Windows
|
||||
282
conanfile.py
282
conanfile.py
@@ -1,149 +1,159 @@
|
||||
from conan import ConanFile, __version__ as conan_version
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
import re
|
||||
|
||||
class Xrpl(ConanFile):
|
||||
name = 'xrpl'
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
|
||||
license = 'ISC'
|
||||
author = 'John Freeman <jfreeman@ripple.com>'
|
||||
url = 'https://github.com/xrplf/rippled'
|
||||
description = 'The XRP Ledger'
|
||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||
from conan import ConanFile
|
||||
from conan import __version__ as conan_version
|
||||
|
||||
|
||||
class Xrpl(ConanFile):
|
||||
name = "xrpl"
|
||||
|
||||
license = "ISC"
|
||||
author = "John Freeman <jfreeman@ripple.com>"
|
||||
url = "https://github.com/xrplf/rippled"
|
||||
description = "The XRP Ledger"
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {
|
||||
'assertions': [True, False],
|
||||
'coverage': [True, False],
|
||||
'fPIC': [True, False],
|
||||
'jemalloc': [True, False],
|
||||
'rocksdb': [True, False],
|
||||
'shared': [True, False],
|
||||
'static': [True, False],
|
||||
'tests': [True, False],
|
||||
'unity': [True, False],
|
||||
'xrpld': [True, False],
|
||||
"assertions": [True, False],
|
||||
"coverage": [True, False],
|
||||
"fPIC": [True, False],
|
||||
"jemalloc": [True, False],
|
||||
"rocksdb": [True, False],
|
||||
"shared": [True, False],
|
||||
"static": [True, False],
|
||||
"tests": [True, False],
|
||||
"unity": [True, False],
|
||||
"xrpld": [True, False],
|
||||
}
|
||||
|
||||
requires = [
|
||||
'grpc/1.50.1',
|
||||
'libarchive/3.8.1',
|
||||
'nudb/2.0.9',
|
||||
'openssl/3.5.4',
|
||||
'soci/4.0.3',
|
||||
'zlib/1.3.1',
|
||||
"ed25519/2015.03",
|
||||
"grpc/1.50.1",
|
||||
"libarchive/3.8.1",
|
||||
"nudb/2.0.9",
|
||||
"openssl/3.5.4",
|
||||
"secp256k1/0.7.0",
|
||||
"soci/4.0.3",
|
||||
"zlib/1.3.1",
|
||||
]
|
||||
|
||||
test_requires = [
|
||||
'doctest/2.4.12',
|
||||
"doctest/2.4.12",
|
||||
]
|
||||
|
||||
tool_requires = [
|
||||
'protobuf/3.21.12',
|
||||
"protobuf/3.21.12",
|
||||
]
|
||||
|
||||
default_options = {
|
||||
'assertions': False,
|
||||
'coverage': False,
|
||||
'fPIC': True,
|
||||
'jemalloc': False,
|
||||
'rocksdb': True,
|
||||
'shared': False,
|
||||
'static': True,
|
||||
'tests': False,
|
||||
'unity': False,
|
||||
'xrpld': False,
|
||||
|
||||
'date/*:header_only': True,
|
||||
'grpc/*:shared': False,
|
||||
'grpc/*:secure': True,
|
||||
'libarchive/*:shared': False,
|
||||
'libarchive/*:with_acl': False,
|
||||
'libarchive/*:with_bzip2': False,
|
||||
'libarchive/*:with_cng': False,
|
||||
'libarchive/*:with_expat': False,
|
||||
'libarchive/*:with_iconv': False,
|
||||
'libarchive/*:with_libxml2': False,
|
||||
'libarchive/*:with_lz4': True,
|
||||
'libarchive/*:with_lzma': False,
|
||||
'libarchive/*:with_lzo': False,
|
||||
'libarchive/*:with_nettle': False,
|
||||
'libarchive/*:with_openssl': False,
|
||||
'libarchive/*:with_pcreposix': False,
|
||||
'libarchive/*:with_xattr': False,
|
||||
'libarchive/*:with_zlib': False,
|
||||
'lz4/*:shared': False,
|
||||
'openssl/*:shared': False,
|
||||
'protobuf/*:shared': False,
|
||||
'protobuf/*:with_zlib': True,
|
||||
'rocksdb/*:enable_sse': False,
|
||||
'rocksdb/*:lite': False,
|
||||
'rocksdb/*:shared': False,
|
||||
'rocksdb/*:use_rtti': True,
|
||||
'rocksdb/*:with_jemalloc': False,
|
||||
'rocksdb/*:with_lz4': True,
|
||||
'rocksdb/*:with_snappy': True,
|
||||
'snappy/*:shared': False,
|
||||
'soci/*:shared': False,
|
||||
'soci/*:with_sqlite3': True,
|
||||
'soci/*:with_boost': True,
|
||||
'xxhash/*:shared': False,
|
||||
"assertions": False,
|
||||
"coverage": False,
|
||||
"fPIC": True,
|
||||
"jemalloc": False,
|
||||
"rocksdb": True,
|
||||
"shared": False,
|
||||
"static": True,
|
||||
"tests": False,
|
||||
"unity": False,
|
||||
"xrpld": False,
|
||||
"date/*:header_only": True,
|
||||
"ed25519/*:shared": False,
|
||||
"grpc/*:shared": False,
|
||||
"grpc/*:secure": True,
|
||||
"libarchive/*:shared": False,
|
||||
"libarchive/*:with_acl": False,
|
||||
"libarchive/*:with_bzip2": False,
|
||||
"libarchive/*:with_cng": False,
|
||||
"libarchive/*:with_expat": False,
|
||||
"libarchive/*:with_iconv": False,
|
||||
"libarchive/*:with_libxml2": False,
|
||||
"libarchive/*:with_lz4": True,
|
||||
"libarchive/*:with_lzma": False,
|
||||
"libarchive/*:with_lzo": False,
|
||||
"libarchive/*:with_nettle": False,
|
||||
"libarchive/*:with_openssl": False,
|
||||
"libarchive/*:with_pcreposix": False,
|
||||
"libarchive/*:with_xattr": False,
|
||||
"libarchive/*:with_zlib": False,
|
||||
"lz4/*:shared": False,
|
||||
"openssl/*:shared": False,
|
||||
"protobuf/*:shared": False,
|
||||
"protobuf/*:with_zlib": True,
|
||||
"rocksdb/*:enable_sse": False,
|
||||
"rocksdb/*:lite": False,
|
||||
"rocksdb/*:shared": False,
|
||||
"rocksdb/*:use_rtti": True,
|
||||
"rocksdb/*:with_jemalloc": False,
|
||||
"rocksdb/*:with_lz4": True,
|
||||
"rocksdb/*:with_snappy": True,
|
||||
"secp256k1/*:shared": False,
|
||||
"snappy/*:shared": False,
|
||||
"soci/*:shared": False,
|
||||
"soci/*:with_sqlite3": True,
|
||||
"soci/*:with_boost": True,
|
||||
"xxhash/*:shared": False,
|
||||
}
|
||||
|
||||
def set_version(self):
|
||||
if self.version is None:
|
||||
path = f'{self.recipe_folder}/src/libxrpl/protocol/BuildInfo.cpp'
|
||||
regex = r'versionString\s?=\s?\"(.*)\"'
|
||||
with open(path, encoding='utf-8') as file:
|
||||
path = f"{self.recipe_folder}/src/libxrpl/protocol/BuildInfo.cpp"
|
||||
regex = r"versionString\s?=\s?\"(.*)\""
|
||||
with open(path, encoding="utf-8") as file:
|
||||
matches = (re.search(regex, line) for line in file)
|
||||
match = next(m for m in matches if m)
|
||||
self.version = match.group(1)
|
||||
|
||||
def configure(self):
|
||||
if self.settings.compiler == 'apple-clang':
|
||||
self.options['boost'].visibility = 'global'
|
||||
if self.settings.compiler in ['clang', 'gcc']:
|
||||
self.options['boost'].without_cobalt = True
|
||||
if self.settings.compiler == "apple-clang":
|
||||
self.options["boost"].visibility = "global"
|
||||
if self.settings.compiler in ["clang", "gcc"]:
|
||||
self.options["boost"].without_cobalt = True
|
||||
|
||||
def requirements(self):
|
||||
# Conan 2 requires transitive headers to be specified
|
||||
transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {}
|
||||
self.requires('boost/1.88.0', force=True, **transitive_headers_opt)
|
||||
self.requires('date/3.0.4', **transitive_headers_opt)
|
||||
self.requires('lz4/1.10.0', force=True)
|
||||
self.requires('protobuf/3.21.12', force=True)
|
||||
self.requires('sqlite3/3.49.1', force=True)
|
||||
transitive_headers_opt = (
|
||||
{"transitive_headers": True} if conan_version.split(".")[0] == "2" else {}
|
||||
)
|
||||
self.requires("boost/1.88.0", force=True, **transitive_headers_opt)
|
||||
self.requires("date/3.0.4", **transitive_headers_opt)
|
||||
self.requires("lz4/1.10.0", force=True)
|
||||
self.requires("protobuf/3.21.12", force=True)
|
||||
self.requires("sqlite3/3.49.1", force=True)
|
||||
if self.options.jemalloc:
|
||||
self.requires('jemalloc/5.3.0')
|
||||
self.requires("jemalloc/5.3.0")
|
||||
if self.options.rocksdb:
|
||||
self.requires('rocksdb/10.5.1')
|
||||
self.requires('xxhash/0.8.3', **transitive_headers_opt)
|
||||
self.requires("rocksdb/10.5.1")
|
||||
self.requires("xxhash/0.8.3", **transitive_headers_opt)
|
||||
|
||||
exports_sources = (
|
||||
'CMakeLists.txt',
|
||||
'cfg/*',
|
||||
'cmake/*',
|
||||
'external/*',
|
||||
'include/*',
|
||||
'src/*',
|
||||
"CMakeLists.txt",
|
||||
"cfg/*",
|
||||
"cmake/*",
|
||||
"external/*",
|
||||
"include/*",
|
||||
"src/*",
|
||||
)
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
# Fix this setting to follow the default introduced in Conan 1.48
|
||||
# to align with our build instructions.
|
||||
self.folders.generators = 'build/generators'
|
||||
self.folders.generators = "build/generators"
|
||||
|
||||
generators = "CMakeDeps"
|
||||
|
||||
generators = 'CMakeDeps'
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables['tests'] = self.options.tests
|
||||
tc.variables['assert'] = self.options.assertions
|
||||
tc.variables['coverage'] = self.options.coverage
|
||||
tc.variables['jemalloc'] = self.options.jemalloc
|
||||
tc.variables['rocksdb'] = self.options.rocksdb
|
||||
tc.variables['BUILD_SHARED_LIBS'] = self.options.shared
|
||||
tc.variables['static'] = self.options.static
|
||||
tc.variables['unity'] = self.options.unity
|
||||
tc.variables['xrpld'] = self.options.xrpld
|
||||
tc.variables["tests"] = self.options.tests
|
||||
tc.variables["assert"] = self.options.assertions
|
||||
tc.variables["coverage"] = self.options.coverage
|
||||
tc.variables["jemalloc"] = self.options.jemalloc
|
||||
tc.variables["rocksdb"] = self.options.rocksdb
|
||||
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
|
||||
tc.variables["static"] = self.options.static
|
||||
tc.variables["unity"] = self.options.unity
|
||||
tc.variables["xrpld"] = self.options.xrpld
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
@@ -158,40 +168,42 @@ class Xrpl(ConanFile):
|
||||
cmake.install()
|
||||
|
||||
def package_info(self):
|
||||
libxrpl = self.cpp_info.components['libxrpl']
|
||||
libxrpl = self.cpp_info.components["libxrpl"]
|
||||
libxrpl.libs = [
|
||||
'xrpl',
|
||||
'xrpl.libpb',
|
||||
'ed25519',
|
||||
'secp256k1',
|
||||
"xrpl",
|
||||
"xrpl.libpb",
|
||||
"ed25519",
|
||||
"secp256k1",
|
||||
]
|
||||
# TODO: Fix the protobufs to include each other relative to
|
||||
# `include/`, not `include/ripple/proto/`.
|
||||
libxrpl.includedirs = ['include', 'include/ripple/proto']
|
||||
libxrpl.includedirs = ["include", "include/ripple/proto"]
|
||||
libxrpl.requires = [
|
||||
'boost::headers',
|
||||
'boost::chrono',
|
||||
'boost::container',
|
||||
'boost::coroutine',
|
||||
'boost::date_time',
|
||||
'boost::filesystem',
|
||||
'boost::json',
|
||||
'boost::program_options',
|
||||
'boost::process',
|
||||
'boost::regex',
|
||||
'boost::system',
|
||||
'boost::thread',
|
||||
'date::date',
|
||||
'grpc::grpc++',
|
||||
'libarchive::libarchive',
|
||||
'lz4::lz4',
|
||||
'nudb::nudb',
|
||||
'openssl::crypto',
|
||||
'protobuf::libprotobuf',
|
||||
'soci::soci',
|
||||
'sqlite3::sqlite',
|
||||
'xxhash::xxhash',
|
||||
'zlib::zlib',
|
||||
"boost::headers",
|
||||
"boost::chrono",
|
||||
"boost::container",
|
||||
"boost::coroutine",
|
||||
"boost::date_time",
|
||||
"boost::filesystem",
|
||||
"boost::json",
|
||||
"boost::program_options",
|
||||
"boost::process",
|
||||
"boost::regex",
|
||||
"boost::system",
|
||||
"boost::thread",
|
||||
"date::date",
|
||||
"ed25519::ed25519",
|
||||
"grpc::grpc++",
|
||||
"libarchive::libarchive",
|
||||
"lz4::lz4",
|
||||
"nudb::nudb",
|
||||
"openssl::crypto",
|
||||
"protobuf::libprotobuf",
|
||||
"soci::soci",
|
||||
"secp256k1::secp256k1",
|
||||
"sqlite3::sqlite",
|
||||
"xxhash::xxhash",
|
||||
"zlib::zlib",
|
||||
]
|
||||
if self.options.rocksdb:
|
||||
libxrpl.requires.append('rocksdb::librocksdb')
|
||||
libxrpl.requires.append("rocksdb::librocksdb")
|
||||
|
||||
2
external/README.md
vendored
2
external/README.md
vendored
@@ -5,5 +5,3 @@ The subdirectories in this directory contain external libraries used by rippled.
|
||||
| Folder | Upstream | Description |
|
||||
| :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- |
|
||||
| `antithesis-sdk` | [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ |
|
||||
| `ed25519-donna` | [Project](https://github.com/floodyberry/ed25519-donna) | [Ed25519](http://ed25519.cr.yp.to/) digital signatures |
|
||||
| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve |
|
||||
|
||||
51
external/ed25519-donna/CMakeLists.txt
vendored
51
external/ed25519-donna/CMakeLists.txt
vendored
@@ -1,51 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(ed25519
|
||||
LANGUAGES C
|
||||
)
|
||||
|
||||
if(PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/output/$<CONFIG>/lib")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET OpenSSL::SSL)
|
||||
find_package(OpenSSL)
|
||||
endif()
|
||||
|
||||
add_library(ed25519 STATIC
|
||||
ed25519.c
|
||||
)
|
||||
add_library(ed25519::ed25519 ALIAS ed25519)
|
||||
target_link_libraries(ed25519 PUBLIC OpenSSL::SSL)
|
||||
if(NOT MSVC)
|
||||
target_compile_options(ed25519 PRIVATE -Wno-implicit-fallthrough)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#[=========================================================[
|
||||
NOTE for macos:
|
||||
https://github.com/floodyberry/ed25519-donna/issues/29
|
||||
our source for ed25519-donna-portable.h has been
|
||||
patched to workaround this.
|
||||
#]=========================================================]
|
||||
target_include_directories(ed25519 PUBLIC
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS ed25519
|
||||
EXPORT ${PROJECT_NAME}-exports
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
install(
|
||||
EXPORT ${PROJECT_NAME}-exports
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
|
||||
FILE ${PROJECT_NAME}-targets.cmake
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
install(
|
||||
FILES ed25519.h
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
183
external/ed25519-donna/README.md
vendored
183
external/ed25519-donna/README.md
vendored
@@ -1,183 +0,0 @@
|
||||
[ed25519](http://ed25519.cr.yp.to/) is an
|
||||
[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA),
|
||||
developed by [Dan Bernstein](http://cr.yp.to/djb.html),
|
||||
[Niels Duif](http://www.nielsduif.nl/),
|
||||
[Tanja Lange](http://hyperelliptic.org/tanja),
|
||||
[Peter Schwabe](http://www.cryptojedi.org/users/peter/),
|
||||
and [Bo-Yin Yang](http://www.iis.sinica.edu.tw/pages/byyang/).
|
||||
|
||||
This project provides performant, portable 32-bit & 64-bit implementations. All implementations are
|
||||
of course constant time in regard to secret data.
|
||||
|
||||
#### Performance
|
||||
|
||||
SSE2 code and benches have not been updated yet. I will do those next.
|
||||
|
||||
Compilers versions are gcc 4.6.3, icc 13.1.1, clang 3.4-1~exp1.
|
||||
|
||||
Batch verification time (in parentheses) is the average time per 1 verification in a batch of 64 signatures. Counts are in thousands of cycles.
|
||||
|
||||
Note that SSE2 performance may be less impressive on AMD & older CPUs with slower SSE ops!
|
||||
|
||||
Visual Studio performance for `ge25519_scalarmult_base_niels` will lag behind a bit until optimized assembler versions of `ge25519_scalarmult_base_choose_niels`
|
||||
are made.
|
||||
|
||||
##### E5200 @ 2.5ghz, march=core2
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Implementation</th><th>Sign</th><th>gcc</th><th>icc</th><th>clang</th><th>Verify</th><th>gcc</th><th>icc</th><th>clang</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>ed25519-donna 64bit </td><td></td><td>100k</td><td>110k</td><td>137k</td><td></td><td>327k (144k) </td><td>342k (163k) </td><td>422k (194k) </td></tr>
|
||||
<tr><td>amd64-64-24k </td><td></td><td>102k</td><td> </td><td> </td><td></td><td>355k (158k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 64bit</td><td></td><td>108k</td><td>111k</td><td>116k</td><td></td><td>353k (155k) </td><td>345k (154k) </td><td>360k (161k) </td></tr>
|
||||
<tr><td>amd64-51-32k </td><td></td><td>116k</td><td> </td><td> </td><td></td><td>380k (175k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 32bit</td><td></td><td>147k</td><td>147k</td><td>156k</td><td></td><td>380k (178k) </td><td>381k (173k) </td><td>430k (192k) </td></tr>
|
||||
<tr><td>ed25519-donna 32bit </td><td></td><td>597k</td><td>335k</td><td>380k</td><td></td><td>1693k (720k)</td><td>1052k (453k)</td><td>1141k (493k)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
##### E3-1270 @ 3.4ghz, march=corei7-avx
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Implementation</th><th>Sign</th><th>gcc</th><th>icc</th><th>clang</th><th>Verify</th><th>gcc</th><th>icc</th><th>clang</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>amd64-64-24k </td><td></td><td> 68k</td><td> </td><td> </td><td></td><td>225k (104k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna 64bit </td><td></td><td> 71k</td><td> 75k</td><td> 90k</td><td></td><td>226k (105k) </td><td>226k (112k) </td><td>277k (125k) </td></tr>
|
||||
<tr><td>amd64-51-32k </td><td></td><td> 72k</td><td> </td><td> </td><td></td><td>218k (107k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 64bit</td><td></td><td> 79k</td><td> 82k</td><td> 92k</td><td></td><td>252k (122k) </td><td>259k (124k) </td><td>282k (131k) </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 32bit</td><td></td><td> 94k</td><td> 95k</td><td>103k</td><td></td><td>296k (146k) </td><td>294k (137k) </td><td>306k (147k) </td></tr>
|
||||
<tr><td>ed25519-donna 32bit </td><td></td><td>525k</td><td>299k</td><td>316k</td><td></td><td>1502k (645k)</td><td>959k (418k) </td><td>954k (416k) </td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
#### Compilation
|
||||
|
||||
No configuration is needed **if you are compiling against OpenSSL**.
|
||||
|
||||
##### Hash Options
|
||||
|
||||
If you are not compiling aginst OpenSSL, you will need a hash function.
|
||||
|
||||
To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`.
|
||||
This should never be used except to verify the code works when OpenSSL is not available.
|
||||
|
||||
To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your
|
||||
custom hash implementation in ed25519-hash-custom.h. The hash must have a 512bit digest and implement
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
|
||||
##### Random Options
|
||||
|
||||
If you are not compiling aginst OpenSSL, you will need a random function for batch verification.
|
||||
|
||||
To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your
|
||||
custom hash implementation in ed25519-randombytes-custom.h. The random function must implement:
|
||||
|
||||
void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len);
|
||||
|
||||
Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG
|
||||
variant of Bob Jenkins [ISAAC](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29)
|
||||
|
||||
##### Minor options
|
||||
|
||||
Use `-DED25519_INLINE_ASM` to disable the use of custom assembler routines and instead rely on portable C.
|
||||
|
||||
Use `-DED25519_FORCE_32BIT` to force the use of 32 bit routines even when compiling for 64 bit.
|
||||
|
||||
##### 32-bit
|
||||
|
||||
gcc ed25519.c -m32 -O3 -c
|
||||
|
||||
##### 64-bit
|
||||
|
||||
gcc ed25519.c -m64 -O3 -c
|
||||
|
||||
##### SSE2
|
||||
|
||||
gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2
|
||||
gcc ed25519.c -m64 -O3 -c -DED25519_SSE2
|
||||
|
||||
clang and icc are also supported
|
||||
|
||||
|
||||
#### Usage
|
||||
|
||||
To use the code, link against `ed25519.o -mbits` and:
|
||||
|
||||
#include "ed25519.h"
|
||||
|
||||
Add `-lssl -lcrypto` when using OpenSSL (Some systems don't need -lcrypto? It might be trial and error).
|
||||
|
||||
To generate a private key, simply generate 32 bytes from a secure
|
||||
cryptographic source:
|
||||
|
||||
ed25519_secret_key sk;
|
||||
randombytes(sk, sizeof(ed25519_secret_key));
|
||||
|
||||
To generate a public key:
|
||||
|
||||
ed25519_public_key pk;
|
||||
ed25519_publickey(sk, pk);
|
||||
|
||||
To sign a message:
|
||||
|
||||
ed25519_signature sig;
|
||||
ed25519_sign(message, message_len, sk, pk, signature);
|
||||
|
||||
To verify a signature:
|
||||
|
||||
int valid = ed25519_sign_open(message, message_len, pk, signature) == 0;
|
||||
|
||||
To batch verify signatures:
|
||||
|
||||
const unsigned char *mp[num] = {message1, message2..}
|
||||
size_t ml[num] = {message_len1, message_len2..}
|
||||
const unsigned char *pkp[num] = {pk1, pk2..}
|
||||
const unsigned char *sigp[num] = {signature1, signature2..}
|
||||
int valid[num]
|
||||
|
||||
/* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */
|
||||
int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0;
|
||||
|
||||
**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in
|
||||
`ed25519-randombytes.h`, to generate random scalars for the verification code.
|
||||
The default implementation now uses OpenSSLs `RAND_bytes`.
|
||||
|
||||
Unlike the [SUPERCOP](http://bench.cr.yp.to/supercop.html) version, signatures are
|
||||
not appended to messages, and there is no need for padding in front of messages.
|
||||
Additionally, the secret key does not contain a copy of the public key, so it is
|
||||
32 bytes instead of 64 bytes, and the public key must be provided to the signing
|
||||
function.
|
||||
|
||||
##### Curve25519
|
||||
|
||||
Curve25519 public keys can be generated thanks to
|
||||
[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html)
|
||||
leveraging Ed25519's precomputed basepoint scalar multiplication.
|
||||
|
||||
curved25519_key sk, pk;
|
||||
randombytes(sk, sizeof(curved25519_key));
|
||||
curved25519_scalarmult_basepoint(pk, sk);
|
||||
|
||||
Note the name is curved25519, a combination of curve and ed25519, to prevent
|
||||
name clashes. Performance is slightly faster than short message ed25519
|
||||
signing due to both using the same code for the scalar multiply.
|
||||
|
||||
#### Testing
|
||||
|
||||
Fuzzing against reference implemenations is now available. See [fuzz/README](fuzz/README.md).
|
||||
|
||||
Building `ed25519.c` with `-DED25519_TEST` and linking with `test.c` will run basic sanity tests
|
||||
and benchmark each function. `test-batch.c` has been incorporated in to `test.c`.
|
||||
|
||||
`test-internals.c` is standalone and built the same way as `ed25519.c`. It tests the math primitives
|
||||
with extreme values to ensure they function correctly. SSE2 is now supported.
|
||||
|
||||
#### Papers
|
||||
|
||||
[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html)
|
||||
579
external/ed25519-donna/curve25519-donna-32bit.h
vendored
579
external/ed25519-donna/curve25519-donna-32bit.h
vendored
@@ -1,579 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
See: https://github.com/floodyberry/curve25519-donna
|
||||
|
||||
32 bit integer curve25519 implementation
|
||||
*/
|
||||
|
||||
typedef uint32_t bignum25519[10];
|
||||
typedef uint32_t bignum25519align16[12];
|
||||
|
||||
static const uint32_t reduce_mask_25 = (1 << 25) - 1;
|
||||
static const uint32_t reduce_mask_26 = (1 << 26) - 1;
|
||||
|
||||
|
||||
/* out = in */
|
||||
DONNA_INLINE static void
|
||||
curve25519_copy(bignum25519 out, const bignum25519 in) {
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
out[3] = in[3];
|
||||
out[4] = in[4];
|
||||
out[5] = in[5];
|
||||
out[6] = in[6];
|
||||
out[7] = in[7];
|
||||
out[8] = in[8];
|
||||
out[9] = in[9];
|
||||
}
|
||||
|
||||
/* out = a + b */
|
||||
DONNA_INLINE static void
|
||||
curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
out[3] = a[3] + b[3];
|
||||
out[4] = a[4] + b[4];
|
||||
out[5] = a[5] + b[5];
|
||||
out[6] = a[6] + b[6];
|
||||
out[7] = a[7] + b[7];
|
||||
out[8] = a[8] + b[8];
|
||||
out[9] = a[9] + b[9];
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t c;
|
||||
out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
|
||||
out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
|
||||
out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
|
||||
out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
|
||||
out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
|
||||
out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
|
||||
out[0] += 19 * c;
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t c;
|
||||
out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
|
||||
out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
|
||||
out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
|
||||
out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
|
||||
out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
|
||||
out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
|
||||
out[0] += 19 * c;
|
||||
}
|
||||
|
||||
/* multiples of p */
|
||||
static const uint32_t twoP0 = 0x07ffffda;
|
||||
static const uint32_t twoP13579 = 0x03fffffe;
|
||||
static const uint32_t twoP2468 = 0x07fffffe;
|
||||
static const uint32_t fourP0 = 0x0fffffb4;
|
||||
static const uint32_t fourP13579 = 0x07fffffc;
|
||||
static const uint32_t fourP2468 = 0x0ffffffc;
|
||||
|
||||
/* out = a - b */
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t c;
|
||||
out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = twoP2468 + a[4] - b[4] + c;
|
||||
out[5] = twoP13579 + a[5] - b[5] ;
|
||||
out[6] = twoP2468 + a[6] - b[6] ;
|
||||
out[7] = twoP13579 + a[7] - b[7] ;
|
||||
out[8] = twoP2468 + a[8] - b[8] ;
|
||||
out[9] = twoP13579 + a[9] - b[9] ;
|
||||
}
|
||||
|
||||
/* out = a - b, where a is the result of a basic op (add,sub) */
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t c;
|
||||
out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
|
||||
out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
|
||||
out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
|
||||
out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
|
||||
out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
|
||||
out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
|
||||
out[0] += 19 * c;
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t c;
|
||||
out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
|
||||
out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
|
||||
out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
|
||||
out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
|
||||
out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
|
||||
out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
|
||||
out[0] += 19 * c;
|
||||
}
|
||||
|
||||
/* out = -a */
|
||||
DONNA_INLINE static void
|
||||
curve25519_neg(bignum25519 out, const bignum25519 a) {
|
||||
uint32_t c;
|
||||
out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
|
||||
out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
|
||||
out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
|
||||
out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
|
||||
out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
|
||||
out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
|
||||
out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
|
||||
out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
|
||||
out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
|
||||
out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
|
||||
out[0] += 19 * c;
|
||||
}
|
||||
|
||||
/* out = a * b */
|
||||
#define curve25519_mul_noinline curve25519_mul
|
||||
static void
|
||||
curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t s0,s1,s2,s3,s4,s5,s6,s7,s8,s9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
r0 = b[0];
|
||||
r1 = b[1];
|
||||
r2 = b[2];
|
||||
r3 = b[3];
|
||||
r4 = b[4];
|
||||
r5 = b[5];
|
||||
r6 = b[6];
|
||||
r7 = b[7];
|
||||
r8 = b[8];
|
||||
r9 = b[9];
|
||||
|
||||
s0 = a[0];
|
||||
s1 = a[1];
|
||||
s2 = a[2];
|
||||
s3 = a[3];
|
||||
s4 = a[4];
|
||||
s5 = a[5];
|
||||
s6 = a[6];
|
||||
s7 = a[7];
|
||||
s8 = a[8];
|
||||
s9 = a[9];
|
||||
|
||||
m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0);
|
||||
m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0);
|
||||
m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0);
|
||||
m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0);
|
||||
m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0);
|
||||
|
||||
r1 *= 2;
|
||||
r3 *= 2;
|
||||
r5 *= 2;
|
||||
r7 *= 2;
|
||||
|
||||
m0 = mul32x32_64(r0, s0);
|
||||
m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0);
|
||||
m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0);
|
||||
m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0);
|
||||
m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0);
|
||||
|
||||
r1 *= 19;
|
||||
r2 *= 19;
|
||||
r3 = (r3 / 2) * 19;
|
||||
r4 *= 19;
|
||||
r5 = (r5 / 2) * 19;
|
||||
r6 *= 19;
|
||||
r7 = (r7 / 2) * 19;
|
||||
r8 *= 19;
|
||||
r9 *= 19;
|
||||
|
||||
m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9));
|
||||
m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9));
|
||||
m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9));
|
||||
m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9));
|
||||
|
||||
r3 *= 2;
|
||||
r5 *= 2;
|
||||
r7 *= 2;
|
||||
r9 *= 2;
|
||||
|
||||
m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9));
|
||||
m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9));
|
||||
m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9));
|
||||
m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9));
|
||||
m8 += (mul32x32_64(r9, s9));
|
||||
|
||||
r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
|
||||
m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
|
||||
m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
|
||||
m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
|
||||
m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
|
||||
m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
|
||||
m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
|
||||
m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
|
||||
m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
|
||||
m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
|
||||
m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
|
||||
r1 += p;
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
out[5] = r5;
|
||||
out[6] = r6;
|
||||
out[7] = r7;
|
||||
out[8] = r8;
|
||||
out[9] = r9;
|
||||
}
|
||||
|
||||
/* out = in*in */
|
||||
static void
|
||||
curve25519_square(bignum25519 out, const bignum25519 in) {
|
||||
uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t d6,d7,d8,d9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
r0 = in[0];
|
||||
r1 = in[1];
|
||||
r2 = in[2];
|
||||
r3 = in[3];
|
||||
r4 = in[4];
|
||||
r5 = in[5];
|
||||
r6 = in[6];
|
||||
r7 = in[7];
|
||||
r8 = in[8];
|
||||
r9 = in[9];
|
||||
|
||||
m0 = mul32x32_64(r0, r0);
|
||||
r0 *= 2;
|
||||
m1 = mul32x32_64(r0, r1);
|
||||
m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2);
|
||||
r1 *= 2;
|
||||
m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 );
|
||||
m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2);
|
||||
r2 *= 2;
|
||||
m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3);
|
||||
m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2);
|
||||
r3 *= 2;
|
||||
m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 );
|
||||
m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 );
|
||||
m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2);
|
||||
|
||||
d6 = r6 * 19;
|
||||
d7 = r7 * 2 * 19;
|
||||
d8 = r8 * 19;
|
||||
d9 = r9 * 2 * 19;
|
||||
|
||||
m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19));
|
||||
m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2));
|
||||
m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 ));
|
||||
m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 ));
|
||||
m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 ));
|
||||
m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2));
|
||||
m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 ));
|
||||
m7 += (mul32x32_64(d9, r8 ));
|
||||
m8 += (mul32x32_64(d9, r9 ));
|
||||
|
||||
r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
|
||||
m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
|
||||
m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
|
||||
m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
|
||||
m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
|
||||
m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
|
||||
m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
|
||||
m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
|
||||
m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
|
||||
m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
|
||||
m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
|
||||
r1 += p;
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
out[5] = r5;
|
||||
out[6] = r6;
|
||||
out[7] = r7;
|
||||
out[8] = r8;
|
||||
out[9] = r9;
|
||||
}
|
||||
|
||||
|
||||
/* out = in ^ (2 * count) */
|
||||
static void
|
||||
curve25519_square_times(bignum25519 out, const bignum25519 in, int count) {
|
||||
uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t d6,d7,d8,d9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
r0 = in[0];
|
||||
r1 = in[1];
|
||||
r2 = in[2];
|
||||
r3 = in[3];
|
||||
r4 = in[4];
|
||||
r5 = in[5];
|
||||
r6 = in[6];
|
||||
r7 = in[7];
|
||||
r8 = in[8];
|
||||
r9 = in[9];
|
||||
|
||||
do {
|
||||
m0 = mul32x32_64(r0, r0);
|
||||
r0 *= 2;
|
||||
m1 = mul32x32_64(r0, r1);
|
||||
m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2);
|
||||
r1 *= 2;
|
||||
m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 );
|
||||
m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2);
|
||||
r2 *= 2;
|
||||
m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3);
|
||||
m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2);
|
||||
r3 *= 2;
|
||||
m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 );
|
||||
m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 );
|
||||
m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2);
|
||||
|
||||
d6 = r6 * 19;
|
||||
d7 = r7 * 2 * 19;
|
||||
d8 = r8 * 19;
|
||||
d9 = r9 * 2 * 19;
|
||||
|
||||
m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19));
|
||||
m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2));
|
||||
m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 ));
|
||||
m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 ));
|
||||
m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 ));
|
||||
m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2));
|
||||
m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 ));
|
||||
m7 += (mul32x32_64(d9, r8 ));
|
||||
m8 += (mul32x32_64(d9, r9 ));
|
||||
|
||||
r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
|
||||
m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
|
||||
m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
|
||||
m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
|
||||
m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
|
||||
m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
|
||||
m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
|
||||
m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
|
||||
m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
|
||||
m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
|
||||
m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
|
||||
r1 += p;
|
||||
} while (--count);
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
out[5] = r5;
|
||||
out[6] = r6;
|
||||
out[7] = r7;
|
||||
out[8] = r8;
|
||||
out[9] = r9;
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
static void
|
||||
curve25519_expand(bignum25519 out, const unsigned char in[32]) {
|
||||
static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}};
|
||||
uint32_t x0,x1,x2,x3,x4,x5,x6,x7;
|
||||
|
||||
if (endian_check.s == 1) {
|
||||
x0 = *(uint32_t *)(in + 0);
|
||||
x1 = *(uint32_t *)(in + 4);
|
||||
x2 = *(uint32_t *)(in + 8);
|
||||
x3 = *(uint32_t *)(in + 12);
|
||||
x4 = *(uint32_t *)(in + 16);
|
||||
x5 = *(uint32_t *)(in + 20);
|
||||
x6 = *(uint32_t *)(in + 24);
|
||||
x7 = *(uint32_t *)(in + 28);
|
||||
} else {
|
||||
#define F(s) \
|
||||
((((uint32_t)in[s + 0]) ) | \
|
||||
(((uint32_t)in[s + 1]) << 8) | \
|
||||
(((uint32_t)in[s + 2]) << 16) | \
|
||||
(((uint32_t)in[s + 3]) << 24))
|
||||
x0 = F(0);
|
||||
x1 = F(4);
|
||||
x2 = F(8);
|
||||
x3 = F(12);
|
||||
x4 = F(16);
|
||||
x5 = F(20);
|
||||
x6 = F(24);
|
||||
x7 = F(28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
out[0] = ( x0 ) & 0x3ffffff;
|
||||
out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & 0x1ffffff;
|
||||
out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & 0x3ffffff;
|
||||
out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & 0x1ffffff;
|
||||
out[4] = (( x3) >> 6) & 0x3ffffff;
|
||||
out[5] = ( x4 ) & 0x1ffffff;
|
||||
out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & 0x3ffffff;
|
||||
out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & 0x1ffffff;
|
||||
out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & 0x3ffffff;
|
||||
out[9] = (( x7) >> 6) & 0x1ffffff;
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array
|
||||
*/
|
||||
static void
|
||||
curve25519_contract(unsigned char out[32], const bignum25519 in) {
|
||||
bignum25519 f;
|
||||
curve25519_copy(f, in);
|
||||
|
||||
#define carry_pass() \
|
||||
f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \
|
||||
f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \
|
||||
f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \
|
||||
f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \
|
||||
f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \
|
||||
f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \
|
||||
f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \
|
||||
f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \
|
||||
f[9] += f[8] >> 26; f[8] &= reduce_mask_26;
|
||||
|
||||
#define carry_pass_full() \
|
||||
carry_pass() \
|
||||
f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25;
|
||||
|
||||
#define carry_pass_final() \
|
||||
carry_pass() \
|
||||
f[9] &= reduce_mask_25;
|
||||
|
||||
carry_pass_full()
|
||||
carry_pass_full()
|
||||
|
||||
/* now t is between 0 and 2^255-1, properly carried. */
|
||||
/* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
|
||||
f[0] += 19;
|
||||
carry_pass_full()
|
||||
|
||||
/* now between 19 and 2^255-1 in both cases, and offset by 19. */
|
||||
f[0] += (reduce_mask_26 + 1) - 19;
|
||||
f[1] += (reduce_mask_25 + 1) - 1;
|
||||
f[2] += (reduce_mask_26 + 1) - 1;
|
||||
f[3] += (reduce_mask_25 + 1) - 1;
|
||||
f[4] += (reduce_mask_26 + 1) - 1;
|
||||
f[5] += (reduce_mask_25 + 1) - 1;
|
||||
f[6] += (reduce_mask_26 + 1) - 1;
|
||||
f[7] += (reduce_mask_25 + 1) - 1;
|
||||
f[8] += (reduce_mask_26 + 1) - 1;
|
||||
f[9] += (reduce_mask_25 + 1) - 1;
|
||||
|
||||
/* now between 2^255 and 2^256-20, and offset by 2^255. */
|
||||
carry_pass_final()
|
||||
|
||||
#undef carry_pass
|
||||
#undef carry_full
|
||||
#undef carry_final
|
||||
|
||||
f[1] <<= 2;
|
||||
f[2] <<= 3;
|
||||
f[3] <<= 5;
|
||||
f[4] <<= 6;
|
||||
f[6] <<= 1;
|
||||
f[7] <<= 3;
|
||||
f[8] <<= 4;
|
||||
f[9] <<= 6;
|
||||
|
||||
#define F(i, s) \
|
||||
out[s+0] |= (unsigned char )(f[i] & 0xff); \
|
||||
out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \
|
||||
out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \
|
||||
out[s+3] = (unsigned char )((f[i] >> 24) & 0xff);
|
||||
|
||||
out[0] = 0;
|
||||
out[16] = 0;
|
||||
F(0,0);
|
||||
F(1,3);
|
||||
F(2,6);
|
||||
F(3,9);
|
||||
F(4,12);
|
||||
F(5,16);
|
||||
F(6,19);
|
||||
F(7,22);
|
||||
F(8,25);
|
||||
F(9,28);
|
||||
#undef F
|
||||
}
|
||||
|
||||
|
||||
/* out = (flag) ? in : out */
|
||||
DONNA_INLINE static void
|
||||
curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint32_t flag) {
|
||||
const uint32_t nb = flag - 1, b = ~nb;
|
||||
const uint32_t *inl = (const uint32_t *)in;
|
||||
uint32_t *outl = (uint32_t *)out;
|
||||
outl[0] = (outl[0] & nb) | (inl[0] & b);
|
||||
outl[1] = (outl[1] & nb) | (inl[1] & b);
|
||||
outl[2] = (outl[2] & nb) | (inl[2] & b);
|
||||
outl[3] = (outl[3] & nb) | (inl[3] & b);
|
||||
outl[4] = (outl[4] & nb) | (inl[4] & b);
|
||||
outl[5] = (outl[5] & nb) | (inl[5] & b);
|
||||
outl[6] = (outl[6] & nb) | (inl[6] & b);
|
||||
outl[7] = (outl[7] & nb) | (inl[7] & b);
|
||||
outl[8] = (outl[8] & nb) | (inl[8] & b);
|
||||
outl[9] = (outl[9] & nb) | (inl[9] & b);
|
||||
outl[10] = (outl[10] & nb) | (inl[10] & b);
|
||||
outl[11] = (outl[11] & nb) | (inl[11] & b);
|
||||
outl[12] = (outl[12] & nb) | (inl[12] & b);
|
||||
outl[13] = (outl[13] & nb) | (inl[13] & b);
|
||||
outl[14] = (outl[14] & nb) | (inl[14] & b);
|
||||
outl[15] = (outl[15] & nb) | (inl[15] & b);
|
||||
outl[16] = (outl[16] & nb) | (inl[16] & b);
|
||||
outl[17] = (outl[17] & nb) | (inl[17] & b);
|
||||
outl[18] = (outl[18] & nb) | (inl[18] & b);
|
||||
outl[19] = (outl[19] & nb) | (inl[19] & b);
|
||||
outl[20] = (outl[20] & nb) | (inl[20] & b);
|
||||
outl[21] = (outl[21] & nb) | (inl[21] & b);
|
||||
outl[22] = (outl[22] & nb) | (inl[22] & b);
|
||||
outl[23] = (outl[23] & nb) | (inl[23] & b);
|
||||
|
||||
}
|
||||
|
||||
/* if (iswap) swap(a, b) */
|
||||
DONNA_INLINE static void
|
||||
curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) {
|
||||
const uint32_t swap = (uint32_t)(-(int32_t)iswap);
|
||||
uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9;
|
||||
|
||||
x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0;
|
||||
x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1;
|
||||
x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2;
|
||||
x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3;
|
||||
x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4;
|
||||
x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5;
|
||||
x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6;
|
||||
x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7;
|
||||
x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8;
|
||||
x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9;
|
||||
}
|
||||
413
external/ed25519-donna/curve25519-donna-64bit.h
vendored
413
external/ed25519-donna/curve25519-donna-64bit.h
vendored
@@ -1,413 +0,0 @@
|
||||
/*
|
||||
Public domain by Adam Langley <agl@imperialviolet.org> &
|
||||
Andrew M. <liquidsun@gmail.com>
|
||||
See: https://github.com/floodyberry/curve25519-donna
|
||||
|
||||
64bit integer curve25519 implementation
|
||||
*/
|
||||
|
||||
typedef uint64_t bignum25519[5];
|
||||
|
||||
static const uint64_t reduce_mask_40 = ((uint64_t)1 << 40) - 1;
|
||||
static const uint64_t reduce_mask_51 = ((uint64_t)1 << 51) - 1;
|
||||
static const uint64_t reduce_mask_56 = ((uint64_t)1 << 56) - 1;
|
||||
|
||||
/* out = in */
|
||||
DONNA_INLINE static void
|
||||
curve25519_copy(bignum25519 out, const bignum25519 in) {
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
out[3] = in[3];
|
||||
out[4] = in[4];
|
||||
}
|
||||
|
||||
/* out = a + b */
|
||||
DONNA_INLINE static void
|
||||
curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
out[3] = a[3] + b[3];
|
||||
out[4] = a[4] + b[4];
|
||||
}
|
||||
|
||||
/* out = a + b, where a and/or b are the result of a basic op (add,sub) */
|
||||
DONNA_INLINE static void
|
||||
curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
out[0] = a[0] + b[0];
|
||||
out[1] = a[1] + b[1];
|
||||
out[2] = a[2] + b[2];
|
||||
out[3] = a[3] + b[3];
|
||||
out[4] = a[4] + b[4];
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint64_t c;
|
||||
out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
|
||||
out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
|
||||
out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
|
||||
out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
|
||||
out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
|
||||
out[0] += c * 19;
|
||||
}
|
||||
|
||||
/* multiples of p */
|
||||
static const uint64_t twoP0 = 0x0fffffffffffda;
|
||||
static const uint64_t twoP1234 = 0x0ffffffffffffe;
|
||||
static const uint64_t fourP0 = 0x1fffffffffffb4;
|
||||
static const uint64_t fourP1234 = 0x1ffffffffffffc;
|
||||
|
||||
/* out = a - b */
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
out[0] = a[0] + twoP0 - b[0];
|
||||
out[1] = a[1] + twoP1234 - b[1];
|
||||
out[2] = a[2] + twoP1234 - b[2];
|
||||
out[3] = a[3] + twoP1234 - b[3];
|
||||
out[4] = a[4] + twoP1234 - b[4];
|
||||
}
|
||||
|
||||
/* out = a - b, where a and/or b are the result of a basic op (add,sub) */
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
out[0] = a[0] + fourP0 - b[0];
|
||||
out[1] = a[1] + fourP1234 - b[1];
|
||||
out[2] = a[2] + fourP1234 - b[2];
|
||||
out[3] = a[3] + fourP1234 - b[3];
|
||||
out[4] = a[4] + fourP1234 - b[4];
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
|
||||
uint64_t c;
|
||||
out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
|
||||
out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
|
||||
out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
|
||||
out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
|
||||
out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
|
||||
out[0] += c * 19;
|
||||
}
|
||||
|
||||
/* out = -a */
|
||||
DONNA_INLINE static void
|
||||
curve25519_neg(bignum25519 out, const bignum25519 a) {
|
||||
uint64_t c;
|
||||
out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51;
|
||||
out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51;
|
||||
out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51;
|
||||
out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51;
|
||||
out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51;
|
||||
out[0] += c * 19;
|
||||
}
|
||||
|
||||
/* out = a * b */
|
||||
DONNA_INLINE static void
|
||||
curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in) {
|
||||
#if !defined(HAVE_NATIVE_UINT128)
|
||||
uint128_t mul;
|
||||
#endif
|
||||
uint128_t t[5];
|
||||
uint64_t r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
|
||||
|
||||
r0 = in[0];
|
||||
r1 = in[1];
|
||||
r2 = in[2];
|
||||
r3 = in[3];
|
||||
r4 = in[4];
|
||||
|
||||
s0 = in2[0];
|
||||
s1 = in2[1];
|
||||
s2 = in2[2];
|
||||
s3 = in2[3];
|
||||
s4 = in2[4];
|
||||
|
||||
#if defined(HAVE_NATIVE_UINT128)
|
||||
t[0] = ((uint128_t) r0) * s0;
|
||||
t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0;
|
||||
t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1;
|
||||
t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1;
|
||||
t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2;
|
||||
#else
|
||||
mul64x64_128(t[0], r0, s0)
|
||||
mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul)
|
||||
mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul)
|
||||
mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul)
|
||||
mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul)
|
||||
#endif
|
||||
|
||||
r1 *= 19;
|
||||
r2 *= 19;
|
||||
r3 *= 19;
|
||||
r4 *= 19;
|
||||
|
||||
#if defined(HAVE_NATIVE_UINT128)
|
||||
t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2;
|
||||
t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3;
|
||||
t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4;
|
||||
t[3] += ((uint128_t) r4) * s4;
|
||||
#else
|
||||
mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul)
|
||||
mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul)
|
||||
mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul)
|
||||
mul64x64_128(mul, r4, s4) add128(t[3], mul)
|
||||
#endif
|
||||
|
||||
|
||||
r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
|
||||
add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
|
||||
add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
|
||||
add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
|
||||
add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
|
||||
r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
|
||||
r1 += c;
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
}
|
||||
|
||||
DONNA_NOINLINE static void
|
||||
curve25519_mul_noinline(bignum25519 out, const bignum25519 in2, const bignum25519 in) {
|
||||
curve25519_mul(out, in2, in);
|
||||
}
|
||||
|
||||
/* out = in^(2 * count) */
|
||||
DONNA_NOINLINE static void
|
||||
curve25519_square_times(bignum25519 out, const bignum25519 in, uint64_t count) {
|
||||
#if !defined(HAVE_NATIVE_UINT128)
|
||||
uint128_t mul;
|
||||
#endif
|
||||
uint128_t t[5];
|
||||
uint64_t r0,r1,r2,r3,r4,c;
|
||||
uint64_t d0,d1,d2,d4,d419;
|
||||
|
||||
r0 = in[0];
|
||||
r1 = in[1];
|
||||
r2 = in[2];
|
||||
r3 = in[3];
|
||||
r4 = in[4];
|
||||
|
||||
do {
|
||||
d0 = r0 * 2;
|
||||
d1 = r1 * 2;
|
||||
d2 = r2 * 2 * 19;
|
||||
d419 = r4 * 19;
|
||||
d4 = d419 * 2;
|
||||
|
||||
#if defined(HAVE_NATIVE_UINT128)
|
||||
t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 ));
|
||||
t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19));
|
||||
t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 ));
|
||||
t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 ));
|
||||
t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 ));
|
||||
#else
|
||||
mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
|
||||
mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
|
||||
mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
|
||||
mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
|
||||
mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
|
||||
#endif
|
||||
|
||||
r0 = lo128(t[0]) & reduce_mask_51;
|
||||
r1 = lo128(t[1]) & reduce_mask_51; shl128(c, t[0], 13); r1 += c;
|
||||
r2 = lo128(t[2]) & reduce_mask_51; shl128(c, t[1], 13); r2 += c;
|
||||
r3 = lo128(t[3]) & reduce_mask_51; shl128(c, t[2], 13); r3 += c;
|
||||
r4 = lo128(t[4]) & reduce_mask_51; shl128(c, t[3], 13); r4 += c;
|
||||
shl128(c, t[4], 13); r0 += c * 19;
|
||||
c = r0 >> 51; r0 &= reduce_mask_51;
|
||||
r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51;
|
||||
r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51;
|
||||
r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51;
|
||||
r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51;
|
||||
r0 += c * 19;
|
||||
} while(--count);
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
curve25519_square(bignum25519 out, const bignum25519 in) {
|
||||
#if !defined(HAVE_NATIVE_UINT128)
|
||||
uint128_t mul;
|
||||
#endif
|
||||
uint128_t t[5];
|
||||
uint64_t r0,r1,r2,r3,r4,c;
|
||||
uint64_t d0,d1,d2,d4,d419;
|
||||
|
||||
r0 = in[0];
|
||||
r1 = in[1];
|
||||
r2 = in[2];
|
||||
r3 = in[3];
|
||||
r4 = in[4];
|
||||
|
||||
d0 = r0 * 2;
|
||||
d1 = r1 * 2;
|
||||
d2 = r2 * 2 * 19;
|
||||
d419 = r4 * 19;
|
||||
d4 = d419 * 2;
|
||||
|
||||
#if defined(HAVE_NATIVE_UINT128)
|
||||
t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 ));
|
||||
t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19));
|
||||
t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 ));
|
||||
t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 ));
|
||||
t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 ));
|
||||
#else
|
||||
mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul)
|
||||
mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul)
|
||||
mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul)
|
||||
mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul)
|
||||
mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul)
|
||||
#endif
|
||||
|
||||
r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51);
|
||||
add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51);
|
||||
add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51);
|
||||
add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51);
|
||||
add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51);
|
||||
r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51;
|
||||
r1 += c;
|
||||
|
||||
out[0] = r0;
|
||||
out[1] = r1;
|
||||
out[2] = r2;
|
||||
out[3] = r3;
|
||||
out[4] = r4;
|
||||
}
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
DONNA_INLINE static void
|
||||
curve25519_expand(bignum25519 out, const unsigned char *in) {
|
||||
static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}};
|
||||
uint64_t x0,x1,x2,x3;
|
||||
|
||||
if (endian_check.s == 1) {
|
||||
x0 = *(uint64_t *)(in + 0);
|
||||
x1 = *(uint64_t *)(in + 8);
|
||||
x2 = *(uint64_t *)(in + 16);
|
||||
x3 = *(uint64_t *)(in + 24);
|
||||
} else {
|
||||
#define F(s) \
|
||||
((((uint64_t)in[s + 0]) ) | \
|
||||
(((uint64_t)in[s + 1]) << 8) | \
|
||||
(((uint64_t)in[s + 2]) << 16) | \
|
||||
(((uint64_t)in[s + 3]) << 24) | \
|
||||
(((uint64_t)in[s + 4]) << 32) | \
|
||||
(((uint64_t)in[s + 5]) << 40) | \
|
||||
(((uint64_t)in[s + 6]) << 48) | \
|
||||
(((uint64_t)in[s + 7]) << 56))
|
||||
|
||||
x0 = F(0);
|
||||
x1 = F(8);
|
||||
x2 = F(16);
|
||||
x3 = F(24);
|
||||
}
|
||||
|
||||
out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13);
|
||||
out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26);
|
||||
out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39);
|
||||
out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12);
|
||||
out[4] = x3 & reduce_mask_51;
|
||||
}
|
||||
|
||||
/* Take a fully reduced polynomial form number and contract it into a
|
||||
* little-endian, 32-byte array
|
||||
*/
|
||||
DONNA_INLINE static void
|
||||
curve25519_contract(unsigned char *out, const bignum25519 input) {
|
||||
uint64_t t[5];
|
||||
uint64_t f, i;
|
||||
|
||||
t[0] = input[0];
|
||||
t[1] = input[1];
|
||||
t[2] = input[2];
|
||||
t[3] = input[3];
|
||||
t[4] = input[4];
|
||||
|
||||
#define curve25519_contract_carry() \
|
||||
t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \
|
||||
t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \
|
||||
t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \
|
||||
t[4] += t[3] >> 51; t[3] &= reduce_mask_51;
|
||||
|
||||
#define curve25519_contract_carry_full() curve25519_contract_carry() \
|
||||
t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51;
|
||||
|
||||
#define curve25519_contract_carry_final() curve25519_contract_carry() \
|
||||
t[4] &= reduce_mask_51;
|
||||
|
||||
curve25519_contract_carry_full()
|
||||
curve25519_contract_carry_full()
|
||||
|
||||
/* now t is between 0 and 2^255-1, properly carried. */
|
||||
/* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
|
||||
t[0] += 19;
|
||||
curve25519_contract_carry_full()
|
||||
|
||||
/* now between 19 and 2^255-1 in both cases, and offset by 19. */
|
||||
t[0] += (reduce_mask_51 + 1) - 19;
|
||||
t[1] += (reduce_mask_51 + 1) - 1;
|
||||
t[2] += (reduce_mask_51 + 1) - 1;
|
||||
t[3] += (reduce_mask_51 + 1) - 1;
|
||||
t[4] += (reduce_mask_51 + 1) - 1;
|
||||
|
||||
/* now between 2^255 and 2^256-20, and offset by 2^255. */
|
||||
curve25519_contract_carry_final()
|
||||
|
||||
#define write51full(n,shift) \
|
||||
f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \
|
||||
for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f;
|
||||
#define write51(n) write51full(n,13*n)
|
||||
write51(0)
|
||||
write51(1)
|
||||
write51(2)
|
||||
write51(3)
|
||||
}
|
||||
|
||||
#if !defined(ED25519_GCC_64BIT_CHOOSE)
|
||||
|
||||
/* out = (flag) ? in : out */
|
||||
DONNA_INLINE static void
|
||||
curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint64_t flag) {
|
||||
const uint64_t nb = flag - 1, b = ~nb;
|
||||
const uint64_t *inq = (const uint64_t *)in;
|
||||
uint64_t *outq = (uint64_t *)out;
|
||||
outq[0] = (outq[0] & nb) | (inq[0] & b);
|
||||
outq[1] = (outq[1] & nb) | (inq[1] & b);
|
||||
outq[2] = (outq[2] & nb) | (inq[2] & b);
|
||||
outq[3] = (outq[3] & nb) | (inq[3] & b);
|
||||
outq[4] = (outq[4] & nb) | (inq[4] & b);
|
||||
outq[5] = (outq[5] & nb) | (inq[5] & b);
|
||||
outq[6] = (outq[6] & nb) | (inq[6] & b);
|
||||
outq[7] = (outq[7] & nb) | (inq[7] & b);
|
||||
outq[8] = (outq[8] & nb) | (inq[8] & b);
|
||||
outq[9] = (outq[9] & nb) | (inq[9] & b);
|
||||
outq[10] = (outq[10] & nb) | (inq[10] & b);
|
||||
outq[11] = (outq[11] & nb) | (inq[11] & b);
|
||||
}
|
||||
|
||||
/* if (iswap) swap(a, b) */
|
||||
DONNA_INLINE static void
|
||||
curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint64_t iswap) {
|
||||
const uint64_t swap = (uint64_t)(-(int64_t)iswap);
|
||||
uint64_t x0,x1,x2,x3,x4;
|
||||
|
||||
x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0;
|
||||
x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1;
|
||||
x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2;
|
||||
x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3;
|
||||
x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4;
|
||||
}
|
||||
|
||||
#endif /* ED25519_GCC_64BIT_CHOOSE */
|
||||
|
||||
#define ED25519_64BIT_TABLES
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
See: https://github.com/floodyberry/curve25519-donna
|
||||
|
||||
Curve25519 implementation agnostic helpers
|
||||
*/
|
||||
|
||||
/*
|
||||
* In: b = 2^5 - 2^0
|
||||
* Out: b = 2^250 - 2^0
|
||||
*/
|
||||
static void
|
||||
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
|
||||
bignum25519 ALIGN(16) t0,c;
|
||||
|
||||
/* 2^5 - 2^0 */ /* b */
|
||||
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
|
||||
/* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b);
|
||||
/* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10);
|
||||
/* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b);
|
||||
/* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20);
|
||||
/* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c);
|
||||
/* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10);
|
||||
/* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b);
|
||||
/* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50);
|
||||
/* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b);
|
||||
/* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100);
|
||||
/* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c);
|
||||
/* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50);
|
||||
/* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b);
|
||||
}
|
||||
|
||||
/*
|
||||
* z^(p - 2) = z(2^255 - 21)
|
||||
*/
|
||||
static void
|
||||
curve25519_recip(bignum25519 out, const bignum25519 z) {
|
||||
bignum25519 ALIGN(16) a,t0,b;
|
||||
|
||||
/* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
|
||||
/* 8 */ curve25519_square_times(t0, a, 2);
|
||||
/* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */
|
||||
/* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */
|
||||
/* 22 */ curve25519_square_times(t0, a, 1);
|
||||
/* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b);
|
||||
/* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b);
|
||||
/* 2^255 - 2^5 */ curve25519_square_times(b, b, 5);
|
||||
/* 2^255 - 21 */ curve25519_mul_noinline(out, b, a);
|
||||
}
|
||||
|
||||
/*
|
||||
* z^((p-5)/8) = z^(2^252 - 3)
|
||||
*/
|
||||
static void
|
||||
curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
|
||||
bignum25519 ALIGN(16) b,c,t0;
|
||||
|
||||
/* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
|
||||
/* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
|
||||
/* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */
|
||||
/* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */
|
||||
/* 22 */ curve25519_square_times(t0, c, 1);
|
||||
/* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b);
|
||||
/* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b);
|
||||
/* 2^252 - 2^2 */ curve25519_square_times(b, b, 2);
|
||||
/* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z);
|
||||
}
|
||||
1112
external/ed25519-donna/curve25519-donna-sse2.h
vendored
1112
external/ed25519-donna/curve25519-donna-sse2.h
vendored
File diff suppressed because it is too large
Load Diff
513
external/ed25519-donna/ed25519-donna-32bit-sse2.h
vendored
513
external/ed25519-donna/ed25519-donna-32bit-sse2.h
vendored
@@ -1,513 +0,0 @@
|
||||
#if defined(ED25519_GCC_32BIT_SSE_CHOOSE)
|
||||
|
||||
#define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS
|
||||
|
||||
DONNA_NOINLINE static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
int32_t breg = (int32_t)b;
|
||||
uint32_t sign = (uint32_t)breg >> 31;
|
||||
uint32_t mask = ~(sign - 1);
|
||||
uint32_t u = (breg + mask) ^ mask;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
/* ysubx+xaddy */
|
||||
"movl %0, %%eax ;\n"
|
||||
"movd %%eax, %%xmm6 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
"pxor %%xmm2, %%xmm2 ;\n"
|
||||
"pxor %%xmm3, %%xmm3 ;\n"
|
||||
|
||||
/* 0 */
|
||||
"movl $0, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movl $1, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm4 ;\n"
|
||||
"pxor %%xmm5, %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 1 */
|
||||
"movl $1, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 0(%1), %%xmm4 ;\n"
|
||||
"movdqa 16(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 32(%1), %%xmm4 ;\n"
|
||||
"movdqa 48(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 2 */
|
||||
"movl $2, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 96(%1), %%xmm4 ;\n"
|
||||
"movdqa 112(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 128(%1), %%xmm4 ;\n"
|
||||
"movdqa 144(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 3 */
|
||||
"movl $3, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 192(%1), %%xmm4 ;\n"
|
||||
"movdqa 208(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 224(%1), %%xmm4 ;\n"
|
||||
"movdqa 240(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 4 */
|
||||
"movl $4, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 288(%1), %%xmm4 ;\n"
|
||||
"movdqa 304(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 320(%1), %%xmm4 ;\n"
|
||||
"movdqa 336(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 5 */
|
||||
"movl $5, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 384(%1), %%xmm4 ;\n"
|
||||
"movdqa 400(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 416(%1), %%xmm4 ;\n"
|
||||
"movdqa 432(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 6 */
|
||||
"movl $6, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 480(%1), %%xmm4 ;\n"
|
||||
"movdqa 496(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 512(%1), %%xmm4 ;\n"
|
||||
"movdqa 528(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 7 */
|
||||
"movl $7, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 576(%1), %%xmm4 ;\n"
|
||||
"movdqa 592(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 608(%1), %%xmm4 ;\n"
|
||||
"movdqa 624(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* 8 */
|
||||
"movl $8, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 672(%1), %%xmm4 ;\n"
|
||||
"movdqa 688(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm0 ;\n"
|
||||
"por %%xmm5, %%xmm1 ;\n"
|
||||
"movdqa 704(%1), %%xmm4 ;\n"
|
||||
"movdqa 720(%1), %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"por %%xmm4, %%xmm2 ;\n"
|
||||
"por %%xmm5, %%xmm3 ;\n"
|
||||
|
||||
/* conditional swap based on sign */
|
||||
"movl %3, %%ecx ;\n"
|
||||
"movl %2, %%eax ;\n"
|
||||
"xorl $1, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm6 ;\n"
|
||||
"pxor %%xmm7, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa %%xmm2, %%xmm4 ;\n"
|
||||
"movdqa %%xmm3, %%xmm5 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm5 ;\n"
|
||||
"pxor %%xmm4, %%xmm0 ;\n"
|
||||
"pxor %%xmm5, %%xmm1 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
|
||||
/* store ysubx */
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"movl %%ecx, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 0(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $26, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 4(%%eax) ;\n"
|
||||
"movd %%xmm0, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $19, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 8(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"shrdl $13, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 12(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrl $6, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 16(%%eax) ;\n"
|
||||
"movl %%edx, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 20(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $25, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 24(%%eax) ;\n"
|
||||
"movd %%xmm1, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $19, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 28(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"shrdl $12, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 32(%%eax) ;\n"
|
||||
"shrl $6, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"xorl %%ecx, %%ecx ;\n"
|
||||
"movl %%edx, 36(%%eax) ;\n"
|
||||
"movl %%ecx, 40(%%eax) ;\n"
|
||||
"movl %%ecx, 44(%%eax) ;\n"
|
||||
|
||||
/* store xaddy */
|
||||
"addl $48, %%eax ;\n"
|
||||
"movdqa %%xmm2, %%xmm0 ;\n"
|
||||
"movdqa %%xmm3, %%xmm1 ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"movl %%ecx, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 0(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $26, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 4(%%eax) ;\n"
|
||||
"movd %%xmm0, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $19, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 8(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"shrdl $13, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 12(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrl $6, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 16(%%eax) ;\n"
|
||||
"movl %%edx, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 20(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $25, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 24(%%eax) ;\n"
|
||||
"movd %%xmm1, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $19, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 28(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"shrdl $12, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 32(%%eax) ;\n"
|
||||
"shrl $6, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"xorl %%ecx, %%ecx ;\n"
|
||||
"movl %%edx, 36(%%eax) ;\n"
|
||||
"movl %%ecx, 40(%%eax) ;\n"
|
||||
"movl %%ecx, 44(%%eax) ;\n"
|
||||
|
||||
/* t2d */
|
||||
"movl %0, %%eax ;\n"
|
||||
"movd %%eax, %%xmm6 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
|
||||
/* 0 */
|
||||
"movl $0, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
|
||||
/* 1 */
|
||||
"movl $1, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 64(%1), %%xmm3 ;\n"
|
||||
"movdqa 80(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 2 */
|
||||
"movl $2, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 160(%1), %%xmm3 ;\n"
|
||||
"movdqa 176(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 3 */
|
||||
"movl $3, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 256(%1), %%xmm3 ;\n"
|
||||
"movdqa 272(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 4 */
|
||||
"movl $4, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 352(%1), %%xmm3 ;\n"
|
||||
"movdqa 368(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 5 */
|
||||
"movl $5, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 448(%1), %%xmm3 ;\n"
|
||||
"movdqa 464(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 6 */
|
||||
"movl $6, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 544(%1), %%xmm3 ;\n"
|
||||
"movdqa 560(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 7 */
|
||||
"movl $7, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 640(%1), %%xmm3 ;\n"
|
||||
"movdqa 656(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* 8 */
|
||||
"movl $8, %%eax ;\n"
|
||||
"movd %%eax, %%xmm7 ;\n"
|
||||
"pshufd $0x00, %%xmm7, %%xmm7 ;\n"
|
||||
"pcmpeqd %%xmm6, %%xmm7 ;\n"
|
||||
"movdqa 736(%1), %%xmm3 ;\n"
|
||||
"movdqa 752(%1), %%xmm4 ;\n"
|
||||
"pand %%xmm7, %%xmm3 ;\n"
|
||||
"pand %%xmm7, %%xmm4 ;\n"
|
||||
"por %%xmm3, %%xmm0 ;\n"
|
||||
"por %%xmm4, %%xmm1 ;\n"
|
||||
|
||||
/* store t2d */
|
||||
"movl %2, %%eax ;\n"
|
||||
"addl $96, %%eax ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"movl %%ecx, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 0(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $26, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 4(%%eax) ;\n"
|
||||
"movd %%xmm0, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm0, %%xmm0 ;\n"
|
||||
"shrdl $19, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 8(%%eax) ;\n"
|
||||
"movd %%xmm0, %%ecx ;\n"
|
||||
"shrdl $13, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 12(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrl $6, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 16(%%eax) ;\n"
|
||||
"movl %%edx, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 20(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $25, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 24(%%eax) ;\n"
|
||||
"movd %%xmm1, %%ecx ;\n"
|
||||
"pshufd $0x39, %%xmm1, %%xmm1 ;\n"
|
||||
"shrdl $19, %%ecx, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"movl %%edx, 28(%%eax) ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"movd %%xmm1, %%edx ;\n"
|
||||
"shrdl $12, %%edx, %%ecx ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"movl %%ecx, 32(%%eax) ;\n"
|
||||
"shrl $6, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%edx ;\n"
|
||||
"xorl %%ecx, %%ecx ;\n"
|
||||
"movl %%edx, 36(%%eax) ;\n"
|
||||
"movl %%ecx, 40(%%eax) ;\n"
|
||||
"movl %%ecx, 44(%%eax) ;\n"
|
||||
"movdqa 0(%%eax), %%xmm0 ;\n"
|
||||
"movdqa 16(%%eax), %%xmm1 ;\n"
|
||||
"movdqa 32(%%eax), %%xmm2 ;\n"
|
||||
|
||||
/* conditionally negate t2d */
|
||||
|
||||
/* set up 2p in to 3/4 */
|
||||
"movl $0x7ffffda, %%ecx ;\n"
|
||||
"movl $0x3fffffe, %%edx ;\n"
|
||||
"movd %%ecx, %%xmm3 ;\n"
|
||||
"movd %%edx, %%xmm5 ;\n"
|
||||
"movl $0x7fffffe, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm4 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm3 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm4 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm3 ;\n"
|
||||
"movdqa %%xmm4, %%xmm5 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm4 ;\n"
|
||||
|
||||
/* subtract and conditionally move */
|
||||
"movl %3, %%ecx ;\n"
|
||||
"sub $1, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm6 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"movdqa %%xmm6, %%xmm7 ;\n"
|
||||
"psubd %%xmm0, %%xmm3 ;\n"
|
||||
"psubd %%xmm1, %%xmm4 ;\n"
|
||||
"psubd %%xmm2, %%xmm5 ;\n"
|
||||
"pand %%xmm6, %%xmm0 ;\n"
|
||||
"pand %%xmm6, %%xmm1 ;\n"
|
||||
"pand %%xmm6, %%xmm2 ;\n"
|
||||
"pandn %%xmm3, %%xmm6 ;\n"
|
||||
"movdqa %%xmm7, %%xmm3 ;\n"
|
||||
"pandn %%xmm4, %%xmm7 ;\n"
|
||||
"pandn %%xmm5, %%xmm3 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm3, %%xmm2 ;\n"
|
||||
|
||||
/* store */
|
||||
"movdqa %%xmm0, 0(%%eax) ;\n"
|
||||
"movdqa %%xmm1, 16(%%eax) ;\n"
|
||||
"movdqa %%xmm2, 32(%%eax) ;\n"
|
||||
:
|
||||
: "m"(u), "r"(&table[pos * 8]), "m"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */
|
||||
: "%eax", "%ecx", "%edx", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* defined(ED25519_GCC_32BIT_SSE_CHOOSE) */
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
static const ge25519 ALIGN(16) ge25519_basepoint = {
|
||||
{0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db},
|
||||
{0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999},
|
||||
{0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000},
|
||||
{0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c}
|
||||
};
|
||||
|
||||
/*
|
||||
d
|
||||
*/
|
||||
|
||||
static const bignum25519 ALIGN(16) ge25519_ecd = {
|
||||
0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3
|
||||
};
|
||||
|
||||
static const bignum25519 ALIGN(16) ge25519_ec2d = {
|
||||
0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67
|
||||
};
|
||||
|
||||
/*
|
||||
sqrt(-1)
|
||||
*/
|
||||
|
||||
static const bignum25519 ALIGN(16) ge25519_sqrtneg1 = {
|
||||
0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92
|
||||
};
|
||||
|
||||
static const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = {
|
||||
{{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}},
|
||||
{{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}},
|
||||
{{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}},
|
||||
{{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}},
|
||||
{{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}},
|
||||
{{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}},
|
||||
{{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}},
|
||||
{{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}},
|
||||
{{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}},
|
||||
{{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}},
|
||||
{{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}},
|
||||
{{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}},
|
||||
{{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}},
|
||||
{{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}},
|
||||
{{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}},
|
||||
{{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}},
|
||||
{{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}},
|
||||
{{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}},
|
||||
{{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}},
|
||||
{{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}},
|
||||
{{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}},
|
||||
{{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}},
|
||||
{{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}},
|
||||
{{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}},
|
||||
{{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}},
|
||||
{{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}},
|
||||
{{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}},
|
||||
{{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}},
|
||||
{{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}},
|
||||
{{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}},
|
||||
{{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}},
|
||||
{{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}}
|
||||
};
|
||||
436
external/ed25519-donna/ed25519-donna-64bit-sse2.h
vendored
436
external/ed25519-donna/ed25519-donna-64bit-sse2.h
vendored
@@ -1,436 +0,0 @@
|
||||
#if defined(ED25519_GCC_64BIT_SSE_CHOOSE)
|
||||
|
||||
#define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS
|
||||
|
||||
DONNA_NOINLINE static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
int64_t breg = (int64_t)b;
|
||||
uint64_t sign = (uint64_t)breg >> 63;
|
||||
uint64_t mask = ~(sign - 1);
|
||||
uint64_t u = (breg + mask) ^ mask;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
/* ysubx+xaddy+t2d */
|
||||
"movq %0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
"pxor %%xmm2, %%xmm2 ;\n"
|
||||
"pxor %%xmm3, %%xmm3 ;\n"
|
||||
"pxor %%xmm4, %%xmm4 ;\n"
|
||||
"pxor %%xmm5, %%xmm5 ;\n"
|
||||
|
||||
/* 0 */
|
||||
"movq $0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm6 ;\n"
|
||||
"pxor %%xmm7, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm6, %%xmm2 ;\n"
|
||||
"por %%xmm7, %%xmm3 ;\n"
|
||||
|
||||
/* 1 */
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 0(%1), %%xmm6 ;\n"
|
||||
"movdqa 16(%1), %%xmm7 ;\n"
|
||||
"movdqa 32(%1), %%xmm8 ;\n"
|
||||
"movdqa 48(%1), %%xmm9 ;\n"
|
||||
"movdqa 64(%1), %%xmm10 ;\n"
|
||||
"movdqa 80(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 2 */
|
||||
"movq $2, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 96(%1), %%xmm6 ;\n"
|
||||
"movdqa 112(%1), %%xmm7 ;\n"
|
||||
"movdqa 128(%1), %%xmm8 ;\n"
|
||||
"movdqa 144(%1), %%xmm9 ;\n"
|
||||
"movdqa 160(%1), %%xmm10 ;\n"
|
||||
"movdqa 176(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 3 */
|
||||
"movq $3, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 192(%1), %%xmm6 ;\n"
|
||||
"movdqa 208(%1), %%xmm7 ;\n"
|
||||
"movdqa 224(%1), %%xmm8 ;\n"
|
||||
"movdqa 240(%1), %%xmm9 ;\n"
|
||||
"movdqa 256(%1), %%xmm10 ;\n"
|
||||
"movdqa 272(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 4 */
|
||||
"movq $4, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 288(%1), %%xmm6 ;\n"
|
||||
"movdqa 304(%1), %%xmm7 ;\n"
|
||||
"movdqa 320(%1), %%xmm8 ;\n"
|
||||
"movdqa 336(%1), %%xmm9 ;\n"
|
||||
"movdqa 352(%1), %%xmm10 ;\n"
|
||||
"movdqa 368(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 5 */
|
||||
"movq $5, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 384(%1), %%xmm6 ;\n"
|
||||
"movdqa 400(%1), %%xmm7 ;\n"
|
||||
"movdqa 416(%1), %%xmm8 ;\n"
|
||||
"movdqa 432(%1), %%xmm9 ;\n"
|
||||
"movdqa 448(%1), %%xmm10 ;\n"
|
||||
"movdqa 464(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 6 */
|
||||
"movq $6, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 480(%1), %%xmm6 ;\n"
|
||||
"movdqa 496(%1), %%xmm7 ;\n"
|
||||
"movdqa 512(%1), %%xmm8 ;\n"
|
||||
"movdqa 528(%1), %%xmm9 ;\n"
|
||||
"movdqa 544(%1), %%xmm10 ;\n"
|
||||
"movdqa 560(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 7 */
|
||||
"movq $7, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 576(%1), %%xmm6 ;\n"
|
||||
"movdqa 592(%1), %%xmm7 ;\n"
|
||||
"movdqa 608(%1), %%xmm8 ;\n"
|
||||
"movdqa 624(%1), %%xmm9 ;\n"
|
||||
"movdqa 640(%1), %%xmm10 ;\n"
|
||||
"movdqa 656(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 8 */
|
||||
"movq $8, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 672(%1), %%xmm6 ;\n"
|
||||
"movdqa 688(%1), %%xmm7 ;\n"
|
||||
"movdqa 704(%1), %%xmm8 ;\n"
|
||||
"movdqa 720(%1), %%xmm9 ;\n"
|
||||
"movdqa 736(%1), %%xmm10 ;\n"
|
||||
"movdqa 752(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* conditionally swap ysubx and xaddy */
|
||||
"movq %3, %%rax ;\n"
|
||||
"xorq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pxor %%xmm15, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa %%xmm2, %%xmm6 ;\n"
|
||||
"movdqa %%xmm3, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pxor %%xmm6, %%xmm0 ;\n"
|
||||
"pxor %%xmm7, %%xmm1 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
|
||||
/* store ysubx */
|
||||
"xorq %%rax, %%rax ;\n"
|
||||
"movd %%xmm0, %%rcx ;\n"
|
||||
"movd %%xmm0, %%r8 ;\n"
|
||||
"movd %%xmm1, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm0, %%xmm0 ;\n"
|
||||
"pshufd $0xee, %%xmm1, %%xmm1 ;\n"
|
||||
"movd %%xmm0, %%rdx ;\n"
|
||||
"movd %%xmm1, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movl %%ecx, 0(%2) ;\n"
|
||||
"movl %%r9d, 4(%2) ;\n"
|
||||
"movl %%r8d, 8(%2) ;\n"
|
||||
"movl %%r10d, 12(%2) ;\n"
|
||||
"movl %%edx, 16(%2) ;\n"
|
||||
"movl %%r11d, 20(%2) ;\n"
|
||||
"movl %%esi, 24(%2) ;\n"
|
||||
"movl %%r12d, 28(%2) ;\n"
|
||||
"movl %%edi, 32(%2) ;\n"
|
||||
"movl %%r13d, 36(%2) ;\n"
|
||||
"movq %%rax, 40(%2) ;\n"
|
||||
|
||||
/* store xaddy */
|
||||
"movd %%xmm2, %%rcx ;\n"
|
||||
"movd %%xmm2, %%r8 ;\n"
|
||||
"movd %%xmm3, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm2, %%xmm2 ;\n"
|
||||
"pshufd $0xee, %%xmm3, %%xmm3 ;\n"
|
||||
"movd %%xmm2, %%rdx ;\n"
|
||||
"movd %%xmm3, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movl %%ecx, 48(%2) ;\n"
|
||||
"movl %%r9d, 52(%2) ;\n"
|
||||
"movl %%r8d, 56(%2) ;\n"
|
||||
"movl %%r10d, 60(%2) ;\n"
|
||||
"movl %%edx, 64(%2) ;\n"
|
||||
"movl %%r11d, 68(%2) ;\n"
|
||||
"movl %%esi, 72(%2) ;\n"
|
||||
"movl %%r12d, 76(%2) ;\n"
|
||||
"movl %%edi, 80(%2) ;\n"
|
||||
"movl %%r13d, 84(%2) ;\n"
|
||||
"movq %%rax, 88(%2) ;\n"
|
||||
|
||||
/* extract t2d */
|
||||
"xorq %%rax, %%rax ;\n"
|
||||
"movd %%xmm4, %%rcx ;\n"
|
||||
"movd %%xmm4, %%r8 ;\n"
|
||||
"movd %%xmm5, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm4, %%xmm4 ;\n"
|
||||
"pshufd $0xee, %%xmm5, %%xmm5 ;\n"
|
||||
"movd %%xmm4, %%rdx ;\n"
|
||||
"movd %%xmm5, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movd %%ecx, %%xmm0 ;\n"
|
||||
"movd %%r9d, %%xmm4 ;\n"
|
||||
"movd %%r8d, %%xmm8 ;\n"
|
||||
"movd %%r10d, %%xmm3 ;\n"
|
||||
"movd %%edx, %%xmm1 ;\n"
|
||||
"movd %%r11d, %%xmm5 ;\n"
|
||||
"movd %%esi, %%xmm6 ;\n"
|
||||
"movd %%r12d, %%xmm7 ;\n"
|
||||
"movd %%edi, %%xmm2 ;\n"
|
||||
"movd %%r13d, %%xmm9 ;\n"
|
||||
"punpckldq %%xmm4, %%xmm0 ;\n"
|
||||
"punpckldq %%xmm3, %%xmm8 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm1 ;\n"
|
||||
"punpckldq %%xmm7, %%xmm6 ;\n"
|
||||
"punpckldq %%xmm9, %%xmm2 ;\n"
|
||||
"punpcklqdq %%xmm8, %%xmm0 ;\n"
|
||||
"punpcklqdq %%xmm6, %%xmm1 ;\n"
|
||||
|
||||
/* set up 2p in to 3/4 */
|
||||
"movl $0x7ffffda, %%ecx ;\n"
|
||||
"movl $0x3fffffe, %%edx ;\n"
|
||||
"movl $0x7fffffe, %%eax ;\n"
|
||||
"movd %%ecx, %%xmm3 ;\n"
|
||||
"movd %%edx, %%xmm5 ;\n"
|
||||
"movd %%eax, %%xmm4 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm3 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm4 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm3 ;\n"
|
||||
"movdqa %%xmm4, %%xmm5 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm4 ;\n"
|
||||
|
||||
/* subtract and conditionally move */
|
||||
"movl %3, %%ecx ;\n"
|
||||
"sub $1, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm6 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"movdqa %%xmm6, %%xmm7 ;\n"
|
||||
"psubd %%xmm0, %%xmm3 ;\n"
|
||||
"psubd %%xmm1, %%xmm4 ;\n"
|
||||
"psubd %%xmm2, %%xmm5 ;\n"
|
||||
"pand %%xmm6, %%xmm0 ;\n"
|
||||
"pand %%xmm6, %%xmm1 ;\n"
|
||||
"pand %%xmm6, %%xmm2 ;\n"
|
||||
"pandn %%xmm3, %%xmm6 ;\n"
|
||||
"movdqa %%xmm7, %%xmm3 ;\n"
|
||||
"pandn %%xmm4, %%xmm7 ;\n"
|
||||
"pandn %%xmm5, %%xmm3 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm3, %%xmm2 ;\n"
|
||||
|
||||
/* store t2d */
|
||||
"movdqa %%xmm0, 96(%2) ;\n"
|
||||
"movdqa %%xmm1, 112(%2) ;\n"
|
||||
"movdqa %%xmm2, 128(%2) ;\n"
|
||||
:
|
||||
: "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */
|
||||
:
|
||||
"%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13",
|
||||
"%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14",
|
||||
"cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* defined(ED25519_GCC_64BIT_SSE_CHOOSE) */
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
static const ge25519 ge25519_basepoint = {
|
||||
{0x00062d608f25d51a,0x000412a4b4f6592a,0x00075b7171a4b31d,0x0001ff60527118fe,0x000216936d3cd6e5},
|
||||
{0x0006666666666658,0x0004cccccccccccc,0x0001999999999999,0x0003333333333333,0x0006666666666666},
|
||||
{0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000},
|
||||
{0x00068ab3a5b7dda3,0x00000eea2a5eadbb,0x0002af8df483c27e,0x000332b375274732,0x00067875f0fd78b7}
|
||||
};
|
||||
|
||||
static const bignum25519 ge25519_ecd = {
|
||||
0x00034dca135978a3,0x0001a8283b156ebd,0x0005e7a26001c029,0x000739c663a03cbb,0x00052036cee2b6ff
|
||||
};
|
||||
|
||||
static const bignum25519 ge25519_ec2d = {
|
||||
0x00069b9426b2f159,0x00035050762add7a,0x0003cf44c0038052,0x0006738cc7407977,0x0002406d9dc56dff
|
||||
};
|
||||
|
||||
static const bignum25519 ge25519_sqrtneg1 = {
|
||||
0x00061b274a0ea0b0,0x0000d5a5fc8f189d,0x0007ef5e9cbd0c60,0x00078595a6804c9e,0x0002b8324804fc1d
|
||||
};
|
||||
|
||||
static const ge25519_niels ge25519_niels_sliding_multiples[32] = {
|
||||
{{0x00003905d740913e,0x0000ba2817d673a2,0x00023e2827f4e67c,0x000133d2e0c21a34,0x00044fd2f9298f81},{0x000493c6f58c3b85,0x0000df7181c325f7,0x0000f50b0b3e4cb7,0x0005329385a44c32,0x00007cf9d3a33d4b},{0x00011205877aaa68,0x000479955893d579,0x00050d66309b67a0,0x0002d42d0dbee5ee,0x0006f117b689f0c6}},
|
||||
{{0x00011fe8a4fcd265,0x0007bcb8374faacc,0x00052f5af4ef4d4f,0x0005314098f98d10,0x0002ab91587555bd},{0x0005b0a84cee9730,0x00061d10c97155e4,0x0004059cc8096a10,0x00047a608da8014f,0x0007a164e1b9a80f},{0x0006933f0dd0d889,0x00044386bb4c4295,0x0003cb6d3162508c,0x00026368b872a2c6,0x0005a2826af12b9b}},
|
||||
{{0x000182c3a447d6ba,0x00022964e536eff2,0x000192821f540053,0x0002f9f19e788e5c,0x000154a7e73eb1b5},{0x0002bc4408a5bb33,0x000078ebdda05442,0x0002ffb112354123,0x000375ee8df5862d,0x0002945ccf146e20},{0x0003dbf1812a8285,0x0000fa17ba3f9797,0x0006f69cb49c3820,0x00034d5a0db3858d,0x00043aabe696b3bb}},
|
||||
{{0x00072c9aaa3221b1,0x000267774474f74d,0x000064b0e9b28085,0x0003f04ef53b27c9,0x0001d6edd5d2e531},{0x00025cd0944ea3bf,0x00075673b81a4d63,0x000150b925d1c0d4,0x00013f38d9294114,0x000461bea69283c9},{0x00036dc801b8b3a2,0x0000e0a7d4935e30,0x0001deb7cecc0d7d,0x000053a94e20dd2c,0x0007a9fbb1c6a0f9}},
|
||||
{{0x0006217e039d8064,0x0006dea408337e6d,0x00057ac112628206,0x000647cb65e30473,0x00049c05a51fadc9},{0x0006678aa6a8632f,0x0005ea3788d8b365,0x00021bd6d6994279,0x0007ace75919e4e3,0x00034b9ed338add7},{0x0004e8bf9045af1b,0x000514e33a45e0d6,0x0007533c5b8bfe0f,0x000583557b7e14c9,0x00073c172021b008}},
|
||||
{{0x00075b0249864348,0x00052ee11070262b,0x000237ae54fb5acd,0x0003bfd1d03aaab5,0x00018ab598029d5c},{0x000700848a802ade,0x0001e04605c4e5f7,0x0005c0d01b9767fb,0x0007d7889f42388b,0x0004275aae2546d8},{0x00032cc5fd6089e9,0x000426505c949b05,0x00046a18880c7ad2,0x0004a4221888ccda,0x0003dc65522b53df}},
|
||||
{{0x0007013b327fbf93,0x0001336eeded6a0d,0x0002b565a2bbf3af,0x000253ce89591955,0x0000267882d17602},{0x0000c222a2007f6d,0x000356b79bdb77ee,0x00041ee81efe12ce,0x000120a9bd07097d,0x000234fd7eec346f},{0x0000a119732ea378,0x00063bf1ba8e2a6c,0x00069f94cc90df9a,0x000431d1779bfc48,0x000497ba6fdaa097}},
|
||||
{{0x0003cd86468ccf0b,0x00048553221ac081,0x0006c9464b4e0a6e,0x00075fba84180403,0x00043b5cd4218d05},{0x0006cc0313cfeaa0,0x0001a313848da499,0x0007cb534219230a,0x00039596dedefd60,0x00061e22917f12de},{0x0002762f9bd0b516,0x0001c6e7fbddcbb3,0x00075909c3ace2bd,0x00042101972d3ec9,0x000511d61210ae4d}},
|
||||
{{0x000386484420de87,0x0002d6b25db68102,0x000650b4962873c0,0x0004081cfd271394,0x00071a7fe6fe2482},{0x000676ef950e9d81,0x0001b81ae089f258,0x00063c4922951883,0x0002f1d54d9b3237,0x0006d325924ddb85},{0x000182b8a5c8c854,0x00073fcbe5406d8e,0x0005de3430cff451,0x000554b967ac8c41,0x0004746c4b6559ee}},
|
||||
{{0x000546c864741147,0x0003a1df99092690,0x0001ca8cc9f4d6bb,0x00036b7fc9cd3b03,0x000219663497db5e},{0x00077b3c6dc69a2b,0x0004edf13ec2fa6e,0x0004e85ad77beac8,0x0007dba2b28e7bda,0x0005c9a51de34fe9},{0x0000f1cf79f10e67,0x00043ccb0a2b7ea2,0x00005089dfff776a,0x0001dd84e1d38b88,0x0004804503c60822}},
|
||||
{{0x000021d23a36d175,0x0004fd3373c6476d,0x00020e291eeed02a,0x00062f2ecf2e7210,0x000771e098858de4},{0x00049ed02ca37fc7,0x000474c2b5957884,0x0005b8388e816683,0x0004b6c454b76be4,0x000553398a516506},{0x0002f5d278451edf,0x000730b133997342,0x0006965420eb6975,0x000308a3bfa516cf,0x0005a5ed1d68ff5a}},
|
||||
{{0x0005e0c558527359,0x0003395b73afd75c,0x000072afa4e4b970,0x00062214329e0f6d,0x000019b60135fefd},{0x0005122afe150e83,0x0004afc966bb0232,0x0001c478833c8268,0x00017839c3fc148f,0x00044acb897d8bf9},{0x000068145e134b83,0x0001e4860982c3cc,0x000068fb5f13d799,0x0007c9283744547e,0x000150c49fde6ad2}},
|
||||
{{0x0001863c9cdca868,0x0003770e295a1709,0x0000d85a3720fd13,0x0005e0ff1f71ab06,0x00078a6d7791e05f},{0x0003f29509471138,0x000729eeb4ca31cf,0x00069c22b575bfbc,0x0004910857bce212,0x0006b2b5a075bb99},{0x0007704b47a0b976,0x0002ae82e91aab17,0x00050bd6429806cd,0x00068055158fd8ea,0x000725c7ffc4ad55}},
|
||||
{{0x00002bf71cd098c0,0x00049dabcc6cd230,0x00040a6533f905b2,0x000573efac2eb8a4,0x0004cd54625f855f},{0x00026715d1cf99b2,0x0002205441a69c88,0x000448427dcd4b54,0x0001d191e88abdc5,0x000794cc9277cb1f},{0x0006c426c2ac5053,0x0005a65ece4b095e,0x0000c44086f26bb6,0x0007429568197885,0x0007008357b6fcc8}},
|
||||
{{0x00039fbb82584a34,0x00047a568f257a03,0x00014d88091ead91,0x0002145b18b1ce24,0x00013a92a3669d6d},{0x0000672738773f01,0x000752bf799f6171,0x0006b4a6dae33323,0x0007b54696ead1dc,0x00006ef7e9851ad0},{0x0003771cc0577de5,0x0003ca06bb8b9952,0x00000b81c5d50390,0x00043512340780ec,0x0003c296ddf8a2af}},
|
||||
{{0x00034d2ebb1f2541,0x0000e815b723ff9d,0x000286b416e25443,0x0000bdfe38d1bee8,0x0000a892c7007477},{0x000515f9d914a713,0x00073191ff2255d5,0x00054f5cc2a4bdef,0x0003dd57fc118bcf,0x0007a99d393490c7},{0x0002ed2436bda3e8,0x00002afd00f291ea,0x0000be7381dea321,0x0003e952d4b2b193,0x000286762d28302f}},
|
||||
{{0x00058e2bce2ef5bd,0x00068ce8f78c6f8a,0x0006ee26e39261b2,0x00033d0aa50bcf9d,0x0007686f2a3d6f17},{0x000036093ce35b25,0x0003b64d7552e9cf,0x00071ee0fe0b8460,0x00069d0660c969e5,0x00032f1da046a9d9},{0x000512a66d597c6a,0x0000609a70a57551,0x000026c08a3c464c,0x0004531fc8ee39e1,0x000561305f8a9ad2}},
|
||||
{{0x0002cc28e7b0c0d5,0x00077b60eb8a6ce4,0x0004042985c277a6,0x000636657b46d3eb,0x000030a1aef2c57c},{0x0004978dec92aed1,0x000069adae7ca201,0x00011ee923290f55,0x00069641898d916c,0x00000aaec53e35d4},{0x0001f773003ad2aa,0x000005642cc10f76,0x00003b48f82cfca6,0x0002403c10ee4329,0x00020be9c1c24065}},
|
||||
{{0x0000e44ae2025e60,0x0005f97b9727041c,0x0005683472c0ecec,0x000188882eb1ce7c,0x00069764c545067e},{0x000387d8249673a6,0x0005bea8dc927c2a,0x0005bd8ed5650ef0,0x0000ef0e3fcd40e1,0x000750ab3361f0ac},{0x00023283a2f81037,0x000477aff97e23d1,0x0000b8958dbcbb68,0x0000205b97e8add6,0x00054f96b3fb7075}},
|
||||
{{0x0005afc616b11ecd,0x00039f4aec8f22ef,0x0003b39e1625d92e,0x0005f85bd4508873,0x00078e6839fbe85d},{0x0005f20429669279,0x00008fafae4941f5,0x00015d83c4eb7688,0x0001cf379eca4146,0x0003d7fe9c52bb75},{0x00032df737b8856b,0x0000608342f14e06,0x0003967889d74175,0x0001211907fba550,0x00070f268f350088}},
|
||||
{{0x0004112070dcf355,0x0007dcff9c22e464,0x00054ada60e03325,0x00025cd98eef769a,0x000404e56c039b8c},{0x00064583b1805f47,0x00022c1baf832cd0,0x000132c01bd4d717,0x0004ecf4c3a75b8f,0x0007c0d345cfad88},{0x00071f4b8c78338a,0x00062cfc16bc2b23,0x00017cf51280d9aa,0x0003bbae5e20a95a,0x00020d754762aaec}},
|
||||
{{0x0004feb135b9f543,0x00063bd192ad93ae,0x00044e2ea612cdf7,0x000670f4991583ab,0x00038b8ada8790b4},{0x0007c36fc73bb758,0x0004a6c797734bd1,0x0000ef248ab3950e,0x00063154c9a53ec8,0x0002b8f1e46f3cee},{0x00004a9cdf51f95d,0x0005d963fbd596b8,0x00022d9b68ace54a,0x0004a98e8836c599,0x000049aeb32ceba1}},
|
||||
{{0x00067d3c63dcfe7e,0x000112f0adc81aee,0x00053df04c827165,0x0002fe5b33b430f0,0x00051c665e0c8d62},{0x00007d0b75fc7931,0x00016f4ce4ba754a,0x0005ace4c03fbe49,0x00027e0ec12a159c,0x000795ee17530f67},{0x00025b0a52ecbd81,0x0005dc0695fce4a9,0x0003b928c575047d,0x00023bf3512686e5,0x0006cd19bf49dc54}},
|
||||
{{0x0007619052179ca3,0x0000c16593f0afd0,0x000265c4795c7428,0x00031c40515d5442,0x0007520f3db40b2e},{0x0006612165afc386,0x0001171aa36203ff,0x0002642ea820a8aa,0x0001f3bb7b313f10,0x0005e01b3a7429e4},{0x00050be3d39357a1,0x0003ab33d294a7b6,0x0004c479ba59edb3,0x0004c30d184d326f,0x00071092c9ccef3c}},
|
||||
{{0x0000523f0364918c,0x000687f56d638a7b,0x00020796928ad013,0x0005d38405a54f33,0x0000ea15b03d0257},{0x0003d8ac74051dcf,0x00010ab6f543d0ad,0x0005d0f3ac0fda90,0x0005ef1d2573e5e4,0x0004173a5bb7137a},{0x00056e31f0f9218a,0x0005635f88e102f8,0x0002cbc5d969a5b8,0x000533fbc98b347a,0x0005fc565614a4e3}},
|
||||
{{0x0006570dc46d7ae5,0x00018a9f1b91e26d,0x000436b6183f42ab,0x000550acaa4f8198,0x00062711c414c454},{0x0002e1e67790988e,0x0001e38b9ae44912,0x000648fbb4075654,0x00028df1d840cd72,0x0003214c7409d466},{0x0001827406651770,0x0004d144f286c265,0x00017488f0ee9281,0x00019e6cdb5c760c,0x0005bea94073ecb8}},
|
||||
{{0x0005bf0912c89be4,0x00062fadcaf38c83,0x00025ec196b3ce2c,0x00077655ff4f017b,0x0003aacd5c148f61},{0x0000ce63f343d2f8,0x0001e0a87d1e368e,0x000045edbc019eea,0x0006979aed28d0d1,0x0004ad0785944f1b},{0x00063b34c3318301,0x0000e0e62d04d0b1,0x000676a233726701,0x00029e9a042d9769,0x0003aff0cb1d9028}},
|
||||
{{0x0005c7eb3a20405e,0x0005fdb5aad930f8,0x0004a757e63b8c47,0x00028e9492972456,0x000110e7e86f4cd2},{0x0006430bf4c53505,0x000264c3e4507244,0x00074c9f19a39270,0x00073f84f799bc47,0x0002ccf9f732bd99},{0x0000d89ed603f5e4,0x00051e1604018af8,0x0000b8eedc4a2218,0x00051ba98b9384d0,0x00005c557e0b9693}},
|
||||
{{0x0001ce311fc97e6f,0x0006023f3fb5db1f,0x0007b49775e8fc98,0x0003ad70adbf5045,0x0006e154c178fe98},{0x0006bbb089c20eb0,0x0006df41fb0b9eee,0x00051087ed87e16f,0x000102db5c9fa731,0x000289fef0841861},{0x00016336fed69abf,0x0004f066b929f9ec,0x0004e9ff9e6c5b93,0x00018c89bc4bb2ba,0x0006afbf642a95ca}},
|
||||
{{0x0000de0c62f5d2c1,0x00049601cf734fb5,0x0006b5c38263f0f6,0x0004623ef5b56d06,0x0000db4b851b9503},{0x00055070f913a8cc,0x000765619eac2bbc,0x0003ab5225f47459,0x00076ced14ab5b48,0x00012c093cedb801},{0x00047f9308b8190f,0x000414235c621f82,0x00031f5ff41a5a76,0x0006736773aab96d,0x00033aa8799c6635}},
|
||||
{{0x0007f51ebd085cf2,0x00012cfa67e3f5e1,0x0001800cf1e3d46a,0x00054337615ff0a8,0x000233c6f29e8e21},{0x0000f588fc156cb1,0x000363414da4f069,0x0007296ad9b68aea,0x0004d3711316ae43,0x000212cd0c1c8d58},{0x0004d5107f18c781,0x00064a4fd3a51a5e,0x0004f4cd0448bb37,0x000671d38543151e,0x0001db7778911914}},
|
||||
{{0x000352397c6bc26f,0x00018a7aa0227bbe,0x0005e68cc1ea5f8b,0x0006fe3e3a7a1d5f,0x00031ad97ad26e2a},{0x00014769dd701ab6,0x00028339f1b4b667,0x0004ab214b8ae37b,0x00025f0aefa0b0fe,0x0007ae2ca8a017d2},{0x000017ed0920b962,0x000187e33b53b6fd,0x00055829907a1463,0x000641f248e0a792,0x0001ed1fc53a6622}}
|
||||
};
|
||||
@@ -1,435 +0,0 @@
|
||||
#if defined(ED25519_GCC_64BIT_32BIT_CHOOSE)
|
||||
|
||||
#define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS
|
||||
|
||||
DONNA_NOINLINE static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
int64_t breg = (int64_t)b;
|
||||
uint64_t sign = (uint64_t)breg >> 63;
|
||||
uint64_t mask = ~(sign - 1);
|
||||
uint64_t u = (breg + mask) ^ mask;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
/* ysubx+xaddy+t2d */
|
||||
"movq %0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
"pxor %%xmm2, %%xmm2 ;\n"
|
||||
"pxor %%xmm3, %%xmm3 ;\n"
|
||||
"pxor %%xmm4, %%xmm4 ;\n"
|
||||
"pxor %%xmm5, %%xmm5 ;\n"
|
||||
|
||||
/* 0 */
|
||||
"movq $0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm6 ;\n"
|
||||
"pxor %%xmm7, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm6, %%xmm2 ;\n"
|
||||
"por %%xmm7, %%xmm3 ;\n"
|
||||
|
||||
/* 1 */
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 0(%1), %%xmm6 ;\n"
|
||||
"movdqa 16(%1), %%xmm7 ;\n"
|
||||
"movdqa 32(%1), %%xmm8 ;\n"
|
||||
"movdqa 48(%1), %%xmm9 ;\n"
|
||||
"movdqa 64(%1), %%xmm10 ;\n"
|
||||
"movdqa 80(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 2 */
|
||||
"movq $2, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 96(%1), %%xmm6 ;\n"
|
||||
"movdqa 112(%1), %%xmm7 ;\n"
|
||||
"movdqa 128(%1), %%xmm8 ;\n"
|
||||
"movdqa 144(%1), %%xmm9 ;\n"
|
||||
"movdqa 160(%1), %%xmm10 ;\n"
|
||||
"movdqa 176(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 3 */
|
||||
"movq $3, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 192(%1), %%xmm6 ;\n"
|
||||
"movdqa 208(%1), %%xmm7 ;\n"
|
||||
"movdqa 224(%1), %%xmm8 ;\n"
|
||||
"movdqa 240(%1), %%xmm9 ;\n"
|
||||
"movdqa 256(%1), %%xmm10 ;\n"
|
||||
"movdqa 272(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 4 */
|
||||
"movq $4, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 288(%1), %%xmm6 ;\n"
|
||||
"movdqa 304(%1), %%xmm7 ;\n"
|
||||
"movdqa 320(%1), %%xmm8 ;\n"
|
||||
"movdqa 336(%1), %%xmm9 ;\n"
|
||||
"movdqa 352(%1), %%xmm10 ;\n"
|
||||
"movdqa 368(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 5 */
|
||||
"movq $5, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 384(%1), %%xmm6 ;\n"
|
||||
"movdqa 400(%1), %%xmm7 ;\n"
|
||||
"movdqa 416(%1), %%xmm8 ;\n"
|
||||
"movdqa 432(%1), %%xmm9 ;\n"
|
||||
"movdqa 448(%1), %%xmm10 ;\n"
|
||||
"movdqa 464(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 6 */
|
||||
"movq $6, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 480(%1), %%xmm6 ;\n"
|
||||
"movdqa 496(%1), %%xmm7 ;\n"
|
||||
"movdqa 512(%1), %%xmm8 ;\n"
|
||||
"movdqa 528(%1), %%xmm9 ;\n"
|
||||
"movdqa 544(%1), %%xmm10 ;\n"
|
||||
"movdqa 560(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 7 */
|
||||
"movq $7, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 576(%1), %%xmm6 ;\n"
|
||||
"movdqa 592(%1), %%xmm7 ;\n"
|
||||
"movdqa 608(%1), %%xmm8 ;\n"
|
||||
"movdqa 624(%1), %%xmm9 ;\n"
|
||||
"movdqa 640(%1), %%xmm10 ;\n"
|
||||
"movdqa 656(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 8 */
|
||||
"movq $8, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 672(%1), %%xmm6 ;\n"
|
||||
"movdqa 688(%1), %%xmm7 ;\n"
|
||||
"movdqa 704(%1), %%xmm8 ;\n"
|
||||
"movdqa 720(%1), %%xmm9 ;\n"
|
||||
"movdqa 736(%1), %%xmm10 ;\n"
|
||||
"movdqa 752(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* conditionally swap ysubx and xaddy */
|
||||
"movq %3, %%rax ;\n"
|
||||
"xorq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pxor %%xmm15, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa %%xmm2, %%xmm6 ;\n"
|
||||
"movdqa %%xmm3, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pxor %%xmm6, %%xmm0 ;\n"
|
||||
"pxor %%xmm7, %%xmm1 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
|
||||
/* store ysubx */
|
||||
"xorq %%rax, %%rax ;\n"
|
||||
"movd %%xmm0, %%rcx ;\n"
|
||||
"movd %%xmm0, %%r8 ;\n"
|
||||
"movd %%xmm1, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm0, %%xmm0 ;\n"
|
||||
"pshufd $0xee, %%xmm1, %%xmm1 ;\n"
|
||||
"movd %%xmm0, %%rdx ;\n"
|
||||
"movd %%xmm1, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movl %%ecx, 0(%2) ;\n"
|
||||
"movl %%r9d, 4(%2) ;\n"
|
||||
"movl %%r8d, 8(%2) ;\n"
|
||||
"movl %%r10d, 12(%2) ;\n"
|
||||
"movl %%edx, 16(%2) ;\n"
|
||||
"movl %%r11d, 20(%2) ;\n"
|
||||
"movl %%esi, 24(%2) ;\n"
|
||||
"movl %%r12d, 28(%2) ;\n"
|
||||
"movl %%edi, 32(%2) ;\n"
|
||||
"movl %%r13d, 36(%2) ;\n"
|
||||
|
||||
/* store xaddy */
|
||||
"movd %%xmm2, %%rcx ;\n"
|
||||
"movd %%xmm2, %%r8 ;\n"
|
||||
"movd %%xmm3, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm2, %%xmm2 ;\n"
|
||||
"pshufd $0xee, %%xmm3, %%xmm3 ;\n"
|
||||
"movd %%xmm2, %%rdx ;\n"
|
||||
"movd %%xmm3, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movl %%ecx, 40(%2) ;\n"
|
||||
"movl %%r9d, 44(%2) ;\n"
|
||||
"movl %%r8d, 48(%2) ;\n"
|
||||
"movl %%r10d, 52(%2) ;\n"
|
||||
"movl %%edx, 56(%2) ;\n"
|
||||
"movl %%r11d, 60(%2) ;\n"
|
||||
"movl %%esi, 64(%2) ;\n"
|
||||
"movl %%r12d, 68(%2) ;\n"
|
||||
"movl %%edi, 72(%2) ;\n"
|
||||
"movl %%r13d, 76(%2) ;\n"
|
||||
|
||||
/* extract t2d */
|
||||
"xorq %%rax, %%rax ;\n"
|
||||
"movd %%xmm4, %%rcx ;\n"
|
||||
"movd %%xmm4, %%r8 ;\n"
|
||||
"movd %%xmm5, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm4, %%xmm4 ;\n"
|
||||
"pshufd $0xee, %%xmm5, %%xmm5 ;\n"
|
||||
"movd %%xmm4, %%rdx ;\n"
|
||||
"movd %%xmm5, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"movq %%rcx, %%r9 ;\n"
|
||||
"movq %%r8, %%r10 ;\n"
|
||||
"movq %%rdx, %%r11 ;\n"
|
||||
"movq %%rsi, %%r12 ;\n"
|
||||
"movq %%rdi, %%r13 ;\n"
|
||||
"shrq $26, %%r9 ;\n"
|
||||
"shrq $26, %%r10 ;\n"
|
||||
"shrq $26, %%r11 ;\n"
|
||||
"shrq $26, %%r12 ;\n"
|
||||
"shrq $26, %%r13 ;\n"
|
||||
"andl $0x3ffffff, %%ecx ;\n"
|
||||
"andl $0x1ffffff, %%r9d ;\n"
|
||||
"andl $0x3ffffff, %%r8d ;\n"
|
||||
"andl $0x1ffffff, %%r10d ;\n"
|
||||
"andl $0x3ffffff, %%edx ;\n"
|
||||
"andl $0x1ffffff, %%r11d ;\n"
|
||||
"andl $0x3ffffff, %%esi ;\n"
|
||||
"andl $0x1ffffff, %%r12d ;\n"
|
||||
"andl $0x3ffffff, %%edi ;\n"
|
||||
"andl $0x1ffffff, %%r13d ;\n"
|
||||
"movd %%ecx, %%xmm0 ;\n"
|
||||
"movd %%r9d, %%xmm4 ;\n"
|
||||
"movd %%r8d, %%xmm8 ;\n"
|
||||
"movd %%r10d, %%xmm3 ;\n"
|
||||
"movd %%edx, %%xmm1 ;\n"
|
||||
"movd %%r11d, %%xmm5 ;\n"
|
||||
"movd %%esi, %%xmm6 ;\n"
|
||||
"movd %%r12d, %%xmm7 ;\n"
|
||||
"movd %%edi, %%xmm2 ;\n"
|
||||
"movd %%r13d, %%xmm9 ;\n"
|
||||
"punpckldq %%xmm4, %%xmm0 ;\n"
|
||||
"punpckldq %%xmm3, %%xmm8 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm1 ;\n"
|
||||
"punpckldq %%xmm7, %%xmm6 ;\n"
|
||||
"punpckldq %%xmm9, %%xmm2 ;\n"
|
||||
"punpcklqdq %%xmm8, %%xmm0 ;\n"
|
||||
"punpcklqdq %%xmm6, %%xmm1 ;\n"
|
||||
|
||||
/* set up 2p in to 3/4 */
|
||||
"movl $0x7ffffda, %%ecx ;\n"
|
||||
"movl $0x3fffffe, %%edx ;\n"
|
||||
"movl $0x7fffffe, %%eax ;\n"
|
||||
"movd %%ecx, %%xmm3 ;\n"
|
||||
"movd %%edx, %%xmm5 ;\n"
|
||||
"movd %%eax, %%xmm4 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm3 ;\n"
|
||||
"punpckldq %%xmm5, %%xmm4 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm3 ;\n"
|
||||
"movdqa %%xmm4, %%xmm5 ;\n"
|
||||
"punpcklqdq %%xmm4, %%xmm4 ;\n"
|
||||
|
||||
/* subtract and conditionally move */
|
||||
"movl %3, %%ecx ;\n"
|
||||
"sub $1, %%ecx ;\n"
|
||||
"movd %%ecx, %%xmm6 ;\n"
|
||||
"pshufd $0x00, %%xmm6, %%xmm6 ;\n"
|
||||
"movdqa %%xmm6, %%xmm7 ;\n"
|
||||
"psubd %%xmm0, %%xmm3 ;\n"
|
||||
"psubd %%xmm1, %%xmm4 ;\n"
|
||||
"psubd %%xmm2, %%xmm5 ;\n"
|
||||
"pand %%xmm6, %%xmm0 ;\n"
|
||||
"pand %%xmm6, %%xmm1 ;\n"
|
||||
"pand %%xmm6, %%xmm2 ;\n"
|
||||
"pandn %%xmm3, %%xmm6 ;\n"
|
||||
"movdqa %%xmm7, %%xmm3 ;\n"
|
||||
"pandn %%xmm4, %%xmm7 ;\n"
|
||||
"pandn %%xmm5, %%xmm3 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm3, %%xmm2 ;\n"
|
||||
|
||||
/* store t2d */
|
||||
"movdqa %%xmm0, 80(%2) ;\n"
|
||||
"movdqa %%xmm1, 96(%2) ;\n"
|
||||
"movd %%xmm2, %%rax ;\n"
|
||||
"movq %%rax, 112(%2) ;\n"
|
||||
:
|
||||
: "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */
|
||||
:
|
||||
"%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13",
|
||||
"%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14",
|
||||
"cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* defined(ED25519_GCC_64BIT_32BIT_CHOOSE) */
|
||||
|
||||
357
external/ed25519-donna/ed25519-donna-64bit-x86.h
vendored
357
external/ed25519-donna/ed25519-donna-64bit-x86.h
vendored
@@ -1,357 +0,0 @@
|
||||
#if defined(ED25519_GCC_64BIT_X86_CHOOSE)
|
||||
|
||||
#define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS
|
||||
|
||||
#if defined(__clang__) || defined (__GNUC__)
|
||||
# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
|
||||
#else
|
||||
# define ATTRIBUTE_NO_SANITIZE_ADDRESS
|
||||
#endif
|
||||
|
||||
ATTRIBUTE_NO_SANITIZE_ADDRESS DONNA_NOINLINE static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
int64_t breg = (int64_t)b;
|
||||
uint64_t sign = (uint64_t)breg >> 63;
|
||||
uint64_t mask = ~(sign - 1);
|
||||
uint64_t u = (breg + mask) ^ mask;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
/* ysubx+xaddy+t2d */
|
||||
"movq %0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm0 ;\n"
|
||||
"pxor %%xmm1, %%xmm1 ;\n"
|
||||
"pxor %%xmm2, %%xmm2 ;\n"
|
||||
"pxor %%xmm3, %%xmm3 ;\n"
|
||||
"pxor %%xmm4, %%xmm4 ;\n"
|
||||
"pxor %%xmm5, %%xmm5 ;\n"
|
||||
|
||||
/* 0 */
|
||||
"movq $0, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm6 ;\n"
|
||||
"pxor %%xmm7, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm6, %%xmm2 ;\n"
|
||||
"por %%xmm7, %%xmm3 ;\n"
|
||||
|
||||
/* 1 */
|
||||
"movq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 0(%1), %%xmm6 ;\n"
|
||||
"movdqa 16(%1), %%xmm7 ;\n"
|
||||
"movdqa 32(%1), %%xmm8 ;\n"
|
||||
"movdqa 48(%1), %%xmm9 ;\n"
|
||||
"movdqa 64(%1), %%xmm10 ;\n"
|
||||
"movdqa 80(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 2 */
|
||||
"movq $2, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 96(%1), %%xmm6 ;\n"
|
||||
"movdqa 112(%1), %%xmm7 ;\n"
|
||||
"movdqa 128(%1), %%xmm8 ;\n"
|
||||
"movdqa 144(%1), %%xmm9 ;\n"
|
||||
"movdqa 160(%1), %%xmm10 ;\n"
|
||||
"movdqa 176(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 3 */
|
||||
"movq $3, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 192(%1), %%xmm6 ;\n"
|
||||
"movdqa 208(%1), %%xmm7 ;\n"
|
||||
"movdqa 224(%1), %%xmm8 ;\n"
|
||||
"movdqa 240(%1), %%xmm9 ;\n"
|
||||
"movdqa 256(%1), %%xmm10 ;\n"
|
||||
"movdqa 272(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 4 */
|
||||
"movq $4, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 288(%1), %%xmm6 ;\n"
|
||||
"movdqa 304(%1), %%xmm7 ;\n"
|
||||
"movdqa 320(%1), %%xmm8 ;\n"
|
||||
"movdqa 336(%1), %%xmm9 ;\n"
|
||||
"movdqa 352(%1), %%xmm10 ;\n"
|
||||
"movdqa 368(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 5 */
|
||||
"movq $5, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 384(%1), %%xmm6 ;\n"
|
||||
"movdqa 400(%1), %%xmm7 ;\n"
|
||||
"movdqa 416(%1), %%xmm8 ;\n"
|
||||
"movdqa 432(%1), %%xmm9 ;\n"
|
||||
"movdqa 448(%1), %%xmm10 ;\n"
|
||||
"movdqa 464(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 6 */
|
||||
"movq $6, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 480(%1), %%xmm6 ;\n"
|
||||
"movdqa 496(%1), %%xmm7 ;\n"
|
||||
"movdqa 512(%1), %%xmm8 ;\n"
|
||||
"movdqa 528(%1), %%xmm9 ;\n"
|
||||
"movdqa 544(%1), %%xmm10 ;\n"
|
||||
"movdqa 560(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 7 */
|
||||
"movq $7, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 576(%1), %%xmm6 ;\n"
|
||||
"movdqa 592(%1), %%xmm7 ;\n"
|
||||
"movdqa 608(%1), %%xmm8 ;\n"
|
||||
"movdqa 624(%1), %%xmm9 ;\n"
|
||||
"movdqa 640(%1), %%xmm10 ;\n"
|
||||
"movdqa 656(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* 8 */
|
||||
"movq $8, %%rax ;\n"
|
||||
"movd %%rax, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm15, %%xmm15 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa 672(%1), %%xmm6 ;\n"
|
||||
"movdqa 688(%1), %%xmm7 ;\n"
|
||||
"movdqa 704(%1), %%xmm8 ;\n"
|
||||
"movdqa 720(%1), %%xmm9 ;\n"
|
||||
"movdqa 736(%1), %%xmm10 ;\n"
|
||||
"movdqa 752(%1), %%xmm11 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm8 ;\n"
|
||||
"pand %%xmm15, %%xmm9 ;\n"
|
||||
"pand %%xmm15, %%xmm10 ;\n"
|
||||
"pand %%xmm15, %%xmm11 ;\n"
|
||||
"por %%xmm6, %%xmm0 ;\n"
|
||||
"por %%xmm7, %%xmm1 ;\n"
|
||||
"por %%xmm8, %%xmm2 ;\n"
|
||||
"por %%xmm9, %%xmm3 ;\n"
|
||||
"por %%xmm10, %%xmm4 ;\n"
|
||||
"por %%xmm11, %%xmm5 ;\n"
|
||||
|
||||
/* conditionally swap ysubx and xaddy */
|
||||
"movq %3, %%rax ;\n"
|
||||
"xorq $1, %%rax ;\n"
|
||||
"movd %%rax, %%xmm14 ;\n"
|
||||
"pxor %%xmm15, %%xmm15 ;\n"
|
||||
"pshufd $0x00, %%xmm14, %%xmm14 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
"pcmpeqd %%xmm14, %%xmm15 ;\n"
|
||||
"movdqa %%xmm2, %%xmm6 ;\n"
|
||||
"movdqa %%xmm3, %%xmm7 ;\n"
|
||||
"pand %%xmm15, %%xmm6 ;\n"
|
||||
"pand %%xmm15, %%xmm7 ;\n"
|
||||
"pxor %%xmm6, %%xmm0 ;\n"
|
||||
"pxor %%xmm7, %%xmm1 ;\n"
|
||||
"pxor %%xmm0, %%xmm2 ;\n"
|
||||
"pxor %%xmm1, %%xmm3 ;\n"
|
||||
|
||||
/* store ysubx */
|
||||
"movq $0x7ffffffffffff, %%rax ;\n"
|
||||
"movd %%xmm0, %%rcx ;\n"
|
||||
"movd %%xmm0, %%r8 ;\n"
|
||||
"movd %%xmm1, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm0, %%xmm0 ;\n"
|
||||
"pshufd $0xee, %%xmm1, %%xmm1 ;\n"
|
||||
"movd %%xmm0, %%rdx ;\n"
|
||||
"movd %%xmm1, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"andq %%rax, %%rcx ;\n"
|
||||
"andq %%rax, %%r8 ;\n"
|
||||
"andq %%rax, %%rdx ;\n"
|
||||
"andq %%rax, %%rsi ;\n"
|
||||
"andq %%rax, %%rdi ;\n"
|
||||
"movq %%rcx, 0(%2) ;\n"
|
||||
"movq %%r8, 8(%2) ;\n"
|
||||
"movq %%rdx, 16(%2) ;\n"
|
||||
"movq %%rsi, 24(%2) ;\n"
|
||||
"movq %%rdi, 32(%2) ;\n"
|
||||
|
||||
/* store xaddy */
|
||||
"movq $0x7ffffffffffff, %%rax ;\n"
|
||||
"movd %%xmm2, %%rcx ;\n"
|
||||
"movd %%xmm2, %%r8 ;\n"
|
||||
"movd %%xmm3, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm2, %%xmm2 ;\n"
|
||||
"pshufd $0xee, %%xmm3, %%xmm3 ;\n"
|
||||
"movd %%xmm2, %%rdx ;\n"
|
||||
"movd %%xmm3, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"andq %%rax, %%rcx ;\n"
|
||||
"andq %%rax, %%r8 ;\n"
|
||||
"andq %%rax, %%rdx ;\n"
|
||||
"andq %%rax, %%rsi ;\n"
|
||||
"andq %%rax, %%rdi ;\n"
|
||||
"movq %%rcx, 40(%2) ;\n"
|
||||
"movq %%r8, 48(%2) ;\n"
|
||||
"movq %%rdx, 56(%2) ;\n"
|
||||
"movq %%rsi, 64(%2) ;\n"
|
||||
"movq %%rdi, 72(%2) ;\n"
|
||||
|
||||
/* extract t2d */
|
||||
"movq $0x7ffffffffffff, %%rax ;\n"
|
||||
"movd %%xmm4, %%rcx ;\n"
|
||||
"movd %%xmm4, %%r8 ;\n"
|
||||
"movd %%xmm5, %%rsi ;\n"
|
||||
"pshufd $0xee, %%xmm4, %%xmm4 ;\n"
|
||||
"pshufd $0xee, %%xmm5, %%xmm5 ;\n"
|
||||
"movd %%xmm4, %%rdx ;\n"
|
||||
"movd %%xmm5, %%rdi ;\n"
|
||||
"shrdq $51, %%rdx, %%r8 ;\n"
|
||||
"shrdq $38, %%rsi, %%rdx ;\n"
|
||||
"shrdq $25, %%rdi, %%rsi ;\n"
|
||||
"shrq $12, %%rdi ;\n"
|
||||
"andq %%rax, %%rcx ;\n"
|
||||
"andq %%rax, %%r8 ;\n"
|
||||
"andq %%rax, %%rdx ;\n"
|
||||
"andq %%rax, %%rsi ;\n"
|
||||
"andq %%rax, %%rdi ;\n"
|
||||
|
||||
/* conditionally negate t2d */
|
||||
"movq %3, %%rax ;\n"
|
||||
"movq $0xfffffffffffda, %%r9 ;\n"
|
||||
"movq $0xffffffffffffe, %%r10 ;\n"
|
||||
"movq %%r10, %%r11 ;\n"
|
||||
"movq %%r10, %%r12 ;\n"
|
||||
"movq %%r10, %%r13 ;\n"
|
||||
"subq %%rcx, %%r9 ;\n"
|
||||
"subq %%r8, %%r10 ;\n"
|
||||
"subq %%rdx, %%r11 ;\n"
|
||||
"subq %%rsi, %%r12 ;\n"
|
||||
"subq %%rdi, %%r13 ;\n"
|
||||
"cmpq $1, %%rax ;\n"
|
||||
"cmove %%r9, %%rcx ;\n"
|
||||
"cmove %%r10, %%r8 ;\n"
|
||||
"cmove %%r11, %%rdx ;\n"
|
||||
"cmove %%r12, %%rsi ;\n"
|
||||
"cmove %%r13, %%rdi ;\n"
|
||||
|
||||
/* store t2d */
|
||||
"movq %%rcx, 80(%2) ;\n"
|
||||
"movq %%r8, 88(%2) ;\n"
|
||||
"movq %%rdx, 96(%2) ;\n"
|
||||
"movq %%rsi, 104(%2) ;\n"
|
||||
"movq %%rdi, 112(%2) ;\n"
|
||||
:
|
||||
: "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */
|
||||
:
|
||||
"%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13",
|
||||
"%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14",
|
||||
"cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* defined(ED25519_GCC_64BIT_X86_CHOOSE) */
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
/* multiples of the base point in packed {ysubx, xaddy, t2d} form */
|
||||
static const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = {
|
||||
{0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f},
|
||||
{0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49},
|
||||
{0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54},
|
||||
{0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44},
|
||||
{0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68},
|
||||
{0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78},
|
||||
{0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23},
|
||||
{0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58},
|
||||
{0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10},
|
||||
{0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56},
|
||||
{0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14},
|
||||
{0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37},
|
||||
{0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02},
|
||||
{0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12},
|
||||
{0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f},
|
||||
{0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41},
|
||||
{0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e},
|
||||
{0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14},
|
||||
{0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41},
|
||||
{0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59},
|
||||
{0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49},
|
||||
{0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20},
|
||||
{0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b},
|
||||
{0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74},
|
||||
{0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69},
|
||||
{0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b},
|
||||
{0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e},
|
||||
{0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39},
|
||||
{0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33},
|
||||
{0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61},
|
||||
{0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45},
|
||||
{0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d},
|
||||
{0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c},
|
||||
{0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21},
|
||||
{0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a},
|
||||
{0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39},
|
||||
{0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22},
|
||||
{0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50},
|
||||
{0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d},
|
||||
{0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45},
|
||||
{0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d},
|
||||
{0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c},
|
||||
{0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27},
|
||||
{0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f},
|
||||
{0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f},
|
||||
{0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22},
|
||||
{0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c},
|
||||
{0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19},
|
||||
{0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71},
|
||||
{0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c},
|
||||
{0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a},
|
||||
{0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02},
|
||||
{0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31},
|
||||
{0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48},
|
||||
{0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c},
|
||||
{0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f},
|
||||
{0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60},
|
||||
{0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63},
|
||||
{0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70},
|
||||
{0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41},
|
||||
{0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24},
|
||||
{0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16},
|
||||
{0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78},
|
||||
{0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13},
|
||||
{0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a},
|
||||
{0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b},
|
||||
{0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d},
|
||||
{0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74},
|
||||
{0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58},
|
||||
{0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12},
|
||||
{0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d},
|
||||
{0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b},
|
||||
{0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c},
|
||||
{0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04},
|
||||
{0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76},
|
||||
{0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11},
|
||||
{0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f},
|
||||
{0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55},
|
||||
{0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57},
|
||||
{0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21},
|
||||
{0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a},
|
||||
{0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19},
|
||||
{0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60},
|
||||
{0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36},
|
||||
{0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07},
|
||||
{0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57},
|
||||
{0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05},
|
||||
{0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f},
|
||||
{0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72},
|
||||
{0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00},
|
||||
{0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c},
|
||||
{0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06},
|
||||
{0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15},
|
||||
{0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07},
|
||||
{0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51},
|
||||
{0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77},
|
||||
{0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e},
|
||||
{0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09},
|
||||
{0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56},
|
||||
{0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43},
|
||||
{0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27},
|
||||
{0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b},
|
||||
{0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46},
|
||||
{0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69},
|
||||
{0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14},
|
||||
{0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55},
|
||||
{0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13},
|
||||
{0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d},
|
||||
{0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31},
|
||||
{0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05},
|
||||
{0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f},
|
||||
{0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a},
|
||||
{0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10},
|
||||
{0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25},
|
||||
{0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08},
|
||||
{0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a},
|
||||
{0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f},
|
||||
{0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38},
|
||||
{0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65},
|
||||
{0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c},
|
||||
{0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e},
|
||||
{0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35},
|
||||
{0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47},
|
||||
{0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47},
|
||||
{0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74},
|
||||
{0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a},
|
||||
{0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56},
|
||||
{0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d},
|
||||
{0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44},
|
||||
{0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58},
|
||||
{0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70},
|
||||
{0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e},
|
||||
{0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41},
|
||||
{0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11},
|
||||
{0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f},
|
||||
{0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10},
|
||||
{0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72},
|
||||
{0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00},
|
||||
{0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05},
|
||||
{0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00},
|
||||
{0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b},
|
||||
{0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05},
|
||||
{0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f},
|
||||
{0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f},
|
||||
{0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40},
|
||||
{0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b},
|
||||
{0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02},
|
||||
{0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c},
|
||||
{0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f},
|
||||
{0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29},
|
||||
{0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71},
|
||||
{0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a},
|
||||
{0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06},
|
||||
{0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30},
|
||||
{0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b},
|
||||
{0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24},
|
||||
{0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49},
|
||||
{0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53},
|
||||
{0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02},
|
||||
{0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e},
|
||||
{0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d},
|
||||
{0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f},
|
||||
{0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07},
|
||||
{0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f},
|
||||
{0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b},
|
||||
{0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f},
|
||||
{0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12},
|
||||
{0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30},
|
||||
{0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45},
|
||||
{0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a},
|
||||
{0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13},
|
||||
{0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f},
|
||||
{0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a},
|
||||
{0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12},
|
||||
{0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b},
|
||||
{0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10},
|
||||
{0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b},
|
||||
{0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e},
|
||||
{0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f},
|
||||
{0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00},
|
||||
{0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33},
|
||||
{0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63},
|
||||
{0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b},
|
||||
{0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16},
|
||||
{0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57},
|
||||
{0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e},
|
||||
{0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73},
|
||||
{0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76},
|
||||
{0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e},
|
||||
{0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16},
|
||||
{0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45},
|
||||
{0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67},
|
||||
{0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a},
|
||||
{0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a},
|
||||
{0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e},
|
||||
{0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62},
|
||||
{0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e},
|
||||
{0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e},
|
||||
{0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78},
|
||||
{0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46},
|
||||
{0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a},
|
||||
{0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26},
|
||||
{0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b},
|
||||
{0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d},
|
||||
{0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45},
|
||||
{0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26},
|
||||
{0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62},
|
||||
{0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d},
|
||||
{0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61},
|
||||
{0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79},
|
||||
{0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39},
|
||||
{0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63},
|
||||
{0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34},
|
||||
{0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56},
|
||||
{0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e},
|
||||
{0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26},
|
||||
{0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f},
|
||||
{0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f},
|
||||
{0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b},
|
||||
{0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39},
|
||||
{0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51},
|
||||
{0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f},
|
||||
{0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f},
|
||||
{0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13},
|
||||
{0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c},
|
||||
{0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60},
|
||||
{0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15},
|
||||
{0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32},
|
||||
{0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b},
|
||||
{0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02},
|
||||
{0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c},
|
||||
{0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05},
|
||||
{0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67},
|
||||
{0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c},
|
||||
{0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37},
|
||||
{0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63},
|
||||
{0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68},
|
||||
{0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c},
|
||||
{0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c},
|
||||
{0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26},
|
||||
{0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08},
|
||||
{0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19},
|
||||
{0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41},
|
||||
{0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b},
|
||||
{0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08},
|
||||
{0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48},
|
||||
{0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54},
|
||||
{0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c},
|
||||
{0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f},
|
||||
{0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25},
|
||||
{0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55},
|
||||
{0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a},
|
||||
{0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59},
|
||||
{0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70},
|
||||
{0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27},
|
||||
{0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f}
|
||||
};
|
||||
275
external/ed25519-donna/ed25519-donna-batchverify.h
vendored
275
external/ed25519-donna/ed25519-donna-batchverify.h
vendored
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
Ed25519 batch verification
|
||||
*/
|
||||
|
||||
#define max_batch_size 64
|
||||
#define heap_batch_size ((max_batch_size * 2) + 1)
|
||||
|
||||
/* which limb is the 128th bit in? */
|
||||
static const size_t limb128bits = (128 + bignum256modm_bits_per_limb - 1) / bignum256modm_bits_per_limb;
|
||||
|
||||
typedef size_t heap_index_t;
|
||||
|
||||
typedef struct batch_heap_t {
|
||||
unsigned char r[heap_batch_size][16]; /* 128 bit random values */
|
||||
ge25519 points[heap_batch_size];
|
||||
bignum256modm scalars[heap_batch_size];
|
||||
heap_index_t heap[heap_batch_size];
|
||||
size_t size;
|
||||
} batch_heap;
|
||||
|
||||
/* swap two values in the heap */
|
||||
static void
|
||||
heap_swap(heap_index_t *heap, size_t a, size_t b) {
|
||||
heap_index_t temp;
|
||||
temp = heap[a];
|
||||
heap[a] = heap[b];
|
||||
heap[b] = temp;
|
||||
}
|
||||
|
||||
/* add the scalar at the end of the list to the heap */
|
||||
static void
|
||||
heap_insert_next(batch_heap *heap) {
|
||||
size_t node = heap->size, parent;
|
||||
heap_index_t *pheap = heap->heap;
|
||||
bignum256modm *scalars = heap->scalars;
|
||||
|
||||
/* insert at the bottom */
|
||||
pheap[node] = (heap_index_t)node;
|
||||
|
||||
/* sift node up to its sorted spot */
|
||||
parent = (node - 1) / 2;
|
||||
while (node && lt256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], bignum256modm_limb_size - 1)) {
|
||||
heap_swap(pheap, parent, node);
|
||||
node = parent;
|
||||
parent = (node - 1) / 2;
|
||||
}
|
||||
heap->size++;
|
||||
}
|
||||
|
||||
/* update the heap when the root element is updated */
|
||||
static void
|
||||
heap_updated_root(batch_heap *heap, size_t limbsize) {
|
||||
size_t node, parent, childr, childl;
|
||||
heap_index_t *pheap = heap->heap;
|
||||
bignum256modm *scalars = heap->scalars;
|
||||
|
||||
/* sift root to the bottom */
|
||||
parent = 0;
|
||||
node = 1;
|
||||
childl = 1;
|
||||
childr = 2;
|
||||
while ((childr < heap->size)) {
|
||||
node = lt256_modm_batch(scalars[pheap[childl]], scalars[pheap[childr]], limbsize) ? childr : childl;
|
||||
heap_swap(pheap, parent, node);
|
||||
parent = node;
|
||||
childl = (parent * 2) + 1;
|
||||
childr = childl + 1;
|
||||
}
|
||||
|
||||
/* sift root back up to its sorted spot */
|
||||
parent = (node - 1) / 2;
|
||||
while (node && lte256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], limbsize)) {
|
||||
heap_swap(pheap, parent, node);
|
||||
node = parent;
|
||||
parent = (node - 1) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* build the heap with count elements, count must be >= 3 */
|
||||
static void
|
||||
heap_build(batch_heap *heap, size_t count) {
|
||||
heap->heap[0] = 0;
|
||||
heap->size = 0;
|
||||
while (heap->size < count)
|
||||
heap_insert_next(heap);
|
||||
}
|
||||
|
||||
/* extend the heap to contain new_count elements */
|
||||
static void
|
||||
heap_extend(batch_heap *heap, size_t new_count) {
|
||||
while (heap->size < new_count)
|
||||
heap_insert_next(heap);
|
||||
}
|
||||
|
||||
/* get the top 2 elements of the heap */
|
||||
static void
|
||||
heap_get_top2(batch_heap *heap, heap_index_t *max1, heap_index_t *max2, size_t limbsize) {
|
||||
heap_index_t h0 = heap->heap[0], h1 = heap->heap[1], h2 = heap->heap[2];
|
||||
if (lt256_modm_batch(heap->scalars[h1], heap->scalars[h2], limbsize))
|
||||
h1 = h2;
|
||||
*max1 = h0;
|
||||
*max2 = h1;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void
|
||||
ge25519_multi_scalarmult_vartime_final(ge25519 *r, ge25519 *point, bignum256modm scalar) {
|
||||
const bignum256modm_element_t topbit = ((bignum256modm_element_t)1 << (bignum256modm_bits_per_limb - 1));
|
||||
size_t limb = limb128bits;
|
||||
bignum256modm_element_t flag;
|
||||
|
||||
if (isone256_modm_batch(scalar)) {
|
||||
/* this will happen most of the time after bos-carter */
|
||||
*r = *point;
|
||||
return;
|
||||
} else if (iszero256_modm_batch(scalar)) {
|
||||
/* this will only happen if all scalars == 0 */
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->y[0] = 1;
|
||||
r->z[0] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
*r = *point;
|
||||
|
||||
/* find the limb where first bit is set */
|
||||
while (!scalar[limb])
|
||||
limb--;
|
||||
|
||||
/* find the first bit */
|
||||
flag = topbit;
|
||||
while ((scalar[limb] & flag) == 0)
|
||||
flag >>= 1;
|
||||
|
||||
/* exponentiate */
|
||||
for (;;) {
|
||||
ge25519_double(r, r);
|
||||
if (scalar[limb] & flag)
|
||||
ge25519_add(r, r, point);
|
||||
|
||||
flag >>= 1;
|
||||
if (!flag) {
|
||||
if (!limb--)
|
||||
break;
|
||||
flag = topbit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* count must be >= 5 */
|
||||
static void
|
||||
ge25519_multi_scalarmult_vartime(ge25519 *r, batch_heap *heap, size_t count) {
|
||||
heap_index_t max1, max2;
|
||||
|
||||
/* start with the full limb size */
|
||||
size_t limbsize = bignum256modm_limb_size - 1;
|
||||
|
||||
/* whether the heap has been extended to include the 128 bit scalars */
|
||||
int extended = 0;
|
||||
|
||||
/* grab an odd number of scalars to build the heap, unknown limb sizes */
|
||||
heap_build(heap, ((count + 1) / 2) | 1);
|
||||
|
||||
for (;;) {
|
||||
heap_get_top2(heap, &max1, &max2, limbsize);
|
||||
|
||||
/* only one scalar remaining, we're done */
|
||||
if (iszero256_modm_batch(heap->scalars[max2]))
|
||||
break;
|
||||
|
||||
/* exhausted another limb? */
|
||||
if (!heap->scalars[max1][limbsize])
|
||||
limbsize -= 1;
|
||||
|
||||
/* can we extend to the 128 bit scalars? */
|
||||
if (!extended && isatmost128bits256_modm_batch(heap->scalars[max1])) {
|
||||
heap_extend(heap, count);
|
||||
heap_get_top2(heap, &max1, &max2, limbsize);
|
||||
extended = 1;
|
||||
}
|
||||
|
||||
sub256_modm_batch(heap->scalars[max1], heap->scalars[max1], heap->scalars[max2], limbsize);
|
||||
ge25519_add(&heap->points[max2], &heap->points[max2], &heap->points[max1]);
|
||||
heap_updated_root(heap, limbsize);
|
||||
}
|
||||
|
||||
ge25519_multi_scalarmult_vartime_final(r, &heap->points[max1], heap->scalars[max1]);
|
||||
}
|
||||
|
||||
/* not actually used for anything other than testing */
|
||||
unsigned char batch_point_buffer[3][32];
|
||||
|
||||
static int
|
||||
ge25519_is_neutral_vartime(const ge25519 *p) {
|
||||
static const unsigned char zero[32] = {0};
|
||||
unsigned char point_buffer[3][32];
|
||||
curve25519_contract(point_buffer[0], p->x);
|
||||
curve25519_contract(point_buffer[1], p->y);
|
||||
curve25519_contract(point_buffer[2], p->z);
|
||||
memcpy(batch_point_buffer[1], point_buffer[1], 32);
|
||||
return (memcmp(point_buffer[0], zero, 32) == 0) && (memcmp(point_buffer[1], point_buffer[2], 32) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
ED25519_FN(ed25519_sign_open_batch) (const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid) {
|
||||
batch_heap ALIGN(16) batch;
|
||||
ge25519 ALIGN(16) p;
|
||||
bignum256modm *r_scalars;
|
||||
size_t i, batchsize;
|
||||
unsigned char hram[64];
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
valid[i] = 1;
|
||||
|
||||
while (num > 3) {
|
||||
batchsize = (num > max_batch_size) ? max_batch_size : num;
|
||||
|
||||
/* generate r (scalars[batchsize+1]..scalars[2*batchsize] */
|
||||
ED25519_FN(ed25519_randombytes_unsafe) (batch.r, batchsize * 16);
|
||||
r_scalars = &batch.scalars[batchsize + 1];
|
||||
for (i = 0; i < batchsize; i++)
|
||||
expand256_modm(r_scalars[i], batch.r[i], 16);
|
||||
|
||||
/* compute scalars[0] = ((r1s1 + r2s2 + ...)) */
|
||||
for (i = 0; i < batchsize; i++) {
|
||||
expand256_modm(batch.scalars[i], RS[i] + 32, 32);
|
||||
mul256_modm(batch.scalars[i], batch.scalars[i], r_scalars[i]);
|
||||
}
|
||||
for (i = 1; i < batchsize; i++)
|
||||
add256_modm(batch.scalars[0], batch.scalars[0], batch.scalars[i]);
|
||||
|
||||
/* compute scalars[1]..scalars[batchsize] as r[i]*H(R[i],A[i],m[i]) */
|
||||
for (i = 0; i < batchsize; i++) {
|
||||
ed25519_hram(hram, RS[i], pk[i], m[i], mlen[i]);
|
||||
expand256_modm(batch.scalars[i+1], hram, 64);
|
||||
mul256_modm(batch.scalars[i+1], batch.scalars[i+1], r_scalars[i]);
|
||||
}
|
||||
|
||||
/* compute points */
|
||||
batch.points[0] = ge25519_basepoint;
|
||||
for (i = 0; i < batchsize; i++)
|
||||
if (!ge25519_unpack_negative_vartime(&batch.points[i+1], pk[i]))
|
||||
goto fallback;
|
||||
for (i = 0; i < batchsize; i++)
|
||||
if (!ge25519_unpack_negative_vartime(&batch.points[batchsize+i+1], RS[i]))
|
||||
goto fallback;
|
||||
|
||||
ge25519_multi_scalarmult_vartime(&p, &batch, (batchsize * 2) + 1);
|
||||
if (!ge25519_is_neutral_vartime(&p)) {
|
||||
ret |= 2;
|
||||
|
||||
fallback:
|
||||
for (i = 0; i < batchsize; i++) {
|
||||
valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1;
|
||||
ret |= (valid[i] ^ 1);
|
||||
}
|
||||
}
|
||||
|
||||
m += batchsize;
|
||||
mlen += batchsize;
|
||||
pk += batchsize;
|
||||
RS += batchsize;
|
||||
num -= batchsize;
|
||||
valid += batchsize;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1;
|
||||
ret |= (valid[i] ^ 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
364
external/ed25519-donna/ed25519-donna-impl-base.h
vendored
364
external/ed25519-donna/ed25519-donna-impl-base.h
vendored
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
conversions
|
||||
*/
|
||||
|
||||
DONNA_INLINE static void
|
||||
ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) {
|
||||
curve25519_mul(r->x, p->x, p->t);
|
||||
curve25519_mul(r->y, p->y, p->z);
|
||||
curve25519_mul(r->z, p->z, p->t);
|
||||
}
|
||||
|
||||
DONNA_INLINE static void
|
||||
ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) {
|
||||
curve25519_mul(r->x, p->x, p->t);
|
||||
curve25519_mul(r->y, p->y, p->z);
|
||||
curve25519_mul(r->z, p->z, p->t);
|
||||
curve25519_mul(r->t, p->x, p->y);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) {
|
||||
curve25519_sub(p->ysubx, r->y, r->x);
|
||||
curve25519_add(p->xaddy, r->y, r->x);
|
||||
curve25519_copy(p->z, r->z);
|
||||
curve25519_mul(p->t2d, r->t, ge25519_ec2d);
|
||||
}
|
||||
|
||||
/*
|
||||
adding & doubling
|
||||
*/
|
||||
|
||||
static void
|
||||
ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) {
|
||||
bignum25519 a,b,c,d,t,u;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_sub(t, q->y, q->x);
|
||||
curve25519_add(u, q->y, q->x);
|
||||
curve25519_mul(a, a, t);
|
||||
curve25519_mul(b, b, u);
|
||||
curve25519_mul(c, p->t, q->t);
|
||||
curve25519_mul(c, c, ge25519_ec2d);
|
||||
curve25519_mul(d, p->z, q->z);
|
||||
curve25519_add(d, d, d);
|
||||
curve25519_sub(r->x, b, a);
|
||||
curve25519_add(r->y, b, a);
|
||||
curve25519_add_after_basic(r->z, d, c);
|
||||
curve25519_sub_after_basic(r->t, d, c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) {
|
||||
bignum25519 a,b,c;
|
||||
|
||||
curve25519_square(a, p->x);
|
||||
curve25519_square(b, p->y);
|
||||
curve25519_square(c, p->z);
|
||||
curve25519_add_reduce(c, c, c);
|
||||
curve25519_add(r->x, p->x, p->y);
|
||||
curve25519_square(r->x, r->x);
|
||||
curve25519_add(r->y, b, a);
|
||||
curve25519_sub(r->z, b, a);
|
||||
curve25519_sub_after_basic(r->x, r->x, r->y);
|
||||
curve25519_sub_after_basic(r->t, c, r->z);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) {
|
||||
const bignum25519 *qb = (const bignum25519 *)q;
|
||||
bignum25519 *rb = (bignum25519 *)r;
|
||||
bignum25519 a,b,c;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */
|
||||
curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */
|
||||
curve25519_add(r->y, r->x, a);
|
||||
curve25519_sub(r->x, r->x, a);
|
||||
curve25519_mul(c, p->t, q->t2d);
|
||||
curve25519_add_reduce(r->t, p->z, p->z);
|
||||
curve25519_copy(r->z, r->t);
|
||||
curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */
|
||||
curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) {
|
||||
const bignum25519 *qb = (const bignum25519 *)q;
|
||||
bignum25519 *rb = (bignum25519 *)r;
|
||||
bignum25519 a,b,c;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */
|
||||
curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */
|
||||
curve25519_add(r->y, r->x, a);
|
||||
curve25519_sub(r->x, r->x, a);
|
||||
curve25519_mul(c, p->t, q->t2d);
|
||||
curve25519_mul(r->t, p->z, q->z);
|
||||
curve25519_add_reduce(r->t, r->t, r->t);
|
||||
curve25519_copy(r->z, r->t);
|
||||
curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */
|
||||
curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_double_partial(ge25519 *r, const ge25519 *p) {
|
||||
ge25519_p1p1 t;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_partial(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_double(ge25519 *r, const ge25519 *p) {
|
||||
ge25519_p1p1 t;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) {
|
||||
ge25519_p1p1 t;
|
||||
ge25519_add_p1p1(&t, p, q);
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) {
|
||||
bignum25519 a,b,c,e,f,g,h;
|
||||
|
||||
curve25519_sub(a, r->y, r->x);
|
||||
curve25519_add(b, r->y, r->x);
|
||||
curve25519_mul(a, a, q->ysubx);
|
||||
curve25519_mul(e, b, q->xaddy);
|
||||
curve25519_add(h, e, a);
|
||||
curve25519_sub(e, e, a);
|
||||
curve25519_mul(c, r->t, q->t2d);
|
||||
curve25519_add(f, r->z, r->z);
|
||||
curve25519_add_after_basic(g, f, c);
|
||||
curve25519_sub_after_basic(f, f, c);
|
||||
curve25519_mul(r->x, e, f);
|
||||
curve25519_mul(r->y, h, g);
|
||||
curve25519_mul(r->z, g, f);
|
||||
curve25519_mul(r->t, e, h);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) {
|
||||
bignum25519 a,b,c,x,y,z,t;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_mul(a, a, q->ysubx);
|
||||
curve25519_mul(x, b, q->xaddy);
|
||||
curve25519_add(y, x, a);
|
||||
curve25519_sub(x, x, a);
|
||||
curve25519_mul(c, p->t, q->t2d);
|
||||
curve25519_mul(t, p->z, q->z);
|
||||
curve25519_add(t, t, t);
|
||||
curve25519_add_after_basic(z, t, c);
|
||||
curve25519_sub_after_basic(t, t, c);
|
||||
curve25519_mul(r->xaddy, x, t);
|
||||
curve25519_mul(r->ysubx, y, z);
|
||||
curve25519_mul(r->z, z, t);
|
||||
curve25519_mul(r->t2d, x, y);
|
||||
curve25519_copy(y, r->ysubx);
|
||||
curve25519_sub(r->ysubx, r->ysubx, r->xaddy);
|
||||
curve25519_add(r->xaddy, r->xaddy, y);
|
||||
curve25519_mul(r->t2d, r->t2d, ge25519_ec2d);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pack & unpack
|
||||
*/
|
||||
|
||||
static void
|
||||
ge25519_pack(unsigned char r[32], const ge25519 *p) {
|
||||
bignum25519 tx, ty, zi;
|
||||
unsigned char parity[32];
|
||||
curve25519_recip(zi, p->z);
|
||||
curve25519_mul(tx, p->x, zi);
|
||||
curve25519_mul(ty, p->y, zi);
|
||||
curve25519_contract(r, ty);
|
||||
curve25519_contract(parity, tx);
|
||||
r[31] ^= ((parity[0] & 1) << 7);
|
||||
}
|
||||
|
||||
static int
|
||||
ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
|
||||
static const unsigned char zero[32] = {0};
|
||||
static const bignum25519 one = {1};
|
||||
unsigned char parity = p[31] >> 7;
|
||||
unsigned char check[32];
|
||||
bignum25519 t, root, num, den, d3;
|
||||
|
||||
curve25519_expand(r->y, p);
|
||||
curve25519_copy(r->z, one);
|
||||
curve25519_square(num, r->y); /* x = y^2 */
|
||||
curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */
|
||||
curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */
|
||||
curve25519_add(den, den, r->z); /* den = dy^2 + 1 */
|
||||
|
||||
/* Computation of sqrt(num/den) */
|
||||
/* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
|
||||
curve25519_square(t, den);
|
||||
curve25519_mul(d3, t, den);
|
||||
curve25519_square(r->x, d3);
|
||||
curve25519_mul(r->x, r->x, den);
|
||||
curve25519_mul(r->x, r->x, num);
|
||||
curve25519_pow_two252m3(r->x, r->x);
|
||||
|
||||
/* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */
|
||||
curve25519_mul(r->x, r->x, d3);
|
||||
curve25519_mul(r->x, r->x, num);
|
||||
|
||||
/* 3. Check if either of the roots works: */
|
||||
curve25519_square(t, r->x);
|
||||
curve25519_mul(t, t, den);
|
||||
curve25519_sub_reduce(root, t, num);
|
||||
curve25519_contract(check, root);
|
||||
if (!ed25519_verify(check, zero, 32)) {
|
||||
curve25519_add_reduce(t, t, num);
|
||||
curve25519_contract(check, t);
|
||||
if (!ed25519_verify(check, zero, 32))
|
||||
return 0;
|
||||
curve25519_mul(r->x, r->x, ge25519_sqrtneg1);
|
||||
}
|
||||
|
||||
curve25519_contract(check, r->x);
|
||||
if ((check[0] & 1) == parity) {
|
||||
curve25519_copy(t, r->x);
|
||||
curve25519_neg(r->x, t);
|
||||
}
|
||||
curve25519_mul(r->t, r->x, r->y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
scalarmults
|
||||
*/
|
||||
|
||||
#define S1_SWINDOWSIZE 5
|
||||
#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2))
|
||||
#define S2_SWINDOWSIZE 7
|
||||
#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2))
|
||||
|
||||
/* computes [s1]p1 + [s2]basepoint */
|
||||
static void
|
||||
ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
|
||||
signed char slide1[256], slide2[256];
|
||||
ge25519_pniels pre1[S1_TABLE_SIZE];
|
||||
ge25519 d1;
|
||||
ge25519_p1p1 t;
|
||||
int32_t i;
|
||||
|
||||
contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
|
||||
contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE);
|
||||
|
||||
ge25519_double(&d1, p1);
|
||||
ge25519_full_to_pniels(pre1, p1);
|
||||
for (i = 0; i < S1_TABLE_SIZE - 1; i++)
|
||||
ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
|
||||
|
||||
/* set neutral */
|
||||
memset(r, 0, sizeof(ge25519));
|
||||
r->y[0] = 1;
|
||||
r->z[0] = 1;
|
||||
|
||||
i = 255;
|
||||
while ((i >= 0) && !(slide1[i] | slide2[i]))
|
||||
i--;
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
ge25519_double_p1p1(&t, r);
|
||||
|
||||
if (slide1[i]) {
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7);
|
||||
}
|
||||
|
||||
if (slide2[i]) {
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7);
|
||||
}
|
||||
|
||||
ge25519_p1p1_to_partial(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
|
||||
|
||||
static uint32_t
|
||||
ge25519_windowb_equal(uint32_t b, uint32_t c) {
|
||||
return ((b ^ c) - 1) >> 31;
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
bignum25519 neg;
|
||||
uint32_t sign = (uint32_t)((unsigned char)b >> 7);
|
||||
uint32_t mask = ~(sign - 1);
|
||||
uint32_t u = (b + mask) ^ mask;
|
||||
uint32_t i;
|
||||
|
||||
/* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */
|
||||
uint8_t packed[96] = {0};
|
||||
packed[0] = 1;
|
||||
packed[32] = 1;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
|
||||
|
||||
/* expand in to t */
|
||||
curve25519_expand(t->ysubx, packed + 0);
|
||||
curve25519_expand(t->xaddy, packed + 32);
|
||||
curve25519_expand(t->t2d , packed + 64);
|
||||
|
||||
/* adjust for sign */
|
||||
curve25519_swap_conditional(t->ysubx, t->xaddy, sign);
|
||||
curve25519_neg(neg, t->t2d);
|
||||
curve25519_swap_conditional(t->t2d, neg, sign);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */
|
||||
|
||||
|
||||
/* computes [s]basepoint */
|
||||
static void
|
||||
ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) {
|
||||
signed char b[64];
|
||||
uint32_t i;
|
||||
ge25519_niels t;
|
||||
|
||||
contract256_window4_modm(b, s);
|
||||
|
||||
ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]);
|
||||
curve25519_sub_reduce(r->x, t.xaddy, t.ysubx);
|
||||
curve25519_add_reduce(r->y, t.xaddy, t.ysubx);
|
||||
memset(r->z, 0, sizeof(bignum25519));
|
||||
curve25519_copy(r->t, t.t2d);
|
||||
r->z[0] = 2;
|
||||
for (i = 3; i < 64; i += 2) {
|
||||
ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
}
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double(r, r);
|
||||
ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]);
|
||||
curve25519_mul(t.t2d, t.t2d, ge25519_ecd);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
for(i = 2; i < 64; i += 2) {
|
||||
ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
390
external/ed25519-donna/ed25519-donna-impl-sse2.h
vendored
390
external/ed25519-donna/ed25519-donna-impl-sse2.h
vendored
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
conversions
|
||||
*/
|
||||
|
||||
static void
|
||||
ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) {
|
||||
packed64bignum25519 ALIGN(16) xz, tt, xzout;
|
||||
curve25519_mul(r->y, p->y, p->z);
|
||||
curve25519_tangle64(xz, p->x, p->z);
|
||||
curve25519_tangleone64(tt, p->t);
|
||||
curve25519_mul_packed64(xzout, xz, tt);
|
||||
curve25519_untangle64(r->x, r->z, xzout);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) {
|
||||
packed64bignum25519 ALIGN(16) zy, xt, xx, zz, ty;
|
||||
curve25519_tangle64(ty, p->t, p->y);
|
||||
curve25519_tangleone64(xx, p->x);
|
||||
curve25519_mul_packed64(xt, xx, ty);
|
||||
curve25519_untangle64(r->x, r->t, xt);
|
||||
curve25519_tangleone64(zz, p->z);
|
||||
curve25519_mul_packed64(zy, zz, ty);
|
||||
curve25519_untangle64(r->z, r->y, zy);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) {
|
||||
curve25519_sub(p->ysubx, r->y, r->x);
|
||||
curve25519_add(p->xaddy, r->x, r->y);
|
||||
curve25519_copy(p->z, r->z);
|
||||
curve25519_mul(p->t2d, r->t, ge25519_ec2d);
|
||||
}
|
||||
|
||||
/*
|
||||
adding & doubling
|
||||
*/
|
||||
|
||||
static void
|
||||
ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) {
|
||||
bignum25519 ALIGN(16) a,b,c,d;
|
||||
packed32bignum25519 ALIGN(16) xx, yy, yypxx, yymxx, bd, ac, bdmac, bdpac;
|
||||
packed64bignum25519 ALIGN(16) at, bu, atbu, ptz, qtz, cd;
|
||||
|
||||
curve25519_tangle32(yy, p->y, q->y);
|
||||
curve25519_tangle32(xx, p->x, q->x);
|
||||
curve25519_add_packed32(yypxx, yy, xx);
|
||||
curve25519_sub_packed32(yymxx, yy, xx);
|
||||
curve25519_tangle64_from32(at, bu, yymxx, yypxx);
|
||||
curve25519_mul_packed64(atbu, at, bu);
|
||||
curve25519_untangle64(a, b, atbu);
|
||||
curve25519_tangle64(ptz, p->t, p->z);
|
||||
curve25519_tangle64(qtz, q->t, q->z);
|
||||
curve25519_mul_packed64(cd, ptz, qtz);
|
||||
curve25519_untangle64(c, d, cd);
|
||||
curve25519_mul(c, c, ge25519_ec2d);
|
||||
curve25519_add_reduce(d, d, d);
|
||||
/* reduce, so no after_basic is needed later */
|
||||
curve25519_tangle32(bd, b, d);
|
||||
curve25519_tangle32(ac, a, c);
|
||||
curve25519_sub_packed32(bdmac, bd, ac);
|
||||
curve25519_add_packed32(bdpac, bd, ac);
|
||||
curve25519_untangle32(r->x, r->t, bdmac);
|
||||
curve25519_untangle32(r->y, r->z, bdpac);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) {
|
||||
bignum25519 ALIGN(16) a,b,c,x;
|
||||
packed64bignum25519 ALIGN(16) xy, zx, ab, cx;
|
||||
packed32bignum25519 ALIGN(16) xc, yz, xt, yc, ac, bc;
|
||||
|
||||
curve25519_add(x, p->x, p->y);
|
||||
curve25519_tangle64(xy, p->x, p->y);
|
||||
curve25519_square_packed64(ab, xy);
|
||||
curve25519_untangle64(a, b, ab);
|
||||
curve25519_tangle64(zx, p->z, x);
|
||||
curve25519_square_packed64(cx, zx);
|
||||
curve25519_untangle64(c, x, cx);
|
||||
curve25519_tangle32(bc, b, c);
|
||||
curve25519_tangle32(ac, a, c);
|
||||
curve25519_add_reduce_packed32(yc, bc, ac);
|
||||
curve25519_untangle32(r->y, c, yc);
|
||||
curve25519_sub(r->z, b, a);
|
||||
curve25519_tangle32(yz, r->y, r->z);
|
||||
curve25519_tangle32(xc, x, c);
|
||||
curve25519_sub_after_basic_packed32(xt, xc, yz);
|
||||
curve25519_untangle32(r->x, r->t, xt);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) {
|
||||
const bignum25519 *qb = (const bignum25519 *)q;
|
||||
bignum25519 *rb = (bignum25519 *)r;
|
||||
bignum25519 ALIGN(16) a,b,c;
|
||||
packed64bignum25519 ALIGN(16) ab, yx, aybx;
|
||||
packed32bignum25519 ALIGN(16) bd, ac, bdac;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_tangle64(ab, a, b);
|
||||
curve25519_tangle64(yx, qb[signbit], qb[signbit^1]);
|
||||
curve25519_mul_packed64(aybx, ab, yx);
|
||||
curve25519_untangle64(a, b, aybx);
|
||||
curve25519_add(r->y, b, a);
|
||||
curve25519_add_reduce(r->t, p->z, p->z);
|
||||
curve25519_mul(c, p->t, q->t2d);
|
||||
curve25519_copy(r->z, r->t);
|
||||
curve25519_add(rb[2+signbit], rb[2+signbit], c);
|
||||
curve25519_tangle32(bd, b, rb[2+(signbit^1)]);
|
||||
curve25519_tangle32(ac, a, c);
|
||||
curve25519_sub_packed32(bdac, bd, ac);
|
||||
curve25519_untangle32(r->x, rb[2+(signbit^1)], bdac);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) {
|
||||
const bignum25519 *qb = (const bignum25519 *)q;
|
||||
bignum25519 *rb = (bignum25519 *)r;
|
||||
bignum25519 ALIGN(16) a,b,c;
|
||||
packed64bignum25519 ALIGN(16) ab, yx, aybx, zt, zt2d, tc;
|
||||
packed32bignum25519 ALIGN(16) bd, ac, bdac;
|
||||
|
||||
curve25519_sub(a, p->y, p->x);
|
||||
curve25519_add(b, p->y, p->x);
|
||||
curve25519_tangle64(ab, a, b);
|
||||
curve25519_tangle64(yx, qb[signbit], qb[signbit^1]);
|
||||
curve25519_mul_packed64(aybx, ab, yx);
|
||||
curve25519_untangle64(a, b, aybx);
|
||||
curve25519_add(r->y, b, a);
|
||||
curve25519_tangle64(zt, p->z, p->t);
|
||||
curve25519_tangle64(zt2d, q->z, q->t2d);
|
||||
curve25519_mul_packed64(tc, zt, zt2d);
|
||||
curve25519_untangle64(r->t, c, tc);
|
||||
curve25519_add_reduce(r->t, r->t, r->t);
|
||||
curve25519_copy(r->z, r->t);
|
||||
curve25519_add(rb[2+signbit], rb[2+signbit], c);
|
||||
curve25519_tangle32(bd, b, rb[2+(signbit^1)]);
|
||||
curve25519_tangle32(ac, a, c);
|
||||
curve25519_sub_packed32(bdac, bd, ac);
|
||||
curve25519_untangle32(r->x, rb[2+(signbit^1)], bdac);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_double(ge25519 *r, const ge25519 *p) {
|
||||
ge25519_p1p1 ALIGN(16) t;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) {
|
||||
ge25519_p1p1 ALIGN(16) t;
|
||||
ge25519_add_p1p1(&t, p, q);
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_double_partial(ge25519 *r, const ge25519 *p) {
|
||||
ge25519_p1p1 ALIGN(16) t;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_partial(r, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) {
|
||||
packed64bignum25519 ALIGN(16) ab, yx, aybx, eg, ff, hh, xz, ty;
|
||||
packed32bignum25519 ALIGN(16) bd, ac, bdac;
|
||||
bignum25519 ALIGN(16) a,b,c,d,e,f,g,h;
|
||||
|
||||
curve25519_sub(a, r->y, r->x);
|
||||
curve25519_add(b, r->y, r->x);
|
||||
curve25519_tangle64(ab, a, b);
|
||||
curve25519_tangle64(yx, q->ysubx, q->xaddy);
|
||||
curve25519_mul_packed64(aybx, ab, yx);
|
||||
curve25519_untangle64(a, b, aybx);
|
||||
curve25519_add(h, b, a);
|
||||
curve25519_add_reduce(d, r->z, r->z);
|
||||
curve25519_mul(c, r->t, q->t2d);
|
||||
curve25519_add(g, d, c); /* d is reduced, so no need for after_basic */
|
||||
curve25519_tangle32(bd, b, d);
|
||||
curve25519_tangle32(ac, a, c);
|
||||
curve25519_sub_packed32(bdac, bd, ac); /* d is reduced, so no need for after_basic */
|
||||
curve25519_untangle32(e, f, bdac);
|
||||
curve25519_tangle64(eg, e, g);
|
||||
curve25519_tangleone64(ff, f);
|
||||
curve25519_mul_packed64(xz, eg, ff);
|
||||
curve25519_untangle64(r->x, r->z, xz);
|
||||
curve25519_tangleone64(hh, h);
|
||||
curve25519_mul_packed64(ty, eg, hh);
|
||||
curve25519_untangle64(r->t, r->y, ty);
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) {
|
||||
ge25519_p1p1 ALIGN(16) t;
|
||||
ge25519 ALIGN(16) f;
|
||||
ge25519_pnielsadd_p1p1(&t, p, q, 0);
|
||||
ge25519_p1p1_to_full(&f, &t);
|
||||
ge25519_full_to_pniels(r, &f);
|
||||
}
|
||||
|
||||
/*
|
||||
pack & unpack
|
||||
*/
|
||||
|
||||
static void
|
||||
ge25519_pack(unsigned char r[32], const ge25519 *p) {
|
||||
bignum25519 ALIGN(16) tx, ty, zi;
|
||||
unsigned char parity[32];
|
||||
curve25519_recip(zi, p->z);
|
||||
curve25519_mul(tx, p->x, zi);
|
||||
curve25519_mul(ty, p->y, zi);
|
||||
curve25519_contract(r, ty);
|
||||
curve25519_contract(parity, tx);
|
||||
r[31] ^= ((parity[0] & 1) << 7);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
|
||||
static const bignum25519 ALIGN(16) one = {1};
|
||||
static const unsigned char zero[32] = {0};
|
||||
unsigned char parity = p[31] >> 7;
|
||||
unsigned char check[32];
|
||||
bignum25519 ALIGN(16) t, root, num, den, d3;
|
||||
|
||||
curve25519_expand(r->y, p);
|
||||
curve25519_copy(r->z, one);
|
||||
curve25519_square_times(num, r->y, 1); /* x = y^2 */
|
||||
curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */
|
||||
curve25519_sub_reduce(num, num, r->z); /* x = y^2 - 1 */
|
||||
curve25519_add(den, den, r->z); /* den = dy^2 + 1 */
|
||||
|
||||
/* Computation of sqrt(num/den) */
|
||||
/* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
|
||||
curve25519_square_times(t, den, 1);
|
||||
curve25519_mul(d3, t, den);
|
||||
curve25519_square_times(r->x, d3, 1);
|
||||
curve25519_mul(r->x, r->x, den);
|
||||
curve25519_mul(r->x, r->x, num);
|
||||
curve25519_pow_two252m3(r->x, r->x);
|
||||
|
||||
/* 2. computation of r->x = t * num * den^3 */
|
||||
curve25519_mul(r->x, r->x, d3);
|
||||
curve25519_mul(r->x, r->x, num);
|
||||
|
||||
/* 3. Check if either of the roots works: */
|
||||
curve25519_square_times(t, r->x, 1);
|
||||
curve25519_mul(t, t, den);
|
||||
curve25519_copy(root, t);
|
||||
curve25519_sub_reduce(root, root, num);
|
||||
curve25519_contract(check, root);
|
||||
if (!ed25519_verify(check, zero, 32)) {
|
||||
curve25519_add_reduce(t, t, num);
|
||||
curve25519_contract(check, t);
|
||||
if (!ed25519_verify(check, zero, 32))
|
||||
return 0;
|
||||
curve25519_mul(r->x, r->x, ge25519_sqrtneg1);
|
||||
}
|
||||
|
||||
curve25519_contract(check, r->x);
|
||||
if ((check[0] & 1) == parity) {
|
||||
curve25519_copy(t, r->x);
|
||||
curve25519_neg(r->x, t);
|
||||
}
|
||||
curve25519_mul(r->t, r->x, r->y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
scalarmults
|
||||
*/
|
||||
|
||||
#define S1_SWINDOWSIZE 5
|
||||
#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2))
|
||||
#define S2_SWINDOWSIZE 7
|
||||
#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2))
|
||||
|
||||
static void
|
||||
ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
|
||||
signed char slide1[256], slide2[256];
|
||||
ge25519_pniels ALIGN(16) pre1[S1_TABLE_SIZE];
|
||||
ge25519 ALIGN(16) d1;
|
||||
ge25519_p1p1 ALIGN(16) t;
|
||||
int32_t i;
|
||||
|
||||
contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
|
||||
contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE);
|
||||
|
||||
ge25519_double(&d1, p1);
|
||||
ge25519_full_to_pniels(pre1, p1);
|
||||
for (i = 0; i < S1_TABLE_SIZE - 1; i++)
|
||||
ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
|
||||
|
||||
/* set neutral */
|
||||
memset(r, 0, sizeof(ge25519));
|
||||
r->y[0] = 1;
|
||||
r->z[0] = 1;
|
||||
|
||||
i = 255;
|
||||
while ((i >= 0) && !(slide1[i] | slide2[i]))
|
||||
i--;
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
ge25519_double_p1p1(&t, r);
|
||||
|
||||
if (slide1[i]) {
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7);
|
||||
}
|
||||
|
||||
if (slide2[i]) {
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7);
|
||||
}
|
||||
|
||||
ge25519_p1p1_to_partial(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
|
||||
|
||||
static uint32_t
|
||||
ge25519_windowb_equal(uint32_t b, uint32_t c) {
|
||||
return ((b ^ c) - 1) >> 31;
|
||||
}
|
||||
|
||||
static void
|
||||
ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
bignum25519 ALIGN(16) neg;
|
||||
uint32_t sign = (uint32_t)((unsigned char)b >> 7);
|
||||
uint32_t mask = ~(sign - 1);
|
||||
uint32_t u = (b + mask) ^ mask;
|
||||
uint32_t i;
|
||||
|
||||
/* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */
|
||||
uint8_t ALIGN(16) packed[96] = {0};
|
||||
packed[0] = 1;
|
||||
packed[32] = 1;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
|
||||
|
||||
/* expand in to t */
|
||||
curve25519_expand(t->ysubx, packed + 0);
|
||||
curve25519_expand(t->xaddy, packed + 32);
|
||||
curve25519_expand(t->t2d , packed + 64);
|
||||
|
||||
/* adjust for sign */
|
||||
curve25519_swap_conditional(t->ysubx, t->xaddy, sign);
|
||||
curve25519_neg(neg, t->t2d);
|
||||
curve25519_swap_conditional(t->t2d, neg, sign);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */
|
||||
|
||||
static void
|
||||
ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t table[256][96], const bignum256modm s) {
|
||||
signed char b[64];
|
||||
uint32_t i;
|
||||
ge25519_niels ALIGN(16) t;
|
||||
|
||||
contract256_window4_modm(b, s);
|
||||
|
||||
ge25519_scalarmult_base_choose_niels(&t, table, 0, b[1]);
|
||||
curve25519_sub_reduce(r->x, t.xaddy, t.ysubx);
|
||||
curve25519_add_reduce(r->y, t.xaddy, t.ysubx);
|
||||
memset(r->z, 0, sizeof(bignum25519));
|
||||
r->z[0] = 2;
|
||||
curve25519_copy(r->t, t.t2d);
|
||||
for (i = 3; i < 64; i += 2) {
|
||||
ge25519_scalarmult_base_choose_niels(&t, table, i / 2, b[i]);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
}
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double_partial(r, r);
|
||||
ge25519_double(r, r);
|
||||
ge25519_scalarmult_base_choose_niels(&t, table, 0, b[0]);
|
||||
curve25519_mul(t.t2d, t.t2d, ge25519_ecd);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
for(i = 2; i < 64; i += 2) {
|
||||
ge25519_scalarmult_base_choose_niels(&t, table, i / 2, b[i]);
|
||||
ge25519_nielsadd2(r, &t);
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/* os */
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__TOS_WIN__) || defined(__WINDOWS__)
|
||||
#define OS_WINDOWS
|
||||
#elif defined(sun) || defined(__sun) || defined(__SVR4) || defined(__svr4__)
|
||||
#define OS_SOLARIS
|
||||
#else
|
||||
#include <sys/param.h> /* need this to define BSD */
|
||||
#define OS_NIX
|
||||
#if defined(__linux__)
|
||||
#define OS_LINUX
|
||||
#elif defined(BSD)
|
||||
#define OS_BSD
|
||||
#if defined(MACOS_X) || (defined(__APPLE__) & defined(__MACH__))
|
||||
#define OS_OSX
|
||||
#elif defined(macintosh) || defined(Macintosh)
|
||||
#define OS_MAC
|
||||
#elif defined(__OpenBSD__)
|
||||
#define OS_OPENBSD
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* compiler */
|
||||
#if defined(_MSC_VER)
|
||||
#define COMPILER_MSVC
|
||||
#endif
|
||||
#if defined(__ICC)
|
||||
#define COMPILER_INTEL
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#if (__GNUC__ >= 3)
|
||||
#define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + (__GNUC_PATCHLEVEL__))
|
||||
#else
|
||||
#define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) )
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__PATHCC__)
|
||||
#define COMPILER_PATHCC
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#define COMPILER_CLANG ((__clang_major__ * 10000) + (__clang_minor__ * 100) + (__clang_patchlevel__))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* cpu */
|
||||
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__ ) || defined(_M_X64)
|
||||
#define CPU_X86_64
|
||||
#elif defined(__i586__) || defined(__i686__) || (defined(_M_IX86) && (_M_IX86 >= 500))
|
||||
#define CPU_X86 500
|
||||
#elif defined(__i486__) || (defined(_M_IX86) && (_M_IX86 >= 400))
|
||||
#define CPU_X86 400
|
||||
#elif defined(__i386__) || (defined(_M_IX86) && (_M_IX86 >= 300)) || defined(__X86__) || defined(_X86_) || defined(__I86__)
|
||||
#define CPU_X86 300
|
||||
#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) || defined(__ia64)
|
||||
#define CPU_IA64
|
||||
#endif
|
||||
|
||||
#if defined(__sparc__) || defined(__sparc) || defined(__sparcv9)
|
||||
#define CPU_SPARC
|
||||
#if defined(__sparcv9)
|
||||
#define CPU_SPARC64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(powerpc) || defined(__PPC__) || defined(__ppc__) || defined(_ARCH_PPC) || defined(__powerpc__) || defined(__powerpc) || defined(POWERPC) || defined(_M_PPC)
|
||||
#define CPU_PPC
|
||||
#if defined(_ARCH_PWR7)
|
||||
#define CPU_POWER7
|
||||
#elif defined(__64BIT__)
|
||||
#define CPU_PPC64
|
||||
#else
|
||||
#define CPU_PPC32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__hppa__) || defined(__hppa)
|
||||
#define CPU_HPPA
|
||||
#endif
|
||||
|
||||
#if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
|
||||
#define CPU_ALPHA
|
||||
#endif
|
||||
|
||||
/* 64 bit cpu */
|
||||
#if defined(CPU_X86_64) || defined(CPU_IA64) || defined(CPU_SPARC64) || defined(__64BIT__) || defined(__LP64__) || defined(_LP64) || (defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64))
|
||||
#define CPU_64BITS
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
136
external/ed25519-donna/ed25519-donna-portable.h
vendored
136
external/ed25519-donna/ed25519-donna-portable.h
vendored
@@ -1,136 +0,0 @@
|
||||
#include "ed25519-donna-portable-identify.h"
|
||||
|
||||
#define mul32x32_64(a,b) (((uint64_t)(a))*(b))
|
||||
|
||||
/* platform */
|
||||
#if defined(COMPILER_MSVC)
|
||||
#include <intrin.h>
|
||||
#if !defined(_DEBUG)
|
||||
#undef mul32x32_64
|
||||
#define mul32x32_64(a,b) __emulu(a,b)
|
||||
#endif
|
||||
#undef inline
|
||||
#define inline __forceinline
|
||||
#define DONNA_INLINE __forceinline
|
||||
#define DONNA_NOINLINE __declspec(noinline)
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#define ROTL32(a,b) _rotl(a,b)
|
||||
#define ROTR32(a,b) _rotr(a,b)
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#define DONNA_INLINE inline __attribute__((always_inline))
|
||||
#define DONNA_NOINLINE __attribute__((noinline))
|
||||
#undef ALIGN
|
||||
#define ALIGN(x) __attribute__((aligned(x)))
|
||||
#define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b)))
|
||||
#define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b)))
|
||||
#endif
|
||||
|
||||
/* uint128_t */
|
||||
#if defined(CPU_64BITS) && !defined(ED25519_FORCE_32BIT)
|
||||
#if defined(COMPILER_CLANG) && (COMPILER_CLANG >= 30100)
|
||||
#define HAVE_NATIVE_UINT128
|
||||
typedef unsigned __int128 uint128_t;
|
||||
#elif defined(COMPILER_MSVC)
|
||||
#define HAVE_UINT128
|
||||
typedef struct uint128_t {
|
||||
uint64_t lo, hi;
|
||||
} uint128_t;
|
||||
#define mul64x64_128(out,a,b) out.lo = _umul128(a,b,&out.hi);
|
||||
#define shr128_pair(out,hi,lo,shift) out = __shiftright128(lo, hi, shift);
|
||||
#define shl128_pair(out,hi,lo,shift) out = __shiftleft128(lo, hi, shift);
|
||||
#define shr128(out,in,shift) shr128_pair(out, in.hi, in.lo, shift)
|
||||
#define shl128(out,in,shift) shl128_pair(out, in.hi, in.lo, shift)
|
||||
#define add128(a,b) { uint64_t p = a.lo; a.lo += b.lo; a.hi += b.hi + (a.lo < p); }
|
||||
#define add128_64(a,b) { uint64_t p = a.lo; a.lo += b; a.hi += (a.lo < p); }
|
||||
#define lo128(a) (a.lo)
|
||||
#define hi128(a) (a.hi)
|
||||
#elif defined(COMPILER_GCC) && !defined(HAVE_NATIVE_UINT128)
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
#define HAVE_NATIVE_UINT128
|
||||
typedef unsigned __int128 uint128_t;
|
||||
#elif (COMPILER_GCC >= 40400)
|
||||
#define HAVE_NATIVE_UINT128
|
||||
typedef unsigned uint128_t __attribute__((mode(TI)));
|
||||
#elif defined(CPU_X86_64)
|
||||
#define HAVE_UINT128
|
||||
typedef struct uint128_t {
|
||||
uint64_t lo, hi;
|
||||
} uint128_t;
|
||||
#define mul64x64_128(out,a,b) __asm__ ("mulq %3" : "=a" (out.lo), "=d" (out.hi) : "a" (a), "rm" (b));
|
||||
#define shr128_pair(out,hi,lo,shift) __asm__ ("shrdq %2,%1,%0" : "+r" (lo) : "r" (hi), "J" (shift)); out = lo;
|
||||
#define shl128_pair(out,hi,lo,shift) __asm__ ("shldq %2,%1,%0" : "+r" (hi) : "r" (lo), "J" (shift)); out = hi;
|
||||
#define shr128(out,in,shift) shr128_pair(out,in.hi, in.lo, shift)
|
||||
#define shl128(out,in,shift) shl128_pair(out,in.hi, in.lo, shift)
|
||||
#define add128(a,b) __asm__ ("addq %4,%2; adcq %5,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b.lo), "rm" (b.hi) : "cc");
|
||||
#define add128_64(a,b) __asm__ ("addq %4,%2; adcq $0,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b) : "cc");
|
||||
#define lo128(a) (a.lo)
|
||||
#define hi128(a) (a.hi)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NATIVE_UINT128)
|
||||
#define HAVE_UINT128
|
||||
#define mul64x64_128(out,a,b) out = (uint128_t)a * b;
|
||||
#define shr128_pair(out,hi,lo,shift) out = (uint64_t)((((uint128_t)hi << 64) | lo) >> (shift));
|
||||
#define shl128_pair(out,hi,lo,shift) out = (uint64_t)(((((uint128_t)hi << 64) | lo) << (shift)) >> 64);
|
||||
#define shr128(out,in,shift) out = (uint64_t)(in >> (shift));
|
||||
#define shl128(out,in,shift) out = (uint64_t)((in << shift) >> 64);
|
||||
#define add128(a,b) a += b;
|
||||
#define add128_64(a,b) a += (uint64_t)b;
|
||||
#define lo128(a) ((uint64_t)a)
|
||||
#define hi128(a) ((uint64_t)(a >> 64))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_UINT128)
|
||||
#error Need a uint128_t implementation!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* endian */
|
||||
#if !defined(ED25519_OPENSSLRNG)
|
||||
static inline void U32TO8_LE(unsigned char *p, const uint32_t v) {
|
||||
p[0] = (unsigned char)(v );
|
||||
p[1] = (unsigned char)(v >> 8);
|
||||
p[2] = (unsigned char)(v >> 16);
|
||||
p[3] = (unsigned char)(v >> 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_UINT128)
|
||||
static inline uint32_t U8TO32_LE(const unsigned char *p) {
|
||||
return
|
||||
(((uint32_t)(p[0]) ) |
|
||||
((uint32_t)(p[1]) << 8) |
|
||||
((uint32_t)(p[2]) << 16) |
|
||||
((uint32_t)(p[3]) << 24));
|
||||
}
|
||||
#else
|
||||
static inline uint64_t U8TO64_LE(const unsigned char *p) {
|
||||
return
|
||||
(((uint64_t)(p[0]) ) |
|
||||
((uint64_t)(p[1]) << 8) |
|
||||
((uint64_t)(p[2]) << 16) |
|
||||
((uint64_t)(p[3]) << 24) |
|
||||
((uint64_t)(p[4]) << 32) |
|
||||
((uint64_t)(p[5]) << 40) |
|
||||
((uint64_t)(p[6]) << 48) |
|
||||
((uint64_t)(p[7]) << 56));
|
||||
}
|
||||
|
||||
static inline void U64TO8_LE(unsigned char *p, const uint64_t v) {
|
||||
p[0] = (unsigned char)(v );
|
||||
p[1] = (unsigned char)(v >> 8);
|
||||
p[2] = (unsigned char)(v >> 16);
|
||||
p[3] = (unsigned char)(v >> 24);
|
||||
p[4] = (unsigned char)(v >> 32);
|
||||
p[5] = (unsigned char)(v >> 40);
|
||||
p[6] = (unsigned char)(v >> 48);
|
||||
p[7] = (unsigned char)(v >> 56);
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
115
external/ed25519-donna/ed25519-donna.h
vendored
115
external/ed25519-donna/ed25519-donna.h
vendored
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
Modified from the amd64-51-30k implementation by
|
||||
Daniel J. Bernstein
|
||||
Niels Duif
|
||||
Tanja Lange
|
||||
Peter Schwabe
|
||||
Bo-Yin Yang
|
||||
*/
|
||||
|
||||
|
||||
#include "ed25519-donna-portable.h"
|
||||
|
||||
#if defined(ED25519_SSE2)
|
||||
#else
|
||||
#if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT)
|
||||
#define ED25519_64BIT
|
||||
#else
|
||||
#define ED25519_32BIT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ED25519_NO_INLINE_ASM)
|
||||
/* detect extra features first so un-needed functions can be disabled throughout */
|
||||
#if defined(ED25519_SSE2)
|
||||
#if defined(COMPILER_GCC) && defined(CPU_X86)
|
||||
#define ED25519_GCC_32BIT_SSE_CHOOSE
|
||||
#elif defined(COMPILER_GCC) && defined(CPU_X86_64)
|
||||
#define ED25519_GCC_64BIT_SSE_CHOOSE
|
||||
#endif
|
||||
#else
|
||||
#if defined(CPU_X86_64)
|
||||
#if defined(COMPILER_GCC)
|
||||
#if defined(ED25519_64BIT)
|
||||
#define ED25519_GCC_64BIT_X86_CHOOSE
|
||||
#else
|
||||
#define ED25519_GCC_64BIT_32BIT_CHOOSE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ED25519_SSE2)
|
||||
#include "curve25519-donna-sse2.h"
|
||||
#elif defined(ED25519_64BIT)
|
||||
#include "curve25519-donna-64bit.h"
|
||||
#else
|
||||
#include "curve25519-donna-32bit.h"
|
||||
#endif
|
||||
|
||||
#include "curve25519-donna-helpers.h"
|
||||
|
||||
/* separate uint128 check for 64 bit sse2 */
|
||||
#if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT)
|
||||
#include "modm-donna-64bit.h"
|
||||
#else
|
||||
#include "modm-donna-32bit.h"
|
||||
#endif
|
||||
|
||||
typedef unsigned char hash_512bits[64];
|
||||
|
||||
/*
|
||||
Timing safe memory compare
|
||||
*/
|
||||
static int
|
||||
ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) {
|
||||
size_t differentbits = 0;
|
||||
while (len--)
|
||||
differentbits |= (*x++ ^ *y++);
|
||||
return (int) (1 & ((differentbits - 1) >> 8));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
|
||||
* with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
|
||||
* Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
|
||||
*/
|
||||
|
||||
typedef struct ge25519_t {
|
||||
bignum25519 x, y, z, t;
|
||||
} ge25519;
|
||||
|
||||
typedef struct ge25519_p1p1_t {
|
||||
bignum25519 x, y, z, t;
|
||||
} ge25519_p1p1;
|
||||
|
||||
typedef struct ge25519_niels_t {
|
||||
bignum25519 ysubx, xaddy, t2d;
|
||||
} ge25519_niels;
|
||||
|
||||
typedef struct ge25519_pniels_t {
|
||||
bignum25519 ysubx, xaddy, z, t2d;
|
||||
} ge25519_pniels;
|
||||
|
||||
#include "ed25519-donna-basepoint-table.h"
|
||||
|
||||
#if defined(ED25519_64BIT)
|
||||
#include "ed25519-donna-64bit-tables.h"
|
||||
#include "ed25519-donna-64bit-x86.h"
|
||||
#else
|
||||
#include "ed25519-donna-32bit-tables.h"
|
||||
#include "ed25519-donna-64bit-x86-32bit.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ED25519_SSE2)
|
||||
#include "ed25519-donna-32bit-sse2.h"
|
||||
#include "ed25519-donna-64bit-sse2.h"
|
||||
#include "ed25519-donna-impl-sse2.h"
|
||||
#else
|
||||
#include "ed25519-donna-impl-base.h"
|
||||
#endif
|
||||
|
||||
11
external/ed25519-donna/ed25519-hash-custom.h
vendored
11
external/ed25519-donna/ed25519-hash-custom.h
vendored
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
a custom hash must have a 512bit digest and implement:
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
*/
|
||||
|
||||
219
external/ed25519-donna/ed25519-hash.h
vendored
219
external/ed25519-donna/ed25519-hash.h
vendored
@@ -1,219 +0,0 @@
|
||||
#if defined(ED25519_REFHASH)
|
||||
|
||||
/* reference/slow SHA-512. really, do not use this */
|
||||
|
||||
#define HASH_BLOCK_SIZE 128
|
||||
#define HASH_DIGEST_SIZE 64
|
||||
|
||||
typedef struct sha512_state_t {
|
||||
uint64_t H[8];
|
||||
uint64_t T[2];
|
||||
uint32_t leftover;
|
||||
uint8_t buffer[HASH_BLOCK_SIZE];
|
||||
} sha512_state;
|
||||
|
||||
typedef sha512_state ed25519_hash_context;
|
||||
|
||||
static const uint64_t sha512_constants[80] = {
|
||||
0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full, 0xe9b5dba58189dbbcull,
|
||||
0x3956c25bf348b538ull, 0x59f111f1b605d019ull, 0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull,
|
||||
0xd807aa98a3030242ull, 0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull,
|
||||
0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull, 0xc19bf174cf692694ull,
|
||||
0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull, 0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull,
|
||||
0x2de92c6f592b0275ull, 0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
|
||||
0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full, 0xbf597fc7beef0ee4ull,
|
||||
0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull, 0x06ca6351e003826full, 0x142929670a0e6e70ull,
|
||||
0x27b70a8546d22ffcull, 0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull,
|
||||
0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull, 0x92722c851482353bull,
|
||||
0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull, 0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull,
|
||||
0xd192e819d6ef5218ull, 0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
|
||||
0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull, 0x34b0bcb5e19b48a8ull,
|
||||
0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull, 0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull,
|
||||
0x748f82ee5defb2fcull, 0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull,
|
||||
0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull, 0xc67178f2e372532bull,
|
||||
0xca273eceea26619cull, 0xd186b8c721c0c207ull, 0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull,
|
||||
0x06f067aa72176fbaull, 0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull,
|
||||
0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull, 0x431d67c49c100d4cull,
|
||||
0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull, 0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull
|
||||
};
|
||||
|
||||
static uint64_t
|
||||
sha512_ROTR64(uint64_t x, int k) {
|
||||
return (x >> k) | (x << (64 - k));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
sha512_LOAD64_BE(const uint8_t *p) {
|
||||
return
|
||||
((uint64_t)p[0] << 56) |
|
||||
((uint64_t)p[1] << 48) |
|
||||
((uint64_t)p[2] << 40) |
|
||||
((uint64_t)p[3] << 32) |
|
||||
((uint64_t)p[4] << 24) |
|
||||
((uint64_t)p[5] << 16) |
|
||||
((uint64_t)p[6] << 8) |
|
||||
((uint64_t)p[7] );
|
||||
}
|
||||
|
||||
static void
|
||||
sha512_STORE64_BE(uint8_t *p, uint64_t v) {
|
||||
p[0] = (uint8_t)(v >> 56);
|
||||
p[1] = (uint8_t)(v >> 48);
|
||||
p[2] = (uint8_t)(v >> 40);
|
||||
p[3] = (uint8_t)(v >> 32);
|
||||
p[4] = (uint8_t)(v >> 24);
|
||||
p[5] = (uint8_t)(v >> 16);
|
||||
p[6] = (uint8_t)(v >> 8);
|
||||
p[7] = (uint8_t)(v );
|
||||
}
|
||||
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x,y,z) (((x | y) & z) | (x & y))
|
||||
#define S0(x) (sha512_ROTR64(x, 28) ^ sha512_ROTR64(x, 34) ^ sha512_ROTR64(x, 39))
|
||||
#define S1(x) (sha512_ROTR64(x, 14) ^ sha512_ROTR64(x, 18) ^ sha512_ROTR64(x, 41))
|
||||
#define G0(x) (sha512_ROTR64(x, 1) ^ sha512_ROTR64(x, 8) ^ (x >> 7))
|
||||
#define G1(x) (sha512_ROTR64(x, 19) ^ sha512_ROTR64(x, 61) ^ (x >> 6))
|
||||
#define W0(in,i) (sha512_LOAD64_BE(&in[i * 8]))
|
||||
#define W1(i) (G1(w[i - 2]) + w[i - 7] + G0(w[i - 15]) + w[i - 16])
|
||||
#define STEP(i) \
|
||||
t1 = S0(r[0]) + Maj(r[0], r[1], r[2]); \
|
||||
t0 = r[7] + S1(r[4]) + Ch(r[4], r[5], r[6]) + sha512_constants[i] + w[i]; \
|
||||
r[7] = r[6]; \
|
||||
r[6] = r[5]; \
|
||||
r[5] = r[4]; \
|
||||
r[4] = r[3] + t0; \
|
||||
r[3] = r[2]; \
|
||||
r[2] = r[1]; \
|
||||
r[1] = r[0]; \
|
||||
r[0] = t0 + t1;
|
||||
|
||||
static void
|
||||
sha512_blocks(sha512_state *S, const uint8_t *in, size_t blocks) {
|
||||
uint64_t r[8], w[80], t0, t1;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 8; i++) r[i] = S->H[i];
|
||||
|
||||
while (blocks--) {
|
||||
for (i = 0; i < 16; i++) { w[i] = W0(in, i); }
|
||||
for (i = 16; i < 80; i++) { w[i] = W1(i); }
|
||||
for (i = 0; i < 80; i++) { STEP(i); }
|
||||
for (i = 0; i < 8; i++) { r[i] += S->H[i]; S->H[i] = r[i]; }
|
||||
S->T[0] += HASH_BLOCK_SIZE * 8;
|
||||
S->T[1] += (!S->T[0]) ? 1 : 0;
|
||||
in += HASH_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash_init(sha512_state *S) {
|
||||
S->H[0] = 0x6a09e667f3bcc908ull;
|
||||
S->H[1] = 0xbb67ae8584caa73bull;
|
||||
S->H[2] = 0x3c6ef372fe94f82bull;
|
||||
S->H[3] = 0xa54ff53a5f1d36f1ull;
|
||||
S->H[4] = 0x510e527fade682d1ull;
|
||||
S->H[5] = 0x9b05688c2b3e6c1full;
|
||||
S->H[6] = 0x1f83d9abfb41bd6bull;
|
||||
S->H[7] = 0x5be0cd19137e2179ull;
|
||||
S->T[0] = 0;
|
||||
S->T[1] = 0;
|
||||
S->leftover = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash_update(sha512_state *S, const uint8_t *in, size_t inlen) {
|
||||
size_t blocks, want;
|
||||
|
||||
/* handle the previous data */
|
||||
if (S->leftover) {
|
||||
want = (HASH_BLOCK_SIZE - S->leftover);
|
||||
want = (want < inlen) ? want : inlen;
|
||||
memcpy(S->buffer + S->leftover, in, want);
|
||||
S->leftover += (uint32_t)want;
|
||||
if (S->leftover < HASH_BLOCK_SIZE)
|
||||
return;
|
||||
in += want;
|
||||
inlen -= want;
|
||||
sha512_blocks(S, S->buffer, 1);
|
||||
}
|
||||
|
||||
/* handle the current data */
|
||||
blocks = (inlen & ~(HASH_BLOCK_SIZE - 1));
|
||||
S->leftover = (uint32_t)(inlen - blocks);
|
||||
if (blocks) {
|
||||
sha512_blocks(S, in, blocks / HASH_BLOCK_SIZE);
|
||||
in += blocks;
|
||||
}
|
||||
|
||||
/* handle leftover data */
|
||||
if (S->leftover)
|
||||
memcpy(S->buffer, in, S->leftover);
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash_final(sha512_state *S, uint8_t *hash) {
|
||||
uint64_t t0 = S->T[0] + (S->leftover * 8), t1 = S->T[1];
|
||||
|
||||
S->buffer[S->leftover] = 0x80;
|
||||
if (S->leftover <= 111) {
|
||||
memset(S->buffer + S->leftover + 1, 0, 111 - S->leftover);
|
||||
} else {
|
||||
memset(S->buffer + S->leftover + 1, 0, 127 - S->leftover);
|
||||
sha512_blocks(S, S->buffer, 1);
|
||||
memset(S->buffer, 0, 112);
|
||||
}
|
||||
|
||||
sha512_STORE64_BE(S->buffer + 112, t1);
|
||||
sha512_STORE64_BE(S->buffer + 120, t0);
|
||||
sha512_blocks(S, S->buffer, 1);
|
||||
|
||||
sha512_STORE64_BE(&hash[ 0], S->H[0]);
|
||||
sha512_STORE64_BE(&hash[ 8], S->H[1]);
|
||||
sha512_STORE64_BE(&hash[16], S->H[2]);
|
||||
sha512_STORE64_BE(&hash[24], S->H[3]);
|
||||
sha512_STORE64_BE(&hash[32], S->H[4]);
|
||||
sha512_STORE64_BE(&hash[40], S->H[5]);
|
||||
sha512_STORE64_BE(&hash[48], S->H[6]);
|
||||
sha512_STORE64_BE(&hash[56], S->H[7]);
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) {
|
||||
ed25519_hash_context ctx;
|
||||
ed25519_hash_init(&ctx);
|
||||
ed25519_hash_update(&ctx, in, inlen);
|
||||
ed25519_hash_final(&ctx, hash);
|
||||
}
|
||||
|
||||
#elif defined(ED25519_CUSTOMHASH)
|
||||
|
||||
#include "ed25519-hash-custom.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
typedef SHA512_CTX ed25519_hash_context;
|
||||
|
||||
static void
|
||||
ed25519_hash_init(ed25519_hash_context *ctx) {
|
||||
SHA512_Init(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen) {
|
||||
SHA512_Update(ctx, in, inlen);
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash) {
|
||||
SHA512_Final(hash, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) {
|
||||
SHA512(in, inlen, hash);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
a custom randombytes must implement:
|
||||
|
||||
void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len);
|
||||
|
||||
ed25519_randombytes_unsafe is used by the batch verification function
|
||||
to create random scalars
|
||||
*/
|
||||
91
external/ed25519-donna/ed25519-randombytes.h
vendored
91
external/ed25519-donna/ed25519-randombytes.h
vendored
@@ -1,91 +0,0 @@
|
||||
#if defined(ED25519_TEST)
|
||||
/*
|
||||
ISAAC+ "variant", the paper is not clear on operator precedence and other
|
||||
things. This is the "first in, first out" option!
|
||||
|
||||
Not threadsafe or securely initialized, only for deterministic testing
|
||||
*/
|
||||
typedef struct isaacp_state_t {
|
||||
uint32_t state[256];
|
||||
unsigned char buffer[1024];
|
||||
uint32_t a, b, c;
|
||||
size_t left;
|
||||
} isaacp_state;
|
||||
|
||||
#define isaacp_step(offset, mix) \
|
||||
x = mm[i + offset]; \
|
||||
a = (a ^ (mix)) + (mm[(i + offset + 128) & 0xff]); \
|
||||
y = (a ^ b) + mm[(x >> 2) & 0xff]; \
|
||||
mm[i + offset] = y; \
|
||||
b = (x + a) ^ mm[(y >> 10) & 0xff]; \
|
||||
U32TO8_LE(out + (i + offset) * 4, b);
|
||||
|
||||
static void
|
||||
isaacp_mix(isaacp_state *st) {
|
||||
uint32_t i, x, y;
|
||||
uint32_t a = st->a, b = st->b, c = st->c;
|
||||
uint32_t *mm = st->state;
|
||||
unsigned char *out = st->buffer;
|
||||
|
||||
c = c + 1;
|
||||
b = b + c;
|
||||
|
||||
for (i = 0; i < 256; i += 4) {
|
||||
isaacp_step(0, ROTL32(a,13))
|
||||
isaacp_step(1, ROTR32(a, 6))
|
||||
isaacp_step(2, ROTL32(a, 2))
|
||||
isaacp_step(3, ROTR32(a,16))
|
||||
}
|
||||
|
||||
st->a = a;
|
||||
st->b = b;
|
||||
st->c = c;
|
||||
st->left = 1024;
|
||||
}
|
||||
|
||||
static void
|
||||
isaacp_random(isaacp_state *st, void *p, size_t len) {
|
||||
size_t use;
|
||||
unsigned char *c = (unsigned char *)p;
|
||||
while (len) {
|
||||
use = (len > st->left) ? st->left : len;
|
||||
memcpy(c, st->buffer + (sizeof(st->buffer) - st->left), use);
|
||||
|
||||
st->left -= use;
|
||||
c += use;
|
||||
len -= use;
|
||||
|
||||
if (!st->left)
|
||||
isaacp_mix(st);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
|
||||
static int initialized = 0;
|
||||
static isaacp_state rng;
|
||||
|
||||
if (!initialized) {
|
||||
memset(&rng, 0, sizeof(rng));
|
||||
isaacp_mix(&rng);
|
||||
isaacp_mix(&rng);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
isaacp_random(&rng, p, len);
|
||||
}
|
||||
#elif defined(ED25519_CUSTOMRNG)
|
||||
|
||||
#include "ed25519-randombytes-custom.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
void
|
||||
ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
|
||||
|
||||
RAND_bytes(p, (int) len);
|
||||
|
||||
}
|
||||
#endif
|
||||
150
external/ed25519-donna/ed25519.c
vendored
150
external/ed25519-donna/ed25519.c
vendored
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
|
||||
Ed25519 reference implementation using Ed25519-donna
|
||||
*/
|
||||
|
||||
|
||||
/* define ED25519_SUFFIX to have it appended to the end of each public function */
|
||||
#if !defined(ED25519_SUFFIX)
|
||||
#define ED25519_SUFFIX
|
||||
#endif
|
||||
|
||||
#define ED25519_FN3(fn,suffix) fn##suffix
|
||||
#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
|
||||
#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX)
|
||||
|
||||
#include "ed25519-donna.h"
|
||||
#include "ed25519.h"
|
||||
#include "ed25519-randombytes.h"
|
||||
#include "ed25519-hash.h"
|
||||
|
||||
/*
|
||||
Generates a (extsk[0..31]) and aExt (extsk[32..63])
|
||||
*/
|
||||
|
||||
DONNA_INLINE static void
|
||||
ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
|
||||
ed25519_hash(extsk, sk, 32);
|
||||
extsk[0] &= 248;
|
||||
extsk[31] &= 127;
|
||||
extsk[31] |= 64;
|
||||
}
|
||||
|
||||
static void
|
||||
ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
|
||||
ed25519_hash_context ctx;
|
||||
ed25519_hash_init(&ctx);
|
||||
ed25519_hash_update(&ctx, RS, 32);
|
||||
ed25519_hash_update(&ctx, pk, 32);
|
||||
ed25519_hash_update(&ctx, m, mlen);
|
||||
ed25519_hash_final(&ctx, hram);
|
||||
}
|
||||
|
||||
void
|
||||
ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
|
||||
bignum256modm a;
|
||||
ge25519 ALIGN(16) A;
|
||||
hash_512bits extsk;
|
||||
|
||||
/* A = aB */
|
||||
ed25519_extsk(extsk, sk);
|
||||
expand256_modm(a, extsk, 32);
|
||||
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||
ge25519_pack(pk, &A);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
|
||||
ed25519_hash_context ctx;
|
||||
bignum256modm r, S, a;
|
||||
ge25519 ALIGN(16) R;
|
||||
hash_512bits extsk, hashr, hram;
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
|
||||
/* r = H(aExt[32..64], m) */
|
||||
ed25519_hash_init(&ctx);
|
||||
ed25519_hash_update(&ctx, extsk + 32, 32);
|
||||
ed25519_hash_update(&ctx, m, mlen);
|
||||
ed25519_hash_final(&ctx, hashr);
|
||||
expand256_modm(r, hashr, 64);
|
||||
|
||||
/* R = rB */
|
||||
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
|
||||
ge25519_pack(RS, &R);
|
||||
|
||||
/* S = H(R,A,m).. */
|
||||
ed25519_hram(hram, RS, pk, m, mlen);
|
||||
expand256_modm(S, hram, 64);
|
||||
|
||||
/* S = H(R,A,m)a */
|
||||
expand256_modm(a, extsk, 32);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(RS + 32, S);
|
||||
}
|
||||
|
||||
int
|
||||
ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
|
||||
ge25519 ALIGN(16) R, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
unsigned char checkR[32];
|
||||
|
||||
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
|
||||
return -1;
|
||||
|
||||
/* hram = H(R,A,m) */
|
||||
ed25519_hram(hash, RS, pk, m, mlen);
|
||||
expand256_modm(hram, hash, 64);
|
||||
|
||||
/* S */
|
||||
expand256_modm(S, RS + 32, 32);
|
||||
|
||||
/* SB - H(R,A,m)A */
|
||||
ge25519_double_scalarmult_vartime(&R, &A, hram, S);
|
||||
ge25519_pack(checkR, &R);
|
||||
|
||||
/* check that R = SB - H(R,A,m)A */
|
||||
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
|
||||
}
|
||||
|
||||
#include "ed25519-donna-batchverify.h"
|
||||
|
||||
/*
|
||||
Fast Curve25519 basepoint scalar multiplication
|
||||
*/
|
||||
|
||||
void
|
||||
ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25519_key e) {
|
||||
curved25519_key ec;
|
||||
bignum256modm s;
|
||||
bignum25519 ALIGN(16) yplusz, zminusy;
|
||||
ge25519 ALIGN(16) p;
|
||||
size_t i;
|
||||
|
||||
/* clamp */
|
||||
for (i = 0; i < 32; i++) ec[i] = e[i];
|
||||
ec[0] &= 248;
|
||||
ec[31] &= 127;
|
||||
ec[31] |= 64;
|
||||
|
||||
expand_raw256_modm(s, ec);
|
||||
|
||||
/* scalar * basepoint */
|
||||
ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
|
||||
|
||||
/* u = (y + z) / (z - y) */
|
||||
curve25519_add(yplusz, p.y, p.z);
|
||||
curve25519_sub(zminusy, p.z, p.y);
|
||||
curve25519_recip(zminusy, zminusy);
|
||||
curve25519_mul(yplusz, yplusz, zminusy);
|
||||
curve25519_contract(pk, yplusz);
|
||||
}
|
||||
|
||||
30
external/ed25519-donna/ed25519.h
vendored
30
external/ed25519-donna/ed25519.h
vendored
@@ -1,30 +0,0 @@
|
||||
#ifndef ED25519_H
|
||||
#define ED25519_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned char ed25519_signature[64];
|
||||
typedef unsigned char ed25519_public_key[32];
|
||||
typedef unsigned char ed25519_secret_key[32];
|
||||
|
||||
typedef unsigned char curved25519_key[32];
|
||||
|
||||
void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk);
|
||||
int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS);
|
||||
void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS);
|
||||
|
||||
int ed25519_sign_open_batch(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid);
|
||||
|
||||
void ed25519_randombytes_unsafe(void *out, size_t count);
|
||||
|
||||
void curved25519_scalarmult_basepoint(curved25519_key pk, const curved25519_key e);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ED25519_H
|
||||
173
external/ed25519-donna/fuzz/README.md
vendored
173
external/ed25519-donna/fuzz/README.md
vendored
@@ -1,173 +0,0 @@
|
||||
This code fuzzes ed25519-donna (and optionally ed25519-donna-sse2) against the ref10 implementations of
|
||||
[curve25519](https://github.com/floodyberry/supercop/tree/master/crypto_scalarmult/curve25519/ref10) and
|
||||
[ed25519](https://github.com/floodyberry/supercop/tree/master/crypto_sign/ed25519/ref10).
|
||||
|
||||
Curve25519 tests that generating a public key from a secret key
|
||||
|
||||
# Building
|
||||
|
||||
## *nix + PHP
|
||||
|
||||
`php build-nix.php (required parameters) (optional parameters)`
|
||||
|
||||
Required parameters:
|
||||
|
||||
* `--function=[curve25519,ed25519]`
|
||||
* `--bits=[32,64]`
|
||||
|
||||
Optional parameters:
|
||||
|
||||
* `--with-sse2`
|
||||
|
||||
Also fuzz against ed25519-donna-sse2
|
||||
* `--with-openssl`
|
||||
|
||||
Build with OpenSSL's SHA-512.
|
||||
|
||||
Default: Reference SHA-512 implementation (slow!)
|
||||
|
||||
* `--compiler=[gcc,clang,icc]`
|
||||
|
||||
Default: gcc
|
||||
|
||||
* `--no-asm`
|
||||
|
||||
Do not use platform specific assembler
|
||||
|
||||
|
||||
example:
|
||||
|
||||
php build-nix.php --bits=64 --function=ed25519 --with-sse2 --compiler=icc
|
||||
|
||||
## Windows
|
||||
|
||||
Create a project with access to the ed25519 files.
|
||||
|
||||
If you are not using OpenSSL, add the `ED25519_REFHASH` define to the projects
|
||||
"Properties/Preprocessor/Preprocessor Definitions" option
|
||||
|
||||
Add the following files to the project:
|
||||
|
||||
* `fuzz/curve25519-ref10.c`
|
||||
* `fuzz/ed25519-ref10.c`
|
||||
* `fuzz/ed25519-donna.c`
|
||||
* `fuzz/ed25519-donna-sse2.c` (optional)
|
||||
* `fuzz-[curve25519/ed25519].c` (depending on which you want to fuzz)
|
||||
|
||||
If you are also fuzzing against ed25519-donna-sse2, add the `ED25519_SSE2` define for `fuzz-[curve25519/ed25519].c` under
|
||||
its "Properties/Preprocessor/Preprocessor Definitions" option.
|
||||
|
||||
# Running
|
||||
|
||||
If everything agrees, the program will only output occasional status dots (every 0x1000 passes)
|
||||
and a 64bit progress count (every 0x20000 passes):
|
||||
|
||||
fuzzing: ref10 curved25519 curved25519-sse2
|
||||
|
||||
................................ [0000000000020000]
|
||||
................................ [0000000000040000]
|
||||
................................ [0000000000060000]
|
||||
................................ [0000000000080000]
|
||||
................................ [00000000000a0000]
|
||||
................................ [00000000000c0000]
|
||||
|
||||
If any of the implementations do not agree with the ref10 implementation, the program will dump
|
||||
the random data that was used, the data generated by the ref10 implementation, and diffs of the
|
||||
ed25519-donna data against the ref10 data.
|
||||
|
||||
## Example errors
|
||||
|
||||
These are example error dumps (with intentionally introduced errors).
|
||||
|
||||
### Ed25519
|
||||
|
||||
Random data:
|
||||
|
||||
* sk, or Secret Key
|
||||
* m, or Message
|
||||
|
||||
Generated data:
|
||||
|
||||
* pk, or Public Key
|
||||
* sig, or Signature
|
||||
* valid, or if the signature of the message is valid with the public key
|
||||
|
||||
Dump:
|
||||
|
||||
sk:
|
||||
0x3b,0xb7,0x17,0x7a,0x66,0xdc,0xb7,0x9a,0x90,0x25,0x07,0x99,0x96,0xf3,0x92,0xef,
|
||||
0x78,0xf8,0xad,0x6c,0x35,0x87,0x81,0x67,0x03,0xe6,0x95,0xba,0x06,0x18,0x7c,0x9c,
|
||||
|
||||
m:
|
||||
0x7c,0x8d,0x3d,0xe1,0x92,0xee,0x7a,0xb8,0x4d,0xc9,0xfb,0x02,0x34,0x1e,0x5a,0x91,
|
||||
0xee,0x01,0xa6,0xb8,0xab,0x37,0x3f,0x3d,0x6d,0xa2,0x47,0xe3,0x27,0x93,0x7c,0xb7,
|
||||
0x77,0x07,0xb6,0x88,0x41,0x22,0xf3,0x3f,0xce,0xcb,0x6b,0x3e,0x2b,0x23,0x68,0x7f,
|
||||
0x5b,0xb9,0xda,0x04,0xbb,0xae,0x42,0x50,0xf5,0xe9,0xc5,0x11,0xbd,0x52,0x76,0x98,
|
||||
0xf1,0x87,0x09,0xb9,0x89,0x0a,0x52,0x69,0x01,0xce,0xe0,0x4a,0xa6,0x46,0x5a,0xe1,
|
||||
0x63,0x14,0xe0,0x81,0x52,0xec,0xcd,0xcf,0x70,0x54,0x7d,0xa3,0x49,0x8b,0xf0,0x89,
|
||||
0x70,0x07,0x12,0x2a,0xd9,0xaa,0x16,0x01,0xb2,0x16,0x3a,0xbb,0xfc,0xfa,0x13,0x5b,
|
||||
0x69,0x83,0x92,0x70,0x95,0x76,0xa0,0x8e,0x16,0x79,0xcc,0xaa,0xb5,0x7c,0xf8,0x7a,
|
||||
|
||||
ref10:
|
||||
pk:
|
||||
0x71,0xb0,0x5e,0x62,0x1b,0xe3,0xe7,0x36,0x91,0x8b,0xc0,0x13,0x36,0x0c,0xc9,0x04,
|
||||
0x16,0xf5,0xff,0x48,0x0c,0x83,0x6b,0x88,0x53,0xa2,0xc6,0x0f,0xf7,0xac,0x42,0x04,
|
||||
|
||||
sig:
|
||||
0x3e,0x05,0xc5,0x37,0x16,0x0b,0x29,0x30,0x89,0xa3,0xe7,0x83,0x08,0x16,0xdd,0x96,
|
||||
0x02,0xfa,0x0d,0x44,0x2c,0x43,0xaa,0x80,0x93,0x04,0x58,0x22,0x09,0xbf,0x11,0xa5,
|
||||
0xcc,0xa5,0x3c,0x9f,0xa0,0xa4,0x64,0x5a,0x4a,0xdb,0x20,0xfb,0xc7,0x9b,0xfd,0x3f,
|
||||
0x08,0xae,0xc4,0x3c,0x1e,0xd8,0xb6,0xb4,0xd2,0x6d,0x80,0x92,0xcb,0x71,0xf3,0x02,
|
||||
|
||||
valid: yes
|
||||
|
||||
ed25519-donna:
|
||||
pk diff:
|
||||
____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
|
||||
____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
|
||||
|
||||
sig diff:
|
||||
0x2c,0xb9,0x25,0x14,0xd0,0x94,0xeb,0xfe,0x46,0x02,0xc2,0xe8,0xa3,0xeb,0xbf,0xb5,
|
||||
0x72,0x84,0xbf,0xc1,0x8a,0x32,0x30,0x99,0xf7,0x58,0xfe,0x06,0xa8,0xdc,0xdc,0xab,
|
||||
0xb5,0x57,0x03,0x33,0x87,0xce,0x54,0x55,0x6a,0x69,0x8a,0xc4,0xb7,0x2a,0xed,0x97,
|
||||
0xb4,0x68,0xe7,0x52,0x7a,0x07,0x55,0x3b,0xa2,0x94,0xd6,0x5e,0xa1,0x61,0x80,0x08,
|
||||
|
||||
valid: no
|
||||
|
||||
In this case, the generated public key matches, but the generated signature is completely
|
||||
different and does not validate.
|
||||
|
||||
### Curve25519
|
||||
|
||||
Random data:
|
||||
|
||||
* sk, or Secret Key
|
||||
|
||||
Generated data:
|
||||
|
||||
* pk, or Public Key
|
||||
|
||||
Dump:
|
||||
|
||||
sk:
|
||||
0x44,0xec,0x0b,0x0e,0xa2,0x0e,0x9c,0x5b,0x8c,0xce,0x7b,0x1d,0x68,0xae,0x0f,0x9e,
|
||||
0x81,0xe2,0x04,0x76,0xda,0x87,0xa4,0x9e,0xc9,0x4f,0x3b,0xf9,0xc3,0x89,0x63,0x70,
|
||||
|
||||
|
||||
ref10:
|
||||
0x24,0x55,0x55,0xc0,0xf9,0x80,0xaf,0x02,0x43,0xee,0x8c,0x7f,0xc1,0xad,0x90,0x95,
|
||||
0x57,0x91,0x14,0x2e,0xf2,0x14,0x22,0x80,0xdd,0x4e,0x3c,0x85,0x71,0x84,0x8c,0x62,
|
||||
|
||||
|
||||
curved25519 diff:
|
||||
0x12,0xd1,0x61,0x2b,0x16,0xb3,0xd8,0x29,0xf8,0xa3,0xba,0x70,0x4e,0x49,0x4f,0x43,
|
||||
0xa1,0x3c,0x6b,0x42,0x11,0x61,0xcc,0x30,0x87,0x73,0x46,0xfb,0x85,0xc7,0x9a,0x35,
|
||||
|
||||
|
||||
curved25519-sse2 diff:
|
||||
____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
|
||||
____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,
|
||||
|
||||
|
||||
In this case, curved25519 is totally wrong, while curved25519-sse2 matches the reference
|
||||
implementation.
|
||||
134
external/ed25519-donna/fuzz/build-nix.php
vendored
134
external/ed25519-donna/fuzz/build-nix.php
vendored
@@ -1,134 +0,0 @@
|
||||
<?php
|
||||
function echoln($str) {
|
||||
echo $str;
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function usage($reason) {
|
||||
echoln("Usage: php build-nix.php [flags]");
|
||||
echoln("Flags in parantheses are optional");
|
||||
echoln("");
|
||||
echoln(" --bits=[32,64]");
|
||||
echoln(" --function=[curve25519,ed25519]");
|
||||
echoln(" (--compiler=[*gcc,clang,icc]) which compiler to use, gcc is default");
|
||||
echoln(" (--with-openssl) use openssl for SHA512");
|
||||
echoln(" (--with-sse2) additionally fuzz against SSE2");
|
||||
echoln(" (--no-asm) don't use platform specific asm");
|
||||
echoln("");
|
||||
if ($reason)
|
||||
echoln($reason);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
system("rm -f *.o");
|
||||
}
|
||||
|
||||
function runcmd($desc, $cmd) {
|
||||
echoln($desc);
|
||||
|
||||
$ret = 0;
|
||||
system($cmd, $ret);
|
||||
if ($ret) {
|
||||
cleanup();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
class argument {
|
||||
var $set, $value;
|
||||
}
|
||||
|
||||
class multiargument extends argument {
|
||||
function multiargument($flag, $legal_values) {
|
||||
global $argc, $argv;
|
||||
|
||||
$this->set = false;
|
||||
|
||||
$map = array();
|
||||
foreach($legal_values as $value)
|
||||
$map[$value] = true;
|
||||
|
||||
for ($i = 1; $i < $argc; $i++) {
|
||||
if (!preg_match("!--".$flag."=(.*)!", $argv[$i], $m))
|
||||
continue;
|
||||
if (isset($map[$m[1]])) {
|
||||
$this->value = $m[1];
|
||||
$this->set = true;
|
||||
return;
|
||||
} else {
|
||||
usage("{$m[1]} is not a valid parameter to --{$flag}!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class flag extends argument {
|
||||
function flag($flag) {
|
||||
global $argc, $argv;
|
||||
|
||||
$this->set = false;
|
||||
|
||||
$flag = "--{$flag}";
|
||||
for ($i = 1; $i < $argc; $i++) {
|
||||
if ($argv[$i] !== $flag)
|
||||
continue;
|
||||
$this->value = true;
|
||||
$this->set = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bits = new multiargument("bits", array("32", "64"));
|
||||
$function = new multiargument("function", array("curve25519", "ed25519"));
|
||||
$compiler = new multiargument("compiler", array("gcc", "clang", "icc"));
|
||||
$with_sse2 = new flag("with-sse2");
|
||||
$with_openssl = new flag("with-openssl");
|
||||
$no_asm = new flag("no-asm");
|
||||
|
||||
$err = "";
|
||||
if (!$bits->set)
|
||||
$err .= "--bits not set\n";
|
||||
if (!$function->set)
|
||||
$err .= "--function not set\n";
|
||||
|
||||
if ($err !== "") {
|
||||
usage($err);
|
||||
exit;
|
||||
}
|
||||
|
||||
$compile = ($compiler->set) ? $compiler->value : "gcc";
|
||||
$link = "";
|
||||
$flags = "-O3 -m{$bits->value}";
|
||||
$ret = 0;
|
||||
|
||||
if ($with_openssl->set) $link .= " -lssl -lcrypto";
|
||||
if (!$with_openssl->set) $flags .= " -DED25519_REFHASH -DED25519_TEST";
|
||||
if ($no_asm->set) $flags .= " -DED25519_NO_INLINE_ASM";
|
||||
|
||||
if ($function->value === "curve25519") {
|
||||
runcmd("building ref10..", "{$compile} {$flags} curve25519-ref10.c -c -o curve25519-ref10.o");
|
||||
runcmd("building ed25519..", "{$compile} {$flags} ed25519-donna.c -c -o ed25519.o");
|
||||
if ($with_sse2->set) {
|
||||
runcmd("building ed25519-sse2..", "{$compile} {$flags} ed25519-donna-sse2.c -c -o ed25519-sse2.o -msse2");
|
||||
$flags .= " -DED25519_SSE2";
|
||||
$link .= " ed25519-sse2.o";
|
||||
}
|
||||
runcmd("linking..", "{$compile} {$flags} {$link} fuzz-curve25519.c ed25519.o curve25519-ref10.o -o fuzz-curve25519");
|
||||
echoln("fuzz-curve25519 built.");
|
||||
} else if ($function->value === "ed25519") {
|
||||
runcmd("building ref10..", "{$compile} {$flags} ed25519-ref10.c -c -o ed25519-ref10.o");
|
||||
runcmd("building ed25519..", "{$compile} {$flags} ed25519-donna.c -c -o ed25519.o");
|
||||
if ($with_sse2->set) {
|
||||
runcmd("building ed25519-sse2..", "{$compile} {$flags} ed25519-donna-sse2.c -c -o ed25519-sse2.o -msse2");
|
||||
$flags .= " -DED25519_SSE2";
|
||||
$link .= " ed25519-sse2.o";
|
||||
}
|
||||
runcmd("linking..", "{$compile} {$flags} {$link} fuzz-ed25519.c ed25519.o ed25519-ref10.o -o fuzz-ed25519");
|
||||
echoln("fuzz-ed25519 built.");
|
||||
}
|
||||
|
||||
|
||||
cleanup();
|
||||
?>
|
||||
1272
external/ed25519-donna/fuzz/curve25519-ref10.c
vendored
1272
external/ed25519-donna/fuzz/curve25519-ref10.c
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
||||
#ifndef CURVE25519_REF10_H
|
||||
#define CURVE25519_REF10_H
|
||||
|
||||
int crypto_scalarmult_base_ref10(unsigned char *q,const unsigned char *n);
|
||||
int crypto_scalarmult_ref10(unsigned char *q, const unsigned char *n, const unsigned char *p);
|
||||
|
||||
#endif /* CURVE25519_REF10_H */
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#define ED25519_SUFFIX _sse2
|
||||
#define ED25519_SSE2
|
||||
#include "../ed25519.c"
|
||||
1
external/ed25519-donna/fuzz/ed25519-donna.c
vendored
1
external/ed25519-donna/fuzz/ed25519-donna.c
vendored
@@ -1 +0,0 @@
|
||||
#include "../ed25519.c"
|
||||
34
external/ed25519-donna/fuzz/ed25519-donna.h
vendored
34
external/ed25519-donna/fuzz/ed25519-donna.h
vendored
@@ -1,34 +0,0 @@
|
||||
#ifndef ED25519_H
|
||||
#define ED25519_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char ed25519_signature[64];
|
||||
typedef unsigned char ed25519_public_key[32];
|
||||
typedef unsigned char ed25519_secret_key[32];
|
||||
|
||||
typedef unsigned char curved25519_key[32];
|
||||
|
||||
void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk);
|
||||
int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS);
|
||||
void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS);
|
||||
|
||||
int ed25519_sign_open_batch(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid);
|
||||
|
||||
void ed25519_randombytes_unsafe(void *out, size_t count);
|
||||
|
||||
void curved25519_scalarmult_basepoint(curved25519_key pk, const curved25519_key e);
|
||||
|
||||
#if defined(ED25519_SSE2)
|
||||
void ed25519_publickey_sse2(const ed25519_secret_key sk, ed25519_public_key pk);
|
||||
int ed25519_sign_open_sse2(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS);
|
||||
void ed25519_sign_sse2(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS);
|
||||
|
||||
int ed25519_sign_open_batch_sse2(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid);
|
||||
|
||||
void ed25519_randombytes_unsafe_sse2(void *out, size_t count);
|
||||
|
||||
void curved25519_scalarmult_basepoint_sse2(curved25519_key pk, const curved25519_key e);
|
||||
#endif
|
||||
|
||||
#endif // ED25519_H
|
||||
4647
external/ed25519-donna/fuzz/ed25519-ref10.c
vendored
4647
external/ed25519-donna/fuzz/ed25519-ref10.c
vendored
File diff suppressed because it is too large
Load Diff
9
external/ed25519-donna/fuzz/ed25519-ref10.h
vendored
9
external/ed25519-donna/fuzz/ed25519-ref10.h
vendored
@@ -1,9 +0,0 @@
|
||||
#ifndef ED25519_REF10_H
|
||||
#define ED25519_REF10_H
|
||||
|
||||
int crypto_sign_pk_ref10(unsigned char *pk,unsigned char *sk);
|
||||
int crypto_sign_ref10(unsigned char *sm,unsigned long long *smlen,const unsigned char *m,unsigned long long mlen,const unsigned char *sk);
|
||||
int crypto_sign_open_ref10(unsigned char *m,unsigned long long *mlen,const unsigned char *sm,unsigned long long smlen,const unsigned char *pk);
|
||||
|
||||
#endif /* ED25519_REF10_H */
|
||||
|
||||
172
external/ed25519-donna/fuzz/fuzz-curve25519.c
vendored
172
external/ed25519-donna/fuzz/fuzz-curve25519.c
vendored
@@ -1,172 +0,0 @@
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ed25519-donna.h"
|
||||
#include "curve25519-ref10.h"
|
||||
|
||||
static void
|
||||
print_diff(const char *desc, const unsigned char *a, const unsigned char *b, size_t len) {
|
||||
size_t p = 0;
|
||||
unsigned char diff;
|
||||
printf("%s diff:\n", desc);
|
||||
while (len--) {
|
||||
diff = *a++ ^ *b++;
|
||||
if (!diff)
|
||||
printf("____,");
|
||||
else
|
||||
printf("0x%02x,", diff);
|
||||
if ((++p & 15) == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_bytes(const char *desc, const unsigned char *bytes, size_t len) {
|
||||
size_t p = 0;
|
||||
printf("%s:\n", desc);
|
||||
while (len--) {
|
||||
printf("0x%02x,", *bytes++);
|
||||
if ((++p & 15) == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
||||
/* chacha20/12 prng */
|
||||
void
|
||||
prng(unsigned char *out, size_t bytes) {
|
||||
static uint32_t state[16];
|
||||
static int init = 0;
|
||||
uint32_t x[16], t;
|
||||
size_t i;
|
||||
|
||||
if (!init) {
|
||||
#if defined(_WIN32)
|
||||
HCRYPTPROV csp;
|
||||
if (!CryptAcquireContext(&csp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
printf("CryptAcquireContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!CryptGenRandom(csp, (DWORD)sizeof(state), (BYTE*)state)) {
|
||||
printf("CryptGenRandom failed\n");
|
||||
exit(1);
|
||||
}
|
||||
CryptReleaseContext(csp, 0);
|
||||
#else
|
||||
FILE *f = NULL;
|
||||
f = fopen("/dev/urandom", "rb");
|
||||
if (!f) {
|
||||
printf("failed to open /dev/urandom\n");
|
||||
exit(1);
|
||||
}
|
||||
if (fread(state, sizeof(state), 1, f) != 1) {
|
||||
printf("read error on /dev/urandom\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
init = 1;
|
||||
}
|
||||
|
||||
while (bytes) {
|
||||
for (i = 0; i < 16; i++) x[i] = state[i];
|
||||
|
||||
#define rotl32(x,k) ((x << k) | (x >> (32 - k)))
|
||||
#define quarter(a,b,c,d) \
|
||||
x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t,16); \
|
||||
x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t,12); \
|
||||
x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t, 8); \
|
||||
x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t, 7);
|
||||
|
||||
for (i = 0; i < 12; i += 2) {
|
||||
quarter( 0, 4, 8,12)
|
||||
quarter( 1, 5, 9,13)
|
||||
quarter( 2, 6,10,14)
|
||||
quarter( 3, 7,11,15)
|
||||
quarter( 0, 5,10,15)
|
||||
quarter( 1, 6,11,12)
|
||||
quarter( 2, 7, 8,13)
|
||||
quarter( 3, 4, 9,14)
|
||||
};
|
||||
|
||||
if (bytes <= 64) {
|
||||
memcpy(out, x, bytes);
|
||||
bytes = 0;
|
||||
} else {
|
||||
memcpy(out, x, 64);
|
||||
bytes -= 64;
|
||||
out += 64;
|
||||
}
|
||||
|
||||
/* don't need a nonce, so last 4 words are the counter. 2^136 bytes can be generated */
|
||||
if (!++state[12]) if (!++state[13]) if (!++state[14]) ++state[15];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
const size_t skmax = 1024;
|
||||
static unsigned char sk[1024][32];
|
||||
unsigned char pk[3][32];
|
||||
unsigned char *skp;
|
||||
size_t ski, pki, i;
|
||||
uint64_t ctr;
|
||||
|
||||
printf("fuzzing: ");
|
||||
printf(" ref10");
|
||||
printf(" curved25519");
|
||||
#if defined(ED25519_SSE2)
|
||||
printf(" curved25519-sse2");
|
||||
#endif
|
||||
printf("\n\n");
|
||||
|
||||
for (ctr = 0, ski = skmax;;ctr++) {
|
||||
if (ski == skmax) {
|
||||
prng((unsigned char *)sk, sizeof(sk));
|
||||
ski = 0;
|
||||
}
|
||||
skp = sk[ski++];
|
||||
|
||||
pki = 0;
|
||||
crypto_scalarmult_base_ref10(pk[pki++], skp);
|
||||
curved25519_scalarmult_basepoint(pk[pki++], skp);
|
||||
#if defined(ED25519_SSE2)
|
||||
curved25519_scalarmult_basepoint_sse2(pk[pki++], skp);
|
||||
#endif
|
||||
|
||||
for (i = 1; i < pki; i++) {
|
||||
if (memcmp(pk[0], pk[i], 32) != 0) {
|
||||
printf("\n\n");
|
||||
print_bytes("sk", skp, 32);
|
||||
print_bytes("ref10", pk[0], 32);
|
||||
print_diff("curved25519", pk[0], pk[1], 32);
|
||||
#if defined(ED25519_SSE2)
|
||||
print_diff("curved25519-sse2", pk[0], pk[2], 32);
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctr && (ctr % 0x1000 == 0)) {
|
||||
printf(".");
|
||||
if ((ctr % 0x20000) == 0) {
|
||||
printf(" [");
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%02x", (unsigned char)(ctr >> ((7 - i) * 8)));
|
||||
printf("]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
219
external/ed25519-donna/fuzz/fuzz-ed25519.c
vendored
219
external/ed25519-donna/fuzz/fuzz-ed25519.c
vendored
@@ -1,219 +0,0 @@
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ed25519-donna.h"
|
||||
#include "ed25519-ref10.h"
|
||||
|
||||
static void
|
||||
print_diff(const char *desc, const unsigned char *a, const unsigned char *b, size_t len) {
|
||||
size_t p = 0;
|
||||
unsigned char diff;
|
||||
printf("%s diff:\n", desc);
|
||||
while (len--) {
|
||||
diff = *a++ ^ *b++;
|
||||
if (!diff)
|
||||
printf("____,");
|
||||
else
|
||||
printf("0x%02x,", diff);
|
||||
if ((++p & 15) == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_bytes(const char *desc, const unsigned char *bytes, size_t len) {
|
||||
size_t p = 0;
|
||||
printf("%s:\n", desc);
|
||||
while (len--) {
|
||||
printf("0x%02x,", *bytes++);
|
||||
if ((++p & 15) == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/* chacha20/12 prng */
|
||||
void
|
||||
prng(unsigned char *out, size_t bytes) {
|
||||
static uint32_t state[16];
|
||||
static int init = 0;
|
||||
uint32_t x[16], t;
|
||||
size_t i;
|
||||
|
||||
if (!init) {
|
||||
#if defined(_WIN32)
|
||||
HCRYPTPROV csp = NULL;
|
||||
if (!CryptAcquireContext(&csp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
printf("CryptAcquireContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!CryptGenRandom(csp, (DWORD)sizeof(state), (BYTE*)state)) {
|
||||
printf("CryptGenRandom failed\n");
|
||||
exit(1);
|
||||
}
|
||||
CryptReleaseContext(csp, 0);
|
||||
#else
|
||||
FILE *f = NULL;
|
||||
f = fopen("/dev/urandom", "rb");
|
||||
if (!f) {
|
||||
printf("failed to open /dev/urandom\n");
|
||||
exit(1);
|
||||
}
|
||||
if (fread(state, sizeof(state), 1, f) != 1) {
|
||||
printf("read error on /dev/urandom\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
init = 1;
|
||||
}
|
||||
|
||||
while (bytes) {
|
||||
for (i = 0; i < 16; i++) x[i] = state[i];
|
||||
|
||||
#define rotl32(x,k) ((x << k) | (x >> (32 - k)))
|
||||
#define quarter(a,b,c,d) \
|
||||
x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t,16); \
|
||||
x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t,12); \
|
||||
x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t, 8); \
|
||||
x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t, 7);
|
||||
|
||||
for (i = 0; i < 12; i += 2) {
|
||||
quarter( 0, 4, 8,12)
|
||||
quarter( 1, 5, 9,13)
|
||||
quarter( 2, 6,10,14)
|
||||
quarter( 3, 7,11,15)
|
||||
quarter( 0, 5,10,15)
|
||||
quarter( 1, 6,11,12)
|
||||
quarter( 2, 7, 8,13)
|
||||
quarter( 3, 4, 9,14)
|
||||
};
|
||||
|
||||
if (bytes <= 64) {
|
||||
memcpy(out, x, bytes);
|
||||
bytes = 0;
|
||||
} else {
|
||||
memcpy(out, x, 64);
|
||||
bytes -= 64;
|
||||
out += 64;
|
||||
}
|
||||
|
||||
/* don't need a nonce, so last 4 words are the counter. 2^136 bytes can be generated */
|
||||
if (!++state[12]) if (!++state[13]) if (!++state[14]) ++state[15];
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct random_data_t {
|
||||
unsigned char sk[32];
|
||||
unsigned char m[128];
|
||||
} random_data;
|
||||
|
||||
typedef struct generated_data_t {
|
||||
unsigned char pk[32];
|
||||
unsigned char sig[64];
|
||||
int valid;
|
||||
} generated_data;
|
||||
|
||||
static void
|
||||
print_generated(const char *desc, generated_data *g) {
|
||||
printf("%s:\n", desc);
|
||||
print_bytes("pk", g->pk, 32);
|
||||
print_bytes("sig", g->sig, 64);
|
||||
printf("valid: %s\n\n", g->valid ? "no" : "yes");
|
||||
}
|
||||
|
||||
static void
|
||||
print_generated_diff(const char *desc, const generated_data *base, generated_data *g) {
|
||||
printf("%s:\n", desc);
|
||||
print_diff("pk", base->pk, g->pk, 32);
|
||||
print_diff("sig", base->sig, g->sig, 64);
|
||||
printf("valid: %s\n\n", (base->valid == g->valid) ? "___" : (g->valid ? "no" : "yes"));
|
||||
}
|
||||
|
||||
int main() {
|
||||
const size_t rndmax = 128;
|
||||
static random_data rnd[128];
|
||||
static generated_data gen[3];
|
||||
random_data *r;
|
||||
generated_data *g;
|
||||
unsigned long long dummylen;
|
||||
unsigned char dummysk[64];
|
||||
unsigned char dummymsg[2][128+64];
|
||||
size_t rndi, geni, i, j;
|
||||
uint64_t ctr;
|
||||
|
||||
printf("fuzzing: ");
|
||||
printf(" ref10");
|
||||
printf(" ed25519-donna");
|
||||
#if defined(ED25519_SSE2)
|
||||
printf(" ed25519-donna-sse2");
|
||||
#endif
|
||||
printf("\n\n");
|
||||
|
||||
for (ctr = 0, rndi = rndmax;;ctr++) {
|
||||
if (rndi == rndmax) {
|
||||
prng((unsigned char *)rnd, sizeof(rnd));
|
||||
rndi = 0;
|
||||
}
|
||||
r = &rnd[rndi++];
|
||||
|
||||
/* ref10, lots of horrible gymnastics to work around the wonky api */
|
||||
geni = 0;
|
||||
g = &gen[geni++];
|
||||
memcpy(dummysk, r->sk, 32); /* pk is appended to the sk, need to copy the sk to a larger buffer */
|
||||
crypto_sign_pk_ref10(dummysk + 32, dummysk);
|
||||
memcpy(g->pk, dummysk + 32, 32);
|
||||
crypto_sign_ref10(dummymsg[0], &dummylen, r->m, 128, dummysk);
|
||||
memcpy(g->sig, dummymsg[0], 64); /* sig is placed in front of the signed message */
|
||||
g->valid = crypto_sign_open_ref10(dummymsg[1], &dummylen, dummymsg[0], 128 + 64, g->pk);
|
||||
|
||||
/* ed25519-donna */
|
||||
g = &gen[geni++];
|
||||
ed25519_publickey(r->sk, g->pk);
|
||||
ed25519_sign(r->m, 128, r->sk, g->pk, g->sig);
|
||||
g->valid = ed25519_sign_open(r->m, 128, g->pk, g->sig);
|
||||
|
||||
#if defined(ED25519_SSE2)
|
||||
/* ed25519-donna-sse2 */
|
||||
g = &gen[geni++];
|
||||
ed25519_publickey_sse2(r->sk, g->pk);
|
||||
ed25519_sign_sse2(r->m, 128, r->sk, g->pk, g->sig);
|
||||
g->valid = ed25519_sign_open_sse2(r->m, 128, g->pk, g->sig);
|
||||
#endif
|
||||
|
||||
/* compare implementations 1..geni against the reference */
|
||||
for (i = 1; i < geni; i++) {
|
||||
if (memcmp(&gen[0], &gen[i], sizeof(generated_data)) != 0) {
|
||||
printf("\n\n");
|
||||
print_bytes("sk", r->sk, 32);
|
||||
print_bytes("m", r->m, 128);
|
||||
print_generated("ref10", &gen[0]);
|
||||
print_generated_diff("ed25519-donna", &gen[0], &gen[1]);
|
||||
#if defined(ED25519_SSE2)
|
||||
print_generated_diff("ed25519-donna-sse2", &gen[0], &gen[2]);
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* print out status */
|
||||
if (ctr && (ctr % 0x1000 == 0)) {
|
||||
printf(".");
|
||||
if ((ctr % 0x20000) == 0) {
|
||||
printf(" [");
|
||||
for (i = 0; i < 8; i++)
|
||||
printf("%02x", (unsigned char)(ctr >> ((7 - i) * 8)));
|
||||
printf("]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
469
external/ed25519-donna/modm-donna-32bit.h
vendored
469
external/ed25519-donna/modm-donna-32bit.h
vendored
@@ -1,469 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989
|
||||
|
||||
k = 32
|
||||
b = 1 << 8 = 256
|
||||
m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
||||
mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b
|
||||
*/
|
||||
|
||||
#define bignum256modm_bits_per_limb 30
|
||||
#define bignum256modm_limb_size 9
|
||||
|
||||
typedef uint32_t bignum256modm_element_t;
|
||||
typedef bignum256modm_element_t bignum256modm[9];
|
||||
|
||||
static const bignum256modm modm_m = {
|
||||
0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8,
|
||||
0x00000014, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00001000
|
||||
};
|
||||
|
||||
static const bignum256modm modm_mu = {
|
||||
0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742,
|
||||
0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x000fffff
|
||||
};
|
||||
|
||||
static bignum256modm_element_t
|
||||
lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
|
||||
return (a - b) >> 31;
|
||||
}
|
||||
|
||||
/* see HAC, Alg. 14.42 Step 4 */
|
||||
static void
|
||||
reduce256_modm(bignum256modm r) {
|
||||
bignum256modm t;
|
||||
bignum256modm_element_t b = 0, pb, mask;
|
||||
|
||||
/* t = r - m */
|
||||
pb = 0;
|
||||
pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b;
|
||||
pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16));
|
||||
|
||||
/* keep r if r was smaller than m */
|
||||
mask = b - 1;
|
||||
r[0] ^= mask & (r[0] ^ t[0]);
|
||||
r[1] ^= mask & (r[1] ^ t[1]);
|
||||
r[2] ^= mask & (r[2] ^ t[2]);
|
||||
r[3] ^= mask & (r[3] ^ t[3]);
|
||||
r[4] ^= mask & (r[4] ^ t[4]);
|
||||
r[5] ^= mask & (r[5] ^ t[5]);
|
||||
r[6] ^= mask & (r[6] ^ t[6]);
|
||||
r[7] ^= mask & (r[7] ^ t[7]);
|
||||
r[8] ^= mask & (r[8] ^ t[8]);
|
||||
}
|
||||
|
||||
/*
|
||||
Barrett reduction, see HAC, Alg. 14.42
|
||||
|
||||
Instead of passing in x, pre-process in to q1 and r1 for efficiency
|
||||
*/
|
||||
static void
|
||||
barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) {
|
||||
bignum256modm q3, r2;
|
||||
uint64_t c;
|
||||
bignum256modm_element_t f, b, pb;
|
||||
|
||||
/* q1 = x >> 248 = 264 bits = 9 30 bit elements
|
||||
q2 = mu * q1
|
||||
q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */
|
||||
c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]);
|
||||
c >>= 30;
|
||||
c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]);
|
||||
f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]);
|
||||
f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]);
|
||||
f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]);
|
||||
f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]);
|
||||
f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]);
|
||||
f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]);
|
||||
f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]);
|
||||
f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30;
|
||||
c += mul32x32_64(modm_mu[8], q1[8]);
|
||||
f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24);
|
||||
|
||||
/* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1)
|
||||
r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */
|
||||
c = mul32x32_64(modm_m[0], q3[0]);
|
||||
r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]);
|
||||
r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]);
|
||||
r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]);
|
||||
r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]);
|
||||
r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]);
|
||||
r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]);
|
||||
r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]);
|
||||
r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]);
|
||||
r2[8] = (bignum256modm_element_t)(c & 0xffffff);
|
||||
|
||||
/* r = r1 - r2
|
||||
if (r < 0) r += (1 << 264) */
|
||||
pb = 0;
|
||||
pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b;
|
||||
pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b;
|
||||
pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b;
|
||||
pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b;
|
||||
pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b;
|
||||
pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b;
|
||||
pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b;
|
||||
pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b;
|
||||
pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24));
|
||||
|
||||
reduce256_modm(r);
|
||||
reduce256_modm(r);
|
||||
}
|
||||
|
||||
/* addition modulo m */
|
||||
static void
|
||||
add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
|
||||
bignum256modm_element_t c;
|
||||
|
||||
c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30;
|
||||
c += x[8] + y[8]; r[8] = c;
|
||||
|
||||
reduce256_modm(r);
|
||||
}
|
||||
|
||||
/* multiplication modulo m */
|
||||
static void
|
||||
mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
|
||||
bignum256modm r1, q1;
|
||||
uint64_t c;
|
||||
bignum256modm_element_t f;
|
||||
|
||||
/* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1)
|
||||
q1 = x >> 248 = 264 bits = 9 30 bit elements */
|
||||
c = mul32x32_64(x[0], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30;
|
||||
c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]);
|
||||
f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]);
|
||||
f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]);
|
||||
f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]);
|
||||
f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]);
|
||||
f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]);
|
||||
f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]);
|
||||
f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]);
|
||||
f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30;
|
||||
c += mul32x32_64(x[8], y[8]);
|
||||
f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff;
|
||||
|
||||
barrett_reduce256_modm(r, q1, r1);
|
||||
}
|
||||
|
||||
static void
|
||||
expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
|
||||
unsigned char work[64] = {0};
|
||||
bignum256modm_element_t x[16];
|
||||
bignum256modm q1;
|
||||
|
||||
memcpy(work, in, len);
|
||||
x[0] = U8TO32_LE(work + 0);
|
||||
x[1] = U8TO32_LE(work + 4);
|
||||
x[2] = U8TO32_LE(work + 8);
|
||||
x[3] = U8TO32_LE(work + 12);
|
||||
x[4] = U8TO32_LE(work + 16);
|
||||
x[5] = U8TO32_LE(work + 20);
|
||||
x[6] = U8TO32_LE(work + 24);
|
||||
x[7] = U8TO32_LE(work + 28);
|
||||
x[8] = U8TO32_LE(work + 32);
|
||||
x[9] = U8TO32_LE(work + 36);
|
||||
x[10] = U8TO32_LE(work + 40);
|
||||
x[11] = U8TO32_LE(work + 44);
|
||||
x[12] = U8TO32_LE(work + 48);
|
||||
x[13] = U8TO32_LE(work + 52);
|
||||
x[14] = U8TO32_LE(work + 56);
|
||||
x[15] = U8TO32_LE(work + 60);
|
||||
|
||||
/* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */
|
||||
out[0] = ( x[0]) & 0x3fffffff;
|
||||
out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff;
|
||||
out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff;
|
||||
out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff;
|
||||
out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff;
|
||||
out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff;
|
||||
out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff;
|
||||
out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff;
|
||||
out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff;
|
||||
|
||||
/* 8*31 = 248 bits, no need to reduce */
|
||||
if (len < 32)
|
||||
return;
|
||||
|
||||
/* q1 = x >> 248 = 264 bits = 9 30 bit elements */
|
||||
q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff;
|
||||
q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff;
|
||||
q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff;
|
||||
q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff;
|
||||
q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff;
|
||||
q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff;
|
||||
q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff;
|
||||
q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff;
|
||||
q1[8] = ((x[15] >> 8) );
|
||||
|
||||
barrett_reduce256_modm(out, q1, out);
|
||||
}
|
||||
|
||||
static void
|
||||
expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
|
||||
bignum256modm_element_t x[8];
|
||||
|
||||
x[0] = U8TO32_LE(in + 0);
|
||||
x[1] = U8TO32_LE(in + 4);
|
||||
x[2] = U8TO32_LE(in + 8);
|
||||
x[3] = U8TO32_LE(in + 12);
|
||||
x[4] = U8TO32_LE(in + 16);
|
||||
x[5] = U8TO32_LE(in + 20);
|
||||
x[6] = U8TO32_LE(in + 24);
|
||||
x[7] = U8TO32_LE(in + 28);
|
||||
|
||||
out[0] = ( x[0]) & 0x3fffffff;
|
||||
out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff;
|
||||
out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff;
|
||||
out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff;
|
||||
out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff;
|
||||
out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff;
|
||||
out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff;
|
||||
out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff;
|
||||
out[8] = ((x[ 7] >> 16) ) & 0x0000ffff;
|
||||
}
|
||||
|
||||
static void
|
||||
contract256_modm(unsigned char out[32], const bignum256modm in) {
|
||||
U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30));
|
||||
U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28));
|
||||
U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26));
|
||||
U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24));
|
||||
U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22));
|
||||
U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20));
|
||||
U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18));
|
||||
U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
contract256_window4_modm(signed char r[64], const bignum256modm in) {
|
||||
char carry;
|
||||
signed char *quads = r;
|
||||
bignum256modm_element_t i, j, v;
|
||||
|
||||
for (i = 0; i < 8; i += 2) {
|
||||
v = in[i];
|
||||
for (j = 0; j < 7; j++) {
|
||||
*quads++ = (v & 15);
|
||||
v >>= 4;
|
||||
}
|
||||
v |= (in[i+1] << 2);
|
||||
for (j = 0; j < 8; j++) {
|
||||
*quads++ = (v & 15);
|
||||
v >>= 4;
|
||||
}
|
||||
}
|
||||
v = in[8];
|
||||
*quads++ = (v & 15); v >>= 4;
|
||||
*quads++ = (v & 15); v >>= 4;
|
||||
*quads++ = (v & 15); v >>= 4;
|
||||
*quads++ = (v & 15); v >>= 4;
|
||||
|
||||
/* making it signed */
|
||||
carry = 0;
|
||||
for(i = 0; i < 63; i++) {
|
||||
r[i] += carry;
|
||||
r[i+1] += (r[i] >> 4);
|
||||
r[i] &= 15;
|
||||
carry = (r[i] >> 3);
|
||||
r[i] -= (carry << 4);
|
||||
}
|
||||
r[63] += carry;
|
||||
}
|
||||
|
||||
static void
|
||||
contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
|
||||
int i,j,k,b;
|
||||
int m = (1 << (windowsize - 1)) - 1, soplen = 256;
|
||||
signed char *bits = r;
|
||||
bignum256modm_element_t v;
|
||||
|
||||
/* first put the binary expansion into r */
|
||||
for (i = 0; i < 8; i++) {
|
||||
v = s[i];
|
||||
for (j = 0; j < 30; j++, v >>= 1)
|
||||
*bits++ = (v & 1);
|
||||
}
|
||||
v = s[8];
|
||||
for (j = 0; j < 16; j++, v >>= 1)
|
||||
*bits++ = (v & 1);
|
||||
|
||||
/* Making it sliding window */
|
||||
for (j = 0; j < soplen; j++) {
|
||||
if (!r[j])
|
||||
continue;
|
||||
|
||||
for (b = 1; (b < (soplen - j)) && (b <= 6); b++) {
|
||||
if ((r[j] + (r[j + b] << b)) <= m) {
|
||||
r[j] += r[j + b] << b;
|
||||
r[j + b] = 0;
|
||||
} else if ((r[j] - (r[j + b] << b)) >= -m) {
|
||||
r[j] -= r[j + b] << b;
|
||||
for (k = j + b; k < soplen; k++) {
|
||||
if (!r[k]) {
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
r[k] = 0;
|
||||
}
|
||||
} else if (r[j + b]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
helpers for batch verifcation, are allowed to be vartime
|
||||
*/
|
||||
|
||||
/* out = a - b, a must be larger than b */
|
||||
static void
|
||||
sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
size_t i = 0;
|
||||
bignum256modm_element_t carry = 0;
|
||||
switch (limbsize) {
|
||||
case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++;
|
||||
case 0:
|
||||
default: out[i] = (a[i] - b[i]) - carry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* is a < b */
|
||||
static int
|
||||
lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
switch (limbsize) {
|
||||
case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1;
|
||||
case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1;
|
||||
case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1;
|
||||
case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1;
|
||||
case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1;
|
||||
case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1;
|
||||
case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1;
|
||||
case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1;
|
||||
case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* is a <= b */
|
||||
static int
|
||||
lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
switch (limbsize) {
|
||||
case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1;
|
||||
case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1;
|
||||
case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1;
|
||||
case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1;
|
||||
case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1;
|
||||
case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1;
|
||||
case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1;
|
||||
case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1;
|
||||
case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* is a == 0 */
|
||||
static int
|
||||
iszero256_modm_batch(const bignum256modm a) {
|
||||
size_t i;
|
||||
for (i = 0; i < 9; i++)
|
||||
if (a[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* is a == 1 */
|
||||
static int
|
||||
isone256_modm_batch(const bignum256modm a) {
|
||||
size_t i;
|
||||
if (a[0] != 1)
|
||||
return 0;
|
||||
for (i = 1; i < 9; i++)
|
||||
if (a[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* can a fit in to (at most) 128 bits */
|
||||
static int
|
||||
isatmost128bits256_modm_batch(const bignum256modm a) {
|
||||
uint32_t mask =
|
||||
((a[8] ) | /* 16 */
|
||||
(a[7] ) | /* 46 */
|
||||
(a[6] ) | /* 76 */
|
||||
(a[5] ) | /* 106 */
|
||||
(a[4] & 0x3fffff00)); /* 128 */
|
||||
|
||||
return (mask == 0);
|
||||
}
|
||||
361
external/ed25519-donna/modm-donna-64bit.h
vendored
361
external/ed25519-donna/modm-donna-64bit.h
vendored
@@ -1,361 +0,0 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989
|
||||
|
||||
k = 32
|
||||
b = 1 << 8 = 256
|
||||
m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
||||
mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b
|
||||
*/
|
||||
|
||||
#define bignum256modm_bits_per_limb 56
|
||||
#define bignum256modm_limb_size 5
|
||||
|
||||
typedef uint64_t bignum256modm_element_t;
|
||||
typedef bignum256modm_element_t bignum256modm[5];
|
||||
|
||||
static const bignum256modm modm_m = {
|
||||
0x12631a5cf5d3ed,
|
||||
0xf9dea2f79cd658,
|
||||
0x000000000014de,
|
||||
0x00000000000000,
|
||||
0x00000010000000
|
||||
};
|
||||
|
||||
static const bignum256modm modm_mu = {
|
||||
0x9ce5a30a2c131b,
|
||||
0x215d086329a7ed,
|
||||
0xffffffffeb2106,
|
||||
0xffffffffffffff,
|
||||
0x00000fffffffff
|
||||
};
|
||||
|
||||
static bignum256modm_element_t
|
||||
lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
|
||||
return (a - b) >> 63;
|
||||
}
|
||||
|
||||
static void
|
||||
reduce256_modm(bignum256modm r) {
|
||||
bignum256modm t;
|
||||
bignum256modm_element_t b = 0, pb, mask;
|
||||
|
||||
/* t = r - m */
|
||||
pb = 0;
|
||||
pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 56)); pb = b;
|
||||
pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 56)); pb = b;
|
||||
pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 56)); pb = b;
|
||||
pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 56)); pb = b;
|
||||
pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 32));
|
||||
|
||||
/* keep r if r was smaller than m */
|
||||
mask = b - 1;
|
||||
|
||||
r[0] ^= mask & (r[0] ^ t[0]);
|
||||
r[1] ^= mask & (r[1] ^ t[1]);
|
||||
r[2] ^= mask & (r[2] ^ t[2]);
|
||||
r[3] ^= mask & (r[3] ^ t[3]);
|
||||
r[4] ^= mask & (r[4] ^ t[4]);
|
||||
}
|
||||
|
||||
static void
|
||||
barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) {
|
||||
bignum256modm q3, r2;
|
||||
uint128_t c, mul;
|
||||
bignum256modm_element_t f, b, pb;
|
||||
|
||||
/* q1 = x >> 248 = 264 bits = 5 56 bit elements
|
||||
q2 = mu * q1
|
||||
q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */
|
||||
mul64x64_128(c, modm_mu[0], q1[3]) mul64x64_128(mul, modm_mu[3], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[2]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[1]) add128(c, mul) shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_mu[0], q1[4]) add128_64(c, f) mul64x64_128(mul, modm_mu[4], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[1]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[2]) add128(c, mul)
|
||||
f = lo128(c); q3[0] = (f >> 40) & 0xffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_mu[4], q1[1]) add128_64(c, f) mul64x64_128(mul, modm_mu[1], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[2]) add128(c, mul)
|
||||
f = lo128(c); q3[0] |= (f << 16) & 0xffffffffffffff; q3[1] = (f >> 40) & 0xffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_mu[4], q1[2]) add128_64(c, f) mul64x64_128(mul, modm_mu[2], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[3]) add128(c, mul)
|
||||
f = lo128(c); q3[1] |= (f << 16) & 0xffffffffffffff; q3[2] = (f >> 40) & 0xffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_mu[4], q1[3]) add128_64(c, f) mul64x64_128(mul, modm_mu[3], q1[4]) add128(c, mul)
|
||||
f = lo128(c); q3[2] |= (f << 16) & 0xffffffffffffff; q3[3] = (f >> 40) & 0xffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_mu[4], q1[4]) add128_64(c, f)
|
||||
f = lo128(c); q3[3] |= (f << 16) & 0xffffffffffffff; q3[4] = (f >> 40) & 0xffff; shr128(f, c, 56);
|
||||
q3[4] |= (f << 16);
|
||||
|
||||
mul64x64_128(c, modm_m[0], q3[0])
|
||||
r2[0] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_m[0], q3[1]) add128_64(c, f) mul64x64_128(mul, modm_m[1], q3[0]) add128(c, mul)
|
||||
r2[1] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_m[0], q3[2]) add128_64(c, f) mul64x64_128(mul, modm_m[2], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[1]) add128(c, mul)
|
||||
r2[2] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_m[0], q3[3]) add128_64(c, f) mul64x64_128(mul, modm_m[3], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[2]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[1]) add128(c, mul)
|
||||
r2[3] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, modm_m[0], q3[4]) add128_64(c, f) mul64x64_128(mul, modm_m[4], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[3], q3[1]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[3]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[2]) add128(c, mul)
|
||||
r2[4] = lo128(c) & 0x0000ffffffffff;
|
||||
|
||||
pb = 0;
|
||||
pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 56)); pb = b;
|
||||
pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 56)); pb = b;
|
||||
pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 56)); pb = b;
|
||||
pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 56)); pb = b;
|
||||
pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 40));
|
||||
|
||||
reduce256_modm(r);
|
||||
reduce256_modm(r);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
|
||||
bignum256modm_element_t c;
|
||||
|
||||
c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56;
|
||||
c += x[1] + y[1]; r[1] = c & 0xffffffffffffff; c >>= 56;
|
||||
c += x[2] + y[2]; r[2] = c & 0xffffffffffffff; c >>= 56;
|
||||
c += x[3] + y[3]; r[3] = c & 0xffffffffffffff; c >>= 56;
|
||||
c += x[4] + y[4]; r[4] = c;
|
||||
|
||||
reduce256_modm(r);
|
||||
}
|
||||
|
||||
static void
|
||||
mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
|
||||
bignum256modm q1, r1;
|
||||
uint128_t c, mul;
|
||||
bignum256modm_element_t f;
|
||||
|
||||
mul64x64_128(c, x[0], y[0])
|
||||
f = lo128(c); r1[0] = f & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[0], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[0]) add128(c, mul)
|
||||
f = lo128(c); r1[1] = f & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[0], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[1]) add128(c, mul)
|
||||
f = lo128(c); r1[2] = f & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[0], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[2]) add128(c, mul) mul64x64_128(mul, x[2], y[1]) add128(c, mul)
|
||||
f = lo128(c); r1[3] = f & 0xffffffffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[0], y[4]) add128_64(c, f) mul64x64_128(mul, x[4], y[0]) add128(c, mul) mul64x64_128(mul, x[3], y[1]) add128(c, mul) mul64x64_128(mul, x[1], y[3]) add128(c, mul) mul64x64_128(mul, x[2], y[2]) add128(c, mul)
|
||||
f = lo128(c); r1[4] = f & 0x0000ffffffffff; q1[0] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[4], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[4]) add128(c, mul) mul64x64_128(mul, x[2], y[3]) add128(c, mul) mul64x64_128(mul, x[3], y[2]) add128(c, mul)
|
||||
f = lo128(c); q1[0] |= (f << 32) & 0xffffffffffffff; q1[1] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[4], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[4]) add128(c, mul) mul64x64_128(mul, x[3], y[3]) add128(c, mul)
|
||||
f = lo128(c); q1[1] |= (f << 32) & 0xffffffffffffff; q1[2] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[4], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[4]) add128(c, mul)
|
||||
f = lo128(c); q1[2] |= (f << 32) & 0xffffffffffffff; q1[3] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
|
||||
mul64x64_128(c, x[4], y[4]) add128_64(c, f)
|
||||
f = lo128(c); q1[3] |= (f << 32) & 0xffffffffffffff; q1[4] = (f >> 24) & 0xffffffff; shr128(f, c, 56);
|
||||
q1[4] |= (f << 32);
|
||||
|
||||
barrett_reduce256_modm(r, q1, r1);
|
||||
}
|
||||
|
||||
static void
|
||||
expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
|
||||
unsigned char work[64] = {0};
|
||||
bignum256modm_element_t x[16];
|
||||
bignum256modm q1;
|
||||
|
||||
memcpy(work, in, len);
|
||||
x[0] = U8TO64_LE(work + 0);
|
||||
x[1] = U8TO64_LE(work + 8);
|
||||
x[2] = U8TO64_LE(work + 16);
|
||||
x[3] = U8TO64_LE(work + 24);
|
||||
x[4] = U8TO64_LE(work + 32);
|
||||
x[5] = U8TO64_LE(work + 40);
|
||||
x[6] = U8TO64_LE(work + 48);
|
||||
x[7] = U8TO64_LE(work + 56);
|
||||
|
||||
/* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */
|
||||
out[0] = ( x[0]) & 0xffffffffffffff;
|
||||
out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff;
|
||||
out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff;
|
||||
out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff;
|
||||
out[4] = ((x[ 3] >> 32) | (x[ 4] << 32)) & 0x0000ffffffffff;
|
||||
|
||||
/* under 252 bits, no need to reduce */
|
||||
if (len < 32)
|
||||
return;
|
||||
|
||||
/* q1 = x >> 248 = 264 bits */
|
||||
q1[0] = ((x[ 3] >> 56) | (x[ 4] << 8)) & 0xffffffffffffff;
|
||||
q1[1] = ((x[ 4] >> 48) | (x[ 5] << 16)) & 0xffffffffffffff;
|
||||
q1[2] = ((x[ 5] >> 40) | (x[ 6] << 24)) & 0xffffffffffffff;
|
||||
q1[3] = ((x[ 6] >> 32) | (x[ 7] << 32)) & 0xffffffffffffff;
|
||||
q1[4] = ((x[ 7] >> 24) );
|
||||
|
||||
barrett_reduce256_modm(out, q1, out);
|
||||
}
|
||||
|
||||
static void
|
||||
expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
|
||||
bignum256modm_element_t x[4];
|
||||
|
||||
x[0] = U8TO64_LE(in + 0);
|
||||
x[1] = U8TO64_LE(in + 8);
|
||||
x[2] = U8TO64_LE(in + 16);
|
||||
x[3] = U8TO64_LE(in + 24);
|
||||
|
||||
out[0] = ( x[0]) & 0xffffffffffffff;
|
||||
out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff;
|
||||
out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff;
|
||||
out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff;
|
||||
out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff;
|
||||
}
|
||||
|
||||
static void
|
||||
contract256_modm(unsigned char out[32], const bignum256modm in) {
|
||||
U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56));
|
||||
U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48));
|
||||
U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40));
|
||||
U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32));
|
||||
}
|
||||
|
||||
static void
|
||||
contract256_window4_modm(signed char r[64], const bignum256modm in) {
|
||||
char carry;
|
||||
signed char *quads = r;
|
||||
bignum256modm_element_t i, j, v, m;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
v = in[i];
|
||||
m = (i == 4) ? 8 : 14;
|
||||
for (j = 0; j < m; j++) {
|
||||
*quads++ = (v & 15);
|
||||
v >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* making it signed */
|
||||
carry = 0;
|
||||
for(i = 0; i < 63; i++) {
|
||||
r[i] += carry;
|
||||
r[i+1] += (r[i] >> 4);
|
||||
r[i] &= 15;
|
||||
carry = (r[i] >> 3);
|
||||
r[i] -= (carry << 4);
|
||||
}
|
||||
r[63] += carry;
|
||||
}
|
||||
|
||||
static void
|
||||
contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
|
||||
int i,j,k,b;
|
||||
int m = (1 << (windowsize - 1)) - 1, soplen = 256;
|
||||
signed char *bits = r;
|
||||
bignum256modm_element_t v;
|
||||
|
||||
/* first put the binary expansion into r */
|
||||
for (i = 0; i < 4; i++) {
|
||||
v = s[i];
|
||||
for (j = 0; j < 56; j++, v >>= 1)
|
||||
*bits++ = (v & 1);
|
||||
}
|
||||
v = s[4];
|
||||
for (j = 0; j < 32; j++, v >>= 1)
|
||||
*bits++ = (v & 1);
|
||||
|
||||
/* Making it sliding window */
|
||||
for (j = 0; j < soplen; j++) {
|
||||
if (!r[j])
|
||||
continue;
|
||||
|
||||
for (b = 1; (b < (soplen - j)) && (b <= 6); b++) {
|
||||
if ((r[j] + (r[j + b] << b)) <= m) {
|
||||
r[j] += r[j + b] << b;
|
||||
r[j + b] = 0;
|
||||
} else if ((r[j] - (r[j + b] << b)) >= -m) {
|
||||
r[j] -= r[j + b] << b;
|
||||
for (k = j + b; k < soplen; k++) {
|
||||
if (!r[k]) {
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
r[k] = 0;
|
||||
}
|
||||
} else if (r[j + b]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
helpers for batch verifcation, are allowed to be vartime
|
||||
*/
|
||||
|
||||
/* out = a - b, a must be larger than b */
|
||||
static void
|
||||
sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
size_t i = 0;
|
||||
bignum256modm_element_t carry = 0;
|
||||
switch (limbsize) {
|
||||
case 4: out[i] = (a[i] - b[i]) ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++;
|
||||
case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++;
|
||||
case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++;
|
||||
case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++;
|
||||
case 0:
|
||||
default: out[i] = (a[i] - b[i]) - carry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* is a < b */
|
||||
static int
|
||||
lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
size_t i = 0;
|
||||
bignum256modm_element_t t, carry = 0;
|
||||
switch (limbsize) {
|
||||
case 4: t = (a[i] - b[i]) ; carry = (t >> 63); i++;
|
||||
case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++;
|
||||
case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++;
|
||||
case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++;
|
||||
case 0: t = (a[i] - b[i]) - carry; carry = (t >> 63);
|
||||
}
|
||||
return (int)carry;
|
||||
}
|
||||
|
||||
/* is a <= b */
|
||||
static int
|
||||
lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
|
||||
size_t i = 0;
|
||||
bignum256modm_element_t t, carry = 0;
|
||||
switch (limbsize) {
|
||||
case 4: t = (b[i] - a[i]) ; carry = (t >> 63); i++;
|
||||
case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++;
|
||||
case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++;
|
||||
case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++;
|
||||
case 0: t = (b[i] - a[i]) - carry; carry = (t >> 63);
|
||||
}
|
||||
return (int)!carry;
|
||||
}
|
||||
|
||||
/* is a == 0 */
|
||||
static int
|
||||
iszero256_modm_batch(const bignum256modm a) {
|
||||
size_t i;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (a[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* is a == 1 */
|
||||
static int
|
||||
isone256_modm_batch(const bignum256modm a) {
|
||||
size_t i;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (a[i] != ((i) ? 0 : 1))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* can a fit in to (at most) 128 bits */
|
||||
static int
|
||||
isatmost128bits256_modm_batch(const bignum256modm a) {
|
||||
uint64_t mask =
|
||||
((a[4] ) | /* 32 */
|
||||
(a[3] ) | /* 88 */
|
||||
(a[2] & 0xffffffffff0000));
|
||||
|
||||
return (mask == 0);
|
||||
}
|
||||
1024
external/ed25519-donna/regression.h
vendored
1024
external/ed25519-donna/regression.h
vendored
File diff suppressed because it is too large
Load Diff
176
external/ed25519-donna/test-internals.c
vendored
176
external/ed25519-donna/test-internals.c
vendored
@@ -1,176 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "ed25519-donna.h"
|
||||
|
||||
static int
|
||||
test_adds() {
|
||||
#if defined(HAVE_UINT128) && !defined(ED25519_SSE2)
|
||||
/* largest result for each limb from a mult or square: all elements except r1 reduced, r1 overflowed as far as possible */
|
||||
static const bignum25519 max_bignum = {
|
||||
0x7ffffffffffff,0x8000000001230,0x7ffffffffffff,0x7ffffffffffff,0x7ffffffffffff
|
||||
};
|
||||
|
||||
/* what max_bignum should fully reduce to */
|
||||
static const unsigned char max_bignum_raw[32] = {
|
||||
0x12,0x00,0x00,0x00,0x00,0x00,0x88,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
/* (max_bignum + max_bignum)^2 */
|
||||
static const unsigned char max_bignum2_squared_raw[32] = {
|
||||
0x10,0x05,0x00,0x00,0x00,0x00,0x80,0xdc,0x51,0x00,0x00,0x00,0x00,0x61,0xed,0x4a,
|
||||
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
/* ((max_bignum + max_bignum) + max_bignum)^2 */
|
||||
static const unsigned char max_bignum3_squared_raw[32] = {
|
||||
0x64,0x0b,0x00,0x00,0x00,0x00,0x20,0x30,0xb8,0x00,0x00,0x00,0x40,0x1a,0x96,0xe8,
|
||||
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
#else
|
||||
/* largest result for each limb from a mult or square: all elements except r1 reduced, r1 overflowed as far as possible */
|
||||
static const bignum25519 ALIGN(16) max_bignum = {
|
||||
0x3ffffff,0x2000300,0x3ffffff,0x1ffffff,0x3ffffff,
|
||||
0x1ffffff,0x3ffffff,0x1ffffff,0x3ffffff,0x1ffffff
|
||||
};
|
||||
|
||||
/* what max_bignum should fully reduce to */
|
||||
static const unsigned char max_bignum2_squared_raw[32] = {
|
||||
0x10,0x05,0x00,0x40,0xc2,0x06,0x40,0x80,0x41,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
/* (max_bignum * max_bignum) */
|
||||
static const unsigned char max_bignum3_squared_raw[32] = {
|
||||
0x64,0x0b,0x00,0x10,0x35,0x0f,0x90,0x60,0x13,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
#endif
|
||||
unsigned char result[32];
|
||||
static const bignum25519 ALIGN(16) zero = {0};
|
||||
bignum25519 ALIGN(16) a, b, c;
|
||||
size_t i;
|
||||
|
||||
/* a = (max_bignum + max_bignum) */
|
||||
curve25519_add(a, max_bignum, max_bignum);
|
||||
|
||||
/* b = ((max_bignum + max_bignum) * (max_bignum + max_bignum)) */
|
||||
curve25519_mul(b, a, a);
|
||||
curve25519_contract(result, b);
|
||||
if (memcmp(result, max_bignum2_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
curve25519_square(b, a);
|
||||
curve25519_contract(result, b);
|
||||
if (memcmp(result, max_bignum2_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
/* b = (max_bignum + max_bignum + max_bignum) */
|
||||
curve25519_add_after_basic(b, a, max_bignum);
|
||||
|
||||
/* a = ((max_bignum + max_bignum + max_bignum) * (max_bignum + max_bignum + max_bignum)) */
|
||||
curve25519_mul(a, b, b);
|
||||
curve25519_contract(result, a);
|
||||
if (memcmp(result, max_bignum3_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
curve25519_square(a, b);
|
||||
curve25519_contract(result, a);
|
||||
if (memcmp(result, max_bignum3_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_subs() {
|
||||
#if defined(HAVE_UINT128) && !defined(ED25519_SSE2)
|
||||
/* largest result for each limb from a mult or square: all elements except r1 reduced, r1 overflowed as far as possible */
|
||||
static const bignum25519 max_bignum = {
|
||||
0x7ffffffffffff,0x8000000001230,0x7ffffffffffff,0x7ffffffffffff,0x7ffffffffffff
|
||||
};
|
||||
|
||||
/* what max_bignum should fully reduce to */
|
||||
static const unsigned char max_bignum_raw[32] = {
|
||||
0x12,0x00,0x00,0x00,0x00,0x00,0x88,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
/* (max_bignum * max_bignum) */
|
||||
static const unsigned char max_bignum_squared_raw[32] = {
|
||||
0x44,0x01,0x00,0x00,0x00,0x00,0x20,0x77,0x14,0x00,0x00,0x00,0x40,0x58,0xbb,0x52,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
#else
|
||||
/* largest result for each limb from a mult or square: all elements except r1 reduced, r1 overflowed as far as possible */
|
||||
static const bignum25519 ALIGN(16) max_bignum = {
|
||||
0x3ffffff,0x2000300,0x3ffffff,0x1ffffff,0x3ffffff,
|
||||
0x1ffffff,0x3ffffff,0x1ffffff,0x3ffffff,0x1ffffff
|
||||
};
|
||||
|
||||
/* what max_bignum should fully reduce to */
|
||||
static const unsigned char max_bignum_raw[32] = {
|
||||
0x12,0x00,0x00,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
/* (max_bignum * max_bignum) */
|
||||
static const unsigned char max_bignum_squared_raw[32] = {
|
||||
0x44,0x01,0x00,0x90,0xb0,0x01,0x10,0x60,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
#endif
|
||||
unsigned char result[32];
|
||||
static const bignum25519 ALIGN(16) zero = {0};
|
||||
bignum25519 ALIGN(16) a, b, c;
|
||||
size_t i;
|
||||
|
||||
/* a = max_bignum - 0, which expands to 2p + max_bignum - 0 */
|
||||
curve25519_sub(a, max_bignum, zero);
|
||||
curve25519_contract(result, a);
|
||||
if (memcmp(result, max_bignum_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
/* b = (max_bignum * max_bignum) */
|
||||
curve25519_mul(b, a, a);
|
||||
curve25519_contract(result, b);
|
||||
if (memcmp(result, max_bignum_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
curve25519_square(b, a);
|
||||
curve25519_contract(result, b);
|
||||
if (memcmp(result, max_bignum_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
/* b = ((a - 0) - 0) */
|
||||
curve25519_sub_after_basic(b, a, zero);
|
||||
curve25519_contract(result, b);
|
||||
if (memcmp(result, max_bignum_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
/* a = (max_bignum * max_bignum) */
|
||||
curve25519_mul(a, b, b);
|
||||
curve25519_contract(result, a);
|
||||
if (memcmp(result, max_bignum_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
curve25519_square(a, b);
|
||||
curve25519_contract(result, a);
|
||||
if (memcmp(result, max_bignum_squared_raw, 32) != 0)
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main() {
|
||||
int ret = 0;
|
||||
int single;
|
||||
single = test_adds();
|
||||
if (single) printf("test_adds: FAILED\n");
|
||||
ret |= single;
|
||||
single = test_subs();
|
||||
if (single) printf("test_subs: FAILED\n");
|
||||
ret |= single;
|
||||
if (!ret) printf("success\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
50
external/ed25519-donna/test-ticks.h
vendored
50
external/ed25519-donna/test-ticks.h
vendored
@@ -1,50 +0,0 @@
|
||||
#include "ed25519-donna-portable-identify.h"
|
||||
|
||||
/* ticks - not tested on anything other than x86 */
|
||||
static uint64_t
|
||||
get_ticks(void) {
|
||||
#if defined(CPU_X86) || defined(CPU_X86_64)
|
||||
#if defined(COMPILER_INTEL)
|
||||
return _rdtsc();
|
||||
#elif defined(COMPILER_MSVC)
|
||||
return __rdtsc();
|
||||
#elif defined(COMPILER_GCC)
|
||||
uint32_t lo, hi;
|
||||
__asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
|
||||
return ((uint64_t)lo | ((uint64_t)hi << 32));
|
||||
#else
|
||||
need rdtsc for this compiler
|
||||
#endif
|
||||
#elif defined(OS_SOLARIS)
|
||||
return (uint64_t)gethrtime();
|
||||
#elif defined(CPU_SPARC) && !defined(OS_OPENBSD)
|
||||
uint64_t t;
|
||||
__asm__ __volatile__("rd %%tick, %0" : "=r" (t));
|
||||
return t;
|
||||
#elif defined(CPU_PPC)
|
||||
uint32_t lo = 0, hi = 0;
|
||||
__asm__ __volatile__("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo));
|
||||
return ((uint64_t)lo | ((uint64_t)hi << 32));
|
||||
#elif defined(CPU_IA64)
|
||||
uint64_t t;
|
||||
__asm__ __volatile__("mov %0=ar.itc" : "=r" (t));
|
||||
return t;
|
||||
#elif defined(OS_NIX)
|
||||
timeval t2;
|
||||
gettimeofday(&t2, NULL);
|
||||
t = ((uint64_t)t2.tv_usec << 32) | (uint64_t)t2.tv_sec;
|
||||
return t;
|
||||
#else
|
||||
need ticks for this platform
|
||||
#endif
|
||||
}
|
||||
|
||||
#define timeit(x,minvar) \
|
||||
ticks = get_ticks(); \
|
||||
x; \
|
||||
ticks = get_ticks() - ticks; \
|
||||
if (ticks < minvar) \
|
||||
minvar = ticks;
|
||||
|
||||
#define maxticks 0xffffffffffffffffull
|
||||
|
||||
260
external/ed25519-donna/test.c
vendored
260
external/ed25519-donna/test.c
vendored
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
Validate ed25519 implementation against the official test vectors from
|
||||
http://ed25519.cr.yp.to/software.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ed25519.h"
|
||||
|
||||
#include "test-ticks.h"
|
||||
|
||||
static void
|
||||
edassert(int check, int round, const char *failreason) {
|
||||
if (check)
|
||||
return;
|
||||
printf("round %d, %s\n", round, failreason);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
edassert_die(const unsigned char *a, const unsigned char *b, size_t len, int round, const char *failreason) {
|
||||
size_t i;
|
||||
if (round > 0)
|
||||
printf("round %d, %s\n", round, failreason);
|
||||
else
|
||||
printf("%s\n", failreason);
|
||||
printf("want: "); for (i = 0; i < len; i++) printf("%02x,", a[i]); printf("\n");
|
||||
printf("got : "); for (i = 0; i < len; i++) printf("%02x,", b[i]); printf("\n");
|
||||
printf("diff: "); for (i = 0; i < len; i++) if (a[i] ^ b[i]) printf("%02x,", a[i] ^ b[i]); else printf(" ,"); printf("\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
edassert_equal(const unsigned char *a, const unsigned char *b, size_t len, const char *failreason) {
|
||||
if (memcmp(a, b, len) == 0)
|
||||
return;
|
||||
edassert_die(a, b, len, -1, failreason);
|
||||
}
|
||||
|
||||
static void
|
||||
edassert_equal_round(const unsigned char *a, const unsigned char *b, size_t len, int round, const char *failreason) {
|
||||
if (memcmp(a, b, len) == 0)
|
||||
return;
|
||||
edassert_die(a, b, len, round, failreason);
|
||||
}
|
||||
|
||||
|
||||
/* test data */
|
||||
typedef struct test_data_t {
|
||||
unsigned char sk[32], pk[32], sig[64];
|
||||
const char *m;
|
||||
} test_data;
|
||||
|
||||
|
||||
test_data dataset[] = {
|
||||
#include "regression.h"
|
||||
};
|
||||
|
||||
/* result of the curve25519 scalarmult ((|255| * basepoint) * basepoint)... 1024 times */
|
||||
const curved25519_key curved25519_expected = {
|
||||
0xac,0xce,0x24,0xb1,0xd4,0xa2,0x36,0x21,
|
||||
0x15,0xe2,0x3e,0x84,0x3c,0x23,0x2b,0x5f,
|
||||
0x95,0x6c,0xc0,0x7b,0x95,0x82,0xd7,0x93,
|
||||
0xd5,0x19,0xb6,0xf1,0xfb,0x96,0xd6,0x04
|
||||
};
|
||||
|
||||
|
||||
/* from ed25519-donna-batchverify.h */
|
||||
extern unsigned char batch_point_buffer[3][32];
|
||||
|
||||
/* y coordinate of the final point from 'amd64-51-30k' with the same random generator */
|
||||
static const unsigned char batch_verify_y[32] = {
|
||||
0x51,0xe7,0x68,0xe0,0xf7,0xa1,0x88,0x45,
|
||||
0xde,0xa1,0xcb,0xd9,0x37,0xd4,0x78,0x53,
|
||||
0x1b,0x95,0xdb,0xbe,0x66,0x59,0x29,0x3b,
|
||||
0x94,0x51,0x2f,0xbc,0x0d,0x66,0xba,0x3f
|
||||
};
|
||||
|
||||
/*
|
||||
static const unsigned char batch_verify_y[32] = {
|
||||
0x5c,0x63,0x96,0x26,0xca,0xfe,0xfd,0xc4,
|
||||
0x2d,0x11,0xa8,0xe4,0xc4,0x46,0x42,0x97,
|
||||
0x97,0x92,0xbe,0xe0,0x3c,0xef,0x96,0x01,
|
||||
0x50,0xa1,0xcc,0x8f,0x50,0x85,0x76,0x7d
|
||||
};
|
||||
|
||||
Introducing the 128 bit r scalars to the heap _before_ the largest scalar
|
||||
fits in to 128 bits alters the heap shape and produces a different,
|
||||
yet still neutral/valid y/z value.
|
||||
|
||||
This was the value of introducing the r scalars when the largest scalar fit
|
||||
in to 135-256 bits. You can produce it with amd64-64-24k / amd64-51-32k
|
||||
with the random sequence used in the first pass by changing
|
||||
|
||||
unsigned long long hlen=((npoints+1)/2)|1;
|
||||
|
||||
to
|
||||
|
||||
unsigned long long hlen=npoints;
|
||||
|
||||
in ge25519_multi_scalarmult.c
|
||||
|
||||
ed25519-donna-batchverify.h has been modified to match the
|
||||
default amd64-64-24k / amd64-51-32k behaviour
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* batch test */
|
||||
#define test_batch_count 64
|
||||
#define test_batch_rounds 96
|
||||
|
||||
typedef enum batch_test_t {
|
||||
batch_no_errors = 0,
|
||||
batch_wrong_message = 1,
|
||||
batch_wrong_pk = 2,
|
||||
batch_wrong_sig = 3
|
||||
} batch_test;
|
||||
|
||||
static int
|
||||
test_batch_instance(batch_test type, uint64_t *ticks) {
|
||||
ed25519_secret_key sks[test_batch_count];
|
||||
ed25519_public_key pks[test_batch_count];
|
||||
ed25519_signature sigs[test_batch_count];
|
||||
unsigned char messages[test_batch_count][128];
|
||||
size_t message_lengths[test_batch_count];
|
||||
const unsigned char *message_pointers[test_batch_count];
|
||||
const unsigned char *pk_pointers[test_batch_count];
|
||||
const unsigned char *sig_pointers[test_batch_count];
|
||||
int valid[test_batch_count], ret, validret;
|
||||
size_t i;
|
||||
uint64_t t;
|
||||
|
||||
/* generate keys */
|
||||
for (i = 0; i < test_batch_count; i++) {
|
||||
ed25519_randombytes_unsafe(sks[i], sizeof(sks[i]));
|
||||
ed25519_publickey(sks[i], pks[i]);
|
||||
pk_pointers[i] = pks[i];
|
||||
}
|
||||
|
||||
/* generate messages */
|
||||
ed25519_randombytes_unsafe(messages, sizeof(messages));
|
||||
for (i = 0; i < test_batch_count; i++) {
|
||||
message_pointers[i] = messages[i];
|
||||
message_lengths[i] = (i & 127) + 1;
|
||||
}
|
||||
|
||||
/* sign messages */
|
||||
for (i = 0; i < test_batch_count; i++) {
|
||||
ed25519_sign(message_pointers[i], message_lengths[i], sks[i], pks[i], sigs[i]);
|
||||
sig_pointers[i] = sigs[i];
|
||||
}
|
||||
|
||||
validret = 0;
|
||||
if (type == batch_wrong_message) {
|
||||
message_pointers[0] = message_pointers[1];
|
||||
validret = 1|2;
|
||||
} else if (type == batch_wrong_pk) {
|
||||
pk_pointers[0] = pk_pointers[1];
|
||||
validret = 1|2;
|
||||
} else if (type == batch_wrong_sig) {
|
||||
sig_pointers[0] = sig_pointers[1];
|
||||
validret = 1|2;
|
||||
}
|
||||
|
||||
/* batch verify */
|
||||
t = get_ticks();
|
||||
ret = ed25519_sign_open_batch(message_pointers, message_lengths, pk_pointers, sig_pointers, test_batch_count, valid);
|
||||
*ticks = get_ticks() - t;
|
||||
edassert_equal((unsigned char *)&validret, (unsigned char *)&ret, sizeof(int), "batch return code");
|
||||
for (i = 0; i < test_batch_count; i++) {
|
||||
validret = ((type == batch_no_errors) || (i != 0)) ? 1 : 0;
|
||||
edassert_equal((unsigned char *)&validret, (unsigned char *)&valid[i], sizeof(int), "individual batch return code");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
test_batch(void) {
|
||||
uint64_t dummy_ticks, ticks[test_batch_rounds], best = maxticks, sum;
|
||||
size_t i, count;
|
||||
|
||||
/* check the first pass for the expected result */
|
||||
test_batch_instance(batch_no_errors, &dummy_ticks);
|
||||
edassert_equal(batch_verify_y, batch_point_buffer[1], 32, "failed to generate expected result");
|
||||
|
||||
/* make sure ge25519_multi_scalarmult_vartime throws an error on the entire batch with wrong data */
|
||||
for (i = 0; i < 4; i++) {
|
||||
test_batch_instance(batch_wrong_message, &dummy_ticks);
|
||||
test_batch_instance(batch_wrong_pk, &dummy_ticks);
|
||||
test_batch_instance(batch_wrong_sig, &dummy_ticks);
|
||||
}
|
||||
|
||||
/* speed test */
|
||||
for (i = 0; i < test_batch_rounds; i++) {
|
||||
test_batch_instance(batch_no_errors, &ticks[i]);
|
||||
if (ticks[i] < best)
|
||||
best = ticks[i];
|
||||
}
|
||||
|
||||
/* take anything within 1% of the best time */
|
||||
for (i = 0, sum = 0, count = 0; i < test_batch_rounds; i++) {
|
||||
if (ticks[i] < (best * 1.01)) {
|
||||
sum += ticks[i];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
printf("%.0f ticks/verification\n", (double)sum / (count * test_batch_count));
|
||||
}
|
||||
|
||||
static void
|
||||
test_main(void) {
|
||||
int i, res;
|
||||
ed25519_public_key pk;
|
||||
ed25519_signature sig;
|
||||
unsigned char forge[1024] = {'x'};
|
||||
curved25519_key csk[2] = {{255}};
|
||||
uint64_t ticks, pkticks = maxticks, signticks = maxticks, openticks = maxticks, curvedticks = maxticks;
|
||||
|
||||
for (i = 0; i < 1024; i++) {
|
||||
ed25519_publickey(dataset[i].sk, pk);
|
||||
edassert_equal_round(dataset[i].pk, pk, sizeof(pk), i, "public key didn't match");
|
||||
ed25519_sign((unsigned char *)dataset[i].m, i, dataset[i].sk, pk, sig);
|
||||
edassert_equal_round(dataset[i].sig, sig, sizeof(sig), i, "signature didn't match");
|
||||
edassert(!ed25519_sign_open((unsigned char *)dataset[i].m, i, pk, sig), i, "failed to open message");
|
||||
|
||||
memcpy(forge, dataset[i].m, i);
|
||||
if (i)
|
||||
forge[i - 1] += 1;
|
||||
|
||||
edassert(ed25519_sign_open(forge, (i) ? i : 1, pk, sig), i, "opened forged message");
|
||||
}
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
curved25519_scalarmult_basepoint(csk[(i & 1) ^ 1], csk[i & 1]);
|
||||
edassert_equal(curved25519_expected, csk[0], sizeof(curved25519_key), "curve25519 failed to generate correct value");
|
||||
|
||||
for (i = 0; i < 2048; i++) {
|
||||
timeit(ed25519_publickey(dataset[0].sk, pk), pkticks)
|
||||
edassert_equal_round(dataset[0].pk, pk, sizeof(pk), i, "public key didn't match");
|
||||
timeit(ed25519_sign((unsigned char *)dataset[0].m, 0, dataset[0].sk, pk, sig), signticks)
|
||||
edassert_equal_round(dataset[0].sig, sig, sizeof(sig), i, "signature didn't match");
|
||||
timeit(res = ed25519_sign_open((unsigned char *)dataset[0].m, 0, pk, sig), openticks)
|
||||
edassert(!res, 0, "failed to open message");
|
||||
timeit(curved25519_scalarmult_basepoint(csk[1], csk[0]), curvedticks);
|
||||
}
|
||||
|
||||
printf("%.0f ticks/public key generation\n", (double)pkticks);
|
||||
printf("%.0f ticks/signature\n", (double)signticks);
|
||||
printf("%.0f ticks/signature verification\n", (double)openticks);
|
||||
printf("%.0f ticks/curve25519 basepoint scalarmult\n", (double)curvedticks);
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
test_main();
|
||||
test_batch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
101
external/secp256k1/.cirrus.yml
vendored
101
external/secp256k1/.cirrus.yml
vendored
@@ -1,101 +0,0 @@
|
||||
env:
|
||||
### cirrus config
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
### compiler options
|
||||
HOST:
|
||||
WRAPPER_CMD:
|
||||
# Specific warnings can be disabled with -Wno-error=foo.
|
||||
# -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual.
|
||||
WERROR_CFLAGS: -Werror -pedantic-errors
|
||||
MAKEFLAGS: -j4
|
||||
BUILD: check
|
||||
### secp256k1 config
|
||||
ECMULTWINDOW: 15
|
||||
ECMULTGENKB: 22
|
||||
ASM: no
|
||||
WIDEMUL: auto
|
||||
WITH_VALGRIND: yes
|
||||
EXTRAFLAGS:
|
||||
### secp256k1 modules
|
||||
EXPERIMENTAL: no
|
||||
ECDH: no
|
||||
RECOVERY: no
|
||||
EXTRAKEYS: no
|
||||
SCHNORRSIG: no
|
||||
MUSIG: no
|
||||
ELLSWIFT: no
|
||||
### test options
|
||||
SECP256K1_TEST_ITERS: 64
|
||||
BENCH: yes
|
||||
SECP256K1_BENCH_ITERS: 2
|
||||
CTIMETESTS: yes
|
||||
# Compile and run the tests
|
||||
EXAMPLES: yes
|
||||
|
||||
cat_logs_snippet: &CAT_LOGS
|
||||
always:
|
||||
cat_tests_log_script:
|
||||
- cat tests.log || true
|
||||
cat_noverify_tests_log_script:
|
||||
- cat noverify_tests.log || true
|
||||
cat_exhaustive_tests_log_script:
|
||||
- cat exhaustive_tests.log || true
|
||||
cat_ctime_tests_log_script:
|
||||
- cat ctime_tests.log || true
|
||||
cat_bench_log_script:
|
||||
- cat bench.log || true
|
||||
cat_config_log_script:
|
||||
- cat config.log || true
|
||||
cat_test_env_script:
|
||||
- cat test_env.log || true
|
||||
cat_ci_env_script:
|
||||
- env
|
||||
|
||||
linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER
|
||||
env_script:
|
||||
- env | tee /tmp/env
|
||||
build_script:
|
||||
- DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm"
|
||||
- docker image prune --force # Cleanup stale layers
|
||||
test_script:
|
||||
- docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh"
|
||||
|
||||
task:
|
||||
name: "ARM64: Linux (Debian stable)"
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: arm64
|
||||
env:
|
||||
ECDH: yes
|
||||
RECOVERY: yes
|
||||
EXTRAKEYS: yes
|
||||
SCHNORRSIG: yes
|
||||
MUSIG: yes
|
||||
ELLSWIFT: yes
|
||||
matrix:
|
||||
# Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU
|
||||
- env: { CC: 'gcc-snapshot' }
|
||||
<< : *LINUX_ARM64_CONTAINER
|
||||
<< : *CAT_LOGS
|
||||
|
||||
task:
|
||||
name: "ARM64: Linux (Debian stable), Valgrind"
|
||||
persistent_worker:
|
||||
labels:
|
||||
type: arm64
|
||||
env:
|
||||
ECDH: yes
|
||||
RECOVERY: yes
|
||||
EXTRAKEYS: yes
|
||||
SCHNORRSIG: yes
|
||||
MUSIG: yes
|
||||
ELLSWIFT: yes
|
||||
WRAPPER_CMD: 'valgrind --error-exitcode=42'
|
||||
SECP256K1_TEST_ITERS: 2
|
||||
matrix:
|
||||
- env: { CC: 'gcc' }
|
||||
- env: { CC: 'clang' }
|
||||
- env: { CC: 'gcc-snapshot' }
|
||||
- env: { CC: 'clang-snapshot' }
|
||||
<< : *LINUX_ARM64_CONTAINER
|
||||
<< : *CAT_LOGS
|
||||
2
external/secp256k1/.gitattributes
vendored
2
external/secp256k1/.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
src/precomputed_ecmult.c linguist-generated
|
||||
src/precomputed_ecmult_gen.c linguist-generated
|
||||
67
external/secp256k1/.gitignore
vendored
67
external/secp256k1/.gitignore
vendored
@@ -1,67 +0,0 @@
|
||||
bench
|
||||
bench_ecmult
|
||||
bench_internal
|
||||
noverify_tests
|
||||
tests
|
||||
exhaustive_tests
|
||||
precompute_ecmult_gen
|
||||
precompute_ecmult
|
||||
ctime_tests
|
||||
ecdh_example
|
||||
ecdsa_example
|
||||
schnorr_example
|
||||
ellswift_example
|
||||
musig_example
|
||||
*.exe
|
||||
*.so
|
||||
*.a
|
||||
*.csv
|
||||
*.log
|
||||
*.trs
|
||||
*.sage.py
|
||||
|
||||
Makefile
|
||||
configure
|
||||
.libs/
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
config.status
|
||||
conftest*
|
||||
*.tar.gz
|
||||
*.la
|
||||
libtool
|
||||
.deps/
|
||||
.dirstamp
|
||||
*.lo
|
||||
*.o
|
||||
*~
|
||||
|
||||
coverage/
|
||||
coverage.html
|
||||
coverage.*.html
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
|
||||
build-aux/ar-lib
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
build-aux/depcomp
|
||||
build-aux/install-sh
|
||||
build-aux/ltmain.sh
|
||||
build-aux/m4/libtool.m4
|
||||
build-aux/m4/lt~obsolete.m4
|
||||
build-aux/m4/ltoptions.m4
|
||||
build-aux/m4/ltsugar.m4
|
||||
build-aux/m4/ltversion.m4
|
||||
build-aux/missing
|
||||
build-aux/compile
|
||||
build-aux/test-driver
|
||||
libsecp256k1.pc
|
||||
|
||||
### CMake
|
||||
/CMakeUserPresets.json
|
||||
# Default CMake build directory.
|
||||
/build
|
||||
174
external/secp256k1/CHANGELOG.md
vendored
174
external/secp256k1/CHANGELOG.md
vendored
@@ -1,174 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.6.0] - 2024-11-04
|
||||
|
||||
#### Added
|
||||
- New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See:
|
||||
- Header file `include/secp256k1_musig.h` which defines the new API.
|
||||
- Document `doc/musig.md` for further notes on API usage.
|
||||
- Usage example `examples/musig.c`.
|
||||
- New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command.
|
||||
|
||||
#### Changed
|
||||
- API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal.
|
||||
- Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++).
|
||||
- Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility.
|
||||
|
||||
#### Removed
|
||||
- Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API.
|
||||
|
||||
#### ABI Compatibility
|
||||
The symbols `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` were removed.
|
||||
Otherwise, the library maintains backward compatibility with versions 0.3.x through 0.5.x.
|
||||
|
||||
## [0.5.1] - 2024-08-01
|
||||
|
||||
#### Added
|
||||
- Added usage example for an ElligatorSwift key exchange.
|
||||
|
||||
#### Changed
|
||||
- The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
|
||||
- "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly.
|
||||
|
||||
#### Fixed
|
||||
- Fixed compilation when the extrakeys module is disabled.
|
||||
|
||||
#### ABI Compatibility
|
||||
The ABI is backward compatible with versions 0.5.0, 0.4.x and 0.3.x.
|
||||
|
||||
## [0.5.0] - 2024-05-06
|
||||
|
||||
#### Added
|
||||
- New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order.
|
||||
|
||||
#### Changed
|
||||
- The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations.
|
||||
- The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
|
||||
- This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB).
|
||||
|
||||
#### ABI Compatibility
|
||||
The ABI is backward compatible with versions 0.4.x and 0.3.x.
|
||||
|
||||
## [0.4.1] - 2023-12-21
|
||||
|
||||
#### Changed
|
||||
- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
|
||||
- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`.
|
||||
|
||||
#### ABI Compatibility
|
||||
The ABI is backward compatible with versions 0.4.0 and 0.3.x.
|
||||
|
||||
## [0.4.0] - 2023-09-04
|
||||
|
||||
#### Added
|
||||
- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
|
||||
ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
|
||||
- Header file `include/secp256k1_ellswift.h` which defines the new API.
|
||||
- Document `doc/ellswift.md` which explains the mathematical background of the scheme.
|
||||
- The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
|
||||
- We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases).
|
||||
|
||||
#### Fixed
|
||||
- Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported.
|
||||
|
||||
#### Changed
|
||||
- When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
|
||||
|
||||
#### ABI Compatibility
|
||||
This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug.
|
||||
|
||||
## [0.3.2] - 2023-05-13
|
||||
We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
|
||||
|
||||
#### Security
|
||||
- Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1.
|
||||
|
||||
#### Fixed
|
||||
- Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far.
|
||||
|
||||
#### Changed
|
||||
- Various improvements and changes to CMake builds. CMake builds remain experimental.
|
||||
- Made API versioning consistent with GNU Autotools builds.
|
||||
- Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library.
|
||||
- Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts.
|
||||
- Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake).
|
||||
|
||||
#### ABI Compatibility
|
||||
The ABI is compatible with versions 0.3.0 and 0.3.1.
|
||||
|
||||
## [0.3.1] - 2023-04-10
|
||||
We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
|
||||
|
||||
#### Security
|
||||
- Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
|
||||
|
||||
#### Added
|
||||
- Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
|
||||
|
||||
#### Changed
|
||||
- Increased minimum required CMake version to 3.13. CMake builds remain experimental.
|
||||
|
||||
#### ABI Compatibility
|
||||
The ABI is compatible with version 0.3.0.
|
||||
|
||||
## [0.3.0] - 2023-03-08
|
||||
|
||||
#### Added
|
||||
- Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported.
|
||||
- Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory.
|
||||
- Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target.
|
||||
|
||||
#### Fixed
|
||||
- Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning.
|
||||
|
||||
#### Changed
|
||||
- Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.)
|
||||
- Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization.
|
||||
|
||||
#### Removed
|
||||
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
|
||||
|
||||
#### ABI Compatibility
|
||||
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
|
||||
|
||||
## [0.2.0] - 2022-12-12
|
||||
|
||||
#### Added
|
||||
- Added usage examples for common use cases in a new `examples/` directory.
|
||||
- Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`.
|
||||
- Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms.
|
||||
|
||||
#### Changed
|
||||
- Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`.
|
||||
- The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API.
|
||||
|
||||
#### Deprecated
|
||||
- Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead.
|
||||
- Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`.
|
||||
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
|
||||
|
||||
#### ABI Compatibility
|
||||
Since this is the first release, we do not compare application binary interfaces.
|
||||
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
|
||||
|
||||
## [0.1.0] - 2013-03-05 to 2021-12-25
|
||||
|
||||
This version was in fact never released.
|
||||
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
|
||||
Therefore, this version number does not uniquely identify a set of source files.
|
||||
|
||||
[0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0
|
||||
[0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1
|
||||
[0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0
|
||||
[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1
|
||||
[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
|
||||
[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
|
||||
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
|
||||
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
|
||||
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
|
||||
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93
|
||||
405
external/secp256k1/CMakeLists.txt
vendored
405
external/secp256k1/CMakeLists.txt
vendored
@@ -1,405 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
#=============================
|
||||
# Project / Package metadata
|
||||
#=============================
|
||||
project(libsecp256k1
|
||||
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
|
||||
# the API. All changes in experimental modules are treated as
|
||||
# backwards-compatible and therefore at most increase the minor version.
|
||||
VERSION 0.6.0
|
||||
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
|
||||
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
|
||||
LANGUAGES C
|
||||
)
|
||||
enable_testing()
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.21)
|
||||
# Emulates CMake 3.21+ behavior.
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(PROJECT_IS_TOP_LEVEL ON)
|
||||
set(${PROJECT_NAME}_IS_TOP_LEVEL ON)
|
||||
else()
|
||||
set(PROJECT_IS_TOP_LEVEL OFF)
|
||||
set(${PROJECT_NAME}_IS_TOP_LEVEL OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The library version is based on libtool versioning of the ABI. The set of
|
||||
# rules for updating the version can be found here:
|
||||
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
# All changes in experimental modules are treated as if they don't affect the
|
||||
# interface and therefore only increase the revision.
|
||||
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5)
|
||||
set(${PROJECT_NAME}_LIB_VERSION_REVISION 0)
|
||||
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
|
||||
|
||||
#=============================
|
||||
# Language setup
|
||||
#=============================
|
||||
set(CMAKE_C_STANDARD 90)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
#=============================
|
||||
# Configurable options
|
||||
#=============================
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries." ON)
|
||||
option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF)
|
||||
if(SECP256K1_DISABLE_SHARED)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
|
||||
|
||||
## Modules
|
||||
|
||||
# We declare all options before processing them, to make sure we can express
|
||||
# dependendencies while processing.
|
||||
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
|
||||
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
|
||||
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
|
||||
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
|
||||
option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON)
|
||||
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
|
||||
|
||||
# Processing must be done in a topological sorting of the dependency graph
|
||||
# (dependent module first).
|
||||
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
|
||||
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_MUSIG)
|
||||
if(DEFINED SECP256K1_ENABLE_MODULE_SCHNORRSIG AND NOT SECP256K1_ENABLE_MODULE_SCHNORRSIG)
|
||||
message(FATAL_ERROR "Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.")
|
||||
endif()
|
||||
set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON)
|
||||
add_compile_definitions(ENABLE_MODULE_MUSIG=1)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
|
||||
if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
|
||||
message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
|
||||
endif()
|
||||
set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
|
||||
add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
|
||||
add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_RECOVERY)
|
||||
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_ECDH)
|
||||
add_compile_definitions(ENABLE_MODULE_ECDH=1)
|
||||
endif()
|
||||
|
||||
option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
|
||||
if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
|
||||
add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
|
||||
endif()
|
||||
|
||||
set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. The default value is a reasonable setting for desktop machines (currently 15). [default=15]")
|
||||
set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
|
||||
include(CheckStringOptionValue)
|
||||
check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE)
|
||||
add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE})
|
||||
|
||||
set(SECP256K1_ECMULT_GEN_KB 86 CACHE STRING "The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms). Larger values result in possibly better signing or key generation performance at the cost of a larger table. Valid choices are 2, 22, 86. The default value is a reasonable setting for desktop machines (currently 86). [default=86]")
|
||||
set_property(CACHE SECP256K1_ECMULT_GEN_KB PROPERTY STRINGS 2 22 86)
|
||||
check_string_option_value(SECP256K1_ECMULT_GEN_KB)
|
||||
if(SECP256K1_ECMULT_GEN_KB EQUAL 2)
|
||||
add_compile_definitions(COMB_BLOCKS=2)
|
||||
add_compile_definitions(COMB_TEETH=5)
|
||||
elseif(SECP256K1_ECMULT_GEN_KB EQUAL 22)
|
||||
add_compile_definitions(COMB_BLOCKS=11)
|
||||
add_compile_definitions(COMB_TEETH=6)
|
||||
elseif(SECP256K1_ECMULT_GEN_KB EQUAL 86)
|
||||
add_compile_definitions(COMB_BLOCKS=43)
|
||||
add_compile_definitions(COMB_TEETH=6)
|
||||
endif()
|
||||
|
||||
set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]")
|
||||
set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64")
|
||||
check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
|
||||
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
|
||||
string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value)
|
||||
add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1)
|
||||
endif()
|
||||
mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
|
||||
|
||||
set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
|
||||
set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
|
||||
check_string_option_value(SECP256K1_ASM)
|
||||
if(SECP256K1_ASM STREQUAL "arm32")
|
||||
enable_language(ASM)
|
||||
include(CheckArm32Assembly)
|
||||
check_arm32_assembly()
|
||||
if(HAVE_ARM32_ASM)
|
||||
add_compile_definitions(USE_EXTERNAL_ASM=1)
|
||||
else()
|
||||
message(FATAL_ERROR "ARM32 assembly requested but not available.")
|
||||
endif()
|
||||
elseif(SECP256K1_ASM)
|
||||
include(CheckX86_64Assembly)
|
||||
check_x86_64_assembly()
|
||||
if(HAVE_X86_64_ASM)
|
||||
set(SECP256K1_ASM "x86_64")
|
||||
add_compile_definitions(USE_ASM_X86_64=1)
|
||||
elseif(SECP256K1_ASM STREQUAL "AUTO")
|
||||
set(SECP256K1_ASM "OFF")
|
||||
else()
|
||||
message(FATAL_ERROR "x86_64 assembly requested but not available.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
|
||||
if(NOT SECP256K1_EXPERIMENTAL)
|
||||
if(SECP256K1_ASM STREQUAL "arm32")
|
||||
message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")
|
||||
set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON")
|
||||
check_string_option_value(SECP256K1_VALGRIND)
|
||||
if(SECP256K1_VALGRIND)
|
||||
find_package(Valgrind MODULE)
|
||||
if(Valgrind_FOUND)
|
||||
set(SECP256K1_VALGRIND ON)
|
||||
include_directories(${Valgrind_INCLUDE_DIR})
|
||||
add_compile_definitions(VALGRIND)
|
||||
elseif(SECP256K1_VALGRIND STREQUAL "AUTO")
|
||||
set(SECP256K1_VALGRIND OFF)
|
||||
else()
|
||||
message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)
|
||||
option(SECP256K1_BUILD_TESTS "Build tests." ON)
|
||||
option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
|
||||
option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})
|
||||
option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)
|
||||
|
||||
# Redefine configuration flags.
|
||||
# We leave assertions on, because they are only used in the examples, and we want them always on there.
|
||||
if(MSVC)
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
else()
|
||||
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
|
||||
string(REGEX REPLACE "-O3( |$)" "-O2\\1" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
endif()
|
||||
|
||||
# Define custom "Coverage" build type.
|
||||
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
|
||||
"Flags used by the C compiler during \"Coverage\" builds."
|
||||
FORCE
|
||||
)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
|
||||
"Flags used for linking binaries during \"Coverage\" builds."
|
||||
FORCE
|
||||
)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
|
||||
"Flags used by the shared libraries linker during \"Coverage\" builds."
|
||||
FORCE
|
||||
)
|
||||
mark_as_advanced(
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||
)
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
set(default_build_type "RelWithDebInfo")
|
||||
if(is_multi_config)
|
||||
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
|
||||
"Supported configuration types."
|
||||
FORCE
|
||||
)
|
||||
else()
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
|
||||
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
|
||||
)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
|
||||
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
|
||||
"Choose the type of build."
|
||||
FORCE
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(TryAppendCFlags)
|
||||
if(MSVC)
|
||||
# Keep the following commands ordered lexicographically.
|
||||
try_append_c_flags(/W3) # Production quality warning level.
|
||||
try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
|
||||
try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
|
||||
try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
|
||||
# Eliminate deprecation warnings for the older, less secure functions.
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
else()
|
||||
# Keep the following commands ordered lexicographically.
|
||||
try_append_c_flags(-pedantic)
|
||||
try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
|
||||
try_append_c_flags(-Wcast-align) # GCC >= 2.95.
|
||||
try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
|
||||
try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
|
||||
try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
|
||||
try_append_c_flags(-Wnested-externs)
|
||||
try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
|
||||
try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
|
||||
try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall.
|
||||
try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only.
|
||||
try_append_c_flags(-Wshadow)
|
||||
try_append_c_flags(-Wstrict-prototypes)
|
||||
try_append_c_flags(-Wundef)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
|
||||
set(print_msan_notice)
|
||||
if(SECP256K1_BUILD_CTIME_TESTS)
|
||||
include(CheckMemorySanitizer)
|
||||
check_memory_sanitizer(msan_enabled)
|
||||
if(msan_enabled)
|
||||
try_append_c_flags(-fno-sanitize-memory-param-retval)
|
||||
set(print_msan_notice YES)
|
||||
endif()
|
||||
unset(msan_enabled)
|
||||
endif()
|
||||
|
||||
set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
|
||||
if(SECP256K1_APPEND_CFLAGS)
|
||||
# Appending to this low-level rule variable is the only way to
|
||||
# guarantee that the flags appear at the end of the command line.
|
||||
string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}")
|
||||
endif()
|
||||
|
||||
set(SECP256K1_APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
|
||||
if(SECP256K1_APPEND_LDFLAGS)
|
||||
# Appending to this low-level rule variable is the only way to
|
||||
# guarantee that the flags appear at the end of the command line.
|
||||
string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " ${SECP256K1_APPEND_LDFLAGS}")
|
||||
string(APPEND CMAKE_C_LINK_EXECUTABLE " ${SECP256K1_APPEND_LDFLAGS}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
endif()
|
||||
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
endif()
|
||||
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
endif()
|
||||
add_subdirectory(src)
|
||||
if(SECP256K1_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
message("\n")
|
||||
message("secp256k1 configure summary")
|
||||
message("===========================")
|
||||
message("Build artifacts:")
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(library_type "Shared")
|
||||
else()
|
||||
set(library_type "Static")
|
||||
endif()
|
||||
|
||||
message(" library type ........................ ${library_type}")
|
||||
message("Optional modules:")
|
||||
message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}")
|
||||
message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
|
||||
message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
|
||||
message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
|
||||
message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
|
||||
message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
|
||||
message("Parameters:")
|
||||
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
|
||||
message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB")
|
||||
message("Optional features:")
|
||||
message(" assembly ............................ ${SECP256K1_ASM}")
|
||||
message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
|
||||
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
|
||||
message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
|
||||
endif()
|
||||
message("Optional binaries:")
|
||||
message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
|
||||
message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
|
||||
set(tests_status "${SECP256K1_BUILD_TESTS}")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||
set(tests_status OFF)
|
||||
endif()
|
||||
message(" tests ............................... ${tests_status}")
|
||||
message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
|
||||
message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
|
||||
message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
|
||||
message("")
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
set(cross_status "FALSE")
|
||||
endif()
|
||||
message("Cross compiling ....................... ${cross_status}")
|
||||
message("Valgrind .............................. ${SECP256K1_VALGRIND}")
|
||||
get_directory_property(definitions COMPILE_DEFINITIONS)
|
||||
string(REPLACE ";" " " definitions "${definitions}")
|
||||
message("Preprocessor defined macros ........... ${definitions}")
|
||||
message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}")
|
||||
message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
|
||||
get_directory_property(compile_options COMPILE_OPTIONS)
|
||||
string(REPLACE ";" " " compile_options "${compile_options}")
|
||||
message("Compile options ....................... " ${compile_options})
|
||||
if(NOT is_multi_config)
|
||||
message("Build type:")
|
||||
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
|
||||
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
|
||||
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
|
||||
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
|
||||
else()
|
||||
message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
|
||||
message("RelWithDebInfo configuration:")
|
||||
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
|
||||
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
|
||||
message("Debug configuration:")
|
||||
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
|
||||
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
endif()
|
||||
if(SECP256K1_APPEND_CFLAGS)
|
||||
message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}")
|
||||
endif()
|
||||
if(SECP256K1_APPEND_LDFLAGS)
|
||||
message("SECP256K1_APPEND_LDFLAGS .............. ${SECP256K1_APPEND_LDFLAGS}")
|
||||
endif()
|
||||
message("")
|
||||
if(print_msan_notice)
|
||||
message(
|
||||
"Note:\n"
|
||||
" MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n"
|
||||
" to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n"
|
||||
)
|
||||
endif()
|
||||
if(SECP256K1_EXPERIMENTAL)
|
||||
message(
|
||||
" ******\n"
|
||||
" WARNING: experimental build\n"
|
||||
" Experimental features do not have stable APIs or properties, and may not be safe for production use.\n"
|
||||
" ******\n"
|
||||
)
|
||||
endif()
|
||||
19
external/secp256k1/CMakePresets.json
vendored
19
external/secp256k1/CMakePresets.json
vendored
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0},
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "dev-mode",
|
||||
"displayName": "Development mode (intended only for developers of the library)",
|
||||
"cacheVariables": {
|
||||
"SECP256K1_EXPERIMENTAL": "ON",
|
||||
"SECP256K1_ENABLE_MODULE_RECOVERY": "ON",
|
||||
"SECP256K1_BUILD_EXAMPLES": "ON"
|
||||
},
|
||||
"warnings": {
|
||||
"dev": true,
|
||||
"uninitialized": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
108
external/secp256k1/CONTRIBUTING.md
vendored
108
external/secp256k1/CONTRIBUTING.md
vendored
@@ -1,108 +0,0 @@
|
||||
# Contributing to libsecp256k1
|
||||
|
||||
## Scope
|
||||
|
||||
libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library.
|
||||
The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem.
|
||||
|
||||
## Adding new functionality or modules
|
||||
|
||||
The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope.
|
||||
|
||||
It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable.
|
||||
Contributors are recommended to provide the following in addition to the new code:
|
||||
|
||||
* **Specification:**
|
||||
A specification can help significantly in reviewing the new code as it provides documentation and context.
|
||||
It may justify various design decisions, give a motivation and outline security goals.
|
||||
If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code.
|
||||
* **Security Arguments:**
|
||||
In addition to a defining the security goals, it should be argued that the new functionality meets these goals.
|
||||
Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security.
|
||||
* **Relevance Arguments:**
|
||||
The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases.
|
||||
|
||||
These are not the only factors taken into account when considering to add new functionality.
|
||||
The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design.
|
||||
|
||||
We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality.
|
||||
|
||||
## Communication channels
|
||||
|
||||
Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board.
|
||||
|
||||
Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic).
|
||||
The channel is `#secp256k1` on Libera Chat.
|
||||
The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1).
|
||||
Chat history logs can be found at https://gnusha.org/secp256k1/.
|
||||
|
||||
## Contributor workflow & peer review
|
||||
|
||||
The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md).
|
||||
|
||||
### Coding conventions
|
||||
|
||||
In addition, libsecp256k1 tries to maintain the following coding conventions:
|
||||
|
||||
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
|
||||
* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
|
||||
* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
|
||||
* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.
|
||||
* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)).
|
||||
* As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)).
|
||||
|
||||
#### Style conventions
|
||||
|
||||
* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures.
|
||||
* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting.
|
||||
* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block:
|
||||
```C
|
||||
void secp256k_foo(void) {
|
||||
unsigned int x; /* declaration */
|
||||
int y = 2*x; /* declaration */
|
||||
x = 17; /* statement */
|
||||
{
|
||||
int a, b; /* declaration */
|
||||
a = x + y; /* statement */
|
||||
secp256k_bar(x, &b); /* statement */
|
||||
}
|
||||
}
|
||||
```
|
||||
* Use `unsigned int` instead of just `unsigned`.
|
||||
* Use `void *ptr` instead of `void* ptr`.
|
||||
* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h).
|
||||
* User-facing comment lines in headers should be limited to 80 chars if possible.
|
||||
* All identifiers in file scope should start with `secp256k1_`.
|
||||
* Avoid trailing whitespace.
|
||||
|
||||
### Tests
|
||||
|
||||
#### Coverage
|
||||
|
||||
This library aims to have full coverage of reachable lines and branches.
|
||||
|
||||
To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
|
||||
|
||||
$ ./configure --enable-coverage
|
||||
|
||||
Run the tests:
|
||||
|
||||
$ make check
|
||||
|
||||
To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
|
||||
|
||||
$ gcovr --exclude 'src/bench*' --print-summary
|
||||
|
||||
To create a HTML report with coloured and annotated source code:
|
||||
|
||||
$ mkdir -p coverage
|
||||
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
|
||||
|
||||
#### Exhaustive tests
|
||||
|
||||
There are tests of several functions in which a small group replaces secp256k1.
|
||||
These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)).
|
||||
|
||||
### Benchmarks
|
||||
|
||||
See `src/bench*.c` for examples of benchmarks.
|
||||
19
external/secp256k1/COPYING
vendored
19
external/secp256k1/COPYING
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2013 Pieter Wuille
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
302
external/secp256k1/Makefile.am
vendored
302
external/secp256k1/Makefile.am
vendored
@@ -1,302 +0,0 @@
|
||||
ACLOCAL_AMFLAGS = -I build-aux/m4
|
||||
|
||||
# AM_CFLAGS will be automatically prepended to CFLAGS by Automake when compiling some foo
|
||||
# which does not have an explicit foo_CFLAGS variable set.
|
||||
AM_CFLAGS = $(SECP_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libsecp256k1.la
|
||||
include_HEADERS = include/secp256k1.h
|
||||
include_HEADERS += include/secp256k1_preallocated.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += src/scalar.h
|
||||
noinst_HEADERS += src/scalar_4x64.h
|
||||
noinst_HEADERS += src/scalar_8x32.h
|
||||
noinst_HEADERS += src/scalar_low.h
|
||||
noinst_HEADERS += src/scalar_impl.h
|
||||
noinst_HEADERS += src/scalar_4x64_impl.h
|
||||
noinst_HEADERS += src/scalar_8x32_impl.h
|
||||
noinst_HEADERS += src/scalar_low_impl.h
|
||||
noinst_HEADERS += src/group.h
|
||||
noinst_HEADERS += src/group_impl.h
|
||||
noinst_HEADERS += src/ecdsa.h
|
||||
noinst_HEADERS += src/ecdsa_impl.h
|
||||
noinst_HEADERS += src/eckey.h
|
||||
noinst_HEADERS += src/eckey_impl.h
|
||||
noinst_HEADERS += src/ecmult.h
|
||||
noinst_HEADERS += src/ecmult_impl.h
|
||||
noinst_HEADERS += src/ecmult_compute_table.h
|
||||
noinst_HEADERS += src/ecmult_compute_table_impl.h
|
||||
noinst_HEADERS += src/ecmult_const.h
|
||||
noinst_HEADERS += src/ecmult_const_impl.h
|
||||
noinst_HEADERS += src/ecmult_gen.h
|
||||
noinst_HEADERS += src/ecmult_gen_impl.h
|
||||
noinst_HEADERS += src/ecmult_gen_compute_table.h
|
||||
noinst_HEADERS += src/ecmult_gen_compute_table_impl.h
|
||||
noinst_HEADERS += src/field_10x26.h
|
||||
noinst_HEADERS += src/field_10x26_impl.h
|
||||
noinst_HEADERS += src/field_5x52.h
|
||||
noinst_HEADERS += src/field_5x52_impl.h
|
||||
noinst_HEADERS += src/field_5x52_int128_impl.h
|
||||
noinst_HEADERS += src/modinv32.h
|
||||
noinst_HEADERS += src/modinv32_impl.h
|
||||
noinst_HEADERS += src/modinv64.h
|
||||
noinst_HEADERS += src/modinv64_impl.h
|
||||
noinst_HEADERS += src/precomputed_ecmult.h
|
||||
noinst_HEADERS += src/precomputed_ecmult_gen.h
|
||||
noinst_HEADERS += src/assumptions.h
|
||||
noinst_HEADERS += src/checkmem.h
|
||||
noinst_HEADERS += src/testutil.h
|
||||
noinst_HEADERS += src/util.h
|
||||
noinst_HEADERS += src/int128.h
|
||||
noinst_HEADERS += src/int128_impl.h
|
||||
noinst_HEADERS += src/int128_native.h
|
||||
noinst_HEADERS += src/int128_native_impl.h
|
||||
noinst_HEADERS += src/int128_struct.h
|
||||
noinst_HEADERS += src/int128_struct_impl.h
|
||||
noinst_HEADERS += src/scratch.h
|
||||
noinst_HEADERS += src/scratch_impl.h
|
||||
noinst_HEADERS += src/selftest.h
|
||||
noinst_HEADERS += src/testrand.h
|
||||
noinst_HEADERS += src/testrand_impl.h
|
||||
noinst_HEADERS += src/hash.h
|
||||
noinst_HEADERS += src/hash_impl.h
|
||||
noinst_HEADERS += src/field.h
|
||||
noinst_HEADERS += src/field_impl.h
|
||||
noinst_HEADERS += src/bench.h
|
||||
noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
|
||||
noinst_HEADERS += src/hsort.h
|
||||
noinst_HEADERS += src/hsort_impl.h
|
||||
noinst_HEADERS += contrib/lax_der_parsing.h
|
||||
noinst_HEADERS += contrib/lax_der_parsing.c
|
||||
noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
|
||||
noinst_HEADERS += contrib/lax_der_privatekey_parsing.c
|
||||
noinst_HEADERS += examples/examples_util.h
|
||||
|
||||
PRECOMPUTED_LIB = libsecp256k1_precomputed.la
|
||||
noinst_LTLIBRARIES = $(PRECOMPUTED_LIB)
|
||||
libsecp256k1_precomputed_la_SOURCES = src/precomputed_ecmult.c src/precomputed_ecmult_gen.c
|
||||
# We need `-I$(top_srcdir)/src` in VPATH builds if libsecp256k1_precomputed_la_SOURCES have been recreated in the build tree.
|
||||
# This helps users and packagers who insist on recreating the precomputed files (e.g., Gentoo).
|
||||
libsecp256k1_precomputed_la_CPPFLAGS = -I$(top_srcdir)/src $(SECP_CONFIG_DEFINES)
|
||||
|
||||
if USE_EXTERNAL_ASM
|
||||
COMMON_LIB = libsecp256k1_common.la
|
||||
else
|
||||
COMMON_LIB =
|
||||
endif
|
||||
noinst_LTLIBRARIES += $(COMMON_LIB)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libsecp256k1.pc
|
||||
|
||||
if USE_EXTERNAL_ASM
|
||||
if USE_ASM_ARM
|
||||
libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s
|
||||
endif
|
||||
endif
|
||||
|
||||
libsecp256k1_la_SOURCES = src/secp256k1.c
|
||||
libsecp256k1_la_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
libsecp256k1_la_LIBADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
|
||||
libsecp256k1_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_CURRENT):$(LIB_VERSION_REVISION):$(LIB_VERSION_AGE)
|
||||
|
||||
noinst_PROGRAMS =
|
||||
if USE_BENCHMARK
|
||||
noinst_PROGRAMS += bench bench_internal bench_ecmult
|
||||
bench_SOURCES = src/bench.c
|
||||
bench_LDADD = libsecp256k1.la
|
||||
bench_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
bench_internal_SOURCES = src/bench_internal.c
|
||||
bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
|
||||
bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
bench_ecmult_SOURCES = src/bench_ecmult.c
|
||||
bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
|
||||
bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
endif
|
||||
|
||||
TESTS =
|
||||
if USE_TESTS
|
||||
TESTS += noverify_tests
|
||||
noinst_PROGRAMS += noverify_tests
|
||||
noverify_tests_SOURCES = src/tests.c
|
||||
noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
|
||||
noverify_tests_LDFLAGS = -static
|
||||
if !ENABLE_COVERAGE
|
||||
TESTS += tests
|
||||
noinst_PROGRAMS += tests
|
||||
tests_SOURCES = $(noverify_tests_SOURCES)
|
||||
tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY
|
||||
tests_LDADD = $(noverify_tests_LDADD)
|
||||
tests_LDFLAGS = $(noverify_tests_LDFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_CTIME_TESTS
|
||||
noinst_PROGRAMS += ctime_tests
|
||||
ctime_tests_SOURCES = src/ctime_tests.c
|
||||
ctime_tests_LDADD = libsecp256k1.la
|
||||
ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
endif
|
||||
|
||||
if USE_EXHAUSTIVE_TESTS
|
||||
noinst_PROGRAMS += exhaustive_tests
|
||||
exhaustive_tests_SOURCES = src/tests_exhaustive.c
|
||||
exhaustive_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
|
||||
if !ENABLE_COVERAGE
|
||||
exhaustive_tests_CPPFLAGS += -DVERIFY
|
||||
endif
|
||||
# Note: do not include $(PRECOMPUTED_LIB) in exhaustive_tests (it uses runtime-generated tables).
|
||||
exhaustive_tests_LDADD = $(COMMON_LIB)
|
||||
exhaustive_tests_LDFLAGS = -static
|
||||
TESTS += exhaustive_tests
|
||||
endif
|
||||
|
||||
if USE_EXAMPLES
|
||||
noinst_PROGRAMS += ecdsa_example
|
||||
ecdsa_example_SOURCES = examples/ecdsa.c
|
||||
ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
|
||||
ecdsa_example_LDADD = libsecp256k1.la
|
||||
ecdsa_example_LDFLAGS = -static
|
||||
if BUILD_WINDOWS
|
||||
ecdsa_example_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
TESTS += ecdsa_example
|
||||
if ENABLE_MODULE_ECDH
|
||||
noinst_PROGRAMS += ecdh_example
|
||||
ecdh_example_SOURCES = examples/ecdh.c
|
||||
ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
|
||||
ecdh_example_LDADD = libsecp256k1.la
|
||||
ecdh_example_LDFLAGS = -static
|
||||
if BUILD_WINDOWS
|
||||
ecdh_example_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
TESTS += ecdh_example
|
||||
endif
|
||||
if ENABLE_MODULE_SCHNORRSIG
|
||||
noinst_PROGRAMS += schnorr_example
|
||||
schnorr_example_SOURCES = examples/schnorr.c
|
||||
schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
|
||||
schnorr_example_LDADD = libsecp256k1.la
|
||||
schnorr_example_LDFLAGS = -static
|
||||
if BUILD_WINDOWS
|
||||
schnorr_example_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
TESTS += schnorr_example
|
||||
endif
|
||||
if ENABLE_MODULE_ELLSWIFT
|
||||
noinst_PROGRAMS += ellswift_example
|
||||
ellswift_example_SOURCES = examples/ellswift.c
|
||||
ellswift_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
|
||||
ellswift_example_LDADD = libsecp256k1.la
|
||||
ellswift_example_LDFLAGS = -static
|
||||
if BUILD_WINDOWS
|
||||
ellswift_example_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
TESTS += ellswift_example
|
||||
endif
|
||||
if ENABLE_MODULE_MUSIG
|
||||
noinst_PROGRAMS += musig_example
|
||||
musig_example_SOURCES = examples/musig.c
|
||||
musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
|
||||
musig_example_LDADD = libsecp256k1.la
|
||||
musig_example_LDFLAGS = -static
|
||||
if BUILD_WINDOWS
|
||||
musig_example_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
TESTS += musig_example
|
||||
endif
|
||||
endif
|
||||
|
||||
### Precomputed tables
|
||||
EXTRA_PROGRAMS = precompute_ecmult precompute_ecmult_gen
|
||||
CLEANFILES = $(EXTRA_PROGRAMS)
|
||||
|
||||
precompute_ecmult_SOURCES = src/precompute_ecmult.c
|
||||
precompute_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
|
||||
precompute_ecmult_LDADD = $(COMMON_LIB)
|
||||
|
||||
precompute_ecmult_gen_SOURCES = src/precompute_ecmult_gen.c
|
||||
precompute_ecmult_gen_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
|
||||
precompute_ecmult_gen_LDADD = $(COMMON_LIB)
|
||||
|
||||
# See Automake manual, Section "Errors with distclean".
|
||||
# We don't list any dependencies for the prebuilt files here because
|
||||
# otherwise make's decision whether to rebuild them (even in the first
|
||||
# build by a normal user) depends on mtimes, and thus is very fragile.
|
||||
# This means that rebuilds of the prebuilt files always need to be
|
||||
# forced by deleting them.
|
||||
src/precomputed_ecmult.c:
|
||||
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult$(EXEEXT)
|
||||
./precompute_ecmult$(EXEEXT)
|
||||
src/precomputed_ecmult_gen.c:
|
||||
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult_gen$(EXEEXT)
|
||||
./precompute_ecmult_gen$(EXEEXT)
|
||||
|
||||
PRECOMP = src/precomputed_ecmult_gen.c src/precomputed_ecmult.c
|
||||
precomp: $(PRECOMP)
|
||||
|
||||
# Ensure the prebuilt files will be build first (only if they don't exist,
|
||||
# e.g., after `make maintainer-clean`).
|
||||
BUILT_SOURCES = $(PRECOMP)
|
||||
|
||||
.PHONY: clean-precomp
|
||||
clean-precomp:
|
||||
rm -f $(PRECOMP)
|
||||
maintainer-clean-local: clean-precomp
|
||||
|
||||
### Pregenerated test vectors
|
||||
### (see the comments in the previous section for detailed rationale)
|
||||
TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
|
||||
|
||||
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
|
||||
mkdir -p $(@D)
|
||||
python3 $(top_srcdir)/tools/tests_wycheproof_generate.py $(top_srcdir)/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
|
||||
|
||||
testvectors: $(TESTVECTORS)
|
||||
|
||||
BUILT_SOURCES += $(TESTVECTORS)
|
||||
|
||||
.PHONY: clean-testvectors
|
||||
clean-testvectors:
|
||||
rm -f $(TESTVECTORS)
|
||||
maintainer-clean-local: clean-testvectors
|
||||
|
||||
### Additional files to distribute
|
||||
EXTRA_DIST = autogen.sh CHANGELOG.md SECURITY.md
|
||||
EXTRA_DIST += doc/release-process.md doc/safegcd_implementation.md
|
||||
EXTRA_DIST += doc/ellswift.md doc/musig.md
|
||||
EXTRA_DIST += examples/EXAMPLES_COPYING
|
||||
EXTRA_DIST += sage/gen_exhaustive_groups.sage
|
||||
EXTRA_DIST += sage/gen_split_lambda_constants.sage
|
||||
EXTRA_DIST += sage/group_prover.sage
|
||||
EXTRA_DIST += sage/prove_group_implementations.sage
|
||||
EXTRA_DIST += sage/secp256k1_params.sage
|
||||
EXTRA_DIST += sage/weierstrass_prover.sage
|
||||
EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
|
||||
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
|
||||
EXTRA_DIST += tools/tests_wycheproof_generate.py
|
||||
|
||||
if ENABLE_MODULE_ECDH
|
||||
include src/modules/ecdh/Makefile.am.include
|
||||
endif
|
||||
|
||||
if ENABLE_MODULE_RECOVERY
|
||||
include src/modules/recovery/Makefile.am.include
|
||||
endif
|
||||
|
||||
if ENABLE_MODULE_EXTRAKEYS
|
||||
include src/modules/extrakeys/Makefile.am.include
|
||||
endif
|
||||
|
||||
if ENABLE_MODULE_SCHNORRSIG
|
||||
include src/modules/schnorrsig/Makefile.am.include
|
||||
endif
|
||||
|
||||
if ENABLE_MODULE_MUSIG
|
||||
include src/modules/musig/Makefile.am.include
|
||||
endif
|
||||
|
||||
if ENABLE_MODULE_ELLSWIFT
|
||||
include src/modules/ellswift/Makefile.am.include
|
||||
endif
|
||||
142
external/secp256k1/README.md
vendored
142
external/secp256k1/README.md
vendored
@@ -1,142 +0,0 @@
|
||||
libsecp256k1
|
||||
============
|
||||
|
||||

|
||||
[](https://web.libera.chat/#secp256k1)
|
||||
|
||||
High-performance high-assurance C library for digital signatures and other cryptographic primitives on the secp256k1 elliptic curve.
|
||||
|
||||
This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.
|
||||
|
||||
Features:
|
||||
* secp256k1 ECDSA signing/verification and key generation.
|
||||
* Additive and multiplicative tweaking of secret/public keys.
|
||||
* Serialization/parsing of secret keys, public keys, signatures.
|
||||
* Constant time, constant memory access signing and public key generation.
|
||||
* Derandomized ECDSA (via RFC6979 or with a caller provided function.)
|
||||
* Very efficient implementation.
|
||||
* Suitable for embedded systems.
|
||||
* No runtime dependencies.
|
||||
* Optional module for public key recovery.
|
||||
* Optional module for ECDH key exchange.
|
||||
* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
|
||||
* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
|
||||
* Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki).
|
||||
|
||||
Implementation details
|
||||
----------------------
|
||||
|
||||
* General
|
||||
* No runtime heap allocation.
|
||||
* Extensive testing infrastructure.
|
||||
* Structured to facilitate review and analysis.
|
||||
* Intended to be portable to any system with a C89 compiler and uint64_t support.
|
||||
* No use of floating types.
|
||||
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
|
||||
* Field operations
|
||||
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
|
||||
* Using 5 52-bit limbs
|
||||
* Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
|
||||
* This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community.
|
||||
* Scalar operations
|
||||
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
|
||||
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
|
||||
* Using 8 32-bit limbs.
|
||||
* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman).
|
||||
* Group operations
|
||||
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
|
||||
* Use addition between points in Jacobian and affine coordinates where possible.
|
||||
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
|
||||
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
|
||||
* Point multiplication for verification (a*P + b*G).
|
||||
* Use wNAF notation for point multiplicands.
|
||||
* Use a much larger window for multiples of G, using precomputed multiples.
|
||||
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
|
||||
* Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
|
||||
* Point multiplication for signing
|
||||
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
|
||||
* Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
|
||||
* Access the table with branch-free conditional moves so memory access is uniform.
|
||||
* No data-dependent branches
|
||||
* Optional runtime blinding which attempts to frustrate differential power analysis.
|
||||
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
|
||||
|
||||
Building with Autotools
|
||||
-----------------------
|
||||
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make check # run the test suite
|
||||
$ sudo make install # optional
|
||||
|
||||
To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.
|
||||
|
||||
Building with CMake (experimental)
|
||||
----------------------------------
|
||||
|
||||
To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.
|
||||
|
||||
### Building on POSIX systems
|
||||
|
||||
$ mkdir build && cd build
|
||||
$ cmake ..
|
||||
$ cmake --build .
|
||||
$ ctest # run the test suite
|
||||
$ sudo cmake --install . # optional
|
||||
|
||||
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags.
|
||||
|
||||
### Cross compiling
|
||||
|
||||
To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
|
||||
For example, to cross compile for Windows:
|
||||
|
||||
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake
|
||||
|
||||
To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):
|
||||
|
||||
$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
|
||||
|
||||
### Building on Windows
|
||||
|
||||
To build on Windows with Visual Studio, a proper [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) must be specified for a new build tree.
|
||||
|
||||
The following example assumes using of Visual Studio 2022 and CMake v3.21+.
|
||||
|
||||
In "Developer Command Prompt for VS 2022":
|
||||
|
||||
>cmake -G "Visual Studio 17 2022" -A x64 -S . -B build
|
||||
>cmake --build build --config RelWithDebInfo
|
||||
|
||||
Usage examples
|
||||
-----------
|
||||
Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
|
||||
* [ECDSA example](examples/ecdsa.c)
|
||||
* [Schnorr signatures example](examples/schnorr.c)
|
||||
* [Deriving a shared secret (ECDH) example](examples/ecdh.c)
|
||||
* [ElligatorSwift key exchange example](examples/ellswift.c)
|
||||
|
||||
To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`.
|
||||
|
||||
Benchmark
|
||||
------------
|
||||
If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build.
|
||||
|
||||
To print the benchmark result to the command line:
|
||||
|
||||
$ ./bench_name
|
||||
|
||||
To create a CSV file for the benchmark result :
|
||||
|
||||
$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
|
||||
|
||||
Reporting a vulnerability
|
||||
------------
|
||||
|
||||
See [SECURITY.md](SECURITY.md)
|
||||
|
||||
Contributing to libsecp256k1
|
||||
------------
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
15
external/secp256k1/SECURITY.md
vendored
15
external/secp256k1/SECURITY.md
vendored
@@ -1,15 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report security issues send an email to secp256k1-security@bitcoincore.org (not for support).
|
||||
|
||||
The following keys may be used to communicate sensitive information to developers:
|
||||
|
||||
| Name | Fingerprint |
|
||||
|------|-------------|
|
||||
| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 |
|
||||
| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 |
|
||||
| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 |
|
||||
|
||||
You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces.
|
||||
3
external/secp256k1/autogen.sh
vendored
3
external/secp256k1/autogen.sh
vendored
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
autoreconf -if --warnings=all
|
||||
91
external/secp256k1/build-aux/m4/bitcoin_secp.m4
vendored
91
external/secp256k1/build-aux/m4/bitcoin_secp.m4
vendored
@@ -1,91 +0,0 @@
|
||||
dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
|
||||
AC_DEFUN([SECP_X86_64_ASM_CHECK],[
|
||||
AC_MSG_CHECKING(for x86_64 assembly availability)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdint.h>]],[[
|
||||
uint64_t a = 11, tmp;
|
||||
__asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
|
||||
]])], [has_x86_64_asm=yes], [has_x86_64_asm=no])
|
||||
AC_MSG_RESULT([$has_x86_64_asm])
|
||||
])
|
||||
|
||||
AC_DEFUN([SECP_ARM32_ASM_CHECK], [
|
||||
AC_MSG_CHECKING(for ARM32 assembly availability)
|
||||
SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="-x assembler"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
.syntax unified
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ldr r0, =0x002A
|
||||
mov r7, #1
|
||||
swi 0
|
||||
]])], [has_arm32_asm=yes], [has_arm32_asm=no])
|
||||
AC_MSG_RESULT([$has_arm32_asm])
|
||||
CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS"
|
||||
])
|
||||
|
||||
AC_DEFUN([SECP_VALGRIND_CHECK],[
|
||||
AC_MSG_CHECKING([for valgrind support])
|
||||
if test x"$has_valgrind" != x"yes"; then
|
||||
CPPFLAGS_TEMP="$CPPFLAGS"
|
||||
CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <valgrind/memcheck.h>
|
||||
]], [[
|
||||
#if defined(NVALGRIND)
|
||||
# error "Valgrind does not support this platform."
|
||||
#endif
|
||||
]])], [has_valgrind=yes])
|
||||
CPPFLAGS="$CPPFLAGS_TEMP"
|
||||
fi
|
||||
AC_MSG_RESULT($has_valgrind)
|
||||
])
|
||||
|
||||
AC_DEFUN([SECP_MSAN_CHECK], [
|
||||
AC_MSG_CHECKING(whether MemorySanitizer is enabled)
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(memory_sanitizer)
|
||||
/* MemorySanitizer is enabled. */
|
||||
# elif
|
||||
# error "MemorySanitizer is disabled."
|
||||
# endif
|
||||
#else
|
||||
# error "__has_feature is not defined."
|
||||
#endif
|
||||
]])], [msan_enabled=yes], [msan_enabled=no])
|
||||
AC_MSG_RESULT([$msan_enabled])
|
||||
])
|
||||
|
||||
dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
|
||||
dnl Append flags to VAR if CC accepts them.
|
||||
AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [
|
||||
AC_MSG_CHECKING([if ${CC} supports $1])
|
||||
SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$1 $CFLAGS"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no])
|
||||
AC_MSG_RESULT($flag_works)
|
||||
CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS"
|
||||
if test x"$flag_works" = x"yes"; then
|
||||
$2="$$2 $1"
|
||||
fi
|
||||
unset flag_works
|
||||
AC_SUBST($2)
|
||||
])
|
||||
|
||||
dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode)
|
||||
dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled
|
||||
AC_DEFUN([SECP_SET_DEFAULT], [
|
||||
if test "${enable_dev_mode+set}" != set; then
|
||||
AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]])
|
||||
fi
|
||||
if test x"$enable_dev_mode" = x"yes"; then
|
||||
$1="$3"
|
||||
else
|
||||
$1="$2"
|
||||
fi
|
||||
])
|
||||
149
external/secp256k1/ci/ci.sh
vendored
149
external/secp256k1/ci/ci.sh
vendored
@@ -1,149 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
# Print commit and relevant CI environment to allow reproducing the job outside of CI.
|
||||
git show --no-patch
|
||||
print_environment() {
|
||||
# Turn off -x because it messes up the output
|
||||
set +x
|
||||
# There are many ways to print variable names and their content. This one
|
||||
# does not rely on bash.
|
||||
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
|
||||
ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
|
||||
EXPERIMENTAL ECDH RECOVERY EXTRAKEYS MUSIG SCHNORRSIG ELLSWIFT \
|
||||
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
|
||||
EXAMPLES \
|
||||
HOST WRAPPER_CMD \
|
||||
CC CFLAGS CPPFLAGS AR NM \
|
||||
UBSAN_OPTIONS ASAN_OPTIONS LSAN_OPTIONS
|
||||
do
|
||||
eval "isset=\${$var+x}"
|
||||
if [ -n "$isset" ]; then
|
||||
eval "val=\${$var}"
|
||||
# shellcheck disable=SC2154
|
||||
printf '%s="%s" ' "$var" "$val"
|
||||
fi
|
||||
done
|
||||
echo "$0"
|
||||
set -x
|
||||
}
|
||||
print_environment
|
||||
|
||||
env >> test_env.log
|
||||
|
||||
# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang).
|
||||
case "${CC:-undefined}" in
|
||||
*gcc*)
|
||||
$CC -v 2>&1 | grep -q "gcc version" || exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${CC+x}" ]; then
|
||||
# The MSVC compiler "cl" doesn't understand "-v"
|
||||
$CC -v || true
|
||||
fi
|
||||
if [ "$WITH_VALGRIND" = "yes" ]; then
|
||||
valgrind --version
|
||||
fi
|
||||
if [ -n "$WRAPPER_CMD" ]; then
|
||||
$WRAPPER_CMD --version
|
||||
fi
|
||||
|
||||
# Workaround for https://bugs.kde.org/show_bug.cgi?id=452758 (fixed in valgrind 3.20.0).
|
||||
case "${CC:-undefined}" in
|
||||
clang*)
|
||||
if [ "$CTIMETESTS" = "yes" ] && [ "$WITH_VALGRIND" = "yes" ]
|
||||
then
|
||||
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
|
||||
else
|
||||
case "$WRAPPER_CMD" in
|
||||
valgrind*)
|
||||
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
./autogen.sh
|
||||
|
||||
./configure \
|
||||
--enable-experimental="$EXPERIMENTAL" \
|
||||
--with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
|
||||
--with-ecmult-window="$ECMULTWINDOW" \
|
||||
--with-ecmult-gen-kb="$ECMULTGENKB" \
|
||||
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
|
||||
--enable-module-ellswift="$ELLSWIFT" \
|
||||
--enable-module-extrakeys="$EXTRAKEYS" \
|
||||
--enable-module-schnorrsig="$SCHNORRSIG" \
|
||||
--enable-module-musig="$MUSIG" \
|
||||
--enable-examples="$EXAMPLES" \
|
||||
--enable-ctime-tests="$CTIMETESTS" \
|
||||
--with-valgrind="$WITH_VALGRIND" \
|
||||
--host="$HOST" $EXTRAFLAGS
|
||||
|
||||
# We have set "-j<n>" in MAKEFLAGS.
|
||||
build_exit_code=0
|
||||
make > make.log 2>&1 || build_exit_code=$?
|
||||
cat make.log
|
||||
if [ $build_exit_code -ne 0 ]; then
|
||||
case "${CC:-undefined}" in
|
||||
*snapshot*)
|
||||
# Ignore internal compiler errors in gcc-snapshot and clang-snapshot
|
||||
grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log
|
||||
return $?;
|
||||
;;
|
||||
*)
|
||||
return 1;
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Print information about binaries so that we can see that the architecture is correct
|
||||
file *tests* || true
|
||||
file bench* || true
|
||||
file .libs/* || true
|
||||
|
||||
# This tells `make check` to wrap test invocations.
|
||||
export LOG_COMPILER="$WRAPPER_CMD"
|
||||
|
||||
make "$BUILD"
|
||||
|
||||
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
|
||||
EXEC='./libtool --mode=execute'
|
||||
if [ -n "$WRAPPER_CMD" ]
|
||||
then
|
||||
EXEC="$EXEC $WRAPPER_CMD"
|
||||
fi
|
||||
|
||||
if [ "$BENCH" = "yes" ]
|
||||
then
|
||||
{
|
||||
$EXEC ./bench_ecmult
|
||||
$EXEC ./bench_internal
|
||||
$EXEC ./bench
|
||||
} >> bench.log 2>&1
|
||||
fi
|
||||
|
||||
if [ "$CTIMETESTS" = "yes" ]
|
||||
then
|
||||
if [ "$WITH_VALGRIND" = "yes" ]; then
|
||||
./libtool --mode=execute valgrind --error-exitcode=42 ./ctime_tests > ctime_tests.log 2>&1
|
||||
else
|
||||
$EXEC ./ctime_tests > ctime_tests.log 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Rebuild precomputed files (if not cross-compiling).
|
||||
if [ -z "$HOST" ]
|
||||
then
|
||||
make clean-precomp clean-testvectors
|
||||
make precomp testvectors
|
||||
fi
|
||||
|
||||
# Check that no repo files have been modified by the build.
|
||||
# (This fails for example if the precomp files need to be updated in the repo.)
|
||||
git diff --exit-code
|
||||
79
external/secp256k1/ci/linux-debian.Dockerfile
vendored
79
external/secp256k1/ci/linux-debian.Dockerfile
vendored
@@ -1,79 +0,0 @@
|
||||
FROM debian:stable-slim
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
# A too high maximum number of file descriptors (with the default value
|
||||
# inherited from the docker host) can cause issues with some of our tools:
|
||||
# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
|
||||
# - valgrind crashing: https://stackoverflow.com/a/75293014
|
||||
# This is not be a problem on our CI hosts, but developers who run the image
|
||||
# on their machines may run into this (e.g., on Arch Linux), so warn them.
|
||||
# (Note that .bashrc is only executed in interactive bash shells.)
|
||||
RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc
|
||||
|
||||
RUN dpkg --add-architecture i386 && \
|
||||
dpkg --add-architecture s390x && \
|
||||
dpkg --add-architecture armhf && \
|
||||
dpkg --add-architecture arm64 && \
|
||||
dpkg --add-architecture ppc64el
|
||||
|
||||
# dkpg-dev: to make pkg-config work in cross-builds
|
||||
# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
git ca-certificates \
|
||||
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
|
||||
gcc clang llvm libclang-rt-dev libc6-dbg \
|
||||
g++ \
|
||||
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \
|
||||
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
|
||||
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
|
||||
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
|
||||
gcc-mingw-w64-x86-64-win32 wine64 wine \
|
||||
gcc-mingw-w64-i686-win32 wine32 \
|
||||
python3 && \
|
||||
if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \
|
||||
apt-get install --no-install-recommends -y \
|
||||
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\
|
||||
fi && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Build and install gcc snapshot
|
||||
ARG GCC_SNAPSHOT_MAJOR=15
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
|
||||
mkdir gcc && cd gcc && \
|
||||
wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
|
||||
wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \
|
||||
sha512sum --check --ignore-missing sha512.sum && \
|
||||
# We should have downloaded exactly one tar.xz file
|
||||
ls && \
|
||||
[ $(ls *.tar.xz | wc -l) -eq "1" ] && \
|
||||
tar xf *.tar.xz && \
|
||||
mkdir gcc-build && cd gcc-build && \
|
||||
../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \
|
||||
make -j $(nproc) && \
|
||||
make install && \
|
||||
cd ../.. && rm -rf gcc && \
|
||||
ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \
|
||||
apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install clang snapshot, see https://apt.llvm.org/
|
||||
RUN \
|
||||
# Setup GPG keys of LLVM repository
|
||||
apt-get update && apt-get install --no-install-recommends -y wget && \
|
||||
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
|
||||
# Add repository for this Debian release
|
||||
. /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
# Determine the version number of the LLVM development branch
|
||||
LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \
|
||||
# Install
|
||||
apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \
|
||||
# Create symlink
|
||||
ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \
|
||||
# Clean up
|
||||
apt-get autoremove -y wget && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
function(check_arm32_assembly)
|
||||
try_compile(HAVE_ARM32_ASM
|
||||
${PROJECT_BINARY_DIR}/check_arm32_assembly
|
||||
SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s
|
||||
)
|
||||
endfunction()
|
||||
@@ -1,18 +0,0 @@
|
||||
include_guard(GLOBAL)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
function(check_memory_sanitizer output)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
check_c_source_compiles("
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(memory_sanitizer)
|
||||
/* MemorySanitizer is enabled. */
|
||||
# elif
|
||||
# error \"MemorySanitizer is disabled.\"
|
||||
# endif
|
||||
#else
|
||||
# error \"__has_feature is not defined.\"
|
||||
#endif
|
||||
" HAVE_MSAN)
|
||||
set(${output} ${HAVE_MSAN} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -1,10 +0,0 @@
|
||||
function(check_string_option_value option)
|
||||
get_property(expected_values CACHE ${option} PROPERTY STRINGS)
|
||||
if(expected_values)
|
||||
if(${option} IN_LIST expected_values)
|
||||
return()
|
||||
endif()
|
||||
message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.")
|
||||
endif()
|
||||
message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.")
|
||||
endfunction()
|
||||
@@ -1,14 +0,0 @@
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
function(check_x86_64_assembly)
|
||||
check_c_source_compiles("
|
||||
#include <stdint.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
uint64_t a = 11, tmp;
|
||||
__asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");
|
||||
}
|
||||
" HAVE_X86_64_ASM)
|
||||
set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE)
|
||||
endfunction()
|
||||
41
external/secp256k1/cmake/FindValgrind.cmake
vendored
41
external/secp256k1/cmake/FindValgrind.cmake
vendored
@@ -1,41 +0,0 @@
|
||||
if(CMAKE_HOST_APPLE)
|
||||
find_program(BREW_COMMAND brew)
|
||||
execute_process(
|
||||
COMMAND ${BREW_COMMAND} --prefix valgrind
|
||||
OUTPUT_VARIABLE valgrind_brew_prefix
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
|
||||
set(hints_paths)
|
||||
if(valgrind_brew_prefix)
|
||||
set(hints_paths ${valgrind_brew_prefix}/include)
|
||||
endif()
|
||||
|
||||
find_path(Valgrind_INCLUDE_DIR
|
||||
NAMES valgrind/memcheck.h
|
||||
HINTS ${hints_paths}
|
||||
)
|
||||
|
||||
if(Valgrind_INCLUDE_DIR)
|
||||
include(CheckCSourceCompiles)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR})
|
||||
check_c_source_compiles("
|
||||
#include <valgrind/memcheck.h>
|
||||
#if defined(NVALGRIND)
|
||||
# error \"Valgrind does not support this platform.\"
|
||||
#endif
|
||||
|
||||
int main() {}
|
||||
" Valgrind_WORKS)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Valgrind
|
||||
REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
Valgrind_INCLUDE_DIR
|
||||
)
|
||||
@@ -1,8 +0,0 @@
|
||||
function(generate_pkg_config_file in_file)
|
||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(exec_prefix \${prefix})
|
||||
set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
|
||||
set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY)
|
||||
endfunction()
|
||||
24
external/secp256k1/cmake/TryAppendCFlags.cmake
vendored
24
external/secp256k1/cmake/TryAppendCFlags.cmake
vendored
@@ -1,24 +0,0 @@
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
function(secp256k1_check_c_flags_internal flags output)
|
||||
string(MAKE_C_IDENTIFIER "${flags}" result)
|
||||
string(TOUPPER "${result}" result)
|
||||
set(result "C_SUPPORTS_${result}")
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
endif()
|
||||
|
||||
# This avoids running a linker.
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
check_c_compiler_flag("${flags}" ${result})
|
||||
|
||||
set(${output} ${${result}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Append flags to the COMPILE_OPTIONS directory property if CC accepts them.
|
||||
macro(try_append_c_flags)
|
||||
secp256k1_check_c_flags_internal("${ARGV}" result)
|
||||
if(result)
|
||||
add_compile_options(${ARGV})
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -1,3 +0,0 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
5
external/secp256k1/cmake/config.cmake.in
vendored
5
external/secp256k1/cmake/config.cmake.in
vendored
@@ -1,5 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
|
||||
|
||||
check_required_components(@PROJECT_NAME@)
|
||||
9
external/secp256k1/cmake/source_arm32.s
vendored
9
external/secp256k1/cmake/source_arm32.s
vendored
@@ -1,9 +0,0 @@
|
||||
.syntax unified
|
||||
.eabi_attribute 24, 1
|
||||
.eabi_attribute 25, 1
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
ldr r0, =0x002A
|
||||
mov r7, #1
|
||||
swi 0
|
||||
@@ -1,3 +0,0 @@
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
|
||||
517
external/secp256k1/configure.ac
vendored
517
external/secp256k1/configure.ac
vendored
@@ -1,517 +0,0 @@
|
||||
AC_PREREQ([2.60])
|
||||
|
||||
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
|
||||
# the API. All changes in experimental modules are treated as
|
||||
# backwards-compatible and therefore at most increase the minor version.
|
||||
define(_PKG_VERSION_MAJOR, 0)
|
||||
define(_PKG_VERSION_MINOR, 6)
|
||||
define(_PKG_VERSION_PATCH, 0)
|
||||
define(_PKG_VERSION_IS_RELEASE, true)
|
||||
|
||||
# The library version is based on libtool versioning of the ABI. The set of
|
||||
# rules for updating the version can be found here:
|
||||
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
# All changes in experimental modules are treated as if they don't affect the
|
||||
# interface and therefore only increase the revision.
|
||||
define(_LIB_VERSION_CURRENT, 5)
|
||||
define(_LIB_VERSION_REVISION, 0)
|
||||
define(_LIB_VERSION_AGE, 0)
|
||||
|
||||
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([build-aux/m4])
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
# Require Automake 1.11.2 for AM_PROG_AR
|
||||
AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
|
||||
|
||||
# Make the compilation flags quiet unless V=1 is used.
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
if test "${CFLAGS+set}" = "set"; then
|
||||
CFLAGS_overridden=yes
|
||||
else
|
||||
CFLAGS_overridden=no
|
||||
fi
|
||||
AC_PROG_CC
|
||||
AM_PROG_AS
|
||||
AM_PROG_AR
|
||||
|
||||
# Clear some cache variables as a workaround for a bug that appears due to a bad
|
||||
# interaction between AM_PROG_AR and LT_INIT when combining MSVC's archiver lib.exe.
|
||||
# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54421
|
||||
AS_UNSET(ac_cv_prog_AR)
|
||||
AS_UNSET(ac_cv_prog_ac_ct_AR)
|
||||
LT_INIT([win32-dll])
|
||||
|
||||
build_windows=no
|
||||
|
||||
case $host_os in
|
||||
*darwin*)
|
||||
if test x$cross_compiling != xyes; then
|
||||
AC_CHECK_PROG([BREW], brew, brew)
|
||||
if test x$BREW = xbrew; then
|
||||
# These Homebrew packages may be keg-only, meaning that they won't be found
|
||||
# in expected paths because they may conflict with system files. Ask
|
||||
# Homebrew where each one is located, then adjust paths accordingly.
|
||||
if $BREW list --versions valgrind >/dev/null; then
|
||||
valgrind_prefix=$($BREW --prefix valgrind 2>/dev/null)
|
||||
VALGRIND_CPPFLAGS="-I$valgrind_prefix/include"
|
||||
fi
|
||||
else
|
||||
AC_CHECK_PROG([PORT], port, port)
|
||||
# If homebrew isn't installed and macports is, add the macports default paths
|
||||
# as a last resort.
|
||||
if test x$PORT = xport; then
|
||||
CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/opt/local/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
cygwin*|mingw*)
|
||||
build_windows=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
# Try if some desirable compiler flags are supported and append them to SECP_CFLAGS.
|
||||
#
|
||||
# These are our own flags, so we append them to our own SECP_CFLAGS variable (instead of CFLAGS) as
|
||||
# recommended in the automake manual (Section "Flag Variables Ordering"). CFLAGS belongs to the user
|
||||
# and we are not supposed to touch it. In the Makefile, we will need to ensure that SECP_CFLAGS
|
||||
# is prepended to CFLAGS when invoking the compiler so that the user always has the last word (flag).
|
||||
#
|
||||
# Another advantage of not touching CFLAGS is that the contents of CFLAGS will be picked up by
|
||||
# libtool for compiling helper executables. For example, when compiling for Windows, libtool will
|
||||
# generate entire wrapper executables (instead of simple wrapper scripts as on Unix) to ensure
|
||||
# proper operation of uninstalled programs linked by libtool against the uninstalled shared library.
|
||||
# These executables are compiled from C source file for which our flags may not be appropriate,
|
||||
# e.g., -std=c89 flag has lead to undesirable warnings in the past.
|
||||
#
|
||||
# TODO We should analogously not touch CPPFLAGS and LDFLAGS but currently there are no issues.
|
||||
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
|
||||
# GCC and compatible (incl. clang)
|
||||
if test "x$GCC" = "xyes"; then
|
||||
# Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported
|
||||
# flags will succeed.
|
||||
# Note that failure to append -Werror does not necessarily mean that -Werror is not
|
||||
# supported. The compiler may already be warning about something unrelated, for example
|
||||
# about some path issue. If that is the case, -Werror cannot be used because all
|
||||
# of those warnings would be turned into errors.
|
||||
SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
|
||||
SECP_TRY_APPEND_CFLAGS([-Werror], CFLAGS)
|
||||
|
||||
SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
|
||||
SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
|
||||
SECP_TRY_APPEND_CFLAGS([-Wall], $1) # GCC >= 2.95 and probably many other compilers
|
||||
SECP_TRY_APPEND_CFLAGS([-Wno-unused-function], $1) # GCC >= 3.0, -Wunused-function is implied by -Wall.
|
||||
SECP_TRY_APPEND_CFLAGS([-Wextra], $1) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
|
||||
SECP_TRY_APPEND_CFLAGS([-Wcast-align], $1) # GCC >= 2.95
|
||||
SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0
|
||||
SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only
|
||||
SECP_TRY_APPEND_CFLAGS([-Wreserved-identifier], $1) # Clang >= 13.0 only
|
||||
SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0
|
||||
|
||||
CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS"
|
||||
fi
|
||||
|
||||
# MSVC
|
||||
# Assume MSVC if we're building for Windows but not with GCC or compatible;
|
||||
# libtool makes the same assumption internally.
|
||||
# Note that "/opt" and "-opt" are equivalent for MSVC; we use "-opt" because "/opt" looks like a path.
|
||||
if test x"$GCC" != x"yes" && test x"$build_windows" = x"yes"; then
|
||||
SECP_TRY_APPEND_CFLAGS([-W3], $1) # Production quality warning level.
|
||||
SECP_TRY_APPEND_CFLAGS([-wd4146], $1) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
|
||||
SECP_TRY_APPEND_CFLAGS([-wd4244], $1) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
|
||||
SECP_TRY_APPEND_CFLAGS([-wd4267], $1) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
|
||||
# Eliminate deprecation warnings for the older, less secure functions.
|
||||
CPPFLAGS="-D_CRT_SECURE_NO_WARNINGS $CPPFLAGS"
|
||||
fi
|
||||
])
|
||||
SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS)
|
||||
|
||||
###
|
||||
### Define config arguments
|
||||
###
|
||||
|
||||
# In dev mode, we enable all binaries and modules by default but individual options can still be overridden explicitly.
|
||||
# Check for dev mode first because SECP_SET_DEFAULT needs enable_dev_mode set.
|
||||
AC_ARG_ENABLE(dev_mode, [], [],
|
||||
[enable_dev_mode=no])
|
||||
|
||||
AC_ARG_ENABLE(benchmark,
|
||||
AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_benchmark], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(coverage,
|
||||
AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]), [],
|
||||
[SECP_SET_DEFAULT([enable_coverage], [no], [no])])
|
||||
|
||||
AC_ARG_ENABLE(tests,
|
||||
AS_HELP_STRING([--enable-tests],[compile tests [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_tests], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(ctime_tests,
|
||||
AS_HELP_STRING([--enable-ctime-tests],[compile constant-time tests [default=yes if valgrind enabled]]), [],
|
||||
[SECP_SET_DEFAULT([enable_ctime_tests], [auto], [auto])])
|
||||
|
||||
AC_ARG_ENABLE(experimental,
|
||||
AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]), [],
|
||||
[SECP_SET_DEFAULT([enable_experimental], [no], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(exhaustive_tests,
|
||||
AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_exhaustive_tests], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(examples,
|
||||
AS_HELP_STRING([--enable-examples],[compile the examples [default=no]]), [],
|
||||
[SECP_SET_DEFAULT([enable_examples], [no], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_ecdh,
|
||||
AS_HELP_STRING([--enable-module-ecdh],[enable ECDH module [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_ecdh], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_recovery,
|
||||
AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module [default=no]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_recovery], [no], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_extrakeys,
|
||||
AS_HELP_STRING([--enable-module-extrakeys],[enable extrakeys module [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_extrakeys], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_schnorrsig,
|
||||
AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_schnorrsig], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_musig,
|
||||
AS_HELP_STRING([--enable-module-musig],[enable MuSig2 module [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_musig], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(module_ellswift,
|
||||
AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
|
||||
[SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])])
|
||||
|
||||
AC_ARG_ENABLE(external_default_callbacks,
|
||||
AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
|
||||
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
|
||||
|
||||
# Test-only override of the (autodetected by the C code) "widemul" setting.
|
||||
# Legal values are:
|
||||
# * int64 (for [u]int64_t),
|
||||
# * int128 (for [unsigned] __int128),
|
||||
# * int128_struct (for int128 implemented as a structure),
|
||||
# * and auto (the default).
|
||||
AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto])
|
||||
|
||||
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm32|no|auto],
|
||||
[assembly to use (experimental: arm32) [default=auto]])],[req_asm=$withval], [req_asm=auto])
|
||||
|
||||
AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE],
|
||||
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
|
||||
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
|
||||
[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
|
||||
[A window size larger than 15 will require you delete the prebuilt precomputed_ecmult.c file so that it can be rebuilt.]
|
||||
[For very large window sizes, use "make -j 1" to reduce memory use during compilation.]
|
||||
[The default value is a reasonable setting for desktop machines (currently 15). [default=15]]
|
||||
)],
|
||||
[set_ecmult_window=$withval], [set_ecmult_window=15])
|
||||
|
||||
AC_ARG_WITH([ecmult-gen-kb], [AS_HELP_STRING([--with-ecmult-gen-kb=2|22|86],
|
||||
[The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms).]
|
||||
[Larger values result in possibly better signing/keygeneration performance at the cost of a larger table.]
|
||||
[The default value is a reasonable setting for desktop machines (currently 86). [default=86]]
|
||||
)],
|
||||
[set_ecmult_gen_kb=$withval], [set_ecmult_gen_kb=86])
|
||||
|
||||
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto],
|
||||
[Build with extra checks for running inside Valgrind [default=auto]]
|
||||
)],
|
||||
[req_valgrind=$withval], [req_valgrind=auto])
|
||||
|
||||
###
|
||||
### Handle config options (except for modules)
|
||||
###
|
||||
|
||||
if test x"$req_valgrind" = x"no"; then
|
||||
enable_valgrind=no
|
||||
else
|
||||
SECP_VALGRIND_CHECK
|
||||
if test x"$has_valgrind" != x"yes"; then
|
||||
if test x"$req_valgrind" = x"yes"; then
|
||||
AC_MSG_ERROR([Valgrind support explicitly requested but valgrind/memcheck.h header not available])
|
||||
fi
|
||||
enable_valgrind=no
|
||||
else
|
||||
enable_valgrind=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x"$enable_ctime_tests" = x"auto"; then
|
||||
enable_ctime_tests=$enable_valgrind
|
||||
fi
|
||||
|
||||
print_msan_notice=no
|
||||
if test x"$enable_ctime_tests" = x"yes"; then
|
||||
SECP_MSAN_CHECK
|
||||
# MSan on Clang >=16 reports unitialized memory in function parameters and return values, even if
|
||||
# the uninitalized variable is never actually "used". This is called "eager" checking, and it's
|
||||
# sounds like good idea for normal use of MSan. However, it yields many false positives in the
|
||||
# ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and
|
||||
# we're only interested in detecting branches (which count as "uses") on secret data.
|
||||
if test x"$msan_enabled" = x"yes"; then
|
||||
SECP_TRY_APPEND_CFLAGS([-fno-sanitize-memory-param-retval], SECP_CFLAGS)
|
||||
print_msan_notice=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x"$enable_coverage" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
|
||||
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
|
||||
# If coverage is enabled, and the user has not overridden CFLAGS,
|
||||
# override Autoconf's value "-g -O2" with "-g". Otherwise we'd end up
|
||||
# with "-O0 --coverage -g -O2".
|
||||
if test "$CFLAGS_overridden" = "no"; then
|
||||
CFLAGS="-g"
|
||||
fi
|
||||
LDFLAGS="--coverage $LDFLAGS"
|
||||
else
|
||||
# Most likely the CFLAGS already contain -O2 because that is autoconf's default.
|
||||
# We still add it here because passing it twice is not an issue, and handling
|
||||
# this case would just add unnecessary complexity (see #896).
|
||||
SECP_CFLAGS="-O2 $SECP_CFLAGS"
|
||||
fi
|
||||
|
||||
if test x"$req_asm" = x"auto"; then
|
||||
SECP_X86_64_ASM_CHECK
|
||||
if test x"$has_x86_64_asm" = x"yes"; then
|
||||
set_asm=x86_64
|
||||
fi
|
||||
if test x"$set_asm" = x; then
|
||||
set_asm=no
|
||||
fi
|
||||
else
|
||||
set_asm=$req_asm
|
||||
case $set_asm in
|
||||
x86_64)
|
||||
SECP_X86_64_ASM_CHECK
|
||||
if test x"$has_x86_64_asm" != x"yes"; then
|
||||
AC_MSG_ERROR([x86_64 assembly requested but not available])
|
||||
fi
|
||||
;;
|
||||
arm32)
|
||||
SECP_ARM32_ASM_CHECK
|
||||
if test x"$has_arm32_asm" != x"yes"; then
|
||||
AC_MSG_ERROR([ARM32 assembly requested but not available])
|
||||
fi
|
||||
;;
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([invalid assembly selection])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Select assembly
|
||||
enable_external_asm=no
|
||||
|
||||
case $set_asm in
|
||||
x86_64)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_ASM_X86_64=1"
|
||||
;;
|
||||
arm32)
|
||||
enable_external_asm=yes
|
||||
;;
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([invalid assembly selection])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$enable_external_asm" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_ASM=1"
|
||||
fi
|
||||
|
||||
|
||||
# Select wide multiplication implementation
|
||||
case $set_widemul in
|
||||
int128_struct)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128_STRUCT=1"
|
||||
;;
|
||||
int128)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT128=1"
|
||||
;;
|
||||
int64)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_FORCE_WIDEMUL_INT64=1"
|
||||
;;
|
||||
auto)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([invalid wide multiplication implementation])
|
||||
;;
|
||||
esac
|
||||
|
||||
error_window_size=['window size for ecmult precomputation not an integer in range [2..24]']
|
||||
case $set_ecmult_window in
|
||||
''|*[[!0-9]]*)
|
||||
# no valid integer
|
||||
AC_MSG_ERROR($error_window_size)
|
||||
;;
|
||||
*)
|
||||
if test "$set_ecmult_window" -lt 2 -o "$set_ecmult_window" -gt 24 ; then
|
||||
# not in range
|
||||
AC_MSG_ERROR($error_window_size)
|
||||
fi
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DECMULT_WINDOW_SIZE=$set_ecmult_window"
|
||||
;;
|
||||
esac
|
||||
|
||||
case $set_ecmult_gen_kb in
|
||||
2)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=2 -DCOMB_TEETH=5"
|
||||
;;
|
||||
22)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=11 -DCOMB_TEETH=6"
|
||||
;;
|
||||
86)
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=43 -DCOMB_TEETH=6"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR(['ecmult gen table size not 2, 22 or 86'])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$enable_valgrind" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES $VALGRIND_CPPFLAGS -DVALGRIND"
|
||||
fi
|
||||
|
||||
# Add -Werror and similar flags passed from the outside (for testing, e.g., in CI).
|
||||
# We don't want to set the user variable CFLAGS in CI because this would disable
|
||||
# autoconf's logic for setting default CFLAGS, which we would like to test in CI.
|
||||
SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS"
|
||||
|
||||
###
|
||||
### Handle module options
|
||||
###
|
||||
|
||||
# Processing must be done in a reverse topological sorting of the dependency graph
|
||||
# (dependent module first).
|
||||
if test x"$enable_module_ellswift" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_module_musig" = x"yes"; then
|
||||
if test x"$enable_module_schnorrsig" = x"no"; then
|
||||
AC_MSG_ERROR([Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.])
|
||||
fi
|
||||
enable_module_schnorrsig=yes
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_MUSIG=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_module_schnorrsig" = x"yes"; then
|
||||
if test x"$enable_module_extrakeys" = x"no"; then
|
||||
AC_MSG_ERROR([Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.])
|
||||
fi
|
||||
enable_module_extrakeys=yes
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_SCHNORRSIG=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_module_extrakeys" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_EXTRAKEYS=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_module_recovery" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_RECOVERY=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_module_ecdh" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDH=1"
|
||||
fi
|
||||
|
||||
if test x"$enable_external_default_callbacks" = x"yes"; then
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1"
|
||||
fi
|
||||
|
||||
###
|
||||
### Check for --enable-experimental if necessary
|
||||
###
|
||||
|
||||
if test x"$enable_experimental" = x"no"; then
|
||||
if test x"$set_asm" = x"arm32"; then
|
||||
AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.])
|
||||
fi
|
||||
fi
|
||||
|
||||
###
|
||||
### Generate output
|
||||
###
|
||||
|
||||
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
|
||||
AC_SUBST(SECP_CFLAGS)
|
||||
AC_SUBST(SECP_CONFIG_DEFINES)
|
||||
AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"])
|
||||
AM_CONDITIONAL([USE_TESTS], [test x"$enable_tests" != x"no"])
|
||||
AM_CONDITIONAL([USE_CTIME_TESTS], [test x"$enable_ctime_tests" = x"yes"])
|
||||
AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$enable_exhaustive_tests" != x"no"])
|
||||
AM_CONDITIONAL([USE_EXAMPLES], [test x"$enable_examples" != x"no"])
|
||||
AM_CONDITIONAL([USE_BENCHMARK], [test x"$enable_benchmark" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"])
|
||||
AM_CONDITIONAL([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = x"yes"])
|
||||
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
|
||||
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"])
|
||||
AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
|
||||
AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT)
|
||||
AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION)
|
||||
AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
echo
|
||||
echo "Build Options:"
|
||||
echo " with external callbacks = $enable_external_default_callbacks"
|
||||
echo " with benchmarks = $enable_benchmark"
|
||||
echo " with tests = $enable_tests"
|
||||
echo " with ctime tests = $enable_ctime_tests"
|
||||
echo " with coverage = $enable_coverage"
|
||||
echo " with examples = $enable_examples"
|
||||
echo " module ecdh = $enable_module_ecdh"
|
||||
echo " module recovery = $enable_module_recovery"
|
||||
echo " module extrakeys = $enable_module_extrakeys"
|
||||
echo " module schnorrsig = $enable_module_schnorrsig"
|
||||
echo " module musig = $enable_module_musig"
|
||||
echo " module ellswift = $enable_module_ellswift"
|
||||
echo
|
||||
echo " asm = $set_asm"
|
||||
echo " ecmult window size = $set_ecmult_window"
|
||||
echo " ecmult gen table size = $set_ecmult_gen_kb KiB"
|
||||
# Hide test-only options unless they're used.
|
||||
if test x"$set_widemul" != xauto; then
|
||||
echo " wide multiplication = $set_widemul"
|
||||
fi
|
||||
echo
|
||||
echo " valgrind = $enable_valgrind"
|
||||
echo " CC = $CC"
|
||||
echo " CPPFLAGS = $CPPFLAGS"
|
||||
echo " SECP_CFLAGS = $SECP_CFLAGS"
|
||||
echo " CFLAGS = $CFLAGS"
|
||||
echo " LDFLAGS = $LDFLAGS"
|
||||
|
||||
if test x"$print_msan_notice" = x"yes"; then
|
||||
echo
|
||||
echo "Note:"
|
||||
echo " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to SECP_CFLAGS"
|
||||
echo " to avoid false positives in ctime_tests. Pass --disable-ctime-tests to avoid this."
|
||||
fi
|
||||
|
||||
if test x"$enable_experimental" = x"yes"; then
|
||||
echo
|
||||
echo "WARNING: Experimental build"
|
||||
echo " Experimental features do not have stable APIs or properties, and may not be safe for"
|
||||
echo " production use."
|
||||
fi
|
||||
148
external/secp256k1/contrib/lax_der_parsing.c
vendored
148
external/secp256k1/contrib/lax_der_parsing.c
vendored
@@ -1,148 +0,0 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2015 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||
***********************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lax_der_parsing.h"
|
||||
|
||||
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
|
||||
size_t rpos, rlen, spos, slen;
|
||||
size_t pos = 0;
|
||||
size_t lenbyte;
|
||||
unsigned char tmpsig[64] = {0};
|
||||
int overflow = 0;
|
||||
|
||||
/* Hack to initialize sig with a correctly-parsed but invalid signature. */
|
||||
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
|
||||
|
||||
/* Sequence tag byte */
|
||||
if (pos == inputlen || input[pos] != 0x30) {
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
|
||||
/* Sequence length bytes */
|
||||
if (pos == inputlen) {
|
||||
return 0;
|
||||
}
|
||||
lenbyte = input[pos++];
|
||||
if (lenbyte & 0x80) {
|
||||
lenbyte -= 0x80;
|
||||
if (lenbyte > inputlen - pos) {
|
||||
return 0;
|
||||
}
|
||||
pos += lenbyte;
|
||||
}
|
||||
|
||||
/* Integer tag byte for R */
|
||||
if (pos == inputlen || input[pos] != 0x02) {
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
|
||||
/* Integer length for R */
|
||||
if (pos == inputlen) {
|
||||
return 0;
|
||||
}
|
||||
lenbyte = input[pos++];
|
||||
if (lenbyte & 0x80) {
|
||||
lenbyte -= 0x80;
|
||||
if (lenbyte > inputlen - pos) {
|
||||
return 0;
|
||||
}
|
||||
while (lenbyte > 0 && input[pos] == 0) {
|
||||
pos++;
|
||||
lenbyte--;
|
||||
}
|
||||
if (lenbyte >= sizeof(size_t)) {
|
||||
return 0;
|
||||
}
|
||||
rlen = 0;
|
||||
while (lenbyte > 0) {
|
||||
rlen = (rlen << 8) + input[pos];
|
||||
pos++;
|
||||
lenbyte--;
|
||||
}
|
||||
} else {
|
||||
rlen = lenbyte;
|
||||
}
|
||||
if (rlen > inputlen - pos) {
|
||||
return 0;
|
||||
}
|
||||
rpos = pos;
|
||||
pos += rlen;
|
||||
|
||||
/* Integer tag byte for S */
|
||||
if (pos == inputlen || input[pos] != 0x02) {
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
|
||||
/* Integer length for S */
|
||||
if (pos == inputlen) {
|
||||
return 0;
|
||||
}
|
||||
lenbyte = input[pos++];
|
||||
if (lenbyte & 0x80) {
|
||||
lenbyte -= 0x80;
|
||||
if (lenbyte > inputlen - pos) {
|
||||
return 0;
|
||||
}
|
||||
while (lenbyte > 0 && input[pos] == 0) {
|
||||
pos++;
|
||||
lenbyte--;
|
||||
}
|
||||
if (lenbyte >= sizeof(size_t)) {
|
||||
return 0;
|
||||
}
|
||||
slen = 0;
|
||||
while (lenbyte > 0) {
|
||||
slen = (slen << 8) + input[pos];
|
||||
pos++;
|
||||
lenbyte--;
|
||||
}
|
||||
} else {
|
||||
slen = lenbyte;
|
||||
}
|
||||
if (slen > inputlen - pos) {
|
||||
return 0;
|
||||
}
|
||||
spos = pos;
|
||||
|
||||
/* Ignore leading zeroes in R */
|
||||
while (rlen > 0 && input[rpos] == 0) {
|
||||
rlen--;
|
||||
rpos++;
|
||||
}
|
||||
/* Copy R value */
|
||||
if (rlen > 32) {
|
||||
overflow = 1;
|
||||
} else if (rlen) {
|
||||
memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
|
||||
}
|
||||
|
||||
/* Ignore leading zeroes in S */
|
||||
while (slen > 0 && input[spos] == 0) {
|
||||
slen--;
|
||||
spos++;
|
||||
}
|
||||
/* Copy S value */
|
||||
if (slen > 32) {
|
||||
overflow = 1;
|
||||
} else if (slen) {
|
||||
memcpy(tmpsig + 64 - slen, input + spos, slen);
|
||||
}
|
||||
|
||||
if (!overflow) {
|
||||
overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
|
||||
}
|
||||
if (overflow) {
|
||||
memset(tmpsig, 0, 64);
|
||||
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
97
external/secp256k1/contrib/lax_der_parsing.h
vendored
97
external/secp256k1/contrib/lax_der_parsing.h
vendored
@@ -1,97 +0,0 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2015 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||
***********************************************************************/
|
||||
|
||||
/****
|
||||
* Please do not link this file directly. It is not part of the libsecp256k1
|
||||
* project and does not promise any stability in its API, functionality or
|
||||
* presence. Projects which use this code should instead copy this header
|
||||
* and its accompanying .c file directly into their codebase.
|
||||
****/
|
||||
|
||||
/* This file defines a function that parses DER with various errors and
|
||||
* violations. This is not a part of the library itself, because the allowed
|
||||
* violations are chosen arbitrarily and do not follow or establish any
|
||||
* standard.
|
||||
*
|
||||
* In many places it matters that different implementations do not only accept
|
||||
* the same set of valid signatures, but also reject the same set of signatures.
|
||||
* The only means to accomplish that is by strictly obeying a standard, and not
|
||||
* accepting anything else.
|
||||
*
|
||||
* Nonetheless, sometimes there is a need for compatibility with systems that
|
||||
* use signatures which do not strictly obey DER. The snippet below shows how
|
||||
* certain violations are easily supported. You may need to adapt it.
|
||||
*
|
||||
* Do not use this for new systems. Use well-defined DER or compact signatures
|
||||
* instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and
|
||||
* secp256k1_ecdsa_signature_parse_compact).
|
||||
*
|
||||
* The supported violations are:
|
||||
* - All numbers are parsed as nonnegative integers, even though X.609-0207
|
||||
* section 8.3.3 specifies that integers are always encoded as two's
|
||||
* complement.
|
||||
* - Integers can have length 0, even though section 8.3.1 says they can't.
|
||||
* - Integers with overly long padding are accepted, violation section
|
||||
* 8.3.2.
|
||||
* - 127-byte long length descriptors are accepted, even though section
|
||||
* 8.1.3.5.c says that they are not.
|
||||
* - Trailing garbage data inside or after the signature is ignored.
|
||||
* - The length descriptor of the sequence is ignored.
|
||||
*
|
||||
* Compared to for example OpenSSL, many violations are NOT supported:
|
||||
* - Using overly long tag descriptors for the sequence or integers inside,
|
||||
* violating section 8.1.2.2.
|
||||
* - Encoding primitive integers as constructed values, violating section
|
||||
* 8.3.1.
|
||||
*/
|
||||
|
||||
#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
||||
#define SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
||||
|
||||
/* #include secp256k1.h only when it hasn't been included yet.
|
||||
This enables this file to be #included directly in other project
|
||||
files (such as tests.c) without the need to set an explicit -I flag,
|
||||
which would be necessary to locate secp256k1.h. */
|
||||
#ifndef SECP256K1_H
|
||||
#include <secp256k1.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Parse a signature in "lax DER" format
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sig: pointer to a signature object
|
||||
* In: input: pointer to the signature to be parsed
|
||||
* inputlen: the length of the array pointed to be input
|
||||
*
|
||||
* This function will accept any valid DER encoded signature, even if the
|
||||
* encoded numbers are out of range. In addition, it will accept signatures
|
||||
* which violate the DER spec in various ways. Its purpose is to allow
|
||||
* validation of the Bitcoin blockchain, which includes non-DER signatures
|
||||
* from before the network rules were updated to enforce DER. Note that
|
||||
* the set of supported violations is a strict subset of what OpenSSL will
|
||||
* accept.
|
||||
*
|
||||
* After the call, sig will always be initialized. If parsing failed or the
|
||||
* encoded numbers are out of range, signature validation with it is
|
||||
* guaranteed to fail for every message and public key.
|
||||
*/
|
||||
int ecdsa_signature_parse_der_lax(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */
|
||||
@@ -1,112 +0,0 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2014, 2015 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||
***********************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lax_der_privatekey_parsing.h"
|
||||
|
||||
int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) {
|
||||
const unsigned char *end = privkey + privkeylen;
|
||||
int lenb = 0;
|
||||
int len = 0;
|
||||
memset(out32, 0, 32);
|
||||
/* sequence header */
|
||||
if (end < privkey+1 || *privkey != 0x30) {
|
||||
return 0;
|
||||
}
|
||||
privkey++;
|
||||
/* sequence length constructor */
|
||||
if (end < privkey+1 || !(*privkey & 0x80)) {
|
||||
return 0;
|
||||
}
|
||||
lenb = *privkey & ~0x80; privkey++;
|
||||
if (lenb < 1 || lenb > 2) {
|
||||
return 0;
|
||||
}
|
||||
if (end < privkey+lenb) {
|
||||
return 0;
|
||||
}
|
||||
/* sequence length */
|
||||
len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
|
||||
privkey += lenb;
|
||||
if (end < privkey+len) {
|
||||
return 0;
|
||||
}
|
||||
/* sequence element 0: version number (=1) */
|
||||
if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) {
|
||||
return 0;
|
||||
}
|
||||
privkey += 3;
|
||||
/* sequence element 1: octet string, up to 32 bytes */
|
||||
if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
|
||||
return 0;
|
||||
}
|
||||
if (privkey[1]) memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
|
||||
if (!secp256k1_ec_seckey_verify(ctx, out32)) {
|
||||
memset(out32, 0, 32);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
|
||||
secp256k1_pubkey pubkey;
|
||||
size_t pubkeylen = 0;
|
||||
if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
|
||||
*privkeylen = 0;
|
||||
return 0;
|
||||
}
|
||||
if (compressed) {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
static const unsigned char middle[] = {
|
||||
0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
|
||||
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
|
||||
0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
|
||||
0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
|
||||
0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
|
||||
0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
|
||||
};
|
||||
unsigned char *ptr = privkey;
|
||||
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
|
||||
memcpy(ptr, key32, 32); ptr += 32;
|
||||
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
|
||||
pubkeylen = 33;
|
||||
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
|
||||
ptr += pubkeylen;
|
||||
*privkeylen = ptr - privkey;
|
||||
} else {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
static const unsigned char middle[] = {
|
||||
0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
|
||||
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
|
||||
0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
|
||||
0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
|
||||
0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
|
||||
0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
|
||||
0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
|
||||
0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
|
||||
};
|
||||
unsigned char *ptr = privkey;
|
||||
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
|
||||
memcpy(ptr, key32, 32); ptr += 32;
|
||||
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
|
||||
pubkeylen = 65;
|
||||
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
|
||||
ptr += pubkeylen;
|
||||
*privkeylen = ptr - privkey;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2014, 2015 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||
***********************************************************************/
|
||||
|
||||
/****
|
||||
* Please do not link this file directly. It is not part of the libsecp256k1
|
||||
* project and does not promise any stability in its API, functionality or
|
||||
* presence. Projects which use this code should instead copy this header
|
||||
* and its accompanying .c file directly into their codebase.
|
||||
****/
|
||||
|
||||
/* This file contains code snippets that parse DER private keys with
|
||||
* various errors and violations. This is not a part of the library
|
||||
* itself, because the allowed violations are chosen arbitrarily and
|
||||
* do not follow or establish any standard.
|
||||
*
|
||||
* It also contains code to serialize private keys in a compatible
|
||||
* manner.
|
||||
*
|
||||
* These functions are meant for compatibility with applications
|
||||
* that require BER encoded keys. When working with secp256k1-specific
|
||||
* code, the simple 32-byte private keys normally used by the
|
||||
* library are sufficient.
|
||||
*/
|
||||
|
||||
#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
||||
#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
||||
|
||||
/* #include secp256k1.h only when it hasn't been included yet.
|
||||
This enables this file to be #included directly in other project
|
||||
files (such as tests.c) without the need to set an explicit -I flag,
|
||||
which would be necessary to locate secp256k1.h. */
|
||||
#ifndef SECP256K1_H
|
||||
#include <secp256k1.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Export a private key in DER format.
|
||||
*
|
||||
* Returns: 1 if the private key was valid.
|
||||
* Args: ctx: pointer to a context object (not secp256k1_context_static).
|
||||
* Out: privkey: pointer to an array for storing the private key in BER.
|
||||
* Should have space for 279 bytes, and cannot be NULL.
|
||||
* privkeylen: Pointer to an int where the length of the private key in
|
||||
* privkey will be stored.
|
||||
* In: seckey: pointer to a 32-byte secret key to export.
|
||||
* compressed: 1 if the key should be exported in
|
||||
* compressed format, 0 otherwise
|
||||
*
|
||||
* This function is purely meant for compatibility with applications that
|
||||
* require BER encoded keys. When working with secp256k1-specific code, the
|
||||
* simple 32-byte private keys are sufficient.
|
||||
*
|
||||
* Note that this function does not guarantee correct DER output. It is
|
||||
* guaranteed to be parsable by secp256k1_ec_privkey_import_der
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *privkey,
|
||||
size_t *privkeylen,
|
||||
const unsigned char *seckey,
|
||||
int compressed
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Import a private key in DER format.
|
||||
* Returns: 1 if a private key was extracted.
|
||||
* Args: ctx: pointer to a context object (cannot be NULL).
|
||||
* Out: seckey: pointer to a 32-byte array for storing the private key.
|
||||
* (cannot be NULL).
|
||||
* In: privkey: pointer to a private key in DER format (cannot be NULL).
|
||||
* privkeylen: length of the DER private key pointed to be privkey.
|
||||
*
|
||||
* This function will accept more than just strict DER, and even allow some BER
|
||||
* violations. The public key stored inside the DER-encoded private key is not
|
||||
* verified for correctness, nor are the curve parameters. Use this function
|
||||
* only if you know in advance it is supposed to contain a secp256k1 private
|
||||
* key.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *privkey,
|
||||
size_t privkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */
|
||||
483
external/secp256k1/doc/ellswift.md
vendored
483
external/secp256k1/doc/ellswift.md
vendored
@@ -1,483 +0,0 @@
|
||||
# ElligatorSwift for secp256k1 explained
|
||||
|
||||
In this document we explain how the `ellswift` module implementation is related to the
|
||||
construction in the
|
||||
["SwiftEC: Shallue–van de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759)
|
||||
paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi.
|
||||
|
||||
* [1. Introduction](#1-introduction)
|
||||
* [2. The decoding function](#2-the-decoding-function)
|
||||
+ [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1)
|
||||
* [3. The encoding function](#3-the-encoding-function)
|
||||
+ [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates)
|
||||
+ [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses)
|
||||
+ [3.3 Finding the inverse](#33-finding-the-inverse)
|
||||
+ [3.4 Dealing with special cases](#34-dealing-with-special-cases)
|
||||
+ [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1)
|
||||
* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates)
|
||||
+ [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1)
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
The `ellswift` module effectively introduces a new 64-byte public key format, with the property
|
||||
that (uniformly random) public keys can be encoded as 64-byte arrays which are computationally
|
||||
indistinguishable from uniform byte arrays. The module provides functions to convert public keys
|
||||
from and to this format, as well as convenience functions for key generation and ECDH that operate
|
||||
directly on ellswift-encoded keys.
|
||||
|
||||
The encoding consists of the concatenation of two (32-byte big endian) encoded field elements $u$
|
||||
and $t.$ Together they encode an x-coordinate on the curve $x$, or (see further) a full point $(x, y)$ on
|
||||
the curve.
|
||||
|
||||
**Decoding** consists of decoding the field elements $u$ and $t$ (values above the field size $p$
|
||||
are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ results in a valid
|
||||
x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function).
|
||||
|
||||
**Encoding** a given $x$ coordinate is conceptually done as follows:
|
||||
* Loop:
|
||||
* Pick a uniformly random field element $u.$
|
||||
* Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements.
|
||||
* With probability $1 - \dfrac{\\#L}{8}$, restart the loop.
|
||||
* Select a uniformly random $t \in L$ and return $(u, t).$
|
||||
|
||||
This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full
|
||||
$(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates).
|
||||
The algorithm finds a uniformly random $(u, t)$ among (almost all) those
|
||||
for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for
|
||||
almost all x-coordinates on the curve (all but at most 39) is close to two times the field size
|
||||
(specifically, it lies in the range $2q \pm (22\sqrt{q} + O(1))$, where $q$ is the size of the field).
|
||||
|
||||
## 2. The decoding function
|
||||
|
||||
First some definitions:
|
||||
* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$
|
||||
* For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement.
|
||||
* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$
|
||||
public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square.
|
||||
This implies that the order of $E$ is either odd, or a multiple of *4*.
|
||||
If $a=0$, this condition is always fulfilled.
|
||||
* For `secp256k1`, $a=0$ and $b=7.$
|
||||
* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$
|
||||
* Let the function $h(x) = 3x^3 + 4a.$
|
||||
* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$
|
||||
* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$
|
||||
* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below.
|
||||
* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below.
|
||||
|
||||
**Note**: In the paper:
|
||||
* $F_u$ corresponds to $F_{0,u}$ there.
|
||||
* $P_u(t)$ is called $P$ there.
|
||||
* All $S_u$ sets together correspond to $S$ there.
|
||||
* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there.
|
||||
|
||||
Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right
|
||||
hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$,
|
||||
out of the three right-hand side factors an even number must be non-squares.
|
||||
This implies that exactly *1* or exactly *3* out of
|
||||
$\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$,
|
||||
at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception
|
||||
to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate.
|
||||
|
||||
**Define** the decoding function $F_u(t)$ as:
|
||||
* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$
|
||||
* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square).
|
||||
|
||||
$P_u(t) = (X(u, t), Y(u, t))$, where:
|
||||
|
||||
$$
|
||||
\begin{array}{lcl}
|
||||
X(u, t) & = & \left\\{\begin{array}{ll}
|
||||
\dfrac{g(u) - t^2}{2t} & a = 0 \\
|
||||
\dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0
|
||||
\end{array}\right. \\
|
||||
Y(u, t) & = & \left\\{\begin{array}{ll}
|
||||
\dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\
|
||||
Y_0(u) + t(X(u, t) - X_0(u)) & a \neq 0
|
||||
\end{array}\right.
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
$P_u(t)$ is defined:
|
||||
* For $a=0$, unless:
|
||||
* $u = 0$ or $t = 0$ (division by zero)
|
||||
* $g(u) = -t^2$ (would give $Y=0$).
|
||||
* For $a \neq 0$, unless:
|
||||
* $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero)
|
||||
* $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$).
|
||||
|
||||
The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$
|
||||
|
||||
The function $\psi_u$ is the same for all curves: $\psi_u(X, Y) = (x_1, x_2, x_3, z)$, where:
|
||||
|
||||
$$
|
||||
\begin{array}{lcl}
|
||||
x_1 & = & \dfrac{X}{2Y} - \dfrac{u}{2} && \\
|
||||
x_2 & = & -\dfrac{X}{2Y} - \dfrac{u}{2} && \\
|
||||
x_3 & = & u + 4Y^2 && \\
|
||||
z & = & \dfrac{g(x_3)}{2Y}(u^2 + ux_1 + x_1^2 + a) = \dfrac{-g(u)g(x_3)}{8Y^3}
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
### 2.1 Decoding for `secp256k1`
|
||||
|
||||
Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is:
|
||||
|
||||
**Define** $F_u(t)$ as:
|
||||
* Let $X = \dfrac{u^3 + b - t^2}{2t}.$
|
||||
* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$
|
||||
* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square.
|
||||
|
||||
To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case
|
||||
$P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$):
|
||||
|
||||
**Define** $F_u(t)$ as:
|
||||
* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$).
|
||||
* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$).
|
||||
* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$).
|
||||
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
|
||||
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
|
||||
* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square.
|
||||
|
||||
The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice,
|
||||
but the approach here is simple enough and gives fairly uniform output even in these cases.
|
||||
|
||||
**Note**: in the paper these conditions result in $\infty$ as output, due to the use of projective coordinates there.
|
||||
We wish to avoid the need for callers to deal with this special case.
|
||||
|
||||
This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and
|
||||
in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate).
|
||||
|
||||
## 3. The encoding function
|
||||
|
||||
To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process:
|
||||
* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$
|
||||
* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$
|
||||
* For each of the found $t$ values, verify that $F_u(t) = x.$
|
||||
* Return the remaining $t$ values.
|
||||
|
||||
The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$
|
||||
|
||||
$$
|
||||
P_u^{-1}(X, Y) = \left\\{\begin{array}{ll}
|
||||
Yu\sqrt{-3} - X & a = 0 \\
|
||||
\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\
|
||||
\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u)
|
||||
\end{array}\right.
|
||||
$$
|
||||
|
||||
The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions,
|
||||
it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the
|
||||
$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected.
|
||||
|
||||
Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$,
|
||||
the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid.
|
||||
This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of
|
||||
$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out.
|
||||
|
||||
Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as
|
||||
$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square,
|
||||
and if so, not include the corresponding $t$ values in the returned set. As this does not need $X$, $Y$, or $t$, this condition can be determined
|
||||
before those values are computed.
|
||||
|
||||
It is not possible that an encoding found through the $x_1$ expression decodes to a different valid x-coordinate using $x_2$ (which would
|
||||
take precedence), for the same reason: if both $x_1$ and $x_2$ decodings were valid, $x_3$ would be valid as well, and thus take
|
||||
precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ and $x_2$ is the only test necessary to guarantee the found $t$
|
||||
values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder;
|
||||
any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder.
|
||||
|
||||
### 3.1 Switching to *v, w* coordinates
|
||||
|
||||
Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and
|
||||
$w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$
|
||||
* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$
|
||||
* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$
|
||||
* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where
|
||||
|
||||
$$
|
||||
\begin{array}{lcl}
|
||||
x_1 & = & v \\
|
||||
x_2 & = & -u - v \\
|
||||
x_3 & = & u + w^2 \\
|
||||
z & = & \dfrac{g(x_3)}{w}(u^2 + uv + v^2 + a) = \dfrac{-g(u)g(x_3)}{w^3}
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$
|
||||
expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable:
|
||||
* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
|
||||
* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
|
||||
* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions).
|
||||
|
||||
### 3.2 Avoiding computing all inverses
|
||||
|
||||
The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the
|
||||
set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary.
|
||||
|
||||
Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a
|
||||
uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8,
|
||||
picking a uniformly random element from that, restarting whenever $\bot$ is picked:
|
||||
|
||||
**Define** *ElligatorSwift(x)* as:
|
||||
* Loop:
|
||||
* Pick a uniformly random field element $u.$
|
||||
* Compute the set $L = F_u^{-1}(x).$
|
||||
* Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$
|
||||
* Select a uniformly random $t \in T.$
|
||||
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
|
||||
|
||||
Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly
|
||||
random element in it, so we do not need to have all $\bot$ values at the end.
|
||||
As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account),
|
||||
we can associate every index in $T$ with exactly one of those formulas, making sure that:
|
||||
* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$
|
||||
* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check).
|
||||
* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those.
|
||||
|
||||
The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting
|
||||
to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases)
|
||||
for an analysis of all the negligible cases.
|
||||
|
||||
If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas,
|
||||
the loop can be simplified to only compute one of the inverses instead of all of them:
|
||||
|
||||
**Define** *ElligatorSwift(x)* as:
|
||||
* Loop:
|
||||
* Pick a uniformly random field element $u.$
|
||||
* Pick a uniformly random integer $c$ in $[0,8).$
|
||||
* Let $t = G_{c,u}(x).$
|
||||
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
|
||||
|
||||
This is implemented in `secp256k1_ellswift_xelligatorswift_var`.
|
||||
|
||||
### 3.3 Finding the inverse
|
||||
|
||||
To implement $G_{c,u}$, we map $c=0$ to the $x_1$ formula, $c=1$ to the $x_2$ formula, and $c=2$ and $c=3$ to the $x_3$ formula.
|
||||
Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting that in each formula, $w$ is a square root of some expression).
|
||||
Ignoring the negligible cases, we get:
|
||||
|
||||
**Define** $G_{c,u}(x)$ as:
|
||||
* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas):
|
||||
* If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence).
|
||||
* If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula)
|
||||
* Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows).
|
||||
* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas):
|
||||
* Let $s = x-u.$
|
||||
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
|
||||
* Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise.
|
||||
* Let $w = \sqrt{s}.$
|
||||
* Depending on $c:$
|
||||
* If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$
|
||||
* If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$
|
||||
|
||||
Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly
|
||||
50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen
|
||||
with negligible probability. A division by 0 in the first branch in fact cannot occur at all, because $u^2 + uv + v^2 + a = 0$
|
||||
implies $g(-u-x) = g(x)$ which would mean the $g(-u-x)$ is square condition has triggered
|
||||
and $\bot$ would have been returned already.
|
||||
|
||||
**Note**: In the paper, the $case$ variable corresponds roughly to the $c$ above, but only takes on 4 possible values (1 to 4).
|
||||
The conditional negation of $w$ at the end is done randomly, which is equivalent, but makes testing harder. We choose to
|
||||
have the $G_{c,u}$ be deterministic, and capture all choices in $c.$
|
||||
|
||||
Now observe that the $c \in \\{1, 5\\}$ and $c \in \\{3, 7\\}$ conditions effectively perform the same $v \rightarrow -u-v$
|
||||
transformation. Furthermore, that transformation has no effect on $s$ in the first branch
|
||||
as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down:
|
||||
|
||||
**Define** $G_{c,u}(x)$ as:
|
||||
* If $c \in \\{0, 1, 4, 5\\}:$
|
||||
* If $g(-u-x)$ is square, return $\bot.$
|
||||
* Let $s = -g(u)/(u^2 + ux + x^2 + a).$
|
||||
* Let $v = x.$
|
||||
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
|
||||
* Let $s = x-u.$
|
||||
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
|
||||
* Let $v = (r/s - u)/2.$
|
||||
* Let $w = \sqrt{s}.$
|
||||
* Depending on $c:$
|
||||
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$
|
||||
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$
|
||||
* If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$
|
||||
* If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$
|
||||
|
||||
This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input.
|
||||
There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values.
|
||||
|
||||
### 3.4 Dealing with special cases
|
||||
|
||||
As mentioned before there are a few cases to deal with which only happen in a negligibly small subset of inputs.
|
||||
For cryptographically sized fields, if only random inputs are going to be considered, it is unnecessary to deal with these. Still, for completeness
|
||||
we analyse them here. They generally fall into two categories: cases in which the encoder would produce $t$ values that
|
||||
do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same
|
||||
$t$ value for multiple $c$ inputs (thereby biasing that encoding):
|
||||
|
||||
* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$):
|
||||
* When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves.
|
||||
Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve
|
||||
fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square).
|
||||
This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$),
|
||||
the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the
|
||||
encoder anyway as there will generally be more than 8.
|
||||
* When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence
|
||||
as it can deal with $g(u)=0$.
|
||||
This is again only possible on even-ordered curves.
|
||||
* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$):
|
||||
* When $s=0$, a division by zero would occur.
|
||||
* When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases.
|
||||
It is equivalent to checking whether $r=0$.
|
||||
This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition.
|
||||
A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first
|
||||
it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero.
|
||||
* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder:
|
||||
* For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve.
|
||||
* For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$.
|
||||
|
||||
**Define** a version of $G_{c,u}(x)$ which deals with all these cases:
|
||||
* If $a=0$ and $u=0$, return $\bot.$
|
||||
* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$
|
||||
* If $c \in \\{0, 1, 4, 5\\}:$
|
||||
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
|
||||
* If $g(-u-x)$ is square, return $\bot.$
|
||||
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
|
||||
* Let $v = x.$
|
||||
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
|
||||
* Let $s = x-u.$
|
||||
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
|
||||
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
|
||||
* If $s = 0$, return $\bot.$
|
||||
* Let $v = (r/s - u)/2.$
|
||||
* Let $w = \sqrt{s}$; return $\bot$ if not square.
|
||||
* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$
|
||||
* Depending on $c:$
|
||||
* If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$
|
||||
* If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$
|
||||
* If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$
|
||||
* If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$
|
||||
* If $a=0$ and $t=0$, return $\bot$ (even curves only).
|
||||
* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$
|
||||
* Return $t.$
|
||||
|
||||
Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once,
|
||||
for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached:
|
||||
* All cases where $P_u(t)$ is not defined:
|
||||
* For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$
|
||||
* For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$
|
||||
* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch.
|
||||
|
||||
These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves.
|
||||
|
||||
### 3.5 Encoding for `secp256k1`
|
||||
|
||||
Specialized for odd-ordered $a=0$ curves:
|
||||
|
||||
**Define** $G_{c,u}(x)$ as:
|
||||
* If $u=0$, return $\bot.$
|
||||
* If $c \in \\{0, 1, 4, 5\\}:$
|
||||
* If $(-u-x)^3 + b$ is square, return $\bot$
|
||||
* Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0).
|
||||
* Let $v = x.$
|
||||
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
|
||||
* Let $s = x-u.$
|
||||
* Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square.
|
||||
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
|
||||
* If $s = 0$, return $\bot.$
|
||||
* Let $v = (r/s - u)/2.$
|
||||
* Let $w = \sqrt{s}$; return $\bot$ if not square.
|
||||
* Depending on $c:$
|
||||
* If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$
|
||||
* If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$
|
||||
* If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$
|
||||
* If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$
|
||||
|
||||
This is implemented in `secp256k1_ellswift_xswiftec_inv_var`.
|
||||
|
||||
And the x-only ElligatorSwift encoding algorithm is still:
|
||||
|
||||
**Define** *ElligatorSwift(x)* as:
|
||||
* Loop:
|
||||
* Pick a uniformly random field element $u.$
|
||||
* Pick a uniformly random integer $c$ in $[0,8).$
|
||||
* Let $t = G_{c,u}(x).$
|
||||
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
|
||||
|
||||
Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them.
|
||||
While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$
|
||||
combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity.
|
||||
|
||||
## 4. Encoding and decoding full *(x, y)* coordinates
|
||||
|
||||
So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding
|
||||
for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information
|
||||
in $t$ as well.
|
||||
|
||||
Note that for any $(X, Y) \in S_u$, $(\pm X, \pm Y)$ are all on $S_u.$ Moreover, all of these are
|
||||
mapped to the same x-coordinate. Negating $X$ or negating $Y$ just results in $x_1$ and $x_2$
|
||||
being swapped, and does not affect $x_3.$ This will not change the outcome x-coordinate as the order
|
||||
of $x_1$ and $x_2$ only matters if both were to be valid, and in that case $x_3$ would be used instead.
|
||||
|
||||
Still, these four $(X, Y)$ combinations all correspond to distinct $t$ values, so we can encode
|
||||
the sign of the y-coordinate in the sign of $X$ or the sign of $Y.$ They correspond to the
|
||||
four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$
|
||||
|
||||
**Note**: In the paper, the sign of the y coordinate is encoded in a separately-coded bit.
|
||||
|
||||
To encode the sign of $y$ in the sign of $Y:$
|
||||
|
||||
**Define** *Decode(u, t)* for full $(x, y)$ as:
|
||||
* Let $(X, Y) = P_u(t).$
|
||||
* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square.
|
||||
* Let $y = \sqrt{g(x)}.$
|
||||
* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$
|
||||
|
||||
And encoding would be done using a $G_{c,u}(x, y)$ function defined as:
|
||||
|
||||
**Define** $G_{c,u}(x, y)$ as:
|
||||
* If $c \in \\{0, 1\\}:$
|
||||
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
|
||||
* If $g(-u-x)$ is square, return $\bot.$
|
||||
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
|
||||
* Let $v = x.$
|
||||
* Otherwise, when $c \in \\{2, 3\\}:$
|
||||
* Let $s = x-u.$
|
||||
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
|
||||
* If $c = 3$ and $r = 0$, return $\bot.$
|
||||
* Let $v = (r/s - u)/2.$
|
||||
* Let $w = \sqrt{s}$; return $\bot$ if not square.
|
||||
* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise.
|
||||
* Depending on $c:$
|
||||
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$
|
||||
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$
|
||||
|
||||
Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$
|
||||
This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$.
|
||||
|
||||
In the above logic, $sign$ can be implemented in several ways, such as parity of the integer representation
|
||||
of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where
|
||||
$-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$.
|
||||
|
||||
### 4.1 Full *(x, y)* coordinates for `secp256k1`
|
||||
|
||||
For $a=0$ curves, there is another option. Note that for those,
|
||||
the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to
|
||||
encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get
|
||||
as decoder:
|
||||
|
||||
**Define** *Decode(u, t)* as:
|
||||
* Let $u'=u$ if $u \neq 0$; $1$ otherwise.
|
||||
* Let $t'=t$ if $t \neq 0$; $1$ otherwise.
|
||||
* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise.
|
||||
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
|
||||
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
|
||||
* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square.
|
||||
* Let $y = \sqrt{g(x)}.$
|
||||
* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise.
|
||||
|
||||
This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$
|
||||
|
||||
The corresponding encoder would invoke the x-only one, but negating the output $t$ if $sign(t) \neq sign(y).$
|
||||
|
||||
This is implemented in `secp256k1_ellswift_elligatorswift_var`.
|
||||
|
||||
Note that this is only intended for encoding points where both the x-coordinate and y-coordinate are unpredictable. When encoding x-only points
|
||||
where the y-coordinate is implicitly even (or implicitly square, or implicitly in $[0,q/2]$), the encoder in
|
||||
[Section 3.5](#35-encoding-for-secp256k1) must be used, or a bias is reintroduced that undoes all the benefit of using ElligatorSwift
|
||||
in the first place.
|
||||
54
external/secp256k1/doc/musig.md
vendored
54
external/secp256k1/doc/musig.md
vendored
@@ -1,54 +0,0 @@
|
||||
Notes on the musig module API
|
||||
===========================
|
||||
|
||||
The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`).
|
||||
A usage example can be found in `examples/musig.c`.
|
||||
|
||||
## API misuse
|
||||
|
||||
The musig API is designed with a focus on misuse resistance.
|
||||
However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation.
|
||||
While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes.
|
||||
|
||||
Therefore, users of the musig module must take great care to make sure of the following:
|
||||
|
||||
1. A unique nonce per signing session is generated in `secp256k1_musig_nonce_gen`.
|
||||
See the corresponding comment in `include/secp256k1_musig.h` for how to ensure that.
|
||||
2. The `secp256k1_musig_secnonce` structure is never copied or serialized.
|
||||
See also the comment on `secp256k1_musig_secnonce` in `include/secp256k1_musig.h`.
|
||||
3. Opaque data structures are never written to or read from directly.
|
||||
Instead, only the provided accessor functions are used.
|
||||
|
||||
## Key Aggregation and (Taproot) Tweaking
|
||||
|
||||
Given a set of public keys, the aggregate public key is computed with `secp256k1_musig_pubkey_agg`.
|
||||
A plain tweak can be added to the resulting public key with `secp256k1_ec_pubkey_tweak_add` by setting the `tweak32` argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with `secp256k1_xonly_pubkey_tweak_add` by setting the `tweak32` argument to the TapTweak hash defined in BIP 341.
|
||||
Both types of tweaking can be combined and invoked multiple times if the specific application requires it.
|
||||
|
||||
## Signing
|
||||
|
||||
This is covered by `examples/musig.c`.
|
||||
Essentially, the protocol proceeds in the following steps:
|
||||
|
||||
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`.
|
||||
2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants.
|
||||
3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`.
|
||||
4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers.
|
||||
5. Someone (not necessarily the signer) aggregates the public nonces with `secp256k1_musig_nonce_agg` and sends it to the signers.
|
||||
6. Process the aggregate nonce with `secp256k1_musig_nonce_process`.
|
||||
7. Create a partial signature with `secp256k1_musig_partial_sign`.
|
||||
8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`.
|
||||
9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`.
|
||||
|
||||
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`.
|
||||
|
||||
Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed.
|
||||
Whenever possible, it is recommended to generate the nonces only after the message is known.
|
||||
This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios.
|
||||
However, it does require two rounds of communication during the signing process.
|
||||
The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing.
|
||||
Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5).
|
||||
|
||||
## Verification
|
||||
|
||||
A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7.
|
||||
94
external/secp256k1/doc/release-process.md
vendored
94
external/secp256k1/doc/release-process.md
vendored
@@ -1,94 +0,0 @@
|
||||
# Release process
|
||||
|
||||
This document outlines the process for releasing versions of the form `$MAJOR.$MINOR.$PATCH`.
|
||||
|
||||
We distinguish between two types of releases: *regular* and *maintenance* releases.
|
||||
Regular releases are releases of a new major or minor version as well as patches of the most recent release.
|
||||
Maintenance releases, on the other hand, are required for patches of older releases.
|
||||
|
||||
You should coordinate with the other maintainers on the release date, if possible.
|
||||
This date will be part of the release entry in [CHANGELOG.md](../CHANGELOG.md) and it should match the dates of the remaining steps in the release process (including the date of the tag and the GitHub release).
|
||||
It is best if the maintainers are present during the release, so they can help ensure that the process is followed correctly and, in the case of a regular release, they are aware that they should not modify the master branch between merging the PR in step 1 and the PR in step 3.
|
||||
|
||||
This process also assumes that there will be no minor releases for old major releases.
|
||||
|
||||
We aim to cut a regular release every 3-4 months, approximately twice as frequent as major Bitcoin Core releases. Every second release should be published one month before the feature freeze of the next major Bitcoin Core release, allowing sufficient time to update the library in Core.
|
||||
|
||||
## Sanity checks
|
||||
Perform these checks when reviewing the release PR (see below):
|
||||
|
||||
1. Ensure `make distcheck` doesn't fail.
|
||||
```shell
|
||||
./autogen.sh && ./configure --enable-dev-mode && make distcheck
|
||||
```
|
||||
2. Check installation with autotools:
|
||||
```shell
|
||||
dir=$(mktemp -d)
|
||||
./autogen.sh && ./configure --prefix=$dir && make clean && make install && ls -RlAh $dir
|
||||
gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=$dir/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"$dir/lib" && ./ecdsa
|
||||
```
|
||||
3. Check installation with CMake:
|
||||
```shell
|
||||
dir=$(mktemp -d)
|
||||
build=$(mktemp -d)
|
||||
cmake -B $build -DCMAKE_INSTALL_PREFIX=$dir && cmake --build $build && cmake --install $build && ls -RlAh $dir
|
||||
gcc -o ecdsa examples/ecdsa.c -I $dir/include -L $dir/lib*/ -l secp256k1 -Wl,-rpath,"$dir/lib",-rpath,"$dir/lib64" && ./ecdsa
|
||||
```
|
||||
4. Use the [`check-abi.sh`](/tools/check-abi.sh) tool to verify that there are no unexpected ABI incompatibilities and that the version number and the release notes accurately reflect all potential ABI changes. To run this tool, the `abi-dumper` and `abi-compliance-checker` packages are required.
|
||||
```shell
|
||||
tools/check-abi.sh
|
||||
```
|
||||
|
||||
## Regular release
|
||||
|
||||
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
|
||||
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by
|
||||
* adding a section for the release (make sure that the version number is a link to a diff between the previous and new version),
|
||||
* removing the `[Unreleased]` section header,
|
||||
* ensuring that the release notes are not missing entries (check the `needs-changelog` label on github), and
|
||||
* including an entry for `### ABI Compatibility` if it doesn't exist,
|
||||
* sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and,
|
||||
* if this is not a patch release,
|
||||
* updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and
|
||||
* updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`.
|
||||
2. Perform the [sanity checks](#sanity-checks) on the PR branch.
|
||||
3. After the PR is merged, tag the commit, and push the tag:
|
||||
```
|
||||
RELEASE_COMMIT=<merge commit of step 1>
|
||||
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
|
||||
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
|
||||
```
|
||||
4. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that
|
||||
* sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`,
|
||||
* increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and
|
||||
* adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md).
|
||||
|
||||
If other maintainers are not present to approve the PR, it can be merged without ACKs.
|
||||
5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
|
||||
6. Send an announcement email to the bitcoin-dev mailing list.
|
||||
|
||||
## Maintenance release
|
||||
|
||||
Note that bug fixes need to be backported only to releases for which no compatible release without the bug exists.
|
||||
|
||||
1. If there's no maintenance branch `$MAJOR.$MINOR`, create one:
|
||||
```
|
||||
git checkout -b $MAJOR.$MINOR v$MAJOR.$MINOR.$((PATCH - 1))
|
||||
git push git@github.com:bitcoin-core/secp256k1.git $MAJOR.$MINOR
|
||||
```
|
||||
2. Open a pull request to the `$MAJOR.$MINOR` branch that
|
||||
* includes the bug fixes,
|
||||
* finalizes the release notes similar to a regular release,
|
||||
* increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`
|
||||
and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`
|
||||
(with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example).
|
||||
3. Perform the [sanity checks](#sanity-checks) on the PR branch.
|
||||
4. After the PRs are merged, update the release branch, tag the commit, and push the tag:
|
||||
```
|
||||
git checkout $MAJOR.$MINOR && git pull
|
||||
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH"
|
||||
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
|
||||
```
|
||||
6. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
|
||||
7. Send an announcement email to the bitcoin-dev mailing list.
|
||||
8. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md).
|
||||
819
external/secp256k1/doc/safegcd_implementation.md
vendored
819
external/secp256k1/doc/safegcd_implementation.md
vendored
@@ -1,819 +0,0 @@
|
||||
# The safegcd implementation in libsecp256k1 explained
|
||||
|
||||
This document explains the modular inverse and Jacobi symbol implementations in the `src/modinv*.h` files.
|
||||
It is based on the paper
|
||||
["Fast constant-time gcd computation and modular inversion"](https://gcd.cr.yp.to/papers.html#safegcd)
|
||||
by Daniel J. Bernstein and Bo-Yin Yang. The references below are for the Date: 2019.04.13 version.
|
||||
|
||||
The actual implementation is in C of course, but for demonstration purposes Python3 is used here.
|
||||
Most implementation aspects and optimizations are explained, except those that depend on the specific
|
||||
number representation used in the C code.
|
||||
|
||||
## 1. Computing the Greatest Common Divisor (GCD) using divsteps
|
||||
|
||||
The algorithm from the paper (section 11), at a very high level, is this:
|
||||
|
||||
```python
|
||||
def gcd(f, g):
|
||||
"""Compute the GCD of an odd integer f and another integer g."""
|
||||
assert f & 1 # require f to be odd
|
||||
delta = 1 # additional state variable
|
||||
while g != 0:
|
||||
assert f & 1 # f will be odd in every iteration
|
||||
if delta > 0 and g & 1:
|
||||
delta, f, g = 1 - delta, g, (g - f) // 2
|
||||
elif g & 1:
|
||||
delta, f, g = 1 + delta, f, (g + f) // 2
|
||||
else:
|
||||
delta, f, g = 1 + delta, f, (g ) // 2
|
||||
return abs(f)
|
||||
```
|
||||
|
||||
It computes the greatest common divisor of an odd integer *f* and any integer *g*. Its inner loop
|
||||
keeps rewriting the variables *f* and *g* alongside a state variable *δ* that starts at *1*, until
|
||||
*g=0* is reached. At that point, *|f|* gives the GCD. Each of the transitions in the loop is called a
|
||||
"division step" (referred to as divstep in what follows).
|
||||
|
||||
For example, *gcd(21, 14)* would be computed as:
|
||||
- Start with *δ=1 f=21 g=14*
|
||||
- Take the third branch: *δ=2 f=21 g=7*
|
||||
- Take the first branch: *δ=-1 f=7 g=-7*
|
||||
- Take the second branch: *δ=0 f=7 g=0*
|
||||
- The answer *|f| = 7*.
|
||||
|
||||
Why it works:
|
||||
- Divsteps can be decomposed into two steps (see paragraph 8.2 in the paper):
|
||||
- (a) If *g* is odd, replace *(f,g)* with *(g,g-f)* or (f,g+f), resulting in an even *g*.
|
||||
- (b) Replace *(f,g)* with *(f,g/2)* (where *g* is guaranteed to be even).
|
||||
- Neither of those two operations change the GCD:
|
||||
- For (a), assume *gcd(f,g)=c*, then it must be the case that *f=a c* and *g=b c* for some integers *a*
|
||||
and *b*. As *(g,g-f)=(b c,(b-a)c)* and *(f,f+g)=(a c,(a+b)c)*, the result clearly still has
|
||||
common factor *c*. Reasoning in the other direction shows that no common factor can be added by
|
||||
doing so either.
|
||||
- For (b), we know that *f* is odd, so *gcd(f,g)* clearly has no factor *2*, and we can remove
|
||||
it from *g*.
|
||||
- The algorithm will eventually converge to *g=0*. This is proven in the paper (see theorem G.3).
|
||||
- It follows that eventually we find a final value *f'* for which *gcd(f,g) = gcd(f',0)*. As the
|
||||
gcd of *f'* and *0* is *|f'|* by definition, that is our answer.
|
||||
|
||||
Compared to more [traditional GCD algorithms](https://en.wikipedia.org/wiki/Euclidean_algorithm), this one has the property of only ever looking at
|
||||
the low-order bits of the variables to decide the next steps, and being easy to make
|
||||
constant-time (in more low-level languages than Python). The *δ* parameter is necessary to
|
||||
guide the algorithm towards shrinking the numbers' magnitudes without explicitly needing to look
|
||||
at high order bits.
|
||||
|
||||
Properties that will become important later:
|
||||
- Performing more divsteps than needed is not a problem, as *f* does not change anymore after *g=0*.
|
||||
- Only even numbers are divided by *2*. This means that when reasoning about it algebraically we
|
||||
do not need to worry about rounding.
|
||||
- At every point during the algorithm's execution the next *N* steps only depend on the bottom *N*
|
||||
bits of *f* and *g*, and on *δ*.
|
||||
|
||||
|
||||
## 2. From GCDs to modular inverses
|
||||
|
||||
We want an algorithm to compute the inverse *a* of *x* modulo *M*, i.e. the number a such that *a x=1
|
||||
mod M*. This inverse only exists if the GCD of *x* and *M* is *1*, but that is always the case if *M* is
|
||||
prime and *0 < x < M*. In what follows, assume that the modular inverse exists.
|
||||
It turns out this inverse can be computed as a side effect of computing the GCD by keeping track
|
||||
of how the internal variables can be written as linear combinations of the inputs at every step
|
||||
(see the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)).
|
||||
Since the GCD is *1*, such an algorithm will compute numbers *a* and *b* such that a x + b M = 1*.
|
||||
Taking that expression *mod M* gives *a x mod M = 1*, and we see that *a* is the modular inverse of *x
|
||||
mod M*.
|
||||
|
||||
A similar approach can be used to calculate modular inverses using the divsteps-based GCD
|
||||
algorithm shown above, if the modulus *M* is odd. To do so, compute *gcd(f=M,g=x)*, while keeping
|
||||
track of extra variables *d* and *e*, for which at every step *d = f/x (mod M)* and *e = g/x (mod M)*.
|
||||
*f/x* here means the number which multiplied with *x* gives *f mod M*. As *f* and *g* are initialized to *M*
|
||||
and *x* respectively, *d* and *e* just start off being *0* (*M/x mod M = 0/x mod M = 0*) and *1* (*x/x mod M
|
||||
= 1*).
|
||||
|
||||
```python
|
||||
def div2(M, x):
|
||||
"""Helper routine to compute x/2 mod M (where M is odd)."""
|
||||
assert M & 1
|
||||
if x & 1: # If x is odd, make it even by adding M.
|
||||
x += M
|
||||
# x must be even now, so a clean division by 2 is possible.
|
||||
return x // 2
|
||||
|
||||
def modinv(M, x):
|
||||
"""Compute the inverse of x mod M (given that it exists, and M is odd)."""
|
||||
assert M & 1
|
||||
delta, f, g, d, e = 1, M, x, 0, 1
|
||||
while g != 0:
|
||||
# Note that while division by two for f and g is only ever done on even inputs, this is
|
||||
# not true for d and e, so we need the div2 helper function.
|
||||
if delta > 0 and g & 1:
|
||||
delta, f, g, d, e = 1 - delta, g, (g - f) // 2, e, div2(M, e - d)
|
||||
elif g & 1:
|
||||
delta, f, g, d, e = 1 + delta, f, (g + f) // 2, d, div2(M, e + d)
|
||||
else:
|
||||
delta, f, g, d, e = 1 + delta, f, (g ) // 2, d, div2(M, e )
|
||||
# Verify that the invariants d=f/x mod M, e=g/x mod M are maintained.
|
||||
assert f % M == (d * x) % M
|
||||
assert g % M == (e * x) % M
|
||||
assert f == 1 or f == -1 # |f| is the GCD, it must be 1
|
||||
# Because of invariant d = f/x (mod M), 1/x = d/f (mod M). As |f|=1, d/f = d*f.
|
||||
return (d * f) % M
|
||||
```
|
||||
|
||||
Also note that this approach to track *d* and *e* throughout the computation to determine the inverse
|
||||
is different from the paper. There (see paragraph 12.1 in the paper) a transition matrix for the
|
||||
entire computation is determined (see section 3 below) and the inverse is computed from that.
|
||||
The approach here avoids the need for 2x2 matrix multiplications of various sizes, and appears to
|
||||
be faster at the level of optimization we're able to do in C.
|
||||
|
||||
|
||||
## 3. Batching multiple divsteps
|
||||
|
||||
Every divstep can be expressed as a matrix multiplication, applying a transition matrix *(1/2 t)*
|
||||
to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper):
|
||||
|
||||
```
|
||||
t = [ u, v ]
|
||||
[ q, r ]
|
||||
|
||||
[ out_f ] = (1/2 * t) * [ in_f ]
|
||||
[ out_g ] = [ in_g ]
|
||||
|
||||
[ out_d ] = (1/2 * t) * [ in_d ] (mod M)
|
||||
[ out_e ] [ in_e ]
|
||||
```
|
||||
|
||||
where *(u, v, q, r)* is *(0, 2, -1, 1)*, *(2, 0, 1, 1)*, or *(2, 0, 0, 1)*, depending on which branch is
|
||||
taken. As above, the resulting *f* and *g* are always integers.
|
||||
|
||||
Performing multiple divsteps corresponds to a multiplication with the product of all the
|
||||
individual divsteps' transition matrices. As each transition matrix consists of integers
|
||||
divided by *2*, the product of these matrices will consist of integers divided by *2<sup>N</sup>* (see also
|
||||
theorem 9.2 in the paper). These divisions are expensive when updating *d* and *e*, so we delay
|
||||
them: we compute the integer coefficients of the combined transition matrix scaled by *2<sup>N</sup>*, and
|
||||
do one division by *2<sup>N</sup>* as a final step:
|
||||
|
||||
```python
|
||||
def divsteps_n_matrix(delta, f, g):
|
||||
"""Compute delta and transition matrix t after N divsteps (multiplied by 2^N)."""
|
||||
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
|
||||
for _ in range(N):
|
||||
if delta > 0 and g & 1:
|
||||
delta, f, g, u, v, q, r = 1 - delta, g, (g - f) // 2, 2*q, 2*r, q-u, r-v
|
||||
elif g & 1:
|
||||
delta, f, g, u, v, q, r = 1 + delta, f, (g + f) // 2, 2*u, 2*v, q+u, r+v
|
||||
else:
|
||||
delta, f, g, u, v, q, r = 1 + delta, f, (g ) // 2, 2*u, 2*v, q , r
|
||||
return delta, (u, v, q, r)
|
||||
```
|
||||
|
||||
As the branches in the divsteps are completely determined by the bottom *N* bits of *f* and *g*, this
|
||||
function to compute the transition matrix only needs to see those bottom bits. Furthermore all
|
||||
intermediate results and outputs fit in *(N+1)*-bit numbers (unsigned for *f* and *g*; signed for *u*, *v*,
|
||||
*q*, and *r*) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit
|
||||
integers could set *N=62* and compute the full transition matrix for 62 steps at once without any
|
||||
big integer arithmetic at all. This is the reason why this algorithm is efficient: it only needs
|
||||
to update the full-size *f*, *g*, *d*, and *e* numbers once every *N* steps.
|
||||
|
||||
We still need functions to compute:
|
||||
|
||||
```
|
||||
[ out_f ] = (1/2^N * [ u, v ]) * [ in_f ]
|
||||
[ out_g ] ( [ q, r ]) [ in_g ]
|
||||
|
||||
[ out_d ] = (1/2^N * [ u, v ]) * [ in_d ] (mod M)
|
||||
[ out_e ] ( [ q, r ]) [ in_e ]
|
||||
```
|
||||
|
||||
Because the divsteps transformation only ever divides even numbers by two, the result of *t [f,g]* is always even. When *t* is a composition of *N* divsteps, it follows that the resulting *f*
|
||||
and *g* will be multiple of *2<sup>N</sup>*, and division by *2<sup>N</sup>* is simply shifting them down:
|
||||
|
||||
```python
|
||||
def update_fg(f, g, t):
|
||||
"""Multiply matrix t/2^N with [f, g]."""
|
||||
u, v, q, r = t
|
||||
cf, cg = u*f + v*g, q*f + r*g
|
||||
# (t / 2^N) should cleanly apply to [f,g] so the result of t*[f,g] should have N zero
|
||||
# bottom bits.
|
||||
assert cf % 2**N == 0
|
||||
assert cg % 2**N == 0
|
||||
return cf >> N, cg >> N
|
||||
```
|
||||
|
||||
The same is not true for *d* and *e*, and we need an equivalent of the `div2` function for division by *2<sup>N</sup> mod M*.
|
||||
This is easy if we have precomputed *1/M mod 2<sup>N</sup>* (which always exists for odd *M*):
|
||||
|
||||
```python
|
||||
def div2n(M, Mi, x):
|
||||
"""Compute x/2^N mod M, given Mi = 1/M mod 2^N."""
|
||||
assert (M * Mi) % 2**N == 1
|
||||
# Find a factor m such that m*M has the same bottom N bits as x. We want:
|
||||
# (m * M) mod 2^N = x mod 2^N
|
||||
# <=> m mod 2^N = (x / M) mod 2^N
|
||||
# <=> m mod 2^N = (x * Mi) mod 2^N
|
||||
m = (Mi * x) % 2**N
|
||||
# Subtract that multiple from x, cancelling its bottom N bits.
|
||||
x -= m * M
|
||||
# Now a clean division by 2^N is possible.
|
||||
assert x % 2**N == 0
|
||||
return (x >> N) % M
|
||||
|
||||
def update_de(d, e, t, M, Mi):
|
||||
"""Multiply matrix t/2^N with [d, e], modulo M."""
|
||||
u, v, q, r = t
|
||||
cd, ce = u*d + v*e, q*d + r*e
|
||||
return div2n(M, Mi, cd), div2n(M, Mi, ce)
|
||||
```
|
||||
|
||||
With all of those, we can write a version of `modinv` that performs *N* divsteps at once:
|
||||
|
||||
```python3
|
||||
def modinv(M, Mi, x):
|
||||
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
|
||||
assert M & 1
|
||||
delta, f, g, d, e = 1, M, x, 0, 1
|
||||
while g != 0:
|
||||
# Compute the delta and transition matrix t for the next N divsteps (this only needs
|
||||
# (N+1)-bit signed integer arithmetic).
|
||||
delta, t = divsteps_n_matrix(delta, f % 2**N, g % 2**N)
|
||||
# Apply the transition matrix t to [f, g]:
|
||||
f, g = update_fg(f, g, t)
|
||||
# Apply the transition matrix t to [d, e]:
|
||||
d, e = update_de(d, e, t, M, Mi)
|
||||
return (d * f) % M
|
||||
```
|
||||
|
||||
This means that in practice we'll always perform a multiple of *N* divsteps. This is not a problem
|
||||
because once *g=0*, further divsteps do not affect *f*, *g*, *d*, or *e* anymore (only *δ* keeps
|
||||
increasing). For variable time code such excess iterations will be mostly optimized away in later
|
||||
sections.
|
||||
|
||||
|
||||
## 4. Avoiding modulus operations
|
||||
|
||||
So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of
|
||||
`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the
|
||||
sign of *f*. These are relatively expensive operations when done generically.
|
||||
|
||||
To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range
|
||||
*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus
|
||||
operation at the end:
|
||||
|
||||
```python
|
||||
def update_de(d, e, t, M, Mi):
|
||||
"""Multiply matrix t/2^N with [d, e] mod M, given Mi=1/M mod 2^N."""
|
||||
u, v, q, r = t
|
||||
cd, ce = u*d + v*e, q*d + r*e
|
||||
# Cancel out bottom N bits of cd and ce.
|
||||
md = -((Mi * cd) % 2**N)
|
||||
me = -((Mi * ce) % 2**N)
|
||||
cd += md * M
|
||||
ce += me * M
|
||||
# And cleanly divide by 2**N.
|
||||
return cd >> N, ce >> N
|
||||
```
|
||||
|
||||
Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|*
|
||||
never exceed *2<sup>N</sup>* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have
|
||||
outputs whose absolute values are at most *2<sup>N</sup>* times the maximum absolute input value. In case the
|
||||
inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming
|
||||
*M > 1*, the multiplication results in numbers in range *(-2<sup>N</sup>M,2<sup>N</sup>M)*. Subtracting less than *2<sup>N</sup>*
|
||||
times *M* to cancel out *N* bits brings that up to *(-2<sup>N+1</sup>M,2<sup>N</sup>M)*, and
|
||||
dividing by *2<sup>N</sup>* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that
|
||||
to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be
|
||||
counteracted by incrementing *d* and *e* by *M* whenever they're negative:
|
||||
|
||||
```python
|
||||
...
|
||||
if d < 0:
|
||||
d += M
|
||||
if e < 0:
|
||||
e += M
|
||||
cd, ce = u*d + v*e, q*d + r*e
|
||||
# Cancel out bottom N bits of cd and ce.
|
||||
...
|
||||
```
|
||||
|
||||
With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the
|
||||
output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de`
|
||||
invocations there are. In what follows, we will try to make this more efficient.
|
||||
|
||||
Note that increasing *d* by *M* is equal to incrementing *cd* by *u M* and *ce* by *q M*. Similarly,
|
||||
increasing *e* by *M* is equal to incrementing *cd* by *v M* and *ce* by *r M*. So we could instead write:
|
||||
|
||||
```python
|
||||
...
|
||||
cd, ce = u*d + v*e, q*d + r*e
|
||||
# Perform the equivalent of incrementing d, e by M when they're negative.
|
||||
if d < 0:
|
||||
cd += u*M
|
||||
ce += q*M
|
||||
if e < 0:
|
||||
cd += v*M
|
||||
ce += r*M
|
||||
# Cancel out bottom N bits of cd and ce.
|
||||
md = -((Mi * cd) % 2**N)
|
||||
me = -((Mi * ce) % 2**N)
|
||||
cd += md * M
|
||||
ce += me * M
|
||||
...
|
||||
```
|
||||
|
||||
Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this
|
||||
increment, and the decrement that cancels out bottom bits. The second one depends on the first
|
||||
one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce*
|
||||
at first, and using that to compute the final *md*, *me* values:
|
||||
|
||||
```python
|
||||
def update_de(d, e, t, M, Mi):
|
||||
"""Multiply matrix t/2^N with [d, e], modulo M."""
|
||||
u, v, q, r = t
|
||||
md, me = 0, 0
|
||||
# Compute what multiples of M to add to cd and ce.
|
||||
if d < 0:
|
||||
md += u
|
||||
me += q
|
||||
if e < 0:
|
||||
md += v
|
||||
me += r
|
||||
# Compute bottom N bits of t*[d,e] + M*[md,me].
|
||||
cd, ce = (u*d + v*e + md*M) % 2**N, (q*d + r*e + me*M) % 2**N
|
||||
# Correct md and me such that the bottom N bits of t*[d,e] + M*[md,me] are zero.
|
||||
md -= (Mi * cd) % 2**N
|
||||
me -= (Mi * ce) % 2**N
|
||||
# Do the full computation.
|
||||
cd, ce = u*d + v*e + md*M, q*d + r*e + me*M
|
||||
# And cleanly divide by 2**N.
|
||||
return cd >> N, ce >> N
|
||||
```
|
||||
|
||||
One last optimization: we can avoid the *md M* and *me M* multiplications in the bottom bits of *cd*
|
||||
and *ce* by moving them to the *md* and *me* correction:
|
||||
|
||||
```python
|
||||
...
|
||||
# Compute bottom N bits of t*[d,e].
|
||||
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
|
||||
# Correct md and me such that the bottom N bits of t*[d,e]+M*[md,me] are zero.
|
||||
# Note that this is not the same as {md = (-Mi * cd) % 2**N} etc. That would also result in N
|
||||
# zero bottom bits, but isn't guaranteed to be a reduction of [0,2^N) compared to the
|
||||
# previous md and me values, and thus would violate our bounds analysis.
|
||||
md -= (Mi*cd + md) % 2**N
|
||||
me -= (Mi*ce + me) % 2**N
|
||||
...
|
||||
```
|
||||
|
||||
The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same
|
||||
range. That also means that the *d* value at the end of `modinv` will be in that range, while we want
|
||||
a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the
|
||||
conditional negation of *d* (based on the sign of *f*) into it as well:
|
||||
|
||||
```python
|
||||
def normalize(sign, v, M):
|
||||
"""Compute sign*v mod M, where v is in range (-2*M,M); output in [0,M)."""
|
||||
assert sign == 1 or sign == -1
|
||||
# v in (-2*M,M)
|
||||
if v < 0:
|
||||
v += M
|
||||
# v in (-M,M). Now multiply v with sign (which can only be 1 or -1).
|
||||
if sign == -1:
|
||||
v = -v
|
||||
# v in (-M,M)
|
||||
if v < 0:
|
||||
v += M
|
||||
# v in [0,M)
|
||||
return v
|
||||
```
|
||||
|
||||
And calling it in `modinv` is simply:
|
||||
|
||||
```python
|
||||
...
|
||||
return normalize(f, d, M)
|
||||
```
|
||||
|
||||
|
||||
## 5. Constant-time operation
|
||||
|
||||
The primary selling point of the algorithm is fast constant-time operation. What code flow still
|
||||
depends on the input data so far?
|
||||
|
||||
- the number of iterations of the while *g ≠ 0* loop in `modinv`
|
||||
- the branches inside `divsteps_n_matrix`
|
||||
- the sign checks in `update_de`
|
||||
- the sign checks in `normalize`
|
||||
|
||||
To make the while loop in `modinv` constant time it can be replaced with a constant number of
|
||||
iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit
|
||||
inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is
|
||||
sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of
|
||||
*⌈724/N⌉* times.
|
||||
|
||||
To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise
|
||||
operations (and hope the C compiler isn't smart enough to turn them back into branches; see
|
||||
`ctime_tests.c` for automated tests that this isn't the case). To do so, observe that a
|
||||
divstep can be written instead as (compare to the inner loop of `gcd` in section 1).
|
||||
|
||||
```python
|
||||
x = -f if delta > 0 else f # set x equal to (input) -f or f
|
||||
if g & 1:
|
||||
g += x # set g to (input) g-f or g+f
|
||||
if delta > 0:
|
||||
delta = -delta
|
||||
f += g # set f to (input) g (note that g was set to g-f before)
|
||||
delta += 1
|
||||
g >>= 1
|
||||
```
|
||||
|
||||
To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the
|
||||
definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As
|
||||
*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows
|
||||
that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then
|
||||
*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*.
|
||||
|
||||
Using this we can write:
|
||||
|
||||
```python
|
||||
x = -f if delta > 0 else f
|
||||
```
|
||||
|
||||
in constant-time form as:
|
||||
|
||||
```python
|
||||
c1 = (-delta) >> 63
|
||||
# Conditionally negate f based on c1:
|
||||
x = (f ^ c1) - c1
|
||||
```
|
||||
|
||||
To use that trick, we need a helper mask variable *c1* that resolves the condition *δ>0* to *-1*
|
||||
(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by
|
||||
the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see
|
||||
`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all
|
||||
numbers in range *[-2<sup>63</sup>,0)* to *-1*, and numbers in range *[0,2<sup>63</sup>)* to *0*.
|
||||
|
||||
Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write:
|
||||
|
||||
```python
|
||||
if g & 1:
|
||||
g += x
|
||||
```
|
||||
|
||||
as:
|
||||
|
||||
```python
|
||||
# Compute c2=0 if g is even and c2=-1 if g is odd.
|
||||
c2 = -(g & 1)
|
||||
# This masks out x if g is even, and leaves x be if g is odd.
|
||||
g += x & c2
|
||||
```
|
||||
|
||||
Using the conditional negation trick again we can write:
|
||||
|
||||
```python
|
||||
if g & 1:
|
||||
if delta > 0:
|
||||
delta = -delta
|
||||
```
|
||||
|
||||
as:
|
||||
|
||||
```python
|
||||
# Compute c3=-1 if g is odd and delta>0, and 0 otherwise.
|
||||
c3 = c1 & c2
|
||||
# Conditionally negate delta based on c3:
|
||||
delta = (delta ^ c3) - c3
|
||||
```
|
||||
|
||||
Finally:
|
||||
|
||||
```python
|
||||
if g & 1:
|
||||
if delta > 0:
|
||||
f += g
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```python
|
||||
f += g & c3
|
||||
```
|
||||
|
||||
It turns out that this can be implemented more efficiently by applying the substitution
|
||||
*η=-δ*. In this representation, negating *δ* corresponds to negating *η*, and incrementing
|
||||
*δ* corresponds to decrementing *η*. This allows us to remove the negation in the *c1*
|
||||
computation:
|
||||
|
||||
```python
|
||||
# Compute a mask c1 for eta < 0, and compute the conditional negation x of f:
|
||||
c1 = eta >> 63
|
||||
x = (f ^ c1) - c1
|
||||
# Compute a mask c2 for odd g, and conditionally add x to g:
|
||||
c2 = -(g & 1)
|
||||
g += x & c2
|
||||
# Compute a mask c for (eta < 0) and odd (input) g, and use it to conditionally negate eta,
|
||||
# and add g to f:
|
||||
c3 = c1 & c2
|
||||
eta = (eta ^ c3) - c3
|
||||
f += g & c3
|
||||
# Incrementing delta corresponds to decrementing eta.
|
||||
eta -= 1
|
||||
g >>= 1
|
||||
```
|
||||
|
||||
A variant of divsteps with better worst-case performance can be used instead: starting *δ* at
|
||||
*1/2* instead of *1*. This reduces the worst case number of iterations to *590* for *256*-bit inputs
|
||||
(which can be shown using convex hull analysis). In this case, the substitution *ζ=-(δ+1/2)*
|
||||
is used instead to keep the variable integral. Incrementing *δ* by *1* still translates to
|
||||
decrementing *ζ* by *1*, but negating *δ* now corresponds to going from *ζ* to *-(ζ+1)*, or
|
||||
*~ζ*. Doing that conditionally based on *c3* is simply:
|
||||
|
||||
```python
|
||||
...
|
||||
c3 = c1 & c2
|
||||
zeta ^= c3
|
||||
...
|
||||
```
|
||||
|
||||
By replacing the loop in `divsteps_n_matrix` with a variant of the divstep code above (extended to
|
||||
also apply all *f* operations to *u*, *v* and all *g* operations to *q*, *r*), a constant-time version of
|
||||
`divsteps_n_matrix` is obtained. The full code will be in section 7.
|
||||
|
||||
These bit fiddling tricks can also be used to make the conditional negations and additions in
|
||||
`update_de` and `normalize` constant-time.
|
||||
|
||||
|
||||
## 6. Variable-time optimizations
|
||||
|
||||
In section 5, we modified the `divsteps_n_matrix` function (and a few others) to be constant time.
|
||||
Constant time operations are only necessary when computing modular inverses of secret data. In
|
||||
other cases, it slows down calculations unnecessarily. In this section, we will construct a
|
||||
faster non-constant time `divsteps_n_matrix` function.
|
||||
|
||||
To do so, first consider yet another way of writing the inner loop of divstep operations in
|
||||
`gcd` from section 1. This decomposition is also explained in the paper in section 8.2. We use
|
||||
the original version with initial *δ=1* and *η=-δ* here.
|
||||
|
||||
```python
|
||||
for _ in range(N):
|
||||
if g & 1 and eta < 0:
|
||||
eta, f, g = -eta, g, -f
|
||||
if g & 1:
|
||||
g += f
|
||||
eta -= 1
|
||||
g >>= 1
|
||||
```
|
||||
|
||||
Whenever *g* is even, the loop only shifts *g* down and decreases *η*. When *g* ends in multiple zero
|
||||
bits, these iterations can be consolidated into one step. This requires counting the bottom zero
|
||||
bits efficiently, which is possible on most platforms; it is abstracted here as the function
|
||||
`count_trailing_zeros`.
|
||||
|
||||
```python
|
||||
def count_trailing_zeros(v):
|
||||
"""
|
||||
When v is zero, consider all N zero bits as "trailing".
|
||||
For a non-zero value v, find z such that v=(d<<z) for some odd d.
|
||||
"""
|
||||
if v == 0:
|
||||
return N
|
||||
else:
|
||||
return (v & -v).bit_length() - 1
|
||||
|
||||
i = N # divsteps left to do
|
||||
while True:
|
||||
# Get rid of all bottom zeros at once. In the first iteration, g may be odd and the following
|
||||
# lines have no effect (until "if eta < 0").
|
||||
zeros = min(i, count_trailing_zeros(g))
|
||||
eta -= zeros
|
||||
g >>= zeros
|
||||
i -= zeros
|
||||
if i == 0:
|
||||
break
|
||||
# We know g is odd now
|
||||
if eta < 0:
|
||||
eta, f, g = -eta, g, -f
|
||||
g += f
|
||||
# g is even now, and the eta decrement and g shift will happen in the next loop.
|
||||
```
|
||||
|
||||
We can now remove multiple bottom *0* bits from *g* at once, but still need a full iteration whenever
|
||||
there is a bottom *1* bit. In what follows, we will get rid of multiple *1* bits simultaneously as
|
||||
well.
|
||||
|
||||
Observe that as long as *η ≥ 0*, the loop does not modify *f*. Instead, it cancels out bottom
|
||||
bits of *g* and shifts them out, and decreases *η* and *i* accordingly - interrupting only when *η*
|
||||
becomes negative, or when *i* reaches *0*. Combined, this is equivalent to adding a multiple of *f* to
|
||||
*g* to cancel out multiple bottom bits, and then shifting them out.
|
||||
|
||||
It is easy to find what that multiple is: we want a number *w* such that *g+w f* has a few bottom
|
||||
zero bits. If that number of bits is *L*, we want *g+w f mod 2<sup>L</sup> = 0*, or *w = -g/f mod 2<sup>L</sup>*. Since *f*
|
||||
is odd, such a *w* exists for any *L*. *L* cannot be more than *i* steps (as we'd finish the loop before
|
||||
doing more) or more than *η+1* steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but
|
||||
apart from that, we're only limited by the complexity of computing *w*.
|
||||
|
||||
This code demonstrates how to cancel up to 4 bits per step:
|
||||
|
||||
```python
|
||||
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
|
||||
i = N
|
||||
while True:
|
||||
zeros = min(i, count_trailing_zeros(g))
|
||||
eta -= zeros
|
||||
g >>= zeros
|
||||
i -= zeros
|
||||
if i == 0:
|
||||
break
|
||||
# We know g is odd now
|
||||
if eta < 0:
|
||||
eta, f, g = -eta, g, -f
|
||||
# Compute limit on number of bits to cancel
|
||||
limit = min(min(eta + 1, i), 4)
|
||||
# Compute w = -g/f mod 2**limit, using the table value for -1/f mod 2**4. Note that f is
|
||||
# always odd, so its inverse modulo a power of two always exists.
|
||||
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
|
||||
# As w = -g/f mod (2**limit), g+w*f mod 2**limit = 0 mod 2**limit.
|
||||
g += w * f
|
||||
assert g % (2**limit) == 0
|
||||
# The next iteration will now shift out at least limit bottom zero bits from g.
|
||||
```
|
||||
|
||||
By using a bigger table more bits can be cancelled at once. The table can also be implemented
|
||||
as a formula. Several formulas are known for computing modular inverses modulo powers of two;
|
||||
some can be found in Hacker's Delight second edition by Henry S. Warren, Jr. pages 245-247.
|
||||
Here we need the negated modular inverse, which is a simple transformation of those:
|
||||
|
||||
- Instead of a 3-bit table:
|
||||
- *-f* or *f ^ 6*
|
||||
- Instead of a 4-bit table:
|
||||
- *1 - f(f + 1)*
|
||||
- *-(f + (((f + 1) & 4) << 1))*
|
||||
- For larger tables the following technique can be used: if *w=-1/f mod 2<sup>L</sup>*, then *w(w f+2)* is
|
||||
*-1/f mod 2<sup>2L</sup>*. This allows extending the previous formulas (or tables). In particular we
|
||||
have this 6-bit function (based on the 3-bit function above):
|
||||
- *f(f<sup>2</sup> - 2)*
|
||||
|
||||
This loop, again extended to also handle *u*, *v*, *q*, and *r* alongside *f* and *g*, placed in
|
||||
`divsteps_n_matrix`, gives a significantly faster, but non-constant time version.
|
||||
|
||||
|
||||
## 7. Final Python version
|
||||
|
||||
All together we need the following functions:
|
||||
|
||||
- A way to compute the transition matrix in constant time, using the `divsteps_n_matrix` function
|
||||
from section 2, but with its loop replaced by a variant of the constant-time divstep from
|
||||
section 5, extended to handle *u*, *v*, *q*, *r*:
|
||||
|
||||
```python
|
||||
def divsteps_n_matrix(zeta, f, g):
|
||||
"""Compute zeta and transition matrix t after N divsteps (multiplied by 2^N)."""
|
||||
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
|
||||
for _ in range(N):
|
||||
c1 = zeta >> 63
|
||||
# Compute x, y, z as conditionally-negated versions of f, u, v.
|
||||
x, y, z = (f ^ c1) - c1, (u ^ c1) - c1, (v ^ c1) - c1
|
||||
c2 = -(g & 1)
|
||||
# Conditionally add x, y, z to g, q, r.
|
||||
g, q, r = g + (x & c2), q + (y & c2), r + (z & c2)
|
||||
c1 &= c2 # reusing c1 here for the earlier c3 variable
|
||||
zeta = (zeta ^ c1) - 1 # inlining the unconditional zeta decrement here
|
||||
# Conditionally add g, q, r to f, u, v.
|
||||
f, u, v = f + (g & c1), u + (q & c1), v + (r & c1)
|
||||
# When shifting g down, don't shift q, r, as we construct a transition matrix multiplied
|
||||
# by 2^N. Instead, shift f's coefficients u and v up.
|
||||
g, u, v = g >> 1, u << 1, v << 1
|
||||
return zeta, (u, v, q, r)
|
||||
```
|
||||
|
||||
- The functions to update *f* and *g*, and *d* and *e*, from section 2 and section 4, with the constant-time
|
||||
changes to `update_de` from section 5:
|
||||
|
||||
```python
|
||||
def update_fg(f, g, t):
|
||||
"""Multiply matrix t/2^N with [f, g]."""
|
||||
u, v, q, r = t
|
||||
cf, cg = u*f + v*g, q*f + r*g
|
||||
return cf >> N, cg >> N
|
||||
|
||||
def update_de(d, e, t, M, Mi):
|
||||
"""Multiply matrix t/2^N with [d, e], modulo M."""
|
||||
u, v, q, r = t
|
||||
d_sign, e_sign = d >> 257, e >> 257
|
||||
md, me = (u & d_sign) + (v & e_sign), (q & d_sign) + (r & e_sign)
|
||||
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
|
||||
md -= (Mi*cd + md) % 2**N
|
||||
me -= (Mi*ce + me) % 2**N
|
||||
cd, ce = u*d + v*e + M*md, q*d + r*e + M*me
|
||||
return cd >> N, ce >> N
|
||||
```
|
||||
|
||||
- The `normalize` function from section 4, made constant time as well:
|
||||
|
||||
```python
|
||||
def normalize(sign, v, M):
|
||||
"""Compute sign*v mod M, where v in (-2*M,M); output in [0,M)."""
|
||||
v_sign = v >> 257
|
||||
# Conditionally add M to v.
|
||||
v += M & v_sign
|
||||
c = (sign - 1) >> 1
|
||||
# Conditionally negate v.
|
||||
v = (v ^ c) - c
|
||||
v_sign = v >> 257
|
||||
# Conditionally add M to v again.
|
||||
v += M & v_sign
|
||||
return v
|
||||
```
|
||||
|
||||
- And finally the `modinv` function too, adapted to use *ζ* instead of *δ*, and using the fixed
|
||||
iteration count from section 5:
|
||||
|
||||
```python
|
||||
def modinv(M, Mi, x):
|
||||
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
|
||||
zeta, f, g, d, e = -1, M, x, 0, 1
|
||||
for _ in range((590 + N - 1) // N):
|
||||
zeta, t = divsteps_n_matrix(zeta, f % 2**N, g % 2**N)
|
||||
f, g = update_fg(f, g, t)
|
||||
d, e = update_de(d, e, t, M, Mi)
|
||||
return normalize(f, d, M)
|
||||
```
|
||||
|
||||
- To get a variable time version, replace the `divsteps_n_matrix` function with one that uses the
|
||||
divsteps loop from section 5, and a `modinv` version that calls it without the fixed iteration
|
||||
count:
|
||||
|
||||
```python
|
||||
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
|
||||
def divsteps_n_matrix_var(eta, f, g):
|
||||
"""Compute eta and transition matrix t after N divsteps (multiplied by 2^N)."""
|
||||
u, v, q, r = 1, 0, 0, 1
|
||||
i = N
|
||||
while True:
|
||||
zeros = min(i, count_trailing_zeros(g))
|
||||
eta, i = eta - zeros, i - zeros
|
||||
g, u, v = g >> zeros, u << zeros, v << zeros
|
||||
if i == 0:
|
||||
break
|
||||
if eta < 0:
|
||||
eta, f, u, v, g, q, r = -eta, g, q, r, -f, -u, -v
|
||||
limit = min(min(eta + 1, i), 4)
|
||||
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
|
||||
g, q, r = g + w*f, q + w*u, r + w*v
|
||||
return eta, (u, v, q, r)
|
||||
|
||||
def modinv_var(M, Mi, x):
|
||||
"""Compute the modular inverse of x mod M, given Mi = 1/M mod 2^N."""
|
||||
eta, f, g, d, e = -1, M, x, 0, 1
|
||||
while g != 0:
|
||||
eta, t = divsteps_n_matrix_var(eta, f % 2**N, g % 2**N)
|
||||
f, g = update_fg(f, g, t)
|
||||
d, e = update_de(d, e, t, M, Mi)
|
||||
return normalize(f, d, Mi)
|
||||
```
|
||||
|
||||
## 8. From GCDs to Jacobi symbol
|
||||
|
||||
We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an
|
||||
extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we
|
||||
make corresponding updates to *j* using
|
||||
[properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties):
|
||||
* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*).
|
||||
* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*).
|
||||
|
||||
These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied
|
||||
very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this
|
||||
calculation is slightly simpler than the one for the modular inverse because we no longer need to
|
||||
keep track of *d* and *e*.
|
||||
|
||||
However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for
|
||||
positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative
|
||||
values. We resolve this by using the following modified steps:
|
||||
|
||||
```python
|
||||
# Before
|
||||
if delta > 0 and g & 1:
|
||||
delta, f, g = 1 - delta, g, (g - f) // 2
|
||||
|
||||
# After
|
||||
if delta > 0 and g & 1:
|
||||
delta, f, g = 1 - delta, g, (g + f) // 2
|
||||
```
|
||||
|
||||
The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4
|
||||
and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm
|
||||
will converge. The justification for posdivsteps is completely empirical: in practice, it appears
|
||||
that the vast majority of nonzero inputs converge to *f=g=gcd(f<sub>0</sub>, g<sub>0</sub>)* in a
|
||||
number of steps proportional to their logarithm.
|
||||
|
||||
Note that:
|
||||
- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached.
|
||||
- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect.
|
||||
- We need to update the termination condition from *g=0* to *f=1*.
|
||||
|
||||
We account for the possibility of nonconvergence by only performing a bounded number of
|
||||
posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not
|
||||
yet been found.
|
||||
|
||||
The optimizations in sections 3-7 above are described in the context of the original divsteps, but
|
||||
in the C implementation we also adapt most of them (not including "avoiding modulus operations",
|
||||
since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate
|
||||
Jacobi symbols for secret data) to the posdivsteps version.
|
||||
31
external/secp256k1/examples/CMakeLists.txt
vendored
31
external/secp256k1/examples/CMakeLists.txt
vendored
@@ -1,31 +0,0 @@
|
||||
function(add_example name)
|
||||
set(target_name ${name}_example)
|
||||
add_executable(${target_name} ${name}.c)
|
||||
target_include_directories(${target_name} PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(${target_name}
|
||||
secp256k1
|
||||
$<$<PLATFORM_ID:Windows>:bcrypt>
|
||||
)
|
||||
set(test_name ${name}_example)
|
||||
add_test(NAME secp256k1_${test_name} COMMAND ${target_name})
|
||||
endfunction()
|
||||
|
||||
add_example(ecdsa)
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_ECDH)
|
||||
add_example(ecdh)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
|
||||
add_example(schnorr)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
|
||||
add_example(ellswift)
|
||||
endif()
|
||||
|
||||
if(SECP256K1_ENABLE_MODULE_MUSIG)
|
||||
add_example(musig)
|
||||
endif()
|
||||
121
external/secp256k1/examples/EXAMPLES_COPYING
vendored
121
external/secp256k1/examples/EXAMPLES_COPYING
vendored
@@ -1,121 +0,0 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
120
external/secp256k1/examples/ecdh.c
vendored
120
external/secp256k1/examples/ecdh.c
vendored
@@ -1,120 +0,0 @@
|
||||
/*************************************************************************
|
||||
* Written in 2020-2022 by Elichai Turkel *
|
||||
* To the extent possible under law, the author(s) have dedicated all *
|
||||
* copyright and related and neighboring rights to the software in this *
|
||||
* file to the public domain worldwide. This software is distributed *
|
||||
* without any warranty. For the CC0 Public Domain Dedication, see *
|
||||
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_ecdh.h>
|
||||
|
||||
#include "examples_util.h"
|
||||
|
||||
int main(void) {
|
||||
unsigned char seckey1[32];
|
||||
unsigned char seckey2[32];
|
||||
unsigned char compressed_pubkey1[33];
|
||||
unsigned char compressed_pubkey2[33];
|
||||
unsigned char shared_secret1[32];
|
||||
unsigned char shared_secret2[32];
|
||||
unsigned char randomize[32];
|
||||
int return_val;
|
||||
size_t len;
|
||||
secp256k1_pubkey pubkey1;
|
||||
secp256k1_pubkey pubkey2;
|
||||
|
||||
/* Before we can call actual API functions, we need to create a "context". */
|
||||
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
if (!fill_random(randomize, sizeof(randomize))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* Randomizing the context is recommended to protect against side-channel
|
||||
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
|
||||
* information about it. This should never fail. */
|
||||
return_val = secp256k1_context_randomize(ctx, randomize);
|
||||
assert(return_val);
|
||||
|
||||
/*** Key Generation ***/
|
||||
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* If the secret key is zero or out of range (greater than secp256k1's
|
||||
* order), we fail. Note that the probability of this occurring is negligible
|
||||
* with a properly functioning random number generator. */
|
||||
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
|
||||
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Public key creation using a valid context with a verified secret key should never fail */
|
||||
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
|
||||
assert(return_val);
|
||||
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
|
||||
assert(return_val);
|
||||
|
||||
/* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
|
||||
len = sizeof(compressed_pubkey1);
|
||||
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED);
|
||||
assert(return_val);
|
||||
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
|
||||
assert(len == sizeof(compressed_pubkey1));
|
||||
|
||||
/* Serialize pubkey2 in a compressed form (33 bytes) */
|
||||
len = sizeof(compressed_pubkey2);
|
||||
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED);
|
||||
assert(return_val);
|
||||
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
|
||||
assert(len == sizeof(compressed_pubkey2));
|
||||
|
||||
/*** Creating the shared secret ***/
|
||||
|
||||
/* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
|
||||
* seckey and valid pubkey */
|
||||
return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL);
|
||||
assert(return_val);
|
||||
|
||||
/* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
|
||||
* seckey and valid pubkey */
|
||||
return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL);
|
||||
assert(return_val);
|
||||
|
||||
/* Both parties should end up with the same shared secret */
|
||||
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
|
||||
assert(return_val == 0);
|
||||
|
||||
printf("Secret Key1: ");
|
||||
print_hex(seckey1, sizeof(seckey1));
|
||||
printf("Compressed Pubkey1: ");
|
||||
print_hex(compressed_pubkey1, sizeof(compressed_pubkey1));
|
||||
printf("\nSecret Key2: ");
|
||||
print_hex(seckey2, sizeof(seckey2));
|
||||
printf("Compressed Pubkey2: ");
|
||||
print_hex(compressed_pubkey2, sizeof(compressed_pubkey2));
|
||||
printf("\nShared Secret: ");
|
||||
print_hex(shared_secret1, sizeof(shared_secret1));
|
||||
|
||||
/* This will clear everything from the context and free the memory */
|
||||
secp256k1_context_destroy(ctx);
|
||||
|
||||
/* It's best practice to try to clear secrets from memory after using them.
|
||||
* This is done because some bugs can allow an attacker to leak memory, for
|
||||
* example through "out of bounds" array access (see Heartbleed), or the OS
|
||||
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
|
||||
*
|
||||
* Here we are preventing these writes from being optimized out, as any good compiler
|
||||
* will remove any writes that aren't used. */
|
||||
secure_erase(seckey1, sizeof(seckey1));
|
||||
secure_erase(seckey2, sizeof(seckey2));
|
||||
secure_erase(shared_secret1, sizeof(shared_secret1));
|
||||
secure_erase(shared_secret2, sizeof(shared_secret2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
137
external/secp256k1/examples/ecdsa.c
vendored
137
external/secp256k1/examples/ecdsa.c
vendored
@@ -1,137 +0,0 @@
|
||||
/*************************************************************************
|
||||
* Written in 2020-2022 by Elichai Turkel *
|
||||
* To the extent possible under law, the author(s) have dedicated all *
|
||||
* copyright and related and neighboring rights to the software in this *
|
||||
* file to the public domain worldwide. This software is distributed *
|
||||
* without any warranty. For the CC0 Public Domain Dedication, see *
|
||||
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
|
||||
#include "examples_util.h"
|
||||
|
||||
int main(void) {
|
||||
/* Instead of signing the message directly, we must sign a 32-byte hash.
|
||||
* Here the message is "Hello, world!" and the hash function was SHA-256.
|
||||
* An actual implementation should just call SHA-256, but this example
|
||||
* hardcodes the output to avoid depending on an additional library.
|
||||
* See https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/81116#81116 */
|
||||
unsigned char msg_hash[32] = {
|
||||
0x31, 0x5F, 0x5B, 0xDB, 0x76, 0xD0, 0x78, 0xC4,
|
||||
0x3B, 0x8A, 0xC0, 0x06, 0x4E, 0x4A, 0x01, 0x64,
|
||||
0x61, 0x2B, 0x1F, 0xCE, 0x77, 0xC8, 0x69, 0x34,
|
||||
0x5B, 0xFC, 0x94, 0xC7, 0x58, 0x94, 0xED, 0xD3,
|
||||
};
|
||||
unsigned char seckey[32];
|
||||
unsigned char randomize[32];
|
||||
unsigned char compressed_pubkey[33];
|
||||
unsigned char serialized_signature[64];
|
||||
size_t len;
|
||||
int is_signature_valid, is_signature_valid2;
|
||||
int return_val;
|
||||
secp256k1_pubkey pubkey;
|
||||
secp256k1_ecdsa_signature sig;
|
||||
/* Before we can call actual API functions, we need to create a "context". */
|
||||
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
if (!fill_random(randomize, sizeof(randomize))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* Randomizing the context is recommended to protect against side-channel
|
||||
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
|
||||
* information about it. This should never fail. */
|
||||
return_val = secp256k1_context_randomize(ctx, randomize);
|
||||
assert(return_val);
|
||||
|
||||
/*** Key Generation ***/
|
||||
if (!fill_random(seckey, sizeof(seckey))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* If the secret key is zero or out of range (greater than secp256k1's
|
||||
* order), we fail. Note that the probability of this occurring is negligible
|
||||
* with a properly functioning random number generator. */
|
||||
if (!secp256k1_ec_seckey_verify(ctx, seckey)) {
|
||||
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Public key creation using a valid context with a verified secret key should never fail */
|
||||
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);
|
||||
assert(return_val);
|
||||
|
||||
/* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */
|
||||
len = sizeof(compressed_pubkey);
|
||||
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey, &len, &pubkey, SECP256K1_EC_COMPRESSED);
|
||||
assert(return_val);
|
||||
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
|
||||
assert(len == sizeof(compressed_pubkey));
|
||||
|
||||
/*** Signing ***/
|
||||
|
||||
/* Generate an ECDSA signature `noncefp` and `ndata` allows you to pass a
|
||||
* custom nonce function, passing `NULL` will use the RFC-6979 safe default.
|
||||
* Signing with a valid context, verified secret key
|
||||
* and the default nonce function should never fail. */
|
||||
return_val = secp256k1_ecdsa_sign(ctx, &sig, msg_hash, seckey, NULL, NULL);
|
||||
assert(return_val);
|
||||
|
||||
/* Serialize the signature in a compact form. Should always return 1
|
||||
* according to the documentation in secp256k1.h. */
|
||||
return_val = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig);
|
||||
assert(return_val);
|
||||
|
||||
|
||||
/*** Verification ***/
|
||||
|
||||
/* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */
|
||||
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) {
|
||||
printf("Failed parsing the signature\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
|
||||
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
|
||||
printf("Failed parsing the public key\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
|
||||
is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey);
|
||||
|
||||
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
|
||||
printf("Secret Key: ");
|
||||
print_hex(seckey, sizeof(seckey));
|
||||
printf("Public Key: ");
|
||||
print_hex(compressed_pubkey, sizeof(compressed_pubkey));
|
||||
printf("Signature: ");
|
||||
print_hex(serialized_signature, sizeof(serialized_signature));
|
||||
|
||||
/* This will clear everything from the context and free the memory */
|
||||
secp256k1_context_destroy(ctx);
|
||||
|
||||
/* Bonus example: if all we need is signature verification (and no key
|
||||
generation or signing), we don't need to use a context created via
|
||||
secp256k1_context_create(). We can simply use the static (i.e., global)
|
||||
context secp256k1_context_static. See its description in
|
||||
include/secp256k1.h for details. */
|
||||
is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static,
|
||||
&sig, msg_hash, &pubkey);
|
||||
assert(is_signature_valid2 == is_signature_valid);
|
||||
|
||||
/* It's best practice to try to clear secrets from memory after using them.
|
||||
* This is done because some bugs can allow an attacker to leak memory, for
|
||||
* example through "out of bounds" array access (see Heartbleed), or the OS
|
||||
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
|
||||
*
|
||||
* Here we are preventing these writes from being optimized out, as any good compiler
|
||||
* will remove any writes that aren't used. */
|
||||
secure_erase(seckey, sizeof(seckey));
|
||||
|
||||
return 0;
|
||||
}
|
||||
121
external/secp256k1/examples/ellswift.c
vendored
121
external/secp256k1/examples/ellswift.c
vendored
@@ -1,121 +0,0 @@
|
||||
/*************************************************************************
|
||||
* Written in 2024 by Sebastian Falbesoner *
|
||||
* To the extent possible under law, the author(s) have dedicated all *
|
||||
* copyright and related and neighboring rights to the software in this *
|
||||
* file to the public domain worldwide. This software is distributed *
|
||||
* without any warranty. For the CC0 Public Domain Dedication, see *
|
||||
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
|
||||
*************************************************************************/
|
||||
|
||||
/** This file demonstrates how to use the ElligatorSwift module to perform
|
||||
* a key exchange according to BIP 324. Additionally, see the documentation
|
||||
* in include/secp256k1_ellswift.h and doc/ellswift.md.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_ellswift.h>
|
||||
|
||||
#include "examples_util.h"
|
||||
|
||||
int main(void) {
|
||||
secp256k1_context* ctx;
|
||||
unsigned char randomize[32];
|
||||
unsigned char auxrand1[32];
|
||||
unsigned char auxrand2[32];
|
||||
unsigned char seckey1[32];
|
||||
unsigned char seckey2[32];
|
||||
unsigned char ellswift_pubkey1[64];
|
||||
unsigned char ellswift_pubkey2[64];
|
||||
unsigned char shared_secret1[32];
|
||||
unsigned char shared_secret2[32];
|
||||
int return_val;
|
||||
|
||||
/* Create a secp256k1 context */
|
||||
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
if (!fill_random(randomize, sizeof(randomize))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* Randomizing the context is recommended to protect against side-channel
|
||||
* leakage. See `secp256k1_context_randomize` in secp256k1.h for more
|
||||
* information about it. This should never fail. */
|
||||
return_val = secp256k1_context_randomize(ctx, randomize);
|
||||
assert(return_val);
|
||||
|
||||
/*** Generate secret keys ***/
|
||||
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
/* If the secret key is zero or out of range (greater than secp256k1's
|
||||
* order), we fail. Note that the probability of this occurring is negligible
|
||||
* with a properly functioning random number generator. */
|
||||
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
|
||||
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generate ElligatorSwift public keys. This should never fail with valid context and
|
||||
verified secret keys. Note that providing additional randomness (fourth parameter) is
|
||||
optional, but recommended. */
|
||||
if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) {
|
||||
printf("Failed to generate randomness\n");
|
||||
return 1;
|
||||
}
|
||||
return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1);
|
||||
assert(return_val);
|
||||
return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey2, seckey2, auxrand2);
|
||||
assert(return_val);
|
||||
|
||||
/*** Create the shared secret on each side ***/
|
||||
|
||||
/* Perform x-only ECDH with seckey1 and ellswift_pubkey2. Should never fail
|
||||
* with a verified seckey and valid pubkey. Note that both parties pass both
|
||||
* EllSwift pubkeys in the same order; the pubkey of the calling party is
|
||||
* determined by the "party" boolean (sixth parameter). */
|
||||
return_val = secp256k1_ellswift_xdh(ctx, shared_secret1, ellswift_pubkey1, ellswift_pubkey2,
|
||||
seckey1, 0, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
|
||||
assert(return_val);
|
||||
|
||||
/* Perform x-only ECDH with seckey2 and ellswift_pubkey1. Should never fail
|
||||
* with a verified seckey and valid pubkey. */
|
||||
return_val = secp256k1_ellswift_xdh(ctx, shared_secret2, ellswift_pubkey1, ellswift_pubkey2,
|
||||
seckey2, 1, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
|
||||
assert(return_val);
|
||||
|
||||
/* Both parties should end up with the same shared secret */
|
||||
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
|
||||
assert(return_val == 0);
|
||||
|
||||
printf( " Secret Key1: ");
|
||||
print_hex(seckey1, sizeof(seckey1));
|
||||
printf( "EllSwift Pubkey1: ");
|
||||
print_hex(ellswift_pubkey1, sizeof(ellswift_pubkey1));
|
||||
printf("\n Secret Key2: ");
|
||||
print_hex(seckey2, sizeof(seckey2));
|
||||
printf( "EllSwift Pubkey2: ");
|
||||
print_hex(ellswift_pubkey2, sizeof(ellswift_pubkey2));
|
||||
printf("\n Shared Secret: ");
|
||||
print_hex(shared_secret1, sizeof(shared_secret1));
|
||||
|
||||
/* This will clear everything from the context and free the memory */
|
||||
secp256k1_context_destroy(ctx);
|
||||
|
||||
/* It's best practice to try to clear secrets from memory after using them.
|
||||
* This is done because some bugs can allow an attacker to leak memory, for
|
||||
* example through "out of bounds" array access (see Heartbleed), or the OS
|
||||
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
|
||||
*
|
||||
* Here we are preventing these writes from being optimized out, as any good compiler
|
||||
* will remove any writes that aren't used. */
|
||||
secure_erase(seckey1, sizeof(seckey1));
|
||||
secure_erase(seckey2, sizeof(seckey2));
|
||||
secure_erase(shared_secret1, sizeof(shared_secret1));
|
||||
secure_erase(shared_secret2, sizeof(shared_secret2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
108
external/secp256k1/examples/examples_util.h
vendored
108
external/secp256k1/examples/examples_util.h
vendored
@@ -1,108 +0,0 @@
|
||||
/*************************************************************************
|
||||
* Copyright (c) 2020-2021 Elichai Turkel *
|
||||
* Distributed under the CC0 software license, see the accompanying file *
|
||||
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
|
||||
* It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
|
||||
*
|
||||
* Platform randomness sources:
|
||||
* Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom
|
||||
* macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html
|
||||
* FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
|
||||
* OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom
|
||||
* Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
* The defined WIN32_NO_STATUS macro disables return code definitions in
|
||||
* windows.h, which avoids "macro redefinition" MSVC warnings in ntstatus.h.
|
||||
*/
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windows.h>
|
||||
#undef WIN32_NO_STATUS
|
||||
#include <ntstatus.h>
|
||||
#include <bcrypt.h>
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#include <sys/random.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error "Couldn't identify the OS"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Returns 1 on success, and 0 on failure. */
|
||||
static int fill_random(unsigned char* data, size_t size) {
|
||||
#if defined(_WIN32)
|
||||
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
|
||||
ssize_t res = getrandom(data, size, 0);
|
||||
if (res < 0 || (size_t)res != size ) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
#elif defined(__APPLE__) || defined(__OpenBSD__)
|
||||
/* If `getentropy(2)` is not available you should fallback to either
|
||||
* `SecRandomCopyBytes` or /dev/urandom */
|
||||
int res = getentropy(data, size);
|
||||
if (res == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_hex(unsigned char* data, size_t size) {
|
||||
size_t i;
|
||||
printf("0x");
|
||||
for (i = 0; i < size; i++) {
|
||||
printf("%02x", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// For SecureZeroMemory
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
|
||||
static void secure_erase(void *ptr, size_t len) {
|
||||
#if defined(_MSC_VER)
|
||||
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
|
||||
SecureZeroMemory(ptr, len);
|
||||
#elif defined(__GNUC__)
|
||||
/* We use a memory barrier that scares the compiler away from optimizing out the memset.
|
||||
*
|
||||
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
|
||||
* in BoringSSL (ISC License):
|
||||
* As best as we can tell, this is sufficient to break any optimisations that
|
||||
* might try to eliminate "superfluous" memsets.
|
||||
* This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
|
||||
* pretty efficient, because the compiler can still implement the memset() efficiently,
|
||||
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
|
||||
* Yang et al. (USENIX Security 2017) for more background.
|
||||
*/
|
||||
memset(ptr, 0, len);
|
||||
__asm__ __volatile__("" : : "r"(ptr) : "memory");
|
||||
#else
|
||||
void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
|
||||
volatile_memset(ptr, 0, len);
|
||||
#endif
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user