Compare commits

...

No commits in common. 'master' and 'gh-pages' have entirely different histories.

  1. 18
      .codecov.yml
  2. 28
      .coveragerc
  3. 8
      .flake8
  4. 17
      .gitattributes
  5. 5
      .github/FUNDING.yml
  6. 41
      .github/scripts/build-windows-wheels.sh
  7. 14
      .github/scripts/install-macos-build-deps.sh
  8. 9
      .github/scripts/install-test-deps.sh
  9. 209
      .github/workflows/build.yml
  10. 62
      .github/workflows/docs.yml
  11. 17
      .gitignore
  12. 0
      .nojekyll
  13. 1
      404.html
  14. 178
      LICENSE-APACHE
  15. 21
      LICENSE-MIT
  16. 4
      MANIFEST.in
  17. 31
      README.md
  18. 32
      _cffi_build/build.py
  19. 170
      _cffi_build/secp256k1.h
  20. 8
      _cffi_build/secp256k1_ecdh.h
  21. 39
      _cffi_build/secp256k1_recovery.h
  22. 449
      api/index.html
  23. 16
      assets/_mkdocstrings.css
  24. 0
      assets/css/custom.css
  25. 0
      assets/images/favicon.ico
  26. BIN
      assets/images/favicon.png
  27. 29
      assets/javascripts/bundle.b1047164.min.js
  28. 7
      assets/javascripts/bundle.b1047164.min.js.map
  29. 1
      assets/javascripts/lunr/min/lunr.ar.min.js
  30. 18
      assets/javascripts/lunr/min/lunr.da.min.js
  31. 18
      assets/javascripts/lunr/min/lunr.de.min.js
  32. 18
      assets/javascripts/lunr/min/lunr.du.min.js
  33. 18
      assets/javascripts/lunr/min/lunr.es.min.js
  34. 18
      assets/javascripts/lunr/min/lunr.fi.min.js
  35. 18
      assets/javascripts/lunr/min/lunr.fr.min.js
  36. 1
      assets/javascripts/lunr/min/lunr.hi.min.js
  37. 18
      assets/javascripts/lunr/min/lunr.hu.min.js
  38. 18
      assets/javascripts/lunr/min/lunr.it.min.js
  39. 1
      assets/javascripts/lunr/min/lunr.ja.min.js
  40. 1
      assets/javascripts/lunr/min/lunr.jp.min.js
  41. 1
      assets/javascripts/lunr/min/lunr.multi.min.js
  42. 18
      assets/javascripts/lunr/min/lunr.nl.min.js
  43. 18
      assets/javascripts/lunr/min/lunr.no.min.js
  44. 18
      assets/javascripts/lunr/min/lunr.pt.min.js
  45. 18
      assets/javascripts/lunr/min/lunr.ro.min.js
  46. 18
      assets/javascripts/lunr/min/lunr.ru.min.js
  47. 1
      assets/javascripts/lunr/min/lunr.stemmer.support.min.js
  48. 18
      assets/javascripts/lunr/min/lunr.sv.min.js
  49. 1
      assets/javascripts/lunr/min/lunr.th.min.js
  50. 18
      assets/javascripts/lunr/min/lunr.tr.min.js
  51. 1
      assets/javascripts/lunr/min/lunr.vi.min.js
  52. 1
      assets/javascripts/lunr/min/lunr.zh.min.js
  53. 206
      assets/javascripts/lunr/tinyseg.js
  54. 6708
      assets/javascripts/lunr/wordcut.js
  55. 48
      assets/javascripts/workers/search.fcfe8b6d.min.js
  56. 7
      assets/javascripts/workers/search.fcfe8b6d.min.js.map
  57. 2
      assets/stylesheets/main.a57b2b03.min.css
  58. 1
      assets/stylesheets/main.a57b2b03.min.css.map
  59. 2
      assets/stylesheets/palette.3f5d1f46.min.css
  60. 1
      assets/stylesheets/palette.3f5d1f46.min.css.map
  61. 3
      coincurve/__init__.py
  62. 239
      coincurve/_windows_libsecp256k1.py
  63. 33
      coincurve/context.py
  64. 115
      coincurve/ecdsa.py
  65. 10
      coincurve/flags.py
  66. 486
      coincurve/keys.py
  67. 13
      coincurve/types.py
  68. 130
      coincurve/utils.py
  69. 3
      docs/.scripts/49_global_refs.py
  70. 2
      docs/.snippets/abbrs.txt
  71. 5
      docs/.snippets/links.txt
  72. 4
      docs/.snippets/refs.txt
  73. 50
      docs/api.md
  74. 131
      docs/history.md
  75. 49
      docs/index.md
  76. 62
      docs/install.md
  77. 43
      docs/users.md
  78. 1
      history/index.html
  79. 1
      index.html
  80. 8
      install/index.html
  81. 123
      mkdocs.yml
  82. 8
      mypy.ini
  83. BIN
      objects.inv
  84. 35
      pyproject.toml
  85. 3
      requirements-dev.txt
  86. 1
      search/search_index.json
  87. 314
      setup.py
  88. 106
      setup_support.py
  89. 28
      sitemap.xml
  90. BIN
      sitemap.xml.gz
  91. 0
      tests/__init__.py
  92. 999
      tests/data/ecdsa_sig.json
  93. 1749
      tests/data/pubkey.json
  94. 50
      tests/samples.py
  95. 53
      tests/test_bench.py
  96. 7
      tests/test_ecdsa.py
  97. 148
      tests/test_keys.py
  98. 106
      tests/test_utils.py
  99. 95
      tox.ini
  100. 1
      users/index.html

18
.codecov.yml

@ -1,18 +0,0 @@
comment:
layout: "diff, files"
behavior: default
branches: null
coverage:
range: 50..100
round: down
precision: 2
status:
project:
default:
target: '70'
patch:
default:
target: '70'

28
.coveragerc

@ -1,28 +0,0 @@
[run]
branch = True
source =
coincurve
tests
omit =
*/_windows_libsecp256k1.py
*/test_bench.py
[paths]
source =
coincurve
.tox/*/lib/python*/site-packages/coincurve
.tox/pypy*/site-packages/coincurve
[report]
exclude_lines =
no cov
no qa
# Ignore missing debug-only code
def __repr__
if self\.debug
# Ignore non-runnable code
if __name__ == .__main__.:

8
.flake8

@ -1,8 +0,0 @@
# TODO: move this to pyproject.toml when supported: https://gitlab.com/pycqa/flake8/-/issues/428
[flake8]
select = B,C,E,F,W,B001,B003,B006,B007,B301,B305,B306,B902,Q000,Q001,Q002,Q003
ignore = E203,E722,W503
exclude = .tox,build
max-line-length = 120
per-file-ignores = coincurve/__init__.py:F401

17
.gitattributes

@ -1,17 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

5
.github/FUNDING.yml

@ -1,5 +0,0 @@
github:
- ofek
custom:
- https://ofek.dev/donate/
- https://paypal.me/ofeklev

41
.github/scripts/build-windows-wheels.sh

@ -1,41 +0,0 @@
#!/bin/bash
set -ex
build_dll() {
./autogen.sh
./configure --host=$1 --enable-module-recovery --enable-experimental --enable-module-ecdh --enable-benchmark=no --enable-tests=no --enable-openssl-tests=no --enable-exhaustive-tests=no --enable-static --disable-dependency-tracking --with-pic
make
}
sudo apt-get install -y mingw-w64
sudo apt-get -f install
mkdir .hidden
cp * .hidden -R
mv .hidden/coincurve/_windows_libsecp256k1.py .hidden/coincurve/_libsecp256k1.py
mv .hidden ../clean
cd ..
curl -sLO "https://github.com/bitcoin-core/secp256k1/archive/$COINCURVE_UPSTREAM_REF.tar.gz"
tar -xzf "$COINCURVE_UPSTREAM_REF.tar.gz"
mv "secp256k1-$COINCURVE_UPSTREAM_REF" secp256k1
mv secp256k1 64bit
cp 64bit 32bit -R
cd 64bit
build_dll x86_64-w64-mingw32
mv .libs/libsecp256k1-0.dll ../clean/coincurve/libsecp256k1.dll
cd ../clean
python setup.py bdist_wheel --plat-name=win_amd64
rm coincurve/libsecp256k1.dll
cd ../32bit
build_dll i686-w64-mingw32
mv .libs/libsecp256k1-0.dll ../clean/coincurve/libsecp256k1.dll
cd ../clean
python setup.py bdist_wheel --plat-name=win32
mv dist/* ../coincurve/dist/
cd ../coincurve

14
.github/scripts/install-macos-build-deps.sh

@ -1,14 +0,0 @@
#!/bin/bash
set -ex
# update brew
brew update
# Update openssl if necessary
brew outdated openssl || brew upgrade openssl
# Install packages needed to build lib-secp256k1
for pkg in automake libtool pkg-config; do
brew list $pkg > /dev/null || brew install $pkg
brew outdated --quiet $pkg || brew upgrade $pkg
done

9
.github/scripts/install-test-deps.sh

@ -1,9 +0,0 @@
#!/bin/bash
set -ex
if [ "$RUNNER_OS" == "macOS" ]; then
./.github/scripts/install-macos-build-deps.sh
fi
python -m pip install --upgrade cffi
python -m pip install --upgrade tox codecov

209
.github/workflows/build.yml

@ -1,209 +0,0 @@
name: build
on:
push:
tags:
- v*
branches:
- master
pull_request:
branches:
- master
concurrency:
group: build-${{ github.head_ref }}
cancel-in-progress: true
env:
COINCURVE_UPSTREAM_REF: d8a246324650c3df8d54d133a8ac3c1b857a7a4e
COINCURVE_IGNORE_SYSTEM_LIB: '1'
CIBW_BEFORE_ALL_MACOS: ./.github/scripts/install-macos-build-deps.sh
CIBW_ENVIRONMENT_PASS_LINUX: >
COINCURVE_UPSTREAM_REF
COINCURVE_IGNORE_SYSTEM_LIB
CIBW_TEST_COMMAND: >
python -c
"from coincurve import PrivateKey;
a=PrivateKey();
b=PrivateKey();
assert a.ecdh(b.public_key.format())==b.ecdh(a.public_key.format())
"
CIBW_SKIP: >
pp*
jobs:
test:
name: Test latest Python
runs-on: ubuntu-latest
env:
PYTHON_VERSION: '3.10'
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v2
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Upgrade Python packaging tools
run: pip install --upgrade pip setuptools wheel
- name: Show runner information
run: |
python --version
pip --version
- name: Install dependencies
run: ./.github/scripts/install-test-deps.sh
- name: Check style and typing
run: tox -e lint,typing
- name: Run tests
run: tox -e ${PYTHON_VERSION}
- name: Run benchmarks
run: tox -e bench
- name: Upload coverage
run: codecov -X gcov
linux-wheels-standard:
name: Build Linux wheels
needs:
- test
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Build wheels
uses: pypa/cibuildwheel@v2.3.1
- uses: actions/upload-artifact@v2
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error
macos-wheels-x86-64:
name: Build macOS wheels
needs:
- test
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Build wheels
uses: pypa/cibuildwheel@v2.3.1
env:
CIBW_ARCHS_MACOS: x86_64
- uses: actions/upload-artifact@v2
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error
macos-wheels-arm:
name: Build macOS wheels for ARM
needs:
- test
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Build wheels
uses: pypa/cibuildwheel@v2.3.1
env:
CIBW_ARCHS_MACOS: arm64
COINCURVE_CROSS_HOST: aarch64-apple-darwin
CFLAGS: -target arm64-apple-macos11
- uses: actions/upload-artifact@v2
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error
windows-wheels-and-sdist:
name: Build Windows wheels and source distribution
needs:
- test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install build dependencies
run: python -m pip install --upgrade cffi
- name: Build source distribution
run: python setup.py sdist
- name: Build Windows wheels
run: ./.github/scripts/build-windows-wheels.sh
- uses: actions/upload-artifact@v2
with:
name: artifacts
path: dist/*
if-no-files-found: error
linux-wheels-arm:
name: Build Linux wheels for ARM
needs:
- test
runs-on: ubuntu-20.04
if: >
github.event_name == 'push'
&&
(github.ref == 'refs/heads/master' || startsWith(github.event.ref, 'refs/tags'))
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: arm64
- name: Build wheels
uses: pypa/cibuildwheel@v2.3.1
env:
CIBW_ARCHS_LINUX: aarch64
- uses: actions/upload-artifact@v2
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error
publish:
name: Publish release
needs:
- linux-wheels-standard
- macos-wheels-x86-64
- macos-wheels-arm
- windows-wheels-and-sdist
- linux-wheels-arm
runs-on: ubuntu-latest
if: >
github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
steps:
- uses: actions/download-artifact@v2
with:
name: artifacts
path: dist
- name: Push build artifacts to PyPI
uses: pypa/gh-action-pypi-publish@v1.4.2
with:
skip_existing: true
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

62
.github/workflows/docs.yml

@ -1,62 +0,0 @@
name: docs
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# Fetch all history for applying timestamps to every page
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Upgrade Python packaging tools
run: pip install --disable-pip-version-check --upgrade pip setuptools wheel
- name: Install dependencies
run: python -m pip install --upgrade tox
- name: Build documentation
run: tox -e docs-ci build
- uses: actions/upload-artifact@v2
with:
name: documentation
path: site
publish:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs:
- build
steps:
- uses: actions/download-artifact@v2
with:
name: documentation
path: site
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
commit_message: ${{ github.event.head_commit.message }}
# Write .nojekyll at the root, see:
# https://help.github.com/en/github/working-with-github-pages/about-github-pages#static-site-generators
enable_jekyll: false
# Only deploy if there were changes
allow_empty_commit: false

17
.gitignore

@ -1,17 +0,0 @@
*.log
*.pyc
/.cache
/.coverage
/.eggs
/.idea
/.mypy_cache
/.tox
/coincurve.egg-info
/build
/dist
/site
/wheelhouse
/pip-wheel-metadata
/coincurve/_libsecp256k1.py
/coincurve/libsecp256k1.dll

0
coincurve/py.typed → .nojekyll

1
404.html

File diff suppressed because one or more lines are too long

178
LICENSE-APACHE

@ -1,178 +0,0 @@
Copyright 2017 Ofek Lev
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

21
LICENSE-MIT

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 Ofek Lev
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.

4
MANIFEST.in

@ -1,4 +0,0 @@
include coincurve/py.typed
include setup_support.py
recursive-include _cffi_build *.py *.h
graft libsecp256k1

31
README.md

@ -1,31 +0,0 @@
# coincurve
| | |
| --- | --- |
| CI/CD | [![CI - Test](https://github.com/ofek/coincurve/actions/workflows/build.yml/badge.svg)](https://github.com/ofek/coincurve/actions/workflows/build.yml) [![CI - Coverage](https://img.shields.io/codecov/c/github/ofek/coincurve/master.svg?logo=codecov&logoColor=red)](https://codecov.io/github/ofek/coincurve) |
| Docs | [![CI - Docs](https://github.com/ofek/coincurve/actions/workflows/docs.yml/badge.svg)](https://github.com/ofek/coincurve/actions/workflows/docs.yml) |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/coincurve.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/coincurve/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/coincurve.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/coincurve/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/coincurve.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/coincurve/) |
| Meta | [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/ambv/black) [![imports - isort](https://img.shields.io/badge/imports-isort-ef8336.svg)](https://github.com/pycqa/isort) [![License - MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-9400d3.svg)](https://spdx.org/licenses/) [![GitHub Sponsors](https://img.shields.io/github/sponsors/ofek?logo=GitHub%20Sponsors&style=social)](https://github.com/sponsors/ofek) |
-----
This library provides well-tested Python bindings for [libsecp256k1](https://github.com/bitcoin-core/secp256k1), the heavily optimized C library
used by [Bitcoin Core](https://github.com/bitcoin/bitcoin) for operations on the elliptic curve [secp256k1](https://en.bitcoin.it/wiki/Secp256k1).
Feel free to read the [documentation](https://ofek.dev/coincurve/)!
## Users
- [Ethereum](https://ethereum.org)
- [LBRY](https://lbry.com)
- [ZeroNet](https://zeronet.io)
- [libp2p](https://libp2p.io)
and [many more](https://ofek.dev/coincurve/users/)!
## License
`coincurve` is distributed under the terms of any of the following licenses:
- [MIT](https://spdx.org/licenses/MIT.html)
- [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)

32
_cffi_build/build.py

@ -1,32 +0,0 @@
import os
from collections import namedtuple
from cffi import FFI
here = os.path.dirname(os.path.abspath(__file__))
Source = namedtuple('Source', ('h', 'include'))
def _mk_ffi(sources, name='_libsecp256k1', **kwargs):
_ffi = FFI()
code = []
for source in sources:
with open(os.path.join(here, source.h), 'rt') as h:
_ffi.cdef(h.read())
code.append(source.include)
code.append('#define PY_USE_BUNDLED')
_ffi.set_source(name, '\n'.join(code), **kwargs)
return _ffi
modules = [
Source('secp256k1.h', '#include <secp256k1.h>'),
Source('secp256k1_ecdh.h', '#include <secp256k1_ecdh.h>'),
Source('secp256k1_recovery.h', '#include <secp256k1_recovery.h>'),
]
ffi = _mk_ffi(modules, libraries=['secp256k1'])

170
_cffi_build/secp256k1.h

@ -1,170 +0,0 @@
typedef struct secp256k1_context_struct secp256k1_context;
typedef struct {
unsigned char data[64];
} secp256k1_pubkey;
typedef struct {
unsigned char data[64];
} secp256k1_ecdsa_signature;
typedef int (*secp256k1_nonce_function)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *algo16,
void *data,
unsigned int attempt
);
#define SECP256K1_FLAGS_TYPE_MASK ...
#define SECP256K1_FLAGS_TYPE_CONTEXT ...
#define SECP256K1_FLAGS_TYPE_COMPRESSION ...
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY ...
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN ...
#define SECP256K1_FLAGS_BIT_COMPRESSION ...
#define SECP256K1_CONTEXT_VERIFY ...
#define SECP256K1_CONTEXT_SIGN ...
#define SECP256K1_CONTEXT_NONE ...
#define SECP256K1_EC_COMPRESSED ...
#define SECP256K1_EC_UNCOMPRESSED ...
secp256k1_context* secp256k1_context_create(
unsigned int flags
);
secp256k1_context* secp256k1_context_clone(
const secp256k1_context* ctx
);
void secp256k1_context_destroy(
secp256k1_context* ctx
);
void secp256k1_context_set_illegal_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
void secp256k1_context_set_error_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
int secp256k1_ec_pubkey_parse(
const secp256k1_context* ctx,
secp256k1_pubkey* pubkey,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ec_pubkey_serialize(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_pubkey* pubkey,
unsigned int flags
);
int secp256k1_ecdsa_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input64
);
int secp256k1_ecdsa_signature_parse_der(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_verify(
const secp256k1_context* ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const secp256k1_pubkey *pubkey
);
int secp256k1_ecdsa_signature_normalize(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
);
extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
extern const secp256k1_nonce_function secp256k1_nonce_function_default;
int secp256k1_ecdsa_sign(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ec_seckey_verify(
const secp256k1_context* ctx,
const unsigned char *seckey
);
int secp256k1_ec_pubkey_create(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
);
int secp256k1_ec_privkey_tweak_add(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_context_randomize(
secp256k1_context* ctx,
const unsigned char *seed32
);
int secp256k1_ec_pubkey_combine(
const secp256k1_context* ctx,
secp256k1_pubkey *out,
const secp256k1_pubkey * const * ins,
size_t n
);

8
_cffi_build/secp256k1_ecdh.h

@ -1,8 +0,0 @@
int secp256k1_ecdh(
const secp256k1_context* ctx,
unsigned char *result,
const secp256k1_pubkey *pubkey,
const unsigned char *privkey,
void *hashfp,
void *data
);

39
_cffi_build/secp256k1_recovery.h

@ -1,39 +0,0 @@
typedef struct {
unsigned char data[65];
} secp256k1_ecdsa_recoverable_signature;
int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature* sig,
const unsigned char *input64,
int recid
);
int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_ecdsa_recoverable_signature* sigin
);
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
int *recid,
const secp256k1_ecdsa_recoverable_signature* sig
);
int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ecdsa_recover(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32
);

449
api/index.html

File diff suppressed because one or more lines are too long

16
assets/_mkdocstrings.css

@ -0,0 +1,16 @@
/* Don't capitalize names. */
h5.doc-heading {
text-transform: none !important;
}
/* Avoid breaking parameters name, etc. in table cells. */
.doc-contents td code {
word-break: normal !important;
}
/* For pieces of Markdown rendered in table cells. */
.doc-contents td p {
margin-top: 0 !important;
margin-bottom: 0 !important;
}

0
docs/assets/css/custom.css → assets/css/custom.css

0
docs/assets/images/favicon.ico → assets/images/favicon.ico

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/images/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

29
assets/javascripts/bundle.b1047164.min.js

File diff suppressed because one or more lines are too long

7
assets/javascripts/bundle.b1047164.min.js.map

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/min/lunr.ar.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.da.min.js

@ -0,0 +1,18 @@
/*!
* Lunr languages, `Danish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d<a&&(d=a)}}function n(){var e,r;if(f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});

18
assets/javascripts/lunr/min/lunr.de.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.du.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.es.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.fi.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.fr.min.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/min/lunr.hi.min.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}});

18
assets/javascripts/lunr/min/lunr.hu.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.it.min.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/min/lunr.ja.min.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n<p.length;n++)r?a.push(new e.Token(p[n],{position:[f,p[n].length],index:a.length})):a.push(p[n]),f+=p[n].length;l=c+1}return a},e.ja.stemmer=function(){return function(e){return e}}(),e.Pipeline.registerFunction(e.ja.stemmer,"stemmer-ja"),e.ja.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",e.ja.trimmer=e.trimmerSupport.generateTrimmer(e.ja.wordCharacters),e.Pipeline.registerFunction(e.ja.trimmer,"trimmer-ja"),e.ja.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.ja.stopWordFilter,"stopWordFilter-ja"),e.jp=e.ja,e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.Pipeline.registerFunction(e.jp.trimmer,"trimmer-jp"),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}});

1
assets/javascripts/lunr/min/lunr.jp.min.js

@ -0,0 +1 @@
module.exports=require("./lunr.ja");

1
assets/javascripts/lunr/min/lunr.multi.min.js

@ -0,0 +1 @@
!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var t=Array.prototype.slice.call(arguments),i=t.join("-"),r="",n=[],s=[],p=0;p<t.length;++p)"en"==t[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[t[p]].wordCharacters,e[t[p]].stopWordFilter&&n.unshift(e[t[p]].stopWordFilter),e[t[p]].stemmer&&(n.push(e[t[p]].stemmer),s.push(e[t[p]].stemmer)));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+i),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}});

18
assets/javascripts/lunr/min/lunr.nl.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.no.min.js

@ -0,0 +1,18 @@
/*!
* Lunr languages, `Norwegian` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a<s&&(a=s)}}function i(){var e,r,n;if(w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});

18
assets/javascripts/lunr/min/lunr.pt.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.ro.min.js

File diff suppressed because one or more lines are too long

18
assets/javascripts/lunr/min/lunr.ru.min.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/min/lunr.stemmer.support.min.js

@ -0,0 +1 @@
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=_.s_size-1-l;m>=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});

18
assets/javascripts/lunr/min/lunr.sv.min.js

@ -0,0 +1,18 @@
/*!
* Lunr languages, `Swedish` language
* https://github.com/MihaiValentin/lunr-languages
*
* Copyright 2014, Mihai Valentin
* http://www.mozilla.org/MPL/
*/
/*!
* based on
* Snowball JavaScript Library v0.3
* http://code.google.com/p/urim/
* http://snowball.tartarus.org/
*
* Copyright 2010, Oleg Mazko
* http://www.mozilla.org/MPL/
*/
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o<a&&(o=a)}}function t(){var e,r=w.limit_backward;if(w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}});

1
assets/javascripts/lunr/min/lunr.th.min.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}});

18
assets/javascripts/lunr/min/lunr.tr.min.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/min/lunr.vi.min.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}});

1
assets/javascripts/lunr/min/lunr.zh.min.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("nodejieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}});

206
assets/javascripts/lunr/tinyseg.js

@ -0,0 +1,206 @@
/**
* export the module via AMD, CommonJS or as a browser global
* Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
*/
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory)
} else if (typeof exports === 'object') {
/**
* Node. Does not work with strict CommonJS, but
* only CommonJS-like environments that support module.exports,
* like Node.
*/
module.exports = factory()
} else {
// Browser globals (root is window)
factory()(root.lunr);
}
}(this, function () {
/**
* Just return a value to define the module export.
* This example returns an object, but the module
* can return a function as the exported value.
*/
return function(lunr) {
// TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript
// (c) 2008 Taku Kudo <taku@chasen.org>
// TinySegmenter is freely distributable under the terms of a new BSD licence.
// For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt
function TinySegmenter() {
var patterns = {
"[一二三四五六七八九十百千万億兆]":"M",
"[一-龠々〆ヵヶ]":"H",
"[ぁ-ん]":"I",
"[ァ-ヴーア-ン゙ー]":"K",
"[a-zA-Za-zA-Z]":"A",
"[0-90-9]":"N"
}
this.chartype_ = [];
for (var i in patterns) {
var regexp = new RegExp(i);
this.chartype_.push([regexp, patterns[i]]);
}
this.BIAS__ = -332
this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378};
this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920};
this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266};
this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352};
this.BP2__ = {"BO":60,"OO":-1762};
this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965};
this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146};
this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699};
this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973};
this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682};
this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669};
this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990};
this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832};
this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649};
this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393};
this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841};
this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68};
this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591};
this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685};
this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156};
this.TW1__ = {"につい":-4681,"東京都":2026};
this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216};
this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287};
this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865};
this.UC1__ = {"A":484,"K":93,"M":645,"O":-505};
this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646};
this.UC3__ = {"A":-1370,"I":2311};
this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646};
this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831};
this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387};
this.UP1__ = {"O":-214};
this.UP2__ = {"B":69,"O":935};
this.UP3__ = {"B":189};
this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422};
this.UQ2__ = {"BH":216,"BI":113,"OK":1759};
this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212};
this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135};
this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568};
this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278};
this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637};
this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343};
this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496};
return this;
}
TinySegmenter.prototype.ctype_ = function(str) {
for (var i in this.chartype_) {
if (str.match(this.chartype_[i][0])) {
return this.chartype_[i][1];
}
}
return "O";
}
TinySegmenter.prototype.ts_ = function(v) {
if (v) { return v; }
return 0;
}
TinySegmenter.prototype.segment = function(input) {
if (input == null || input == undefined || input == "") {
return [];
}
var result = [];
var seg = ["B3","B2","B1"];
var ctype = ["O","O","O"];
var o = input.split("");
for (i = 0; i < o.length; ++i) {
seg.push(o[i]);
ctype.push(this.ctype_(o[i]))
}
seg.push("E1");
seg.push("E2");
seg.push("E3");
ctype.push("O");
ctype.push("O");
ctype.push("O");
var word = seg[3];
var p1 = "U";
var p2 = "U";
var p3 = "U";
for (var i = 4; i < seg.length - 3; ++i) {
var score = this.BIAS__;
var w1 = seg[i-3];
var w2 = seg[i-2];
var w3 = seg[i-1];
var w4 = seg[i];
var w5 = seg[i+1];
var w6 = seg[i+2];
var c1 = ctype[i-3];
var c2 = ctype[i-2];
var c3 = ctype[i-1];
var c4 = ctype[i];
var c5 = ctype[i+1];
var c6 = ctype[i+2];
score += this.ts_(this.UP1__[p1]);
score += this.ts_(this.UP2__[p2]);
score += this.ts_(this.UP3__[p3]);
score += this.ts_(this.BP1__[p1 + p2]);
score += this.ts_(this.BP2__[p2 + p3]);
score += this.ts_(this.UW1__[w1]);
score += this.ts_(this.UW2__[w2]);
score += this.ts_(this.UW3__[w3]);
score += this.ts_(this.UW4__[w4]);
score += this.ts_(this.UW5__[w5]);
score += this.ts_(this.UW6__[w6]);
score += this.ts_(this.BW1__[w2 + w3]);
score += this.ts_(this.BW2__[w3 + w4]);
score += this.ts_(this.BW3__[w4 + w5]);
score += this.ts_(this.TW1__[w1 + w2 + w3]);
score += this.ts_(this.TW2__[w2 + w3 + w4]);
score += this.ts_(this.TW3__[w3 + w4 + w5]);
score += this.ts_(this.TW4__[w4 + w5 + w6]);
score += this.ts_(this.UC1__[c1]);
score += this.ts_(this.UC2__[c2]);
score += this.ts_(this.UC3__[c3]);
score += this.ts_(this.UC4__[c4]);
score += this.ts_(this.UC5__[c5]);
score += this.ts_(this.UC6__[c6]);
score += this.ts_(this.BC1__[c2 + c3]);
score += this.ts_(this.BC2__[c3 + c4]);
score += this.ts_(this.BC3__[c4 + c5]);
score += this.ts_(this.TC1__[c1 + c2 + c3]);
score += this.ts_(this.TC2__[c2 + c3 + c4]);
score += this.ts_(this.TC3__[c3 + c4 + c5]);
score += this.ts_(this.TC4__[c4 + c5 + c6]);
// score += this.ts_(this.TC5__[c4 + c5 + c6]);
score += this.ts_(this.UQ1__[p1 + c1]);
score += this.ts_(this.UQ2__[p2 + c2]);
score += this.ts_(this.UQ3__[p3 + c3]);
score += this.ts_(this.BQ1__[p2 + c2 + c3]);
score += this.ts_(this.BQ2__[p2 + c3 + c4]);
score += this.ts_(this.BQ3__[p3 + c2 + c3]);
score += this.ts_(this.BQ4__[p3 + c3 + c4]);
score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]);
score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]);
score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]);
score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]);
var p = "O";
if (score > 0) {
result.push(word);
word = "";
p = "B";
}
p1 = p2;
p2 = p3;
p3 = p;
word += seg[i];
}
result.push(word);
return result;
}
lunr.TinySegmenter = TinySegmenter;
};
}));

6708
assets/javascripts/lunr/wordcut.js

File diff suppressed because one or more lines are too long

48
assets/javascripts/workers/search.fcfe8b6d.min.js

File diff suppressed because one or more lines are too long

7
assets/javascripts/workers/search.fcfe8b6d.min.js.map

File diff suppressed because one or more lines are too long

2
assets/stylesheets/main.a57b2b03.min.css

File diff suppressed because one or more lines are too long

1
assets/stylesheets/main.a57b2b03.min.css.map

File diff suppressed because one or more lines are too long

2
assets/stylesheets/palette.3f5d1f46.min.css

File diff suppressed because one or more lines are too long

1
assets/stylesheets/palette.3f5d1f46.min.css.map

File diff suppressed because one or more lines are too long

3
coincurve/__init__.py

@ -1,3 +0,0 @@
from coincurve.context import GLOBAL_CONTEXT, Context
from coincurve.keys import PrivateKey, PublicKey
from coincurve.utils import verify_signature

239
coincurve/_windows_libsecp256k1.py

@ -1,239 +0,0 @@
import os
from cffi import FFI
BASE_DEFINITIONS = """
typedef struct secp256k1_context_struct secp256k1_context;
typedef struct {
unsigned char data[64];
} secp256k1_pubkey;
typedef struct {
unsigned char data[64];
} secp256k1_ecdsa_signature;
typedef int (*secp256k1_nonce_function)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *algo16,
void *data,
unsigned int attempt
);
#define SECP256K1_FLAGS_TYPE_MASK 255
#define SECP256K1_FLAGS_TYPE_CONTEXT 1
#define SECP256K1_FLAGS_TYPE_COMPRESSION 2
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY 256
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN 512
#define SECP256K1_FLAGS_BIT_COMPRESSION 256
#define SECP256K1_CONTEXT_VERIFY 257
#define SECP256K1_CONTEXT_SIGN 513
#define SECP256K1_CONTEXT_NONE 1
#define SECP256K1_EC_COMPRESSED 258
#define SECP256K1_EC_UNCOMPRESSED 2
secp256k1_context* secp256k1_context_create(
unsigned int flags
);
secp256k1_context* secp256k1_context_clone(
const secp256k1_context* ctx
);
void secp256k1_context_destroy(
secp256k1_context* ctx
);
void secp256k1_context_set_illegal_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
void secp256k1_context_set_error_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
);
int secp256k1_ec_pubkey_parse(
const secp256k1_context* ctx,
secp256k1_pubkey* pubkey,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ec_pubkey_serialize(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_pubkey* pubkey,
unsigned int flags
);
int secp256k1_ecdsa_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input64
);
int secp256k1_ecdsa_signature_parse_der(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const unsigned char *input,
size_t inputlen
);
int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context* ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
const secp256k1_ecdsa_signature* sig
);
int secp256k1_ecdsa_verify(
const secp256k1_context* ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const secp256k1_pubkey *pubkey
);
int secp256k1_ecdsa_signature_normalize(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
);
extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
extern const secp256k1_nonce_function secp256k1_nonce_function_default;
int secp256k1_ecdsa_sign(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ec_seckey_verify(
const secp256k1_context* ctx,
const unsigned char *seckey
);
int secp256k1_ec_pubkey_create(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
);
int secp256k1_ec_privkey_tweak_add(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context* ctx,
unsigned char *seckey,
const unsigned char *tweak
);
int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
);
int secp256k1_context_randomize(
secp256k1_context* ctx,
const unsigned char *seed32
);
int secp256k1_ec_pubkey_combine(
const secp256k1_context* ctx,
secp256k1_pubkey *out,
const secp256k1_pubkey * const * ins,
size_t n
);
"""
RECOVERY_DEFINITIONS = """
typedef struct {
unsigned char data[65];
} secp256k1_ecdsa_recoverable_signature;
int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature* sig,
const unsigned char *input64,
int recid
);
int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_ecdsa_recoverable_signature* sigin
);
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context* ctx,
unsigned char *output64,
int *recid,
const secp256k1_ecdsa_recoverable_signature* sig
);
int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
);
int secp256k1_ecdsa_recover(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32
);
"""
ECDH_DEFINITIONS = """
int secp256k1_ecdh(
const secp256k1_context* ctx,
unsigned char *result,
const secp256k1_pubkey *pubkey,
const unsigned char *privkey,
void *hashfp,
void *data
);
"""
ffi = FFI()
ffi.cdef(BASE_DEFINITIONS)
ffi.cdef(RECOVERY_DEFINITIONS)
ffi.cdef(ECDH_DEFINITIONS)
here = os.path.dirname(os.path.abspath(__file__))
lib = ffi.dlopen(os.path.join(here, 'libsecp256k1.dll'))

33
coincurve/context.py

@ -1,33 +0,0 @@
from os import urandom
from threading import Lock
from coincurve.flags import CONTEXT_ALL, CONTEXT_FLAGS
from ._libsecp256k1 import ffi, lib
class Context:
def __init__(self, seed: bytes = None, flag=CONTEXT_ALL, name: str = ''):
if flag not in CONTEXT_FLAGS:
raise ValueError('{} is an invalid context flag.'.format(flag))
self._lock = Lock()
self.ctx = ffi.gc(lib.secp256k1_context_create(flag), lib.secp256k1_context_destroy)
self.reseed(seed)
self.name = name
def reseed(self, seed: bytes = None):
"""
Protects against certain possible future side-channel timing attacks.
"""
with self._lock:
seed = urandom(32) if not seed or len(seed) != 32 else seed
res = lib.secp256k1_context_randomize(self.ctx, ffi.new('unsigned char [32]', seed))
assert res == 1
def __repr__(self):
return self.name or super().__repr__()
GLOBAL_CONTEXT = Context(name='GLOBAL_CONTEXT')

115
coincurve/ecdsa.py

@ -1,115 +0,0 @@
from coincurve.context import GLOBAL_CONTEXT, Context
from coincurve.types import Hasher
from coincurve.utils import bytes_to_int, int_to_bytes, sha256
from ._libsecp256k1 import ffi, lib
MAX_SIG_LENGTH = 72
CDATA_SIG_LENGTH = 64
def cdata_to_der(cdata, context: Context = GLOBAL_CONTEXT) -> bytes:
der = ffi.new('unsigned char[%d]' % MAX_SIG_LENGTH)
der_length = ffi.new('size_t *', MAX_SIG_LENGTH)
lib.secp256k1_ecdsa_signature_serialize_der(context.ctx, der, der_length, cdata)
return bytes(ffi.buffer(der, der_length[0]))
def der_to_cdata(der: bytes, context: Context = GLOBAL_CONTEXT):
cdata = ffi.new('secp256k1_ecdsa_signature *')
parsed = lib.secp256k1_ecdsa_signature_parse_der(context.ctx, cdata, der, len(der))
if not parsed:
raise ValueError('The DER-encoded signature could not be parsed.')
return cdata
def recover(message: bytes, recover_sig, hasher: Hasher = sha256, context: Context = GLOBAL_CONTEXT):
msg_hash = hasher(message) if hasher is not None else message
if len(msg_hash) != 32:
raise ValueError('Message hash must be 32 bytes long.')
pubkey = ffi.new('secp256k1_pubkey *')
recovered = lib.secp256k1_ecdsa_recover(context.ctx, pubkey, recover_sig, msg_hash)
if recovered:
return pubkey
raise ValueError('failed to recover ECDSA public key')
def serialize_recoverable(recover_sig, context: Context = GLOBAL_CONTEXT) -> bytes:
output = ffi.new('unsigned char[%d]' % CDATA_SIG_LENGTH)
recid = ffi.new('int *')
lib.secp256k1_ecdsa_recoverable_signature_serialize_compact(context.ctx, output, recid, recover_sig)
return bytes(ffi.buffer(output, CDATA_SIG_LENGTH)) + int_to_bytes(recid[0])
def deserialize_recoverable(serialized: bytes, context: Context = GLOBAL_CONTEXT):
if len(serialized) != 65:
raise ValueError('Serialized signature must be 65 bytes long.')
ser_sig, rec_id = serialized[:64], bytes_to_int(serialized[64:])
if not 0 <= rec_id <= 3:
raise ValueError('Invalid recovery id.')
recover_sig = ffi.new('secp256k1_ecdsa_recoverable_signature *')
parsed = lib.secp256k1_ecdsa_recoverable_signature_parse_compact(context.ctx, recover_sig, ser_sig, rec_id)
if not parsed:
raise ValueError('Failed to parse recoverable signature.')
return recover_sig
"""
Warning:
The functions below may change and are not tested!
"""
def serialize_compact(raw_sig, context: Context = GLOBAL_CONTEXT): # no cov
output = ffi.new('unsigned char[%d]' % CDATA_SIG_LENGTH)
res = lib.secp256k1_ecdsa_signature_serialize_compact(context.ctx, output, raw_sig)
assert res == 1
return bytes(ffi.buffer(output, CDATA_SIG_LENGTH))
def deserialize_compact(ser_sig: bytes, context: Context = GLOBAL_CONTEXT): # no cov
if len(ser_sig) != 64:
raise Exception('invalid signature length')
raw_sig = ffi.new('secp256k1_ecdsa_signature *')
res = lib.secp256k1_ecdsa_signature_parse_compact(context.ctx, raw_sig, ser_sig)
assert res == 1
return raw_sig
def signature_normalize(raw_sig, context: Context = GLOBAL_CONTEXT): # no cov
"""
Check and optionally convert a signature to a normalized lower-S form.
This function always return a tuple containing a boolean (True if
not previously normalized or False if signature was already
normalized), and the normalized signature.
"""
sigout = ffi.new('secp256k1_ecdsa_signature *')
res = lib.secp256k1_ecdsa_signature_normalize(context.ctx, sigout, raw_sig)
return not not res, sigout
def recoverable_convert(recover_sig, context: Context = GLOBAL_CONTEXT): # no cov
normal_sig = ffi.new('secp256k1_ecdsa_signature *')
lib.secp256k1_ecdsa_recoverable_signature_convert(context.ctx, normal_sig, recover_sig)
return normal_sig

10
coincurve/flags.py

@ -1,10 +0,0 @@
from ._libsecp256k1 import lib
CONTEXT_SIGN = lib.SECP256K1_CONTEXT_SIGN
CONTEXT_VERIFY = lib.SECP256K1_CONTEXT_VERIFY
CONTEXT_ALL = CONTEXT_SIGN | CONTEXT_VERIFY
CONTEXT_NONE = lib.SECP256K1_CONTEXT_NONE
CONTEXT_FLAGS = {CONTEXT_SIGN, CONTEXT_VERIFY, CONTEXT_ALL, CONTEXT_NONE}
EC_COMPRESSED = lib.SECP256K1_EC_COMPRESSED
EC_UNCOMPRESSED = lib.SECP256K1_EC_UNCOMPRESSED

486
coincurve/keys.py

@ -1,486 +0,0 @@
from typing import Tuple
from asn1crypto.keys import ECDomainParameters, ECPointBitString, ECPrivateKey, PrivateKeyAlgorithm, PrivateKeyInfo
from coincurve.context import GLOBAL_CONTEXT, Context
from coincurve.ecdsa import cdata_to_der, der_to_cdata, deserialize_recoverable, recover, serialize_recoverable
from coincurve.flags import EC_COMPRESSED, EC_UNCOMPRESSED
from coincurve.types import Hasher, Nonce
from coincurve.utils import (
DEFAULT_NONCE,
bytes_to_int,
der_to_pem,
get_valid_secret,
hex_to_bytes,
int_to_bytes_padded,
pad_scalar,
pem_to_der,
sha256,
validate_secret,
)
from ._libsecp256k1 import ffi, lib
class PrivateKey:
def __init__(self, secret: bytes = None, context: Context = GLOBAL_CONTEXT):
"""
:param secret: The secret used to initialize the private key.
If not provided or `None`, a new key will be generated.
"""
self.secret: bytes = validate_secret(secret) if secret is not None else get_valid_secret()
self.context = context
self.public_key: PublicKey = PublicKey.from_valid_secret(self.secret, self.context)
def sign(self, message: bytes, hasher: Hasher = sha256, custom_nonce: Nonce = DEFAULT_NONCE) -> bytes:
"""
Create an ECDSA signature.
:param message: The message to sign.
:param hasher: The hash function to use, which must return 32 bytes. By default,
the `sha256` algorithm is used. If `None`, no hashing occurs.
:param custom_nonce: Custom nonce data in the form `(nonce_function, input_data)`. Refer to
[secp256k1.h](https://github.com/bitcoin-core/secp256k1/blob/f8c0b57e6ba202b1ce7c5357688de97c9c067697/include/secp256k1.h#L546-L547).
:return: The ECDSA signature.
:raises ValueError: If the message hash was not 32 bytes long, the nonce generation
function failed, or the private key was invalid.
"""
msg_hash = hasher(message) if hasher is not None else message
if len(msg_hash) != 32:
raise ValueError('Message hash must be 32 bytes long.')
signature = ffi.new('secp256k1_ecdsa_signature *')
nonce_fn, nonce_data = custom_nonce
signed = lib.secp256k1_ecdsa_sign(self.context.ctx, signature, msg_hash, self.secret, nonce_fn, nonce_data)
if not signed:
raise ValueError('The nonce generation function failed, or the private key was invalid.')
return cdata_to_der(signature, self.context)
def sign_recoverable(self, message: bytes, hasher: Hasher = sha256, custom_nonce: Nonce = DEFAULT_NONCE) -> bytes:
"""
Create a recoverable ECDSA signature.
:param message: The message to sign.
:param hasher: The hash function to use, which must return 32 bytes. By default,
the `sha256` algorithm is used. If `None`, no hashing occurs.
:param custom_nonce: Custom nonce data in the form `(nonce_function, input_data)`. Refer to
[secp256k1_recovery.h](https://github.com/bitcoin-core/secp256k1/blob/f8c0b57e6ba202b1ce7c5357688de97c9c067697/include/secp256k1_recovery.h#L78-L79).
:return: The recoverable ECDSA signature.
:raises ValueError: If the message hash was not 32 bytes long, the nonce generation
function failed, or the private key was invalid.
"""
msg_hash = hasher(message) if hasher is not None else message
if len(msg_hash) != 32:
raise ValueError('Message hash must be 32 bytes long.')
signature = ffi.new('secp256k1_ecdsa_recoverable_signature *')
nonce_fn, nonce_data = custom_nonce
signed = lib.secp256k1_ecdsa_sign_recoverable(
self.context.ctx, signature, msg_hash, self.secret, nonce_fn, nonce_data
)
if not signed:
raise ValueError('The nonce generation function failed, or the private key was invalid.')
return serialize_recoverable(signature, self.context)
def ecdh(self, public_key: bytes) -> bytes:
"""
Compute an EC Diffie-Hellman secret in constant time.
!!! note
This prevents malleability by returning `sha256(compressed_public_key)` instead of the `x` coordinate
directly. See #9.
:param public_key: The formatted public key.
:return: The 32 byte shared secret.
:raises ValueError: If the public key could not be parsed or was invalid.
"""
secret = ffi.new('unsigned char [32]')
lib.secp256k1_ecdh(self.context.ctx, secret, PublicKey(public_key).public_key, self.secret, ffi.NULL, ffi.NULL)
return bytes(ffi.buffer(secret, 32))
def add(self, scalar: bytes, update: bool = False):
"""
Add a scalar to the private key.
:param scalar: The scalar with which to add.
:param update: Whether or not to update and return the private key in-place.
:return: The new private key, or the modified private key if `update` is `True`.
:rtype: PrivateKey
:raises ValueError: If the tweak was out of range or the resulting private key was invalid.
"""
scalar = pad_scalar(scalar)
secret = ffi.new('unsigned char [32]', self.secret)
success = lib.secp256k1_ec_privkey_tweak_add(self.context.ctx, secret, scalar)
if not success:
raise ValueError('The tweak was out of range, or the resulting private key is invalid.')
secret = bytes(ffi.buffer(secret, 32))
if update:
self.secret = secret
self._update_public_key()
return self
return PrivateKey(secret, self.context)
def multiply(self, scalar: bytes, update: bool = False):
"""
Multiply the private key by a scalar.
:param scalar: The scalar with which to multiply.
:param update: Whether or not to update and return the private key in-place.
:return: The new private key, or the modified private key if `update` is `True`.
:rtype: PrivateKey
"""
scalar = validate_secret(scalar)
secret = ffi.new('unsigned char [32]', self.secret)
lib.secp256k1_ec_privkey_tweak_mul(self.context.ctx, secret, scalar)
secret = bytes(ffi.buffer(secret, 32))
if update:
self.secret = secret
self._update_public_key()
return self
return PrivateKey(secret, self.context)
def to_hex(self) -> str:
"""
:return: The private key encoded as a hex string.
"""
return self.secret.hex()
def to_int(self) -> int:
"""
:return: The private key as an integer.
"""
return bytes_to_int(self.secret)
def to_pem(self) -> bytes:
"""
:return: The private key encoded in PEM format.
"""
return der_to_pem(self.to_der())
def to_der(self) -> bytes:
"""
:return: The private key encoded in DER format.
"""
pk = ECPrivateKey(
{
'version': 'ecPrivkeyVer1',
'private_key': self.to_int(),
'public_key': ECPointBitString(self.public_key.format(compressed=False)),
}
)
return PrivateKeyInfo(
{
'version': 0,
'private_key_algorithm': PrivateKeyAlgorithm(
{
'algorithm': 'ec',
'parameters': ECDomainParameters(name='named', value='1.3.132.0.10'),
}
),
'private_key': pk,
}
).dump()
@classmethod
def from_hex(cls, hexed: str, context: Context = GLOBAL_CONTEXT):
"""
:param hexed: The private key encoded as a hex string.
:param context:
:return: The private key.
:rtype: PrivateKey
"""
return PrivateKey(hex_to_bytes(hexed), context)
@classmethod
def from_int(cls, num: int, context: Context = GLOBAL_CONTEXT):
"""
:param num: The private key as an integer.
:param context:
:return: The private key.
:rtype: PrivateKey
"""
return PrivateKey(int_to_bytes_padded(num), context)
@classmethod
def from_pem(cls, pem: bytes, context: Context = GLOBAL_CONTEXT):
"""
:param pem: The private key encoded in PEM format.
:param context:
:return: The private key.
:rtype: PrivateKey
"""
return PrivateKey(
int_to_bytes_padded(PrivateKeyInfo.load(pem_to_der(pem)).native['private_key']['private_key']), context
)
@classmethod
def from_der(cls, der: bytes, context: Context = GLOBAL_CONTEXT):
"""
:param der: The private key encoded in DER format.
:param context:
:return: The private key.
:rtype: PrivateKey
"""
return PrivateKey(int_to_bytes_padded(PrivateKeyInfo.load(der).native['private_key']['private_key']), context)
def _update_public_key(self):
created = lib.secp256k1_ec_pubkey_create(self.context.ctx, self.public_key.public_key, self.secret)
if not created:
raise ValueError('Invalid secret.')
def __eq__(self, other) -> bool:
return self.secret == other.secret
class PublicKey:
def __init__(self, data, context: Context = GLOBAL_CONTEXT):
"""
:param data: The formatted public key. This class supports parsing
compressed (33 bytes, header byte `0x02` or `0x03`),
uncompressed (65 bytes, header byte `0x04`), or
hybrid (65 bytes, header byte `0x06` or `0x07`) format public keys.
:type data: bytes
:param context:
:raises ValueError: If the public key could not be parsed or was invalid.
"""
if not isinstance(data, bytes):
self.public_key = data
else:
public_key = ffi.new('secp256k1_pubkey *')
parsed = lib.secp256k1_ec_pubkey_parse(context.ctx, public_key, data, len(data))
if not parsed:
raise ValueError('The public key could not be parsed or is invalid.')
self.public_key = public_key
self.context = context
@classmethod
def from_secret(cls, secret: bytes, context: Context = GLOBAL_CONTEXT):
"""
Derive a public key from a private key secret.
:param secret: The private key secret.
:param context:
:return: The public key.
:rtype: PublicKey
"""
public_key = ffi.new('secp256k1_pubkey *')
created = lib.secp256k1_ec_pubkey_create(context.ctx, public_key, validate_secret(secret))
if not created: # no cov
raise ValueError(
'Somehow an invalid secret was used. Please '
'submit this as an issue here: '
'https://github.com/ofek/coincurve/issues/new'
)
return PublicKey(public_key, context)
@classmethod
def from_valid_secret(cls, secret: bytes, context: Context = GLOBAL_CONTEXT):
public_key = ffi.new('secp256k1_pubkey *')
created = lib.secp256k1_ec_pubkey_create(context.ctx, public_key, secret)
if not created:
raise ValueError('Invalid secret.')
return PublicKey(public_key, context)
@classmethod
def from_point(cls, x: int, y: int, context: Context = GLOBAL_CONTEXT):
"""
Derive a public key from a coordinate point in the form `(x, y)`.
:param x:
:param y:
:param context:
:return: The public key.
:rtype: PublicKey
"""
return PublicKey(b'\x04' + int_to_bytes_padded(x) + int_to_bytes_padded(y), context)
@classmethod
def from_signature_and_message(
cls, signature: bytes, message: bytes, hasher: Hasher = sha256, context: Context = GLOBAL_CONTEXT
):
"""
Recover an ECDSA public key from a recoverable signature.
:param signature: The recoverable ECDSA signature.
:param message: The message that was supposedly signed.
:param hasher: The hash function to use, which must return 32 bytes. By default,
the `sha256` algorithm is used. If `None`, no hashing occurs.
:param context:
:return: The public key that signed the message.
:rtype: PublicKey
:raises ValueError: If the message hash was not 32 bytes long or recovery of the ECDSA public key failed.
"""
return PublicKey(
recover(message, deserialize_recoverable(signature, context=context), hasher=hasher, context=context)
)
@classmethod
def combine_keys(cls, public_keys, context: Context = GLOBAL_CONTEXT):
"""
Add a number of public keys together.
:param public_keys: A sequence of public keys.
:type public_keys: List[PublicKey]
:param context:
:return: The combined public key.
:rtype: PublicKey
:raises ValueError: If the sum of the public keys was invalid.
"""
public_key = ffi.new('secp256k1_pubkey *')
combined = lib.secp256k1_ec_pubkey_combine(
context.ctx, public_key, [pk.public_key for pk in public_keys], len(public_keys)
)
if not combined:
raise ValueError('The sum of the public keys is invalid.')
return PublicKey(public_key, context)
def format(self, compressed: bool = True) -> bytes:
"""
Format the public key.
:param compressed: Whether or to use the compressed format.
:return: The 33 byte formatted public key, or the 65 byte formatted public key if `compressed` is `False`.
"""
length = 33 if compressed else 65
serialized = ffi.new('unsigned char [%d]' % length)
output_len = ffi.new('size_t *', length)
lib.secp256k1_ec_pubkey_serialize(
self.context.ctx, serialized, output_len, self.public_key, EC_COMPRESSED if compressed else EC_UNCOMPRESSED
)
return bytes(ffi.buffer(serialized, length))
def point(self) -> Tuple[int, int]:
"""
:return: The public key as a coordinate point.
"""
public_key = self.format(compressed=False)
return bytes_to_int(public_key[1:33]), bytes_to_int(public_key[33:])
def verify(self, signature: bytes, message: bytes, hasher: Hasher = sha256) -> bool:
"""
:param signature: The ECDSA signature.
:param message: The message that was supposedly signed.
:param hasher: The hash function to use, which must return 32 bytes. By default,
the `sha256` algorithm is used. If `None`, no hashing occurs.
:return: A boolean indicating whether or not the signature is correct.
:raises ValueError: If the message hash was not 32 bytes long or the DER-encoded signature could not be parsed.
"""
msg_hash = hasher(message) if hasher is not None else message
if len(msg_hash) != 32:
raise ValueError('Message hash must be 32 bytes long.')
verified = lib.secp256k1_ecdsa_verify(self.context.ctx, der_to_cdata(signature), msg_hash, self.public_key)
# A performance hack to avoid global bool() lookup.
return not not verified
def add(self, scalar: bytes, update: bool = False):
"""
Add a scalar to the public key.
:param scalar: The scalar with which to add.
:param update: Whether or not to update and return the public key in-place.
:return: The new public key, or the modified public key if `update` is `True`.
:rtype: PublicKey
:raises ValueError: If the tweak was out of range or the resulting public key was invalid.
"""
scalar = pad_scalar(scalar)
new_key = ffi.new('secp256k1_pubkey *', self.public_key[0])
success = lib.secp256k1_ec_pubkey_tweak_add(self.context.ctx, new_key, scalar)
if not success:
raise ValueError('The tweak was out of range, or the resulting public key is invalid.')
if update:
self.public_key = new_key
return self
return PublicKey(new_key, self.context)
def multiply(self, scalar: bytes, update: bool = False):
"""
Multiply the public key by a scalar.
:param scalar: The scalar with which to multiply.
:param update: Whether or not to update and return the public key in-place.
:return: The new public key, or the modified public key if `update` is `True`.
:rtype: PublicKey
"""
scalar = validate_secret(scalar)
new_key = ffi.new('secp256k1_pubkey *', self.public_key[0])
lib.secp256k1_ec_pubkey_tweak_mul(self.context.ctx, new_key, scalar)
if update:
self.public_key = new_key
return self
return PublicKey(new_key, self.context)
def combine(self, public_keys, update: bool = False):
"""
Add a number of public keys together.
:param public_keys: A sequence of public keys.
:type public_keys: List[PublicKey]
:param update: Whether or not to update and return the public key in-place.
:return: The combined public key, or the modified public key if `update` is `True`.
:rtype: PublicKey
:raises ValueError: If the sum of the public keys was invalid.
"""
new_key = ffi.new('secp256k1_pubkey *')
combined = lib.secp256k1_ec_pubkey_combine(
self.context.ctx, new_key, [pk.public_key for pk in [self, *public_keys]], len(public_keys) + 1
)
if not combined:
raise ValueError('The sum of the public keys is invalid.')
if update:
self.public_key = new_key
return self
return PublicKey(new_key, self.context)
def __eq__(self, other) -> bool:
return self.format(compressed=False) == other.format(compressed=False)

13
coincurve/types.py

@ -1,13 +0,0 @@
import sys
from typing import Optional, Tuple
from ._libsecp256k1 import ffi
# https://bugs.python.org/issue42965
if sys.version_info >= (3, 9, 2):
from collections.abc import Callable
else:
from typing import Callable
Hasher = Optional[Callable[[bytes], bytes]]
Nonce = Tuple[ffi.CData, ffi.CData]

130
coincurve/utils.py

@ -1,130 +0,0 @@
from base64 import b64decode, b64encode
from hashlib import sha256 as _sha256
from os import environ, urandom
from typing import Generator
from coincurve.context import GLOBAL_CONTEXT, Context
from coincurve.types import Hasher
from ._libsecp256k1 import ffi, lib
GROUP_ORDER = (
b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
b'\xfe\xba\xae\xdc\xe6\xafH\xa0;\xbf\xd2^\x8c\xd06AA'
)
GROUP_ORDER_INT = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
KEY_SIZE = 32
ZERO = b'\x00'
PEM_HEADER = b'-----BEGIN PRIVATE KEY-----\n'
PEM_FOOTER = b'-----END PRIVATE KEY-----\n'
if environ.get('COINCURVE_BUILDING_DOCS') != 'true':
DEFAULT_NONCE = (ffi.NULL, ffi.NULL)
def sha256(bytestr: bytes) -> bytes:
return _sha256(bytestr).digest()
else: # no cov
class __Nonce(tuple):
def __repr__(self):
return '(ffi.NULL, ffi.NULL)'
class __HasherSHA256:
def __call__(self, bytestr: bytes) -> bytes:
return _sha256(bytestr).digest()
def __repr__(self):
return 'sha256'
DEFAULT_NONCE = __Nonce((ffi.NULL, ffi.NULL)) # type: ignore
sha256 = __HasherSHA256()
def pad_hex(hexed: str) -> str:
# Pad odd-length hex strings.
return hexed if not len(hexed) & 1 else f'0{hexed}'
def bytes_to_int(bytestr: bytes) -> int:
return int.from_bytes(bytestr, 'big')
def int_to_bytes(num: int) -> bytes:
return num.to_bytes((num.bit_length() + 7) // 8 or 1, 'big')
def int_to_bytes_padded(num: int) -> bytes:
return pad_scalar(num.to_bytes((num.bit_length() + 7) // 8 or 1, 'big'))
def hex_to_bytes(hexed: str) -> bytes:
return pad_scalar(bytes.fromhex(pad_hex(hexed)))
def chunk_data(data: bytes, size: int) -> Generator[bytes, None, None]:
return (data[i : i + size] for i in range(0, len(data), size))
def der_to_pem(der: bytes) -> bytes:
return b''.join([PEM_HEADER, b'\n'.join(chunk_data(b64encode(der), 64)), b'\n', PEM_FOOTER])
def pem_to_der(pem: bytes) -> bytes:
return b64decode(b''.join(pem.strip().splitlines()[1:-1]))
def get_valid_secret() -> bytes:
while True:
secret = urandom(KEY_SIZE)
if ZERO < secret < GROUP_ORDER:
return secret
def pad_scalar(scalar: bytes) -> bytes:
return (ZERO * (KEY_SIZE - len(scalar))) + scalar
def validate_secret(secret: bytes) -> bytes:
if not 0 < bytes_to_int(secret) < GROUP_ORDER_INT:
raise ValueError('Secret scalar must be greater than 0 and less than {}.'.format(GROUP_ORDER_INT))
return pad_scalar(secret)
def verify_signature(
signature: bytes, message: bytes, public_key: bytes, hasher: Hasher = sha256, context: Context = GLOBAL_CONTEXT
) -> bool:
"""
:param signature: The ECDSA signature.
:param message: The message that was supposedly signed.
:param public_key: The formatted public key.
:param hasher: The hash function to use, which must return 32 bytes. By default,
the `sha256` algorithm is used. If `None`, no hashing occurs.
:param context:
:return: A boolean indicating whether or not the signature is correct.
:raises ValueError: If the public key could not be parsed or was invalid, the message hash was
not 32 bytes long, or the DER-encoded signature could not be parsed.
"""
pubkey = ffi.new('secp256k1_pubkey *')
pubkey_parsed = lib.secp256k1_ec_pubkey_parse(context.ctx, pubkey, public_key, len(public_key))
if not pubkey_parsed:
raise ValueError('The public key could not be parsed or is invalid.')
msg_hash = hasher(message) if hasher is not None else message
if len(msg_hash) != 32:
raise ValueError('Message hash must be 32 bytes long.')
sig = ffi.new('secp256k1_ecdsa_signature *')
sig_parsed = lib.secp256k1_ecdsa_signature_parse_der(context.ctx, sig, signature, len(signature))
if not sig_parsed:
raise ValueError('The DER-encoded signature could not be parsed.')
verified = lib.secp256k1_ecdsa_verify(context.ctx, sig, msg_hash, pubkey)
# A performance hack to avoid global bool() lookup.
return not not verified

3
docs/.scripts/49_global_refs.py

@ -1,3 +0,0 @@
def patch(lines):
"""This ensures that links and abbreviations are always available."""
lines.extend(('', '--8<-- "refs.txt"', ''))

2
docs/.snippets/abbrs.txt

@ -1,2 +0,0 @@
*[ECDH]: Elliptic-curve Diffie–Hellman
*[PyPI]: Python Package Index

5
docs/.snippets/links.txt

@ -1,5 +0,0 @@
[Bitcoin Core]: https://github.com/bitcoin/bitcoin
[ECDH]: https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman
[RFC 6979]: https://tools.ietf.org/html/rfc6979
[libsecp256k1]: https://github.com/bitcoin-core/secp256k1
[secp256k1]: https://en.bitcoin.it/wiki/Secp256k1

4
docs/.snippets/refs.txt

@ -1,4 +0,0 @@
--8<--
links.txt
abbrs.txt
--8<--

50
docs/api.md

@ -1,50 +0,0 @@
# Developer Interface
-----
All objects are available directly under the root namespace `coincurve`.
::: coincurve.verify_signature
rendering:
show_root_full_path: false
selection:
docstring_style: restructured-text
::: coincurve.PrivateKey
rendering:
show_root_full_path: false
selection:
docstring_style: restructured-text
members:
- __init__
- sign
- sign_recoverable
- ecdh
- add
- multiply
- to_hex
- to_pem
- to_der
- to_int
- from_hex
- from_pem
- from_der
- from_int
::: coincurve.PublicKey
rendering:
show_root_full_path: false
selection:
docstring_style: restructured-text
members:
- __init__
- verify
- format
- point
- combine
- add
- multiply
- combine_keys
- from_signature_and_message
- from_secret
- from_point

131
docs/history.md

@ -1,131 +0,0 @@
# History
-----
Important changes are emphasized.
## master
## Unreleased
## 17.0.0
- **Breaking:** Drop support for Python 3.6
- Fix wheels for Apple M1
- Upgrade [libsecp256k1][] to the latest available version
## 16.0.0
- Wheels for Apple Silicon and musl linux (Alpine)
- No wheels for PyPy until the build system is fixed
## 15.0.1
- Fix the `combine` method of `PublicKey`
## 15.0.0
- **Breaking:** Drop support for Python 2
- **Breaking:** Binary wheels for CPython require version 19.3 or later of ``pip`` to install
- Build AArch64 binary wheels for Linux
- Build binary wheels for PyPy3.6 7.3.3 & PyPy3.7 7.3.3 on Linux
- Upgrade [libsecp256k1][] to the latest available version
- Upgrade libgmp to the latest available version
- Introduce `COINCURVE_UPSTREAM_REF` environment variable to select an alternative [libsecp256k1][] version when building from source
- Support PEP 561 type hints
- Added support for supplying a custom nonce to `PrivateKey.sign_recoverable`
## 14.0.0
**IMPORTANT: This will be the final release that supports Python 2.**
- **New:** Binary wheels for Python 3.9
- **Breaking:** Drop support for Python 3.5
- Fetch [libsecp256k1][] source if the system installation lacks ECDH support
- Fix innocuous `setuptools` warning when building from source
- Switch CI/CD to GitHub Actions
## 13.0.0
- **New:** Binary wheels for Python 3.8
- Support building on OpenBSD
- Improve handling of PEM private key deserialization
- Improve ECDH documentation
- Improvements from [libsecp256k1][] master
## 12.0.0
- **New:** Binary wheels on Linux for PyPy3.6 v7.1.1-beta
- **New:** Binary wheels on macOS for Python 3.8.0-alpha.3
- **New:** Binary wheels on Linux are now also built with the new [manylinux2010](https://www.python.org/dev/peps/pep-0571) spec for 64-bit platforms
- Improvements from [libsecp256k1][] master
## 11.0.0
- Fix some linking scenarios by placing bundled [libsecp256k1][] dir first in path
- Allow override of system [libsecp256k1][] with environment variable
- Add benchmarks
- Use Codecov to track coverage
- Use black for code formatting
## 10.0.0
- Support tox for testing
- Compatibility with latest [libsecp256k1][] ECDH API
- Make libgmp optional when building from source
## 9.0.0
- Fixed wheels for macOS
- **Breaking:** Drop support for 32-bit macOS
## 8.0.2
- No longer package tests
## 8.0.0
- **New:** Binary wheels for Python 3.7
- **Changed:** Binary wheels on macOS for Python 3.5 now use Homebrew
Python for compilation due to new security requirements
- Make build system support new GitHub & PyPI security requirements
- Improvements from [libsecp256k1][] master
## 7.1.0
- Pin version of [libsecp256k1][]
- Improve docs
## 7.0.0
- Improvements from [libsecp256k1][] master
- Fix build script
## 6.0.0
- Resolved #6. You can choose to use this or remain on `5.2.0`. This will only be a temporary change, see 3e93480b3e38c6b9beb0bc2de83bc3630fc74c46.
## 5.2.0
- Added support for supplying a custom nonce to `PrivateKey.sign`
## 5.1.0
- Added `PublicKey.combine_keys` class method
- Improvements to documentation
## 5.0.1
- Fixed an issue where secret validation would occasionally erroneously error
on user-provided secrets (secrets not generated by Coincurve itself) if there
were not exactly 256 bits of entropy. See #5.
## 5.0.0
- **Breaking:** Coincurve is now dual-licensed under the terms of `MIT` and `Apache-2.0`
- Performance improvements from [libsecp256k1][] master
- Improvements to documentation.
## 4.5.1
- First public stable release

49
docs/index.md

@ -1,49 +0,0 @@
# coincurve
| | |
| --- | --- |
| CI/CD | [![CI - Test](https://github.com/ofek/coincurve/actions/workflows/build.yml/badge.svg)](https://github.com/ofek/coincurve/actions/workflows/build.yml) [![CI - Coverage](https://img.shields.io/codecov/c/github/ofek/coincurve/master.svg?logo=codecov&logoColor=red)](https://codecov.io/github/ofek/coincurve) |
| Docs | [![CI - Docs](https://github.com/ofek/coincurve/actions/workflows/docs.yml/badge.svg)](https://github.com/ofek/coincurve/actions/workflows/docs.yml) |
| Package | [![PyPI - Version](https://img.shields.io/pypi/v/coincurve.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/coincurve/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/coincurve.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/coincurve/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/coincurve.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/coincurve/) |
| Meta | [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/ambv/black) [![imports - isort](https://img.shields.io/badge/imports-isort-ef8336.svg)](https://github.com/pycqa/isort) [![License - MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-9400d3.svg)](https://spdx.org/licenses/) [![GitHub Sponsors](https://img.shields.io/github/sponsors/ofek?logo=GitHub%20Sponsors&style=social)](https://github.com/sponsors/ofek) |
-----
This library provides well-tested Python bindings for [libsecp256k1][], the heavily optimized
C library used by [Bitcoin Core][] for operations on the elliptic curve [secp256k1][].
## Features
- Fastest available implementation (more than 10x faster than OpenSSL)
- Clean, easy to use API
- Frequent updates from the development version of [libsecp256k1][]
- Linux, macOS, and Windows all have binary packages for multiple architectures
- Deterministic signatures as specified by [RFC 6979][]
- Non-malleable signatures (lower-S form) by default
- Secure, non-malleable [ECDH][] implementation
## Users
- [Ethereum](https://ethereum.org)
- [LBRY](https://lbry.com)
- [ZeroNet](https://zeronet.io)
- [libp2p](https://libp2p.io)
and [many more](users.md)!
## License
`coincurve` is distributed under the terms of any of the following licenses:
- [MIT](https://spdx.org/licenses/MIT.html)
- [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)
## Navigation
Desktop readers can use keyboard shortcuts to navigate.
| Keys | Action |
| --- | --- |
| <ul><li><kbd>,</kbd> (comma)</li><li><kbd>p</kbd></li></ul> | Navigate to the "previous" page |
| <ul><li><kbd>.</kbd> (period)</li><li><kbd>n</kbd></li></ul> | Navigate to the "next" page |
| <ul><li><kbd>/</kbd></li><li><kbd>s</kbd></li></ul> | Display the search modal |

62
docs/install.md

@ -1,62 +0,0 @@
# Installation
-----
`coincurve` is available on PyPI and can be installed with [pip](https://pip.pypa.io):
```
pip install coincurve
```
## Wheel
Binary wheels are available for most platforms and require at least version `19.3` of pip to install.
| | | | | |
| --- | --- | --- | --- | --- |
| | macOS | Windows | Linux (glibc) | Linux (musl) |
| CPython 3.7 | <ul><li>x86_64</li></ul> | <ul><li>x86_64</li><li>x86</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> |
| CPython 3.8 | <ul><li>x86_64</li><li>ARM64</li></ul> | <ul><li>x86_64</li><li>x86</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> |
| CPython 3.9 | <ul><li>x86_64</li><li>ARM64</li></ul> | <ul><li>x86_64</li><li>x86</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> |
| CPython 3.10 | <ul><li>x86_64</li><li>ARM64</li></ul> | <ul><li>x86_64</li><li>x86</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> | <ul><li>x86_64</li><li>i686</li><li>AArch64</li></ul> |
## Source
If you are on a platform without support for pre-compiled wheels, you will need certain system packages in order to build from source.
A few environment variables influence the build:
- `COINCURVE_UPSTREAM_REF` - This is the Git reference of [libsecp256k1][] to use rather than the (frequently updated) default.
- `COINCURVE_IGNORE_SYSTEM_LIB` - The presence of this will force fetching of [libsecp256k1][] even if it's already detected at the system level.
!!! tip
To avoid installing the binary wheels on compatible distributions, use the `--no-binary` option.
```
pip install coincurve --no-binary coincurve
```
### Alpine
```
sudo apk add autoconf automake build-base libffi-dev libtool pkgconfig python3-dev
```
### Debian/Ubuntu
```
sudo apt-get install -y autoconf automake build-essential libffi-dev libtool pkg-config python3-dev
```
### RHEL/CentOS
```
sudo yum install -y autoconf automake gcc gcc-c++ libffi-devel libtool make pkgconfig python3-devel
```
### macOS
```
xcode-select --install
brew install autoconf automake libffi libtool pkg-config python
```

43
docs/users.md

@ -1,43 +0,0 @@
# Users
-----
## Organizations
| Name | Projects |
| --- | --- |
| [Anyl](https://github.com/Anylsite) | <ul><li><a href=https://github.com/Anylsite/anyledger-backend/blob/cb9e277ef4ba775384a1eb80ff1577418f88684e/requirements.in#L5> anyledger-backend </a></li></ul> |
| [ARK](https://ark.io) | <ul><li><a href=https://github.com/ArkEcosystem/python-crypto/blob/1bd016f76b41eba9711be748c1caf20d8042f590/setup.py#L9> python-crypto </a></li></ul> |
| [Augur](https://www.augur.net) | <ul><li><a href=https://github.com/AugurProject/augur-core/blob/5388e00120d3e2328b5ccc70960bedff1c8a03dd/requirements.txt#L9> augur-core </a></li></ul> |
| [Blockcerts](https://www.blockcerts.org) | <ul><li><a href=https://github.com/blockchain-certificates/cert-issuer/blob/9b0ed451ef686018a507acd8bb7d217263a6fbf4/ethereum_requirements.txt#L2> cert-issuer </a></li></ul> |
| [ECIES](https://ecies.org) | <ul><li><a href=https://github.com/ecies/py/blob/7d4bd252129410eb1472d9e3cf0fd9f1fcfaf174/pyproject.toml#L38> py </a></li></ul> |
| [Elements](https://elementsproject.org) | <ul><li><a href=https://github.com/ElementsProject/lightning/blob/d134580419b90f2299cfa3646906b8b8b96c356e/requirements.txt#L33> lightning </a></li></ul> |
| [Ethereum](https://ethereum.org) | <ul><li><a href=https://github.com/ethereum/alexandria/blob/adba4114fbd5f707181da602abd977e008e463c9/setup.py#L67> alexandria </a></li><li><a href=https://github.com/ethereum/ddht/blob/341e84e9163338556cd48dd2fcfda9eedec3eb45/setup.py#L73> ddht </a></li><li><a href=https://github.com/ethereum/eth-keys/blob/dd4f00a5d2f2b394665ccecc9817f753e58cc7bc/setup.py#L10> eth-keys </a></li><li><a href=https://github.com/ethereum/eth-tester/blob/1e37e846915374914bdc2950fbb2f9ea6ca2f3ec/tox.ini#L16> eth-tester </a></li><li><a href=https://github.com/ethereum/py-evm/blob/5e949a457fbe6692dcd9e9e2f141a1848000a0c2/setup.py#L26> py-evm </a></li><li><a href=https://github.com/ethereum/pydevp2p/blob/b09b8a06a152f34cd7dc7950b14b04e3f01511af/requirements.txt#L8> pydevp2p </a></li><li><a href=https://github.com/ethereum/trinity/blob/65609f8fda7d880c0efe859ea84a7d0935c02edb/setup.py#L39> trinity </a></li></ul> |
| [Gnosis](https://gnosis.io) | <ul><li><a href=https://github.com/gnosis/gnosis-py/blob/7bad62eb83b50cf952227f5ae1019c95b8b4d9cd/README.rst#quick-start> gnosis-py </a></li></ul> |
| [Golem Network](https://golem.network) | <ul><li><a href=https://github.com/golemfactory/concent/blob/23ffa9464c995a628aa570bc9a0a05d29f48b044/concent_api/requirements.lock#L18> concent </a></li><li><a href=https://github.com/golemfactory/golem/blob/6280b5d946640e81c475c66c5de4a9e53cbfcc69/requirements.txt#L25> golem </a></li><li><a href=https://github.com/golemfactory/golem-messages/blob/aae2a60a88c938f5ed7012b838cf2a29934b58b2/setup.py#L41> golem-messages </a></li></ul> |
| [ICON Foundation](https://icon.foundation) | <ul><li><a href=https://github.com/icon-project/goloop/blob/6c8341e0c29fc7f9136221f315e8a76af9b5450c/pyee/requirements.txt#L2> goloop </a></li><li><a href=https://github.com/icon-project/icon-sdk-python/blob/cb293688c154349cabeb9b3f50a1cab29e91859d/requirements.txt#L2> icon-sdk-python </a></li><li><a href=https://github.com/icon-project/icon-service/blob/73c8d4521374207ef77e63b789fd511fc6d028b8/requirements.txt#L3> icon-service </a></li><li><a href=https://github.com/icon-project/loopchain/blob/9f29e8914918e12d683f2e1318c9b3c52dbee08d/requirements.txt#L11> loopchain </a></li><li><a href=https://github.com/icon-project/t-bears/pull/77> t-bears </a></li></ul> |
| [LBRY](https://lbry.com) | <ul><li><a href=https://github.com/lbryio/lbry-android-sdk/blob/b0331248cdb7b1ca4a866e4aaa166dd820549e56/recipes/coincurve/__init__.py> lbry-android-sdk </a></li><li><a href=https://github.com/lbryio/lbry-sdk/blob/7486ee95371c238d51e1c2552113ad25bfaf0426/setup.py#L53> lbry-sdk </a></li></ul> |
| [libp2p](https://libp2p.io) | <ul><li><a href=https://github.com/libp2p/py-libp2p/blob/12786f4e26783b530279a6f89089cf69af8e3922/setup.py#L73> py-libp2p </a></li></ul> |
| [Microsoft](https://www.microsoft.com) | <ul><li><a href=https://github.com/microsoft/CCF/blob/f6670587ec1cb6c0faf8efcc6e4d08b8f4c1fd60/tests/requirements.txt#L4> CCF </a></li></ul> |
| [NuCypher](https://www.nucypher.com) | <ul><li><a href=https://github.com/nucypher/nucypher/blob/24a57e1c810aa6408ecfc24942956925146aa024/requirements.txt#L16> nucypher </a></li><li><a href=https://github.com/nucypher/nucypher-monitor/blob/f8df51a37d0299c36541b26ef13d72fa390c294e/requirements.txt#L17> nucypher-monitor </a></li></ul> |
| [Quantstamp](https://quantstamp.com) | <ul><li><a href=https://github.com/quantstamp/qsp-protocol-node/blob/6f776b01c91a3b1c306ab74932324ea367fa6157/requirements.txt#L32> qsp-protocol-node </a></li></ul> |
| [QuarkChain](https://www.quarkchain.io) | <ul><li><a href=https://github.com/QuarkChain/pyquarkchain/blob/1f858f46efe31c3fb3bac20cdbd44eb94d89fb63/requirements.txt#L4> pyquarkchain </a></li></ul> |
| [Raiden Network](https://raiden.network) | <ul><li><a href=https://github.com/raiden-network/demo-train/blob/66d187bd4f9e83a7d8d0cc43fc5d31c8444745f5/requirements.txt#L16> demo-train </a></li><li><a href=https://github.com/raiden-network/light-client/blob/8da39f8f164a3d93674889db39875003e1bc6e93/e2e-environment/synapse/auth/eth_auth_provider.py#L20> light-client </a></li><li><a href=https://github.com/raiden-network/microraiden/blob/2d51e78afaf3c0a8ddab87e59a5260c0064cdbdd/requirements.txt#L5> microraiden </a></li><li><a href=https://github.com/raiden-network/raiden/blob/e4c0f6d22788eddf51da551f11ea988a8dd5fd0d/requirements/requirements.in#L4> raiden </a></li><li><a href=https://github.com/raiden-network/raiden-contracts/blob/93230caa554f6f29e55b4521aafd0af20b710b1f/requirements.txt#L3> raiden-contracts </a></li><li><a href=https://github.com/raiden-network/raiden-service-bundle/blob/1ba6a265016eca4ade0ed4f2a198cebc570c11d3/build/synapse/Dockerfile#L18> raiden-service-bundle </a></li><li><a href=https://github.com/raiden-network/raiden-services/blob/b5d0f81447fbe476ed8185d825560b2b9327d455/src/raiden_libs/utils.py#L4> raiden-services </a></li><li><a href=https://github.com/raiden-network/raiden-wizard/blob/bf2fe8662be4db2c36bcc920d8e31cec888a496e/requirements.txt#L17> raiden-wizard </a></li><li><a href=https://github.com/raiden-network/raidex/blob/master/requirements.txt#L12> raidex </a></li></ul> |
| [SKALE Network](https://skale.network) | <ul><li><a href=https://github.com/skalenetwork/libBLS/blob/785b7ab11f78512f6466b6dc996c4db44825696a/.travis.yml#L46> libBLS </a></li><li><a href=https://github.com/skalenetwork/sgx.py/blob/efff7d1a09abbea2c703cc21b25f9a6d9e7fcb79/setup.py#L11> sgx.py </a></li></ul> |
## Projects
- [bit](https://github.com/ofek/bit/blob/776f97ae7f9b3f05157113abc913eb141b2817ee/setup.py#L44)
- [btcrecover](https://github.com/gurnec/btcrecover/commit/f113867fa22d2f5b22175cc2b5b3892351bc1109)
- [crankycoin](https://github.com/cranklin/crankycoin/blob/7663a1c5429b3ddd11997b6a2e3488018789bf3b/requirements.txt#L2)
- [ForkDelta](https://github.com/forkdelta/backend-replacement/blob/97ccd1a19544f26d242a8412113086f0c0dd5760/requirements.txt#L46)
- [Heimdall](https://github.com/maddevsio/heimdall/blob/21f16880030cfdb1c1c97969158bec02ca6c0336/requirements.txt#L14)
- [HoneyBadgerBFT](https://github.com/initc3/HoneyBadgerBFT-Python/blob/e8bcbc081dfb5d1e7298039d47bbebf7048b8e62/setup.py#L30)
- [JoinMarket](https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/dc581e9c99d7db6436ed9f8913b6ce614bcef8d8/jmbitcoin/setup.py#L13)
- [minichain](https://github.com/kigawas/minichain/blob/0ae0437fdc4aa05e73c4d31a8df91d371542c8fe/pyproject.toml#L13)
- [Nekoyume](https://github.com/nekoyume/nekoyume/blob/0dec2d6f1002091f3f727bd645ce67fadd85faeb/setup.cfg#L45)
- [NuCypher](https://github.com/nucypher/nucypher/blob/24a57e1c810aa6408ecfc24942956925146aa024/requirements.txt#L16)
- [python-idex](https://github.com/sammchardy/python-idex/blob/24cee970172491a7f7d5f52558727a77384cce26/requirements.txt#L2)
- [Rotki](https://github.com/rotki/rotki/blob/70508f99f890bcbd520f1efe7776194d6a5e5e06/requirements.txt#L8)
- [Vyper](https://github.com/vyperlang/vyper/blob/3bd0bf96856554810065fa9cfb89afef7625d436/Dockerfile#L15)
- [ZeroNet](https://github.com/HelloZeroNet/ZeroNet/blob/454c0b2e7e000fda7000cba49027541fbf327b96/requirements.txt#L12)

1
history/index.html

File diff suppressed because one or more lines are too long

1
index.html

File diff suppressed because one or more lines are too long

8
install/index.html

File diff suppressed because one or more lines are too long

123
mkdocs.yml

@ -1,123 +0,0 @@
site_name: coincurve
site_description: Cross-platform Python bindings for libsecp256k1
site_author: Ofek Lev
site_url: https://ofek.dev/coincurve/
repo_name: ofek/coincurve
repo_url: https://github.com/ofek/coincurve
edit_uri: blob/master/docs
copyright: 'Copyright &copy; Ofek Lev 2017-present'
docs_dir: docs
site_dir: site
theme:
name: material
language: en
features:
- navigation.instant
palette:
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: teal
accent: teal
toggle:
icon: material/weather-night
name: Switch to light mode
- media: "(prefers-color-scheme: light)"
scheme: default
primary: teal
accent: teal
toggle:
icon: material/weather-sunny
name: Switch to dark mode
font:
text: Roboto
code: Roboto Mono
icon:
logo: material/circle-multiple
repo: fontawesome/brands/github-alt
favicon: assets/images/favicon.ico
nav:
- About: index.md
- Install: install.md
- API Reference: api.md
- Users: users.md
- History: history.md
plugins:
# Built-in
- search:
# Extra
- minify:
minify_html: true
- git-revision-date-localized:
type: date
- mkdocstrings:
default_handler: python
handlers:
python:
rendering:
show_if_no_docstring: true
show_root_heading: true
show_source: true
markdown_extensions:
# Built-in
- markdown.extensions.abbr:
- markdown.extensions.admonition:
- markdown.extensions.footnotes:
- markdown.extensions.meta:
- markdown.extensions.tables:
- markdown.extensions.toc:
permalink: true
# Extra
- mkpatcher:
location: docs/.scripts
- pymdownx.arithmatex:
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret:
- pymdownx.critic:
- pymdownx.details:
- pymdownx.emoji:
# https://github.com/twitter/twemoji
# https://raw.githubusercontent.com/facelessuser/pymdown-extensions/master/pymdownx/twemoji_db.py
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.highlight:
guess_lang: false
linenums_style: pymdownx-inline
use_pygments: true
- pymdownx.inlinehilite:
- pymdownx.keys:
- pymdownx.magiclink:
repo_url_shortener: true
repo_url_shorthand: true
social_url_shorthand: true
provider: github
user: ofek
repo: coincurve
- pymdownx.mark:
- pymdownx.progressbar:
- pymdownx.smartsymbols:
- pymdownx.snippets:
base_path: docs/.snippets
- pymdownx.superfences:
- pymdownx.tabbed:
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde:
extra:
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/ofek
- icon: fontawesome/solid/blog
link: https://ofek.dev/words/
- icon: fontawesome/brands/twitter
link: https://twitter.com/Ofekmeister
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/ofeklev/
extra_css:
- assets/css/custom.css
- https://cdn.jsdelivr.net/gh/tonsky/FiraCode@5.2/distr/fira_code.css

8
mypy.ini

@ -1,8 +0,0 @@
[mypy]
disallow_untyped_defs = false
follow_imports = normal
ignore_missing_imports = true
pretty = true
show_column_numbers = true
warn_no_return = false
warn_unused_ignores = true

BIN
objects.inv

Binary file not shown.

35
pyproject.toml

@ -1,35 +0,0 @@
[tool.black]
line-length = 120
py36 = true
skip-string-normalization = true
include = '\.pyi?$'
exclude = '''
/(
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| _cffi_build
| build
| dist
)/
|
(
setup\.py$
| _libsecp256k1\.py$
)
'''
[tool.isort]
default_section = 'THIRDPARTY'
force_grid_wrap = 0
include_trailing_comma = true
known_first_party = 'coincurve'
line_length = 120
multi_line_output = 3
skip_glob = 'setup.py'
use_parentheses = true

3
requirements-dev.txt

@ -1,3 +0,0 @@
coverage
pytest
pytest-benchmark

1
search/search_index.json

File diff suppressed because one or more lines are too long

314
setup.py

@ -1,314 +0,0 @@
import errno
import os
import os.path
import platform
import shutil
import subprocess
import tarfile
from distutils import log
from distutils.command.build_clib import build_clib as _build_clib
from distutils.command.build_ext import build_ext as _build_ext
from distutils.errors import DistutilsError
from io import BytesIO
import sys
from setuptools import Distribution as _Distribution, setup, find_packages, __version__ as setuptools_version
from setuptools.command.develop import develop as _develop
from setuptools.command.egg_info import egg_info as _egg_info
from setuptools.command.sdist import sdist as _sdist
try:
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
except ImportError:
_bdist_wheel = None
pass
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from setup_support import absolute, build_flags, detect_dll, has_system_lib # noqa: E402
BUILDING_FOR_WINDOWS = detect_dll()
MAKE = 'gmake' if platform.system() in ['FreeBSD', 'OpenBSD'] else 'make'
# IMPORTANT: keep in sync with .github/workflows/build.yml
#
# Version of libsecp256k1 to download if none exists in the `libsecp256k1` directory
UPSTREAM_REF = os.getenv('COINCURVE_UPSTREAM_REF') or 'd8a246324650c3df8d54d133a8ac3c1b857a7a4e'
LIB_TARBALL_URL = f'https://github.com/bitcoin-core/secp256k1/archive/{UPSTREAM_REF}.tar.gz'
# We require setuptools >= 3.3
if [int(i) for i in setuptools_version.split('.', 2)[:2]] < [3, 3]:
raise SystemExit(
'Your setuptools version ({}) is too old to correctly install this '
'package. Please upgrade to a newer version (>= 3.3).'.format(setuptools_version)
)
def download_library(command):
if command.dry_run:
return
libdir = absolute('libsecp256k1')
if os.path.exists(os.path.join(libdir, 'autogen.sh')):
# Library already downloaded
return
if not os.path.exists(libdir):
command.announce('downloading libsecp256k1 source code', level=log.INFO)
try:
import requests
r = requests.get(LIB_TARBALL_URL, stream=True)
status_code = r.status_code
if status_code == 200:
content = BytesIO(r.raw.read())
content.seek(0)
with tarfile.open(fileobj=content) as tf:
dirname = tf.getnames()[0].partition('/')[0]
tf.extractall()
shutil.move(dirname, libdir)
else:
raise SystemExit('Unable to download secp256k1 library: HTTP-Status: %d', status_code)
except requests.exceptions.RequestException as e:
raise SystemExit('Unable to download secp256k1 library: %s', str(e))
class egg_info(_egg_info):
def run(self):
# Ensure library has been downloaded (sdist might have been skipped)
download_library(self)
_egg_info.run(self)
class sdist(_sdist):
def run(self):
download_library(self)
_sdist.run(self)
if _bdist_wheel:
class bdist_wheel(_bdist_wheel):
def run(self):
download_library(self)
_bdist_wheel.run(self)
else:
bdist_wheel = None
class build_clib(_build_clib):
def initialize_options(self):
_build_clib.initialize_options(self)
self.build_flags = None
def finalize_options(self):
_build_clib.finalize_options(self)
if self.build_flags is None:
self.build_flags = {'include_dirs': [], 'library_dirs': [], 'define': []}
def get_source_files(self):
# Ensure library has been downloaded (sdist might have been skipped)
download_library(self)
return [
absolute(os.path.join(root, filename))
for root, _, filenames in os.walk(absolute('libsecp256k1'))
for filename in filenames
]
def build_libraries(self, libraries):
raise Exception('build_libraries')
def check_library_list(self, libraries):
raise Exception('check_library_list')
def get_library_names(self):
return build_flags('libsecp256k1', 'l', os.path.abspath(self.build_temp))
def run(self):
if has_system_lib():
log.info('Using system library')
return
build_temp = os.path.abspath(self.build_temp)
try:
os.makedirs(build_temp)
except OSError as e:
if e.errno != errno.EEXIST:
raise
if not os.path.exists(absolute('libsecp256k1')):
# library needs to be downloaded
self.get_source_files()
if not os.path.exists(absolute('libsecp256k1/configure')):
# configure script hasn't been generated yet
autogen = absolute('libsecp256k1/autogen.sh')
os.chmod(absolute(autogen), 0o755)
subprocess.check_call([autogen], cwd=absolute('libsecp256k1'))
for filename in [
'libsecp256k1/configure',
'libsecp256k1/build-aux/compile',
'libsecp256k1/build-aux/config.guess',
'libsecp256k1/build-aux/config.sub',
'libsecp256k1/build-aux/depcomp',
'libsecp256k1/build-aux/install-sh',
'libsecp256k1/build-aux/missing',
'libsecp256k1/build-aux/test-driver',
]:
try:
os.chmod(absolute(filename), 0o755)
except OSError as e:
# some of these files might not exist depending on autoconf version
if e.errno != errno.ENOENT:
# If the error isn't 'No such file or directory' something
# else is wrong and we want to know about it
raise
cmd = [
absolute('libsecp256k1/configure'),
'--disable-shared',
'--enable-static',
'--disable-dependency-tracking',
'--with-pic',
'--enable-module-recovery',
'--prefix',
os.path.abspath(self.build_clib),
'--enable-experimental',
'--enable-module-ecdh',
'--enable-benchmark=no',
'--enable-tests=no',
'--enable-openssl-tests=no',
'--enable-exhaustive-tests=no',
]
if 'COINCURVE_CROSS_HOST' in os.environ:
cmd.append('--host={}'.format(os.environ['COINCURVE_CROSS_HOST']))
log.debug('Running configure: {}'.format(' '.join(cmd)))
subprocess.check_call(cmd, cwd=build_temp)
subprocess.check_call([MAKE], cwd=build_temp)
subprocess.check_call([MAKE, 'install'], cwd=build_temp)
self.build_flags['include_dirs'].extend(build_flags('libsecp256k1', 'I', build_temp))
self.build_flags['library_dirs'].extend(build_flags('libsecp256k1', 'L', build_temp))
if not has_system_lib():
self.build_flags['define'].append(('CFFI_ENABLE_RECOVERY', None))
else:
pass
class build_ext(_build_ext):
def run(self):
if self.distribution.has_c_libraries():
_build_clib = self.get_finalized_command('build_clib')
self.include_dirs.append(os.path.join(_build_clib.build_clib, 'include'))
self.include_dirs.extend(_build_clib.build_flags['include_dirs'])
self.library_dirs.insert(0, os.path.join(_build_clib.build_clib, 'lib'))
self.library_dirs.extend(_build_clib.build_flags['library_dirs'])
self.define = _build_clib.build_flags['define']
return _build_ext.run(self)
class develop(_develop):
def run(self):
if not has_system_lib():
raise DistutilsError(
"This library is not usable in 'develop' mode when using the "
'bundled libsecp256k1. See README for details.'
)
_develop.run(self)
package_data = {'coincurve': ['py.typed']}
if BUILDING_FOR_WINDOWS:
class Distribution(_Distribution):
def is_pure(self):
return False
package_data['coincurve'].append('libsecp256k1.dll')
setup_kwargs = dict()
else:
class Distribution(_Distribution):
def has_c_libraries(self):
return not has_system_lib()
setup_kwargs = dict(
setup_requires=['cffi>=1.3.0', 'requests'],
ext_package='coincurve',
cffi_modules=['_cffi_build/build.py:ffi'],
cmdclass={
'build_clib': build_clib,
'build_ext': build_ext,
'develop': develop,
'egg_info': egg_info,
'sdist': sdist,
'bdist_wheel': bdist_wheel,
},
)
setup(
name='coincurve',
version='17.0.0',
description='Cross-platform Python CFFI bindings for libsecp256k1',
long_description=open('README.md', 'r').read(),
long_description_content_type='text/markdown',
author_email='Ofek Lev <oss@ofek.dev>',
license='MIT OR Apache-2.0',
python_requires='>=3.7',
install_requires=['asn1crypto', 'cffi>=1.3.0'],
packages=find_packages(exclude=('_cffi_build', '_cffi_build.*', 'libsecp256k1', 'tests')),
package_data=package_data,
distclass=Distribution,
zip_safe=False,
project_urls={
'Documentation': 'https://ofek.dev/coincurve/',
'Issues': 'https://github.com/ofek/coincurve/issues',
'Source': 'https://github.com/ofek/coincurve',
},
keywords=[
'secp256k1',
'crypto',
'elliptic curves',
'bitcoin',
'ethereum',
'cryptocurrency',
],
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries',
'Topic :: Security :: Cryptography',
],
**setup_kwargs
)

106
setup_support.py

@ -1,106 +0,0 @@
import glob
import os
import shutil
import subprocess
from contextlib import contextmanager
from tempfile import mkdtemp
@contextmanager
def workdir():
cwd = os.getcwd()
tmpdir = mkdtemp()
os.chdir(tmpdir)
try:
yield
finally:
os.chdir(cwd)
shutil.rmtree(tmpdir)
@contextmanager
def redirect(stdchannel, dest_filename):
oldstdchannel = os.dup(stdchannel.fileno())
dest_file = open(dest_filename, 'w')
os.dup2(dest_file.fileno(), stdchannel.fileno())
try:
yield
finally:
if oldstdchannel is not None:
os.dup2(oldstdchannel, stdchannel.fileno())
if dest_file is not None:
dest_file.close()
def absolute(*paths):
op = os.path
return op.realpath(op.abspath(op.join(op.dirname(__file__), *paths)))
def build_flags(library, type_, path):
"""Return separated build flags from pkg-config output"""
pkg_config_path = [path]
if 'PKG_CONFIG_PATH' in os.environ:
pkg_config_path.append(os.environ['PKG_CONFIG_PATH'])
if 'LIB_DIR' in os.environ:
pkg_config_path.append(os.environ['LIB_DIR'])
pkg_config_path.append(os.path.join(os.environ['LIB_DIR'], 'pkgconfig'))
options = ['--static', {'I': '--cflags-only-I', 'L': '--libs-only-L', 'l': '--libs-only-l'}[type_]]
return [
flag.strip('-{}'.format(type_))
for flag in subprocess.check_output(
['pkg-config'] + options + [library], env=dict(os.environ, PKG_CONFIG_PATH=':'.join(pkg_config_path))
)
.decode('UTF-8')
.split()
]
def _find_lib():
if 'COINCURVE_IGNORE_SYSTEM_LIB' in os.environ:
return False
from cffi import FFI
ffi = FFI()
try:
ffi.dlopen('secp256k1')
if os.path.exists('/usr/include/secp256k1_ecdh.h'):
return True
else:
# The system library lacks the ecdh module
return False
except OSError:
if 'LIB_DIR' in os.environ:
for path in glob.glob(os.path.join(os.environ['LIB_DIR'], '*secp256k1*')):
try:
FFI().dlopen(path)
return True
except OSError:
pass
# We couldn't locate libsecp256k1 so we'll use the bundled one
return False
else:
# If we got this far then the system library should be good enough
return True
_has_system_lib = None
def has_system_lib():
global _has_system_lib
if _has_system_lib is None:
_has_system_lib = _find_lib()
return _has_system_lib
def detect_dll():
here = os.path.dirname(os.path.abspath(__file__))
for fn in os.listdir(os.path.join(here, 'coincurve')):
if fn.endswith('.dll'):
return True
return False

28
sitemap.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://ofek.dev/coincurve/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://ofek.dev/coincurve/api/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://ofek.dev/coincurve/history/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://ofek.dev/coincurve/install/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://ofek.dev/coincurve/users/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

BIN
sitemap.xml.gz

Binary file not shown.

0
tests/__init__.py

999
tests/data/ecdsa_sig.json

@ -1,999 +0,0 @@
{
"vectors": [
{
"msg": "9e5755ec2f328cc8635a55415d0e9a09c2b6f2c9b0343c945fbbfe08247a4cbe",
"sig": "30440220132382ca59240c2e14ee7ff61d90fc63276325f4cbe8169fc53ade4a407c2fc802204d86fbe3bde6975dd5a91fdc95ad6544dcdf0dab206f02224ce7e2b151bd82ab01",
"privkey": "31a84594060e103f5a63eb742bd46cf5f5900d8406e2726dedfc61c7cf43ebad"
},
{
"msg": "2d46a712699bae19a634563d74d04cc2da497b841456da270dccb75ac2f7c4e7",
"sig": "3045022100d80cf7abc9ab601373780cee3733d2cb5ff69ba1452ec2d2a058adf9645c13be0220011d1213b7d152f72fd8759b45276ba32d9c909602e5ec89550baf3aaa8ed95001",
"privkey": "7177f0d04c79fa0b8c91fe90c1cf1d44772d1fba6e5eb9b281a22cd3aafb51fe"
},
{
"msg": "c94f4ec84be928017cbbb447d2ab5b5d4d69e5e5fd03da7eae4378a1b1c9c402",
"sig": "3045022100d0f5b740cbe3ee5b098d3c5afdefa61bb0797cb4e7b596afbd38174e1c653bb602200329e9f1a09632de477664814791ac31544e04715db68f4b02657ba35863e71101",
"privkey": "989e500d6b1397f2c5dcdf43c58ac2f14df753eb6089654e07ff946b3f84f3d5"
},
{
"msg": "dfeb2092955572ce0695aa038f58df5499949e18f58785553c3e83343cd5eb93",
"sig": "30440220692c01edf8aeab271df3ed4e8d57a170f014f8f9d65031aac28b5e1840acfb5602205075f9d1fdbf5079ee052e5f3572d518b3594ef49582899ec44d065f71a5519201",
"privkey": "39dfc615f2b718397f6903b0c46c47c5687e97d3d2a5e1f2b200f459f7b1219b"
},
{
"msg": "49e558d232ca204ecc27b321b197bfe0e165acd5fe46f986d5b007c68c2dcbd7",
"sig": "30440220330f62769e8e0fd43721029e1343b7f2c2575edc568007aa1b4458b2928dfc530220549c8967e8e8f414be10c6e2d36f451f1c50007c28511f9410fd7a921220190401",
"privkey": "1e17c938ef3754781130edcbe8fa2c8a27ecb43f93d333e64d89af3d9c26c23a"
},
{
"msg": "12a683325e3063e4d9d32d38f878300d84d4ebb63247607dfb2bd72849e5fb14",
"sig": "3045022100f1391011657e358464165b53f0993a1a637f6e296c1a8f6a984d522b441b470602206c78004f1489c398aeb05b6db63d0839875f4751b117a6bd239b173428f1c2e201",
"privkey": "9120318c2d0792a29516b18a3467051445e5a6c358da577dcf06ea5ddfb8839f"
},
{
"msg": "06e42f8adc7c2ac118b6e6d1082940c66f7d2544fa2eaae0d2b1d016fea26092",
"sig": "304402202c947ee0cf77bce3c4aab68737f07f9c43733a961552da82798a2628d6650a7c02205bb4a8634e8204bc3da98ddb1c5a7d7f5a2f4d60ee447e6e7ab20cff9dfdc5bc01",
"privkey": "a7433f154076cd9317e048562fe60529140a1155a1497ebd165b081c053e8944"
},
{
"msg": "43307439480b2d4c3a95e725d1a13a97ec032cdbdda467533dce304513752d46",
"sig": "3045022100ac6123107cc08a63fb80e2af53937cf5aa7dee9f4e233a668d6c15d0b474903b02205bdcd30cae23c89692ee53badd610385b84567f98dc65babf000055f33877ac801",
"privkey": "58a127499af1fa4f6cc95d6b2213171762a3be0d929246f27044d64de24c4db2"
},
{
"msg": "3a75a427f8311ae278b76bcce9a2ba99b9adc1ee91d653f9f00052b9e154b511",
"sig": "304402202f54a17ffa1b631f67232785b469d794969d3fdb140bb683ae8097217ec12c7d0220159f78ceece7e2fa1dea9e31f53374aebe6b8d893588c27e951bbc40b7ca57cf01",
"privkey": "17449f296f72790a85284a3eead10e775b452a32e7cdf1f0e68f109e5732d8a4"
},
{
"msg": "d2ae97ae7b0b488f3a9cca6b7ed92832b4a6a7a3546a3ed9964eb51fbb2fcd98",
"sig": "3045022100c842a06f6818768fc3d93d98332affc7160fc2f58ba6fc0239c2c9cf951e6bc302202756c90464f85193a52a29001eaf824d3b0602028d4c8f5abadf6995262bc7e001",
"privkey": "229d075d7a48c5725f21e585e9effb08c80ea768883fc372ed3ad48af60a653d"
},
{
"msg": "3492a279ef2ddfebc47cc7ee28be41b5ffc03c54b738f657862590237e56841b",
"sig": "30440220708aae22df437d7280fd8e06b9ab043abc26f6286973e94df9ae28982c534fa5022063724a156b0766c59fe75c571a5f47b80f313676f60830699b0f0c171841c32a01",
"privkey": "f2f83ccb7ecd11e6ef61a8a090890b6db56e87810be8f283626f6028843e70c2"
},
{
"msg": "bab37255a348dcfd8864aa2bd1b964c951da28370743905f892bbf5533b2c881",
"sig": "3044022054cc561ced7052b9b0d709578e691e8e4edb04e2a38d1b79fbdbf16302674c6f022013c9ec89010fe1d9643019c7bb863abd618d4dd492c116d8fb099710e33f5b5101",
"privkey": "c476e1df4d6bc771b23836b58616ed5bb6417baaab3c533dd255562d41cce2df"
},
{
"msg": "3543080c755844091a26bc812fefa40d00663f57622bdb63334ffbdd70ac8cfd",
"sig": "3044022066b520cb7f51656e610aefb238bfa5a62426953b22cc09689408429b68ff53f902205971ec48692210b050683f9ab2cd4443ade8a9d0ae3f95d32e865458515b8e4601",
"privkey": "e9fd9db20943a760c4cf89a9eb8aa150405686332c8a2ab8789ef19593312ac9"
},
{
"msg": "aa05ef24738774890500e5d4f25f2801802a4c20f1be4f06721220d065abe042",
"sig": "3045022100d081a3dcc756f91b4c6aaaa5eb57c18ebe733086391c4a0761a9b11a43dd477002205cf7ce2565d977572dd10fc17875d07b2f8e3d824740db45a30f8977f57c7a1d01",
"privkey": "251e11bc1fdf9ce349c904af6f3df523e906e0367e18c96e111104715fbbfcbc"
},
{
"msg": "57176b5966096a1818148936e1c56bea9717a7b9f4e3decf582b4ae3585e794d",
"sig": "304502210093a5c31daffcaa47b22a1f34dd969510acb76440879e91c51bb1b465fedfa6d302206edf49b1ad26bae5a1c179ae6913d3f3c3fcc0c5a3c7abec07d8adb315a0782a01",
"privkey": "099796458bffc713b89b1332089b093f8ed08039fa1d8323d7a8b198225d89d5"
},
{
"msg": "8b339212a72cbea99b8e882e4ce7c32a1a1f0e5185d3c8e4b99c9a8ebfe58060",
"sig": "30440220640997e496194c03b7e56fe5b97a44bbad81df5a9c2501138453b86e3d1ad16a02201a1dd1ffdbe9300184b7b1ff7d0a1339dd677a081acc2208050e0dde313f515b01",
"privkey": "00417c436e3f135eb2292eb5d88cab40157b0989dc0d917ab6e87e8faa0f1ee5"
},
{
"msg": "f1415142ca90a4f6d1f5c63dd0d776642e34bc3fe3a9ea1427afdf9d71d79231",
"sig": "304402202364525dea549ced7856a0551be97d73b1e5f20237e857cd0193f3aacaa6e1100220245974967a1f0a849a3aa7492f044c53fb10a0198c280caf075aad9beb80126401",
"privkey": "1d77dcd3d3631285c0a99a6c669d804fb603cc8a788c4568a46971b46718453a"
},
{
"msg": "e5a093e9d225f09961f35f44b3171962b2ad3f9c859c3c21d0f03fc7dfadbd51",
"sig": "304402200d2a510384e4ec4d294150598e893ef97827c11c61a081cf694cf53e1c0dfcc102200eed9c0dbe6294f692ead6d729eddfe9267411d67a08031012c4b46230561bb701",
"privkey": "df693dfdca61122d2e633d2a2d8f4270a9199624d06f9230325d82708da5e9d2"
},
{
"msg": "42f5f89f123967d7ecb0f0ffbac97d1e414d22f8aeea5f61ab18c67d9b05b062",
"sig": "3045022100a251fd56b0630c642143c05cc20fef8979163e85d8dd4413acf97c7f0b21832002206959532ff89b8515c5934f7dedef47c8ea1c3b0f3e1630f85445cc6989b8e61c01",
"privkey": "3e21112d32f27677d715c4f12d4005d551a5a523d7c63717f2166ebea89addc5"
},
{
"msg": "f1914da938a0c2e8112c769591ee070ac4123b9c487c0ed7fab6b04473bf7714",
"sig": "3044022010c823ef2f6bb11e4a974723499be7a4fc9610da16229ae49e025525eca9088102203e3ae2173dcc83b754e39fbc88eb1b31effda488c1c9632572513146ed5c7dfe01",
"privkey": "ec3eaa66a6ef4b6c31acd75528218e702419bdf1c086431137926fe71daaaea0"
},
{
"msg": "3cf9fb4cf59c6d37da6c36e0d680b1d364800e94b54f2b9074d755a456a0d7f4",
"sig": "3045022100cd40d40dbef9ac2e27f3c8d40a7f8dd538d417a7bfbcd0c00a6e92c93bcb145202205172d09504b59aeb6d2afc298441615665e4ec8fb7bf064a9364ac5f6ad2171201",
"privkey": "a51997dff0ae72ff3005ae6cad243a5d5c6864691d238fd58123bea364008009"
},
{
"msg": "ada128dfd83338a8b0f5ead162a0fc7acaa513d5c13b9b1d5d921d2648e674f5",
"sig": "3044022075c1178f1bb941fdfa4fa4e21f056c5717a5a94247030c321ad51ac6d8a2a860022036759348c6e87c3b27388ba92895ccc6c7af659f57b4205a236bebccfe6f3e3f01",
"privkey": "9a8114c3bfe3656290a0d092bb80a9f5c67b3e938ba719424c5c8c83e13ce266"
},
{
"msg": "d23cdc4accc2566b82fe6270e144f366f08007dffcf9e47c1c66d40708747da0",
"sig": "3045022100fbe82220345d27c870e152048698340e70d701ab868a5482a7cc22977962f8d4022009181b343e76c8645dc640762d49911df336941d79dedccba313ba03dd8c28b701",
"privkey": "f1d7fb29ab98d00f46135b74de1b7ea80f3e38360c9ee0cd7056404c5d1db57b"
},
{
"msg": "e89e786443b5634afbe711f66530326320a0e5ec27d1c42697e5fbc11e5ce169",
"sig": "3045022100be23de4212c4bca5d1be2882ab339aa8a586dd656daae12aa2287cdfb2809af002200d460339847f0c08311a59343997d5e307136a4fc0494f84aacbbf918deb11ff01",
"privkey": "ab8f7d2eb73af6349990d2b4296d98432da8bbd858863bfa136e234a56351090"
},
{
"msg": "ba7de66731341e48fca15ef5b62c88f19b2aee7786987d73754be8e339f706aa",
"sig": "304402202c2c1b9bee9b018df561d1f45ec07527ac916e8e56a915862cf80a4fe73779c8022037aff510509b3704390da0db4b647540647f897df5a211648f4180a292b12bca01",
"privkey": "d142f008e4ee702e6ddbf6f5429e4b39e0cd59034018a332635e6fab028f2fbe"
},
{
"msg": "1ddaa971fd3b025d0566d9bf893a0043329379e2c52561ad3ebd3815bae0e818",
"sig": "30440220110aa7dfe50948e3a8ae149a01d9b3824e7274a6f380e64d8b189b01e71ebc4902207712465f4f09e039f46d06fa949ab5f875a0f612c86c76702c07a4007532122f01",
"privkey": "c03a06e7e3958f790f3d1bbd8c9938e3c1636301a04b15b2774d27381a383d35"
},
{
"msg": "c5b4b2981c007f5e5b6aceb950985e64f8c5afec77955e973bc65f1a913ccd2d",
"sig": "3045022100d9f8081fc24e267dd5e2a70604277496c9c8a20b7c37f3d788e92e7356754b6e02207ffdafb0ba4efee3211a1d8e4623f13b63141054c942cd47e388faf3489bb8ff01",
"privkey": "795b50f2d308bf999565a084c8f709e6393f69a7842ce889c5addbd17c24ff5c"
},
{
"msg": "1544d33544fa93334739a60a35bab4390b523bdbaa43ba3956ca450ad03f6201",
"sig": "304402204d74290c6daedc88e3fdae9edac89984065c2774ed69d90668544aacc6e7e16402201ec57cf928279f30d56d8e5a1a46cd976cc7117bf2d03c9123833f08db6132ee01",
"privkey": "fd2190d00de40b004f9a5d6d06829fe87eb1b11e483e94023fa01b41c27da90b"
},
{
"msg": "cd40650b1d22d7a7777ac3a6d8701c12b485dd3859dacbaca56ad4ee4a3f6024",
"sig": "30450221008c17c93e1aa880c36c87ec08fe52ed68a96ee014a4cb8045fdd08a0537cdb602022045728db5a2bc1860cdf0767122e567f903a0de25f770d3a96b51833b2530e03e01",
"privkey": "3a6857669abb2d6f2f529b548f6386435856ebc98d8760e75642ff30a149454a"
},
{
"msg": "5817d0ffe477cab901884793ce1e5d40302941ea7460a2b468b7b02f08203527",
"sig": "304402205ab83ee406a958901837e7f155fa8c043558963fcac8156515166bf5d008b21c022026e18000c7050b8d7415337b10eccef395db63c6fdd8b008d2b613ac2583e8d201",
"privkey": "9054a4c8279b1812748c690f7de4a8305e7ba2afa27bb30a70ec2be6cfdcd104"
},
{
"msg": "082bca2d141957a5bcf2e6f0653557ddb12d0ef393d89c5c41849464cca6b8f3",
"sig": "3045022100d62ef631bc28d285f0ea2bde820c4edd321539e209c3575b139b4fa7fb571e35022015f47f15f24d40900ad13ddcf9809a4f8f45e8c1af2a241cd2641df02772809a01",
"privkey": "eb75f55fc51a5664c46889eb93af6834b8fc4760ffd12f36f2a7a54180765644"
},
{
"msg": "58a7fca8920df4322b3118241aca431418796937f2dbb32bf36b2c230ac3ce78",
"sig": "3045022100efed6c4c4287746b5870de319fd0fd1e7f39cfe19771764eea8bcc2641bb87120220284f66abc53254d9fce663ecc1648d417251b246c1f72e2668e786d65b01db0a01",
"privkey": "9d6cc489b02c25d0a33f3e2c71dc90c71bb91942bea45d543f41907f026fdf94"
},
{
"msg": "33cfeae00abc4f593d9499a7e11e314f9ead2bc6d033977d91fa13df224b56c4",
"sig": "304402205d51ef7d53b77f1e4933e38b72e60e2cb505f5c04c4589691c4afb66d45299b302202a9b34129c747c1a98dbbee519ccb8f45354cbe36b4e4bc6e9cb0079d8a8b0df01",
"privkey": "cdeee2375309bcb5cdf33d6e43f8949b3936a0bb776bb20b40087150c4eaaa9d"
},
{
"msg": "789d7a8a926e65c632dd4ae279c23c7cbbe1938082000a4f7e663dae4d2e6565",
"sig": "3045022100c316f7d0f51e6ea313d2b03805d695ac4426f959d14d9138ef171deddf0e593702203a94ff889daed2b366a17d5b0bbbe46f96faa439f3e0bf3da3755f2313cfd9e501",
"privkey": "f22cce5bfc11406b3c2013be86cda5e5597a10c99f045af275aa5c4136ae8247"
},
{
"msg": "cad973f4d052f59654c8b714e4c777c297217de855f7e72679ddc4d88353179a",
"sig": "30440220140c11ee563970fd34a31076fb92a81320bad49373682aab2d11ad0e9e71da5902202bc4a45f694e1a25b89e87b21b659afe87e83f57a53a2fe7a4160a93fab4331701",
"privkey": "9056b9aeb9b88e4b2d2cc34a3be77e6120551c9ec9991aeac46d75b3b07307ab"
},
{
"msg": "08f3306ded0c07980fc8e008c6805fa19582a1c635f892d0027256b8f6e658ef",
"sig": "3045022100ea0f425a8f27a9fc82286ca7545207cfe0ca1e41d54ad3168836086bc097740b022027ede91105e79097d091efa8d3045ee9a2e250ee9029245560caa5b8bb5450fd01",
"privkey": "54f8d7d845453d60ee39167ea8c0b3203487eb9fd7f9aa83f8b92ee41799d3ac"
},
{
"msg": "ab440f7e37a9ac189e08850866f9fec3fc2c323dc802f5cc13c9b2dd6ea9c366",
"sig": "30450221008e6a5185622e53f986c0f865b376b69cf7e2297b681c7b4baf92396808e90de90220633313c8afcb4bde5d1e099871e75df82245c9f2fe24bcdae86e53a48116f74001",
"privkey": "ee1eda8fc9d0cb958fa518d0b95189c7eb82202e6d07099b8a6a11106797af70"
},
{
"msg": "c0d12e0b35fa92dd04ca66b9e9537a71c5683a4fe5da9354e9f74cec0746251e",
"sig": "304402201e78c59ad8c6ea7ea75735696271eca86851f7d65b2c6771eb5ebbae2c3a5c0a02203f0e9b34333f544e692f7ae92ef6ad68fc455099760944d3e074bc994f2da7bb01",
"privkey": "56983efa120cfd3a7fb92df780a60463decd5f47c6422c6dd0538a68d3c7bfec"
},
{
"msg": "98f7eeb9417e950aa953c110b245adba213084db4bbd58978f2aac125ec2e584",
"sig": "3045022100ba311522b51cfceb11f8fadb34a79f5a75e7eb6b5878c907fb63c983feaf695402205b9e0910415722ce1bf94ac5b6c3bcb09919d3497999ecdde7de6fa76f3d00b301",
"privkey": "04dbf45e1b5620e3ca700a82e4e83a971551e25e15abfcf49c8a201a4174bb58"
},
{
"msg": "2e18fcb984ba778c0017cdf882a862dfcadee1ba4c7ad44937006a7ee0ee90cb",
"sig": "3044022013ccb3f7845476ceea2b990d15ec53253f333ebc1cf392e96590d88aac70dff902202c4874427363f84ab7bf331d2a811d57399237d58fe0ceef34056f26bcd9de2501",
"privkey": "8bfb17789767931b9602e3a1310ae79ffbd5fe7fe1f2583099568a4308cb80c8"
},
{
"msg": "d6fe1d5d5670b02f399ab0125c57fdaa181ae93aeea97c5ad238e0521dc10873",
"sig": "304402202d633a9bbdf3e486fbcd8dae7afb7b9604cf9a806d72121d08a95895d16db21202202f83e6d1c5d17d676885bc05660271770618acaccd35a30b1d3723176c1b395201",
"privkey": "e74ff299a3e399fc7833799b1591c128102d441361dc2ec77810d99abf280fae"
},
{
"msg": "798a41c8bc899e458e9e07d3d83410752ea580020accae54a3ff65ebdf607f54",
"sig": "3045022100ac0d8bee62c3aa92ee6f29c98978a7e47d179f6954fb2b04b977489a2d24e7af022057808f4c12d8deb7737827a1543e88bbd44abbafb4d4db43e2b5a6566d0e821801",
"privkey": "cd4d9c04ec290aa6fe5cb0e34e3f585beaddcba4f39d883bcd0a7e989801a778"
},
{
"msg": "1bafdf652c98542066d53aedf3b0fdd1d3517bc6fcb0155be621ed0032675a1a",
"sig": "304402204ffba8cc994840f5824b2217188bd0e671cc4b787ac33509c774a4075c62a989022041129edaee766692b1c8d9301974f6daeb7139d463bad561f650801f097b4b2601",
"privkey": "51385eadf7238fa581b13905b83ff1c59cb7923d2afdfe2b29396ec9da1f708e"
},
{
"msg": "6fc96a01cf2e3ab6ab277cce670d446f0da3a25bc4344c02651cda1510bda8cc",
"sig": "30450221008bf5889acf97948be7bf6afd1da1504bab75d841c09e3e6cf1cc445da0ed5cd2022030cf8407f6aabdd056e1d4cc14b4a0e4ac09c6cb45f572788f5353fda223923701",
"privkey": "20dc42c28ec79d4b62d84e2be93945888178a0c29aa9b67cb1afa5e4ff4f1073"
},
{
"msg": "524fc94cd49f7fb80b5d2a111d7fa9f9022b79f5368608dc5b50d1706e7e7fce",
"sig": "3045022100d391974a51503f4b8675328abdbeecc998b54bf6de23492f57631c15b8f7ef8a022075e1d215853ce491a0efb1b2ca60776142a26b1e8975158988569c2db2af87b601",
"privkey": "8cdfd627ab00b392e38c27ab8eaae73b202f306deea075815bec61a0d2cec7b2"
},
{
"msg": "d2a53bebeaeb041272699990b027da459ca5badb811e4ad57b3445c56e5112d7",
"sig": "3045022100e2e221910d4ce1fbd7d489a4807a5d11e6fa45f35a997ea5583f8508a1faaf1102200d5fc4fa852eb1b26abfaf6799559a7165b4590707ac446019acf2d468712c1801",
"privkey": "021144fa085375c86c681cd021ad5ed3e7070503309745e97143194248dca839"
},
{
"msg": "63446421e65a1fde302d32b962dcc75a2286b7c2f0491c25b3fb6f051b208dc4",
"sig": "304402200c792c52f28ffdcccda08d7875b3a62e665dbd65ffdd80b0767fefe7af88bcb102207780c849bbd193e805916fded694b89376136cc7b2b8567f52179fd10c64a48601",
"privkey": "dae1c4edd2a889f677615ba48e22e9144580360cb3c7094495579b3a4c17ee24"
},
{
"msg": "53751b08cdfd84b6e7a72d9d32f8684efcec290ec4ff53e5d2b66d85fe1075e4",
"sig": "304402206fa2f2ec4f36d3b92f901d6d1935f6167752c13bce38fde71e1cccace629abe802201575d02c1f9599e19e72c1552a1e67c2b84d780bb663cfe26f0200f7857152ac01",
"privkey": "81560d6c8f7f56947e85c05a5bf58247972a91974dc886fda04557e42cf7aeb6"
},
{
"msg": "a8f00b68747f932865b1e652495e2ee2b962d58ae65a803a83d5dd723b961195",
"sig": "30440220113a2d165fa751a5fbbd96032fe0ba55a9f7395c546c56460c74800206c7689d022037cf2dbd41bfca49004f603aa6476f9a2ead3c0e55f4fe437b4f968379b8951f01",
"privkey": "3648124d1c85eab5ab6a9e48377e1727d1da31b9dafe46844bdbda5381364b16"
},
{
"msg": "c0c93d49025eba4dcc15427306e598ce42b2b301dfda34e8fc944a10cbdf827d",
"sig": "3045022100fc15d1c1a7ab3647c56aec5fa47f1d3d52d082fb797701e32278ecc0ae93dc3f022074bd65fb1164ce8f856dd8c0d5432bef396357302409ca101f02904b7b7fd44801",
"privkey": "5516f2b53a5e43cc284f074d8960a918e67afc6c0c6fb74246fefdf2ae55b0eb"
},
{
"msg": "8cf263c83989fa23970f41b30fdaaf226792c0348d21da89d659bca19fd6d26c",
"sig": "3044022072a768ab0f2f878492d56153ee51b170deb652b6b2a8fe940ded965dd32e49180220300b9252ba85a611adb8827c315d47c2cc33627db9be8e283fdf09b527bd21f701",
"privkey": "467904e0c8850c5b84066e2c135096df2374e5a2066c0e94114b1d06eb98c454"
},
{
"msg": "ab2e3da1e5a5f2acb51e00f7f8e6cda712882080f24bcd9ea43ca555577f3b30",
"sig": "3045022100b1e275667ba42709e6a6da1306df173728b032c42fe955e60721819d7ca77c2302201219d9db72e278fab11dbc80fd14191d2d37a13fb31338280cf2837d64e27b7c01",
"privkey": "6a7536d6733334e204ac5bfa2172c86f7446fd32cd7180027391087f98f18116"
},
{
"msg": "6eba52cd7a8f859632b2b5e8a6ac69581ce266d82a6b010c7b666d3afd0e19df",
"sig": "3045022100fcaa0e84521f46c9a9dcff5da933c981fd2d0275c2cef76881243c6390077ba702207f7aefa9e2e9d2b27526a34c26bfa57b7cb2e22ddbd9ecd830e7cfaf81a7b10b01",
"privkey": "e814cd0bf690b780f8c615cc6f1202247b5218725e76eca315faf9b438c5e554"
},
{
"msg": "85b07d8a8d4100a4302ca49cfde58266911ab1ad45368cf7451dbd9b6f45eb78",
"sig": "3045022100fe510f6954ac3f2fba233f109ec7a08dd93aa955336e47fe7b095f1d79cfe198022037925a771d139f2649a5665a3281b4a363ca96fef8843444f23f101400f247f001",
"privkey": "4f4587386955963eaaac84b32eefff63b32dfbb540bfb578ff7b0cf9f01298b1"
},
{
"msg": "13063f26e50c5b6e62ea39fda446e3beaccf50ad07441241df62e3115f939552",
"sig": "3045022100d44570f08a9e64119d9885d73f688e51176807a4143856d06b684fff4a8ac2da02205f757d21c8c56258c63034d9b169c402889532493cab2c06c697154f44705a9a01",
"privkey": "b6b2e1edbcf892e41285f4ac942a331c4a88d785267c45c8095059c5914d3a98"
},
{
"msg": "738516a95cdb7d1b374324ab22e642b3b23db43464d898e80789eccb25240e6d",
"sig": "30440220655630c6bef940bc7360febfc8e7a09614e871b7ad8c500ad658a6ba7f1669d502202ad85b78a32a10c28b2d581d7e364f6c2b7caacb24a61e31130f2fae5a951de701",
"privkey": "23bf641b12ea841b7a8386a2ff4f378c8d33218fd147906db34c64363f59c1ae"
},
{
"msg": "2a7f44ec15c00e5c457c545a7bd27dcf38ad636cd98d48f0964496d3a01f781f",
"sig": "3044022059bfd164d817b91b94dba6c3843cc85d08442662a9f3736b12f294630f75578b022017f6dffcc2039291bcf0719281b2e599044a63709e94ab0050ebe37a2394933c01",
"privkey": "86b53e69d27fa695bf8217b0a78d72651584e24f1d85e928647310ecc04d33da"
},
{
"msg": "865c6d42b0ca9767593c8736c8b5151753f9c0068c9c52eaaf4305a19e2ea559",
"sig": "304402202b995842e430ed36900761f11440116c4a0ca5c4702aecf293625e608011b3df0220051b45eacacb9448cadd96cf4daef05db8f41dddfcb1943cb8ed67ded4a8e9e901",
"privkey": "8ca07dc245d61105afc9b40e69bbd1532b65e72094f929c117c5a72b4b6ddd25"
},
{
"msg": "5170ee5b8311f24570aa8a639e33c22c8f883e8d947548d47e1e330b965cc57d",
"sig": "3045022100d523659075fe10d9f6cc3e75cc74bf94ee65f4a099eabf7fe6dbe24bbc17f65c02204423cb40c94d732a8a51487b9e398fdca78005bdf1571b7126d67d9f50b712c901",
"privkey": "44e488036d994a53d6d62bd6e3201b7d61aac740157bc25ea41c7da37b5d6149"
},
{
"msg": "29b9327f728c7107537475f99ac50f28e33ec0f68f4db619ff0f8e5b314935f5",
"sig": "3044022035bc811ac5054c04febe41208c422922750ac045acc1cacf2529666a7fb7e40d022071837d85c64cf07a1d598de345125306053c3c9014b408898dc5edd04dd919e401",
"privkey": "1dc87fae4276cdae8ffd67563e0f8539231582818b2e2226dbbe159c021e61a0"
},
{
"msg": "99c751a334d1a3687432e87a34301beae87ec78aed2d48ce066f118b476a85b0",
"sig": "3045022100efcfddecdfbd8157fbe996563256efdc6f29955fab32edb3efed9cab08ef1dcb022067b01f720312ae64475eccb6381e1d3fa342cbcf2852b1ca6a53f5b1a6e16ff901",
"privkey": "6e9f1467ebbfa71faa565e02a8663fd138487dc9526e5d096cfbb2ad38883d22"
},
{
"msg": "76bdddc10926a641df369a6179ad622c6188d3081a3cc90d8dec398c68ab7af6",
"sig": "304402204d275af1bcd7ad578aff98d8a1551a83584b8ee9b57ef6d425fd191426f6f63a02206cb25c37fff11029f8fa5c2b99d0aa5bbc5a5fc484c863a49ab4ab4479892b3201",
"privkey": "f64b62c51f2de8f4643857ba12f81a433764a3e0cd9fa2316b8e202cad9778bd"
},
{
"msg": "f87a7e12df4d4a0ed99ec33e3ce805151526bdbced2bbcb0a012019a5cec7f99",
"sig": "3044022029fa907c4e4ba985b362c2e291291271c6acbbecaf4c49b938261ea6f255ddde02206cfc13e0dbc8d5ec4c98684fb36087738f9b449cb0bd9d930cda0025083543d201",
"privkey": "c21f2a248126a5b5d964d404911682ae1cbe7b7741681226867337dab8974fcb"
},
{
"msg": "493f0c699d505325bfd1dd86e28d7bf94d698120dc10d475aa2547bfdcf5d66e",
"sig": "3045022100c716b0c65339df2357089c202f4644603c21d7139f2cd77336f871834c27150d02206ef0c8cad1605b3957a15695db5fada122b9a8b9b4c49743088e88f93112320101",
"privkey": "5a4b74a8e52b8f2dfd45c2ff015641be2b1f66fc285661de8fc65badbd6707f5"
},
{
"msg": "82c5878eb438661cf7c50655890ed64c374611f3cef2e309a76565f745fc2c96",
"sig": "3044022030db6955679658577e9a7cac8f7081105a173647362178efa7c74bc813396b8102206836332abe41ab0e23e6f62b0aa08666dbe8228c5138638ed0c2351c22e6c57301",
"privkey": "aa6db6512e8b33be3543a46a908f26720402e3c15bd70ba8ebdfe7ab80787afc"
},
{
"msg": "652c4068be47d9437d49d36173e095118367e1d9d0e86295604c0eb94484d5ea",
"sig": "3044022065c05eecb47346d6b45b588a90eb0f5489a23f93170557eb969f258adffabde902202682a1ab6397c49892e349ba581fd623033a35910c97f4079e4c2e505dfdb21f01",
"privkey": "ef0d812b85eec684b3314de835f73fc06c3c90078d404862133643c3347ebe15"
},
{
"msg": "a04a3ee113f5d3054fd1eaacf8f3b1db506122c413ab346250e08ef6b5be8236",
"sig": "3045022100ff6927f3d0c14cfff2ac2c8b47b20ac99baa48ac72726aca35e87af7965725730220654333918dc7615a2e1f5b59af74a1565c281db62201c54befc6158222f8284f01",
"privkey": "b85e9ba6297a46fa4f017742485616c61ce5dbf080782ba1dd961933b7390e18"
},
{
"msg": "428f1dde2440673a19d0b97fe46ece447721e61a700376cc56263e63cac5a3da",
"sig": "3044022070ebbfb49ab2d2529546115e55f8aabb7784bd38fa16eb6a5cc6ac7ccce2fce202206d9afb41c0254c2aa1ba4fe3a05be5d5c1297803adb701197c918609184c2cda01",
"privkey": "c17b6ff03bc75792c3a3b4ed5612140e2f9d9e5d6b21650701523665b3819b05"
},
{
"msg": "ca0d05a273ef3b2782059307d838599eb027b0962798d71efc00648a5b07b744",
"sig": "30450221009c88cd669ab7743fc2f3ccde723fa8ef653f951f67abad5afe8031c6fa3652c4022012cf4d5d66bc0e9d40322489ceedce43bcad5fb41cbf92a6ea0f387c4b3b214f01",
"privkey": "c658044aab784be15a5776d2c4346e1099368a45f06853277352d70823ea7572"
},
{
"msg": "f6f4aa6943deafc1879c00589208656e927422b5f25cc9526a9fa6139c66613c",
"sig": "304402205325ccf115446eef902499ead3734d02065dfd337d924ca615f5d00b1580ef8b02205285496cb0cb63e8ccebf4ff999c922bc3bb5d4a4eb3267fa2c5608e6d0b5b1301",
"privkey": "480989d814f56895a0c5781497adb1ab82744c009815f00362321dcdb709f036"
},
{
"msg": "f5747a05e3488bd03da4210f9233131e1983f9e969d23330b3858a6c71f5c484",
"sig": "30450221009e81de985b1bad7843c72cfb6ee2a30295f13ffb7e1c3b10ddd505cd5d6feb6d02203389442e24b7027466eeebf44a9390ff8f9832716544a4f508574fa919b4848701",
"privkey": "db1e27ec5686db0d8a2b7c609847652067534751944f610bc7ba9f3792e92fda"
},
{
"msg": "ee0a83c20ff143b6629bd9599b5beb2e63384be72a53221c3263bb83efde8647",
"sig": "3044022063f2d7f32985641841f7c218e7a90add74b82e76004eb349d9e122162a574d7c022070e4793900af91b659030179ef46db54f478d74a31b31dd527af0952c49d461f01",
"privkey": "88624e28090c22fa80888c3f15000bd52da334c7b295587773a172aa95bffe2c"
},
{
"msg": "80aaab2aba272c8ccb67022ae9a54bbfaf8443bb37d2f922021a681bc4252a90",
"sig": "304402204457849658bacecab40c4893021d2e567fc86f1c2ed2b20d9f1982138f7f00450220225b04c91531470606088263b28b3df2cccc5a9f1df36130d8960343ed89e13c01",
"privkey": "ac461d001fce26e7f75fd82fb910e839d6e92bca1db3969fd78e74674d3a6bff"
},
{
"msg": "285b0f5cc3c35deb52d5e1f5fe6e7c5a82a0c3ae10249c39c4b81307bbc9a1df",
"sig": "304402205eed90c7c43c9dced57edcce95ae69e5babadaff58f033055d998e4df596121702201e47072efa39405f2920b240b56d3ee41c0b1c2adbef1f161c8da1e7eda6fbde01",
"privkey": "786f5c06867cc7e8a6b16c003ad6809da46851a8e3024527e93af60b1ff70a07"
},
{
"msg": "d615006da4b6aeb980bc12f769e263821890003123b1d2439c69da2cecbe51bc",
"sig": "3045022100e13137464625b65c0403b71a3ff57b42da0f5d35be2384da2a4f52e93d8039b302207ae93812fb1aeffaf60c39b0096b39f2fd73bf2e695be8bddea458a2bd55b89101",
"privkey": "226140d24cc86b64a1c2aadc77bc8b05552386da2d707668b3c460f69d70108b"
},
{
"msg": "0c26d76afb90e2fe6a8c4b2a9d2496e2a6e27f25380885f7985d8c1ab7d2dda6",
"sig": "304402207dfd5a172204356d4dbffe018b04cd6c123a48daf9b9fc201cf7e32088989b11022030217c1dce7e1d039ac011138569c4c897fd201694b10052a1f3ecb2aade3a7901",
"privkey": "1e807394e21a0412d2d48711c0be3685a49fa3810ff84517b5adb1189ebc452e"
},
{
"msg": "ae93855f5897620269b0fbb6f2444fabf304c570c2bc3d1342aa3b0615ad5b70",
"sig": "3045022100bd83f85e36346c428909a60eddd7b1c52abfaf662cab6fc810e0fc398371f83d02207caafa58dceabf7176c2e3b8a8890e47b9c1cddd1cf000ba428a91c396932c7301",
"privkey": "c8d382437c63d3debc2844e00c7eea0e0f400b111e805ba32695de93fc150a65"
},
{
"msg": "b9df3eba9ad579c1840fab29448186122ae27c9add5b5fd6c8a2c7556e0fda8c",
"sig": "30450221008bded4f87ee25852e45908397876b3601c6a0e177dc986bc43f52c5e25fe5d9a02205473929f0502abfc9ae0da25086b13d92e0ee4f1e1c9fcaf334fb4623048dbe101",
"privkey": "54a92b44ea83313d0779475a1e664ad132abc53dfd8e4742ef81d01b3ef657e5"
},
{
"msg": "f304cff5f74fc72bddb353ecb5d1a250848ca764ace690cc308d00b247577226",
"sig": "3045022100c1f9fc9a63f0d26677bfd68687dd0e56a6342bc536a71c9b1f3a2bbd2a48360e022040a3f3179228bb89b82ebb648073e713cb759c1cb7d4e4f5486c29945d5c55e501",
"privkey": "b59821f0dba07cf87f0bcfb4310c6ab4e676ca319fc6c0d9d11ae80be8a0468b"
},
{
"msg": "77ba3ec6b8fa5c2b8f6e4bfab18b2b51ecc94586a41a1dd80290665913412266",
"sig": "304402205d9fb1e3c6ea1b18849cbb2666ba5d5c67bffa78d6952e7b0f009226db6eac85022043cecaab697ed0684d53b497ac61ae614477ccc153c87f938e5a3302bb70d59f01",
"privkey": "a62d04ca999d3b5311f317edec9418fbb065805872b25dcf69c088ad7d3b9d11"
},
{
"msg": "63c7a73d7d35dd73b94d23b446bde100dc15e3544222b9c7e6c9d0be84b1f5d6",
"sig": "30450221008043f2ee24182f28ecfc6c53cc3a51ae6da4ab902ca4dbcbcc629f3480b9a97c022052e44edd783f81cae9bcbf4e7185da17a82c09894bc44b0405392aa00000f85901",
"privkey": "57b66d323c278d6aa3799db509d1909da6d7f69385b2627f8785712777f8236d"
},
{
"msg": "2ce5f3aff72b0867bc0b7c286dd49f011f65eb563a93cafef5d554ef3d9c1488",
"sig": "304402206b1cacf8fcc9e813f421f88ec8541c04de7f00430e1332829ded5ff73f218835022055b9da3bc1de4ed413f35765529c1df9d5b9b8e8ba1fbc7507c6e8fd747b191601",
"privkey": "81db6a86b8e6d840a97da1969d5ccb9b9eb4f9d36f6e59df65bcd42b9f3ef12b"
},
{
"msg": "475ab4796a2038629a3b9f43a14d5a2c86467bc1e32ba654e87ba67ff99d2890",
"sig": "304402207d3375beafa30381e9ec3b32b0ab819d67c7f63c61df796993085ed9f61a1a100220050e89b744e94e4d7301701d602886a39e0529740c24f6a0f8bed0d91cc01ed501",
"privkey": "8b51025a732cd22a179591598414b66bc370295c1d35284f706d468de4684dda"
},
{
"msg": "af1a72105095a243242132ad24085c444fc78bce26de4421467266d248536b87",
"sig": "3044022025accec34080896b7ef072474e0096fc58ae84bd73f045027007925dbb7fb5e002205602c0a5cce0b4d9e10a3009f9dca9d2599b694b6ef0e7c4360b08d35fbd607001",
"privkey": "5f0cc5d1b7996f0187a0e1c709981dc6dc944e92f908367eebd82f1babd2ea63"
},
{
"msg": "029b0efbdf0374c6a23593cd7c6917a9404b9fa43ed32428a82be05bc7f2fc3a",
"sig": "304402205fee5f55838ab4f7f7551b64ed346565f64dd5b42e2694d7c372233db2fae37d0220026e8f5d54af25529d7ca1a4991a1385e7ea3ea9fb37db826d81aa32b0aeadbd01",
"privkey": "b7906b63b11eeeb3f69586b7a8323aab9f4dd51c157f813d24f8e34407eb5c18"
},
{
"msg": "9db7ee956f52eba9fbfabcf840d9c107117a00f5e2874eeb54a91025951d2ea9",
"sig": "304402201fed017ec208e65cca442552269487cd15961c2603f6aa19fd035491cd4fa09602200d0c5c9ac89dd501c34f3b7403a82832f58153bb77d070c44fd8f9396dd0c2b401",
"privkey": "3e89238cb4a7de25f833f4b3cd3374cd5687d9cbb858de906a570818e14031db"
},
{
"msg": "b502771c17443b8835fd6582fb2b44512b66f9bbe92dbed5e710b76fe35bcc56",
"sig": "3045022100a424be7d1cad14f52a4bc99736635e3130dceff4f9321dc3eec31915a99d365202202c573a3a8d2d24a79ae70ea15e32e0a79819406edcf54bcbae4d49ff87512c8001",
"privkey": "6a4aa42e630ede3342539fae35f43c6fa02c94c634753adcc2130de76e62dafe"
},
{
"msg": "5c66cbe4059db5bc8046fc393266d2db410a81ec2a02ecae0368aa0eb35d68c6",
"sig": "304302204203bed95a0e92b6a4b6776551e01473b891487b051824cf707ca553b40972c7021f64f496fab45d743ffa95a520a7a6f5e98c49379e69f0b8a7dbeb98b576215001",
"privkey": "d7e3eb80f852de183837573ad3aef624e16e8302f7d0d4b4d5ff4abf9063e438"
},
{
"msg": "12e16733960b2c7d5de1f06b824094bd116ee9ed83b680233298be7cead86741",
"sig": "304502210091d303cb2e80690531645c79743cdb29906fe6119023844b8c66c81d39c9e299022021e6614ab44c6da7bba1d7de4b37871cfaea7a76df43bb5b90ffc6f61fa7e86f01",
"privkey": "0686905b967248099704688e15d8e3eeeeb58ff24a06e8c7a0e17b534a4714f9"
},
{
"msg": "2309bde84fa5fd4ed530fa7ba01af3dbb71e7967df1792a53b13bfa8225dca77",
"sig": "3045022100e8f17e0c541518d5eaa7ddfe24d7caec497783da37b7605522039024bcb835a2022075d5ef13cef091ebb861006299cac29fa762c2d635b3be798649633e4d8e0cf301",
"privkey": "4ded96d9315bf52be4ef30a2295d76a3c6a997a331555bebb5012491b6d315a5"
},
{
"msg": "1453bb7e9be2757cfac795c751dcac6ea24a1a597d8ec4b5c0131142a985e17e",
"sig": "304402201a686a1eca60be4ec2d95f22765af2afe91a6493ae70dee9ec0ab8915792c02a022071aa6f6f48f2c04e1a56e116eca35cb36866595561cd10e75bfdaf7f08f2af2e01",
"privkey": "6d9ed1aae9dc352667d4feb5e3f41f51da9ef9eb56a58b2497d502779680ac4a"
},
{
"msg": "863f7f5d7f0619816d65ef3eac2121c9d3b3a6980b044074652f99c70abf539d",
"sig": "304402200fcb08df78fd9aa098d627f6683faaf6535cb4452ac075a228ee72a3e5cdb16b02206936c264990abb530ab705249e564bb4bfa7227edbb71c5686387f7d82ec251501",
"privkey": "34f87676d627e5ce30cec37ca8b7add7b30e82f3e510b8ebac31fcedcabdb22a"
},
{
"msg": "9d3469873f54a1c26498eaffa9fc7c49644664cc4b25297fefc1b1b8429f6674",
"sig": "304402206735289ce27cf7e55251526382a07eb9e4a132971834082002d4464faf012c1602204a6c9b451f9ad560bd5c10561a551f33b712d553dd209b5e9f12fec46c2ef9f201",
"privkey": "8b4bf88a79deedef116259d5dcc331e4e566c04f1581c2ce0d02e6e2f15b1ce0"
},
{
"msg": "f479dd8ca6bef32889a4a0159462eb2b56e387b6ad15f8ae0b09e1f489d49cb3",
"sig": "3044022046df345f1bacaee73ab2157bcbe6e1b333d2abbe5cce53fb5a50f81c952caead022071ef3cab8a146da86366c1f79ccc7edc76bc630ab0e30956305ae041b908be7701",
"privkey": "d3259f9685535af057328f4b4aba66311fa654da96b01a4161749f12d27fdf60"
},
{
"msg": "9b4ecdd6c6fd1a43ba3cdbf534a8eb0159d0216ccbff47c3e41665776f00aeba",
"sig": "3045022100e7f0b77b9f767b6cfcf33ecf00a5dde22fc7fb46f87a3289f09501dfd889a0360220645639cfb7bcf062d3bc62a81c27c79d6909758f2ee37b08032b2351988a7b5601",
"privkey": "3a6f3397de4bedee3cce0568298f039d97ef8f4ea1d3d136e6c857cc3cf477a4"
},
{
"msg": "bc64a2216423e642a30a0f1d790f3cec68b71f06618494723541d3c778237c5e",
"sig": "3045022100f85ea06b50d834109e5a0cb1e4f506e86cddb875867a9c3b28b48b1ae086589c02206e875f5abce1a66c30cb082243dbd9ceca233ccfc758cf91bd16cbf08648f98501",
"privkey": "3783268c39a70a6ba824e2adbaa07cb11f94b39b63cc3e8d53cf3603042c5fd3"
},
{
"msg": "3962c385ea39d4df584dc1d9b93c1424bce2bef2aebff1a26dc7ed181e57ca50",
"sig": "3044022043d17ebe7a376f79dd2ecd1b745548d9633e5c7871dd521f922af941c7ad47cb02203190a04501956eb66840ff7f7af13fb492e51b59ac981a6ae9e43fb06552365401",
"privkey": "c26e9a48223b3a3966495620a14db81803ffb6f3b3a69932b72b65f52b46ca80"
},
{
"msg": "f87d0fe24e507120efd2d10aeed2905131d296d50e688684d1bb847e68c02bef",
"sig": "3045022100fe995bc6c1bc4e6f60fd8054baa3685cb09344fb83b18496f0a74da81a4ca46d02203ae1bed24bee86d68bad7501091593c5db3442b6f21fe02445ff14a0574d98af01",
"privkey": "53dc1c26dcbcd6220e7329e5d12fcf17d838b9f8936333b03d0abed3cfd3ac2d"
},
{
"msg": "62d97d2a26ab35d9e2d18e4335f7e45665a712eb65a1b2da9c2824339c4f9780",
"sig": "3045022100e8542c42cb929f670c2c7e5faf2b46ff9a02852704e91e1a79097610476ed4f302206d9aa52a7b886fb4062a87ffb587e54c0c2a5a7ed1c12dcf112123e1b827b51401",
"privkey": "6742a01cbff6a2e83a4f68a338c6f0c0995f6cac6e842c6f06de8337fc679f19"
},
{
"msg": "364f0f3c7f17aab5567cb6ab0d9a364a59ad8ff294a006eb89193396618ff58e",
"sig": "3045022100ec728047c10274e6c1f3ee2404a9bfb5d58beebed4ed7d0c80901926a2c5caa4022027f1905073e6730963b440c22e150504b47ae4b02b10dde1aa2177a169a80c9a01",
"privkey": "f2415dd427697296d40dfc72084df1249b04d33cedbc880df1d9a6c88917dd9d"
},
{
"msg": "d0080a4d6d945980321e346feefa6d8056cde94b974210dc2064837d8f47ebaf",
"sig": "3045022100a81edb49b4d7544d27a5cd7e112b4caf58898cb83d76740934c151e79566f97802200156257235e64803ad6b15ee58d0eb7a103fbe1f6ea024fc25420db1d4b22b5b01",
"privkey": "a7ba1b4480cf766d833940311d8a8c59a22d761858443412a94aa3407e330c16"
},
{
"msg": "f09feb58a0f48e1678434d3995d12185a9d340baf3d19902a4680a532456cd20",
"sig": "3045022100df54f5a3f4791b77107c11ac15b0ed7ac59cdc8a46234031f16317d1dfba946402203d768943db33aa775d86000428699ac45e683d9d0b4b5ecd47b99ec7c548709601",
"privkey": "ecc32707de9576a9e91fa013190253e12ef780a5d30a0b0806da2ac05678eb6e"
},
{
"msg": "2e8e25a6cf4c689b3560007bbe26a3df37dbf0eb5562c68b8efcb42fd5760f1b",
"sig": "304402206d2f9b5b37afa234eabc8e9905f7094c56cb936b038abce5166a0e35b82ff9ad02206e0060d1b784e880f517a5d8607c77a82e93d6dab3c3b0ceffbd9e632ed3c78d01",
"privkey": "bd42ee836125cdb5cc41ef767933be53fd374924441c4ef829b18c88ae1340f8"
},
{
"msg": "5d659bd8337e119afa182ead19ef91f5d2f4dc6f5849e8fc56b4e6045204679a",
"sig": "304402203ebb171ab9732a29344b2c5474f46068a7466c6db0694ce2935bb85f5a6cb57602201b80113965c0670f3b0065b0c3a527b89a4c328865362767d8fdd6d5c97258a201",
"privkey": "17324fd463b6990e89218846d24f13813e415ac8c29faa2c6e7b2a6169e32e8c"
},
{
"msg": "1cb65e2253db80412c92e092db5864c2074fae2e0800ee213b4ee82d69d639d4",
"sig": "304402205c216ab6a7cb4bb9d33360999d2e00ac6b7c6e956150db10865ba8fcb87cda90022064fceefaee8c40a8f5ed8cee478d45d0e5da1aa15d29e103d1cfda7748f8160101",
"privkey": "5edd47eb6580ae11bf3a148e01ed28a94d6a7912621707408da31ce4c541f46c"
},
{
"msg": "5ad8d22c2e648851a09d74f1f47d2f116b51e4cb662a7f6b217f609f6d578901",
"sig": "304402203c151a74e81770d564b18efbb895f0df2f4d225d8e215e671b5fa44b43b098f70220540f560d75456eef77ba2e52848326624ec76ae7edff7b2199b822d78e62a0b601",
"privkey": "0a2804f109b57c7768f1d034112ecf46c705c6bf01b68c24220ff80e332e1023"
},
{
"msg": "53c82bb675afbb5f6ceea4f6b3bdb777cca87f9f27fca9c688432b69b80a8d9a",
"sig": "3045022100f49e0096e15d8d2183240fc3013fb71696aed95977d9788e1f6b99394006f0b502203d01efe4296b409db81a4e6cd601a7440859249339ca7c3a62188537802b488201",
"privkey": "9d0b7120991d0910765b1dd563a787ab9ed51afdab8fb6c214fa3c6d6e32a08f"
},
{
"msg": "51ba637c78e753468782866a8eac39fed07f10e2e38946ae0ce7a9a087aeabc4",
"sig": "304402202067df8cec2b427a98fb7e0ec60715a4512102b74b651c9600a5b4883a0e5a2e02200daf8fb6d240f12f6a7afb2e9cb138160e16009498e49c8fc8f7f198dd1eda5001",
"privkey": "a73b76b643651ce1211f0f98ab19050a3aed4774f9ca2521249581c3b505817c"
},
{
"msg": "5aa29ded6e2f76817a66fd97d28838a35b61bcb4f04bd7c9418f99786d9b67ff",
"sig": "304402205c5b3b02b9e0d50e2c5abe23cb046dcbb541b37f90c06bdad2d8a25bb91eaf050220346cf30343afa33695e160d2e8a66fa98fb2f8eaec1816178caadc223f93720701",
"privkey": "c9b796aa7aaebafcf3e7a2ab52b2dcc59acb926ded580c85ac95fb7333922c71"
},
{
"msg": "e79b7d427349690bd001f4bf0a3fcb61a9a62f710dd7b84fa04a9ac8621dae22",
"sig": "304502210081a3126be36cef173363ac2b3d157e6b12ae905ebe0cc76bedece1f4451f2fed022046896d45d55e8698f6b628e930b09e230a778075e1c2ca5e1c61e75347eedc1e01",
"privkey": "a79e2a1d32fdec5d2425af329680cc7e466f37b559fe54a9414f383e0c02ce3e"
},
{
"msg": "116eb6113b0e918e4590d9c0b6e335da67ca3c4e9ff65abf11655a8eea47e4f0",
"sig": "304502210094626b44fd9475c5f1300bdb3f66227371b42bf169ba0d75a9c5babd37ffc946022052b21f0bd6053814b76532320360c4ad93c0b856f4c80f43a4ff7757b3870a1f01",
"privkey": "326117f45d2e6e19c287813c7ad10e40be40d543951c9e81ce2547cb887e1308"
},
{
"msg": "1c354d127988b843c7e73cc55767272a6ef7290b13ae90651202ce51653a9aa3",
"sig": "304402202fc5e5f3ad67a0b9515b0afe1f8e76b829ec604f112045cb34ccda7876f9f1110220090627218a60f449af87bc4703d8bdf226e502775d17fcc05ca86bbf125650c901",
"privkey": "7bb2bb79141834fc87df40d66db087c943613dba9ae64f44a7b6a78f4116df72"
},
{
"msg": "f30ebdd3c9d82677fa3a1666c091d9edfb9a73bc44ad4e9addd8de7fe9216459",
"sig": "30450221009f649d2f5269d5bcc3636c5f7115952b93babbbcd679a746b7fc62d5b7645e9f02200e6fb9d63f00275f9fcfc91441e0110482a6931ae683d5b92cce9663a50b0d0801",
"privkey": "39884d1f793eb949ce5bb07dd1b045e5024904eca7845f2e2a682b3bd716f1a2"
},
{
"msg": "a1c2b956c8d16378f8b37ba5a6507a39b2019f4920cea9e0fd8954535017d929",
"sig": "3045022100bd7cfc17f329f5248a3e90884ff27f6e43989b6955f0235027d633c80d414cba02205f465341ce8cdac4b3dbd3aed639816a883b3e10ec0c42dd00dc8151a8afe6b401",
"privkey": "7a214c6fe5a723dfa73db996d223a67e58f83f3b835bd054798f993146d962c1"
},
{
"msg": "2a0425e8362bde896e2ea09a1228359e62911e8f9710e80918f26a74f0952cf0",
"sig": "3045022100c1f17cbe35264ec7643ecb9e9d9eb96251ff7fc627d288c5b9987a0907de33f1022005484896418729326860e8abeacfc7ac511f163e766510ae8f17df56f188558f01",
"privkey": "529e409a353f09bfec047cad40cc74c8990680498f30269b2869b1804b47410c"
},
{
"msg": "dfe1ae0090ae3a721a001dbd9b3e33ceb4028c887b74b2b9557609229184a8c4",
"sig": "3044022002bebdab55b43bbeefc4c92fbcb0c8ec6462a63f80cf6b5b5876e2e8ece24a2f022006e667ab416bfa3c9052565a5199f16f4c68e9aaac3e5b20d52ae1286e8eaf9c01",
"privkey": "d2fc0076b87e6aee2852492a7092a49f80dd7a4fba43b1119ca23a0d5833f870"
},
{
"msg": "a0fd53dafe53e8362b26116ec475e58da990cf7cf68c81c5bb643dd98e3952fb",
"sig": "304402205419be40e45705c8ede1de4aa194bea70c5aec160aa3ff0b7b897135097437da022076729f0571e5ab1c2a76d0f768103be8fe8170863f7501ead08d50fc5037b26b01",
"privkey": "68260c731196804f1f6a5325c0ea3fa6d8fb1b9964db1ea41f3add37dc65d31f"
},
{
"msg": "4d23d02f8c91ec285631c4084bb6dfff6d8a96bfaf78ec3fe5f48ef25b4e911e",
"sig": "304402201ad146e7601eae64f06689dc5bebe1e5fa8f4dc0aaa1dda72659153b1db8ff4102204b5b3f639231a567c5c839f6c804febf9558403f553b6d1acdbb602aa790a0e701",
"privkey": "f48fca4688a9d6f522f345cfda72b847191b77ec891d39f54c422c0b0a4ad528"
},
{
"msg": "88155ae33b918ecf6bafc7f24fe75b9de573e0f7217fda91fd2ca6b33c51ba0b",
"sig": "304402206af1fadaddf318e5cc6ea0d630c966a9aa6fdcfa1c51188dd18a30a5ce9292d702207b53272a1a29f92d9cc335005a9777a6352de56541694b42c3610f8287f3688e01",
"privkey": "31b614dbfa8820d15fa932946142ccf1e1f12c9dd57a6a7547e4fd80c5e418c5"
},
{
"msg": "4dd10d1a99d91fa5677cff8285b8f1bc8c3e3addf2c45c4d7d5b3c7ed75f6970",
"sig": "30450221008f930b4e25f295f3c5a5e87fc0ec52bb915b96dacf2130be56540a6683d7a17802207b9f7eb912a8eca3990a6e192f01c072287f63202fbfcae20688117d30cc1a8f01",
"privkey": "db8b58e63fffcac3fc0b3d475059738d4c4f549ff3f0944bb9695353efb799a1"
},
{
"msg": "925a060c837b7732e411d6dd6323c09f8cb8b2245b7855a51ec095f17828b953",
"sig": "3045022100e687b57e41c22c2f78aa75f000410bfddc852469e32352ce5e759a81c14ebe1702204ec924703af322348b6f06fd62567e689258988fe9928ab8987bbf25ca8a164301",
"privkey": "08c1df65ddd6405219f2f20c905693477db910566cbefc1fa3a53593c14d1157"
},
{
"msg": "16ba4a02006bd0764558a71601542408b5dce7839ed91fdd3c229d37afd5cb66",
"sig": "3045022100eeec3696d777d1d4cc658ef6236356e32a92cee32670dc566e5ee28df32fe6f80220558c75df7de5286d89f7cdc7de3e1cb8d45aa73f34a05dad48e1079685813f2001",
"privkey": "c82829e681cc6cb6f124b4e1a0ea68d9aa063cf64be68fc95f6ccd095d97cf90"
},
{
"msg": "977394a3cdb1151a226393902e9d4003b63678bbb4f67d784e45cbff6831a611",
"sig": "3045022100d3023f62a83b3d7a252fc7ddeb3072f1dd9c25b0c604f1c68959f22b9266186f02207e4d9f9ab40bd5fde9e55b42b05324d54bfd307a1b5c32a35ae2ce26ca8f1ce401",
"privkey": "1aabaf1d2953ff2b5f3f5ce80d5ab318bc31cad97eeb0fbf0f126b21b720c4ec"
},
{
"msg": "0c9ebc4b38648729b33d86a001308c099b020e2cd2c989b82e9316b3687bc7fd",
"sig": "304402203aad8e8efb5721c59456d5121512db983672342dd2945f5666389f4fcef37d61022005b9a0d5ffd84e309ac186e91ceab6c5ffdb10afbde94f2c7fa904a1c241204901",
"privkey": "60f77c61b9fc3e3fdfbafb33a97d5da172c7223db73a22e8c19d8aee8e6bf8dd"
},
{
"msg": "e672cf35e5b186843607321255beb9a626e9b16582ffe6cba68251cfa2d26edd",
"sig": "304402207a84304fa4d6521840d6e1b9582602a12574c1dba1f7088221748d08839e6101022076773ff0fb876865a3318f939e0f07721034e6886f6a9afe9546543df238e59401",
"privkey": "64e7e1a9a9e7b80cb5dae781b9d4060ac5129a2bb254076bc1bf1b3b5d0b6068"
},
{
"msg": "7972a81012267be81555aac3644b4d6aac91061717ed33552b3cbbb5825151e4",
"sig": "3045022100f67a1f761743f7abf3ba3e0f0097e93579fc45cdba95476e5f5b9d8155ebc11402202984c12e518f5a6b3c59e248bf2660f9b4313f6030cf0b10a5bde3125aca1aad01",
"privkey": "af681d1431a137ca2ccfd9456123af2a50901826985d1b4d46ac33fe7439a0d6"
},
{
"msg": "2884813390313e6832156ad2b86050d04dbfc3a810c1adb38a4ccfc3031db3e9",
"sig": "30450221009fc5d7058df747afb88e47dd18a9d8d73949b1af1ac4a7f4324b7e6d5ff499b602206e353305f58dfb727062bafd7dfe797c9f3071230f3780f5875d331bd99fbe5301",
"privkey": "c6904733a3f4a8786d04eb725ac9d7814ec66c667ee7f56d7e9c1d39c7a06d0a"
},
{
"msg": "17dd2ab0e67376ec6dcfccaed832a5a154710034818a78498b2987a9453d61a5",
"sig": "3045022100d2c15d6611c1bde642076edf2b89fa2e1062c99c866935d4b7eca979a0ea63a10220624da519888c2316c265b554281b327d471eb98cf8c3fb72a7c7dbee22553edc01",
"privkey": "493a3a53de5389e4c75092732be209d2716b93795add2210f6a1460c92fe238f"
},
{
"msg": "bf0bfaa0d35c77239d0c98b900c5dc4efdca9a83eaa0c1fc4c7a8d50c5136384",
"sig": "3044022032f05dc70f0b08a5b586732f377928ae5edaddf7d58d3cabf0e262d768db47cf02206faf588d1682554be1773f11fc52b0101aaad3acdedddce71ceb2cd4d0ed46f801",
"privkey": "649306bf872e1626d8531d655a38e4ed7c455af514dc9a90dd1bc434223a2e70"
},
{
"msg": "eb73158bcf51a0d754baaf7e68c20c385185644acb701cf9d54fd41487f83709",
"sig": "3045022100beec086b0341c966e02014c7576b7d0d0ae007489bdece567fa64de4b810a09902203cbc3e4f414f766c4653c53f52272ab2b87c88d49d8be05bd2810bf67f4a9f0f01",
"privkey": "0548d0c8d32215ac696d32ae2f28c785d86d68433345fd83e6101b7bdbcd7199"
},
{
"msg": "8558f4a0e8714bb6fe788d0a0c1e4bf5622eee75a163118dd312dd0bf12bc971",
"sig": "304502210093fb277d192b50368665826384f3f537917b4ab9122e3826c9039e45871fab380220745c193fa30a2a582be64072a71f8476e1ec8ee374424689f0656b24fb1c002d01",
"privkey": "303b41d5ba88eab108428fcdacb335ea96929989372069ae4cd27e692ffb3955"
},
{
"msg": "727402055ed837f5eaf1329ac81082929aee22abe2246c6dcb483ee8c31b580a",
"sig": "30440220181a4a02b57b3223808dbde211d2cbb502f9d66c31975ae9f94cea26dddd5e0602204e6eaa65344ea524c207429647a27fefb4eb967c403c080e46877f61d22eb4fc01",
"privkey": "982e3cae8f991b965b44541243e2e9de3122c8faf05718ea7fa5ef00b4098220"
},
{
"msg": "29a4c44b4d8a4d920fec9368f0dfbde2d245eeab89016af90e7019ef6e020f91",
"sig": "3044022038abb43bc0a1f4bda4d0dcd9e13d983a24e8c4b299dca06d61459fc56edb39fb02207fd3e3e37fa318907ee41222ec7cd4ce085b35c64dec1d8c6b61424306db50e601",
"privkey": "fc85d8dd8c854dbf7ec922c6124c654aebb61263b0572ff922beb523a743654f"
},
{
"msg": "6f15ebe59374436bd4d6b1ddc7a2a016679ad682f077a8a096db0ac0f159229e",
"sig": "3045022100aa23abb03621b4834084e2372c8aa571b125a4e897d7a8b3690890e7cae22f08022021a5534de67162c0e02f946f49f72ea1cabc753395b80cbbfec117c2b253cc0f01",
"privkey": "c5fbec66e7c8b8d37e3dc65aec3ce66321983e87a7f48022e6d67f23f133fd2b"
},
{
"msg": "08854040e59a06d8fa647274c751e69980a53045c7e10dac29e6c1f2293f8096",
"sig": "3045022100fafb9d2b34ae5a6efba997e865c34ac02402bdd1eacd4e51859e35ed16f73832022044bf0182a26d15905c672bae0dfb1ddd21264795947b591507f786541faba37301",
"privkey": "86410a06d6053dd75d05ab51e3a08608018bb7d70c14199ecbf0167cf459a3cc"
},
{
"msg": "66d7220679b951b05ceee33cafa9490de8669514790200a5f86409722ffd5a23",
"sig": "3045022100cfad593cc4e424ccc6b7dcc8d576eb34d837ff3862ced984e61b3c0031ea11b4022034dc395f1c4cf1d84f074f45e4583ad15b94ebd74366f138d6b3228ac1cc1a2901",
"privkey": "148d9ae3cd5de9347b0ef76dd49022c416e05cab1d3e9f91de0bffabd9728aa3"
},
{
"msg": "16d5f60b487f97c54ca4931e1804ff5e7f31b1a7546b90a515780b6aae66c67b",
"sig": "304402202eaa80e56f1fb665cb995bf12e4ad161e275c59a13930a78a1c8b990b2b40711022070603f86e4dbc0b89bfe02aa941bc901a2de2d880253f641c83c0fd6e59988ea01",
"privkey": "00b1ecd81941a3fbafe4420b9e96c36f40cb5067ccd0c128dcb40c4f9d508e68"
},
{
"msg": "efe532630bef5f6404ab56e4329a08800c5f2ee06743b58c5c69bf47e78b27a5",
"sig": "30450221008807c44f387e9db50eea548928c1129308cf501f3bbe3fc1a4cabc400e57ab64022062d127baac5aa2d1fe08404b7ce8984a8fe1bdef50efd41eac5ee28b3d0e5ff301",
"privkey": "fb2ea5631dbc89764f2f592de36f1e087a313461f44c70fb231b0ef7928143c1"
},
{
"msg": "02ceba7e7cfa451c9af56995c36f77252b3ec4a653bbc41ac94ea2751e8e7a07",
"sig": "304402200b028943013a0fdd47eba1117b89bc838a269ab923ffb3adfb125fdf971c7737022050f416497dc081b223c50349fea72a4cfec33c588474ea6dc9d7823076de856901",
"privkey": "35ce2144bc6e3fd449cc57516f2e0f63a9878a592ed1b6cce21c3de85d98d3af"
},
{
"msg": "038decd7e8ecf898206c4af77fc8a6342d5b543a60f121685715319a6de3d947",
"sig": "304402201046959b39f101a68880dcd8958cd2908d228bc115988691d1cbc3f7bf5090a702202c2a82c6504ac301223d33608f7e9314825355b4e0907e6d7a965d8a90b14f5c01",
"privkey": "d71f018138fa752798132a8393f81f32c474bd60cecda2aa1baeb5a4b00e86e4"
},
{
"msg": "517398a39596dea9899429688afe62c49ff2265f177b32ea452fab47ac57928e",
"sig": "3044022041c9adb3aa577da5f6a4ec2237bc7ade73b0f1db122a4ed3152fd53723067dd10220774bf2d35837da21ad6073330449ef969b3f28d1cf3ed8e35664e75d0257855b01",
"privkey": "533b93438ceccd4d12401e86b6810200211dcdeefec130410fd978814a8e76ac"
},
{
"msg": "eb18410a53353de79a56a86f95ed94f7cc8efb20c7662f6acd1d0cb46dec6729",
"sig": "304402203beff0b6d06157a96bd48d84b70b2c8d5e4be1e60c358db05bab94c7b03685fb02205a3c07368ad539c0edff9ffc35f4d44cab663fbb3cb03f8e466929b5c9efd5c401",
"privkey": "5d006eeabbadd13ffcac0944381081f6f0dd7b3564fa5e9e0c0b2c8418d1ca52"
},
{
"msg": "c886d6c0d4e62bd8c65c1d3319b32a82dcc4fb5780896c287f3bfac415a768ed",
"sig": "3044022068541ffbaab7dfdc9dd0d2a8e0d8d3a7e1acae685bceac3f1a0a19b61bdb9bf20220544d24dad0c195d0d57d2dbac2d22b328eb118da055f0e741b4346931a66de1c01",
"privkey": "c0d837694699e53ed82bf4fedfe7e8cf70dc02dbcad884c3b822b3ef6ddc5a19"
},
{
"msg": "826f8c6ab61ed5928a1d6d9cd6d69082ec9f9e45c4e73f2121bf061ca1d88a87",
"sig": "3045022100e1d3b83cf96d324fb9bf2ac9096c70758799bf330104edcbf6c16ba672e8968d02206a9a826cf32840db5f2ddf887e819eb8f41d14e8be2e94aa0e7f064d96a4d21701",
"privkey": "3f523b03447d06bfa64fc78db115c7e5828739f38ba39663095309ae6051c092"
},
{
"msg": "da71ad31c818c04ce018937d33a2428be6d4199af6e24f01b83f26212e3cb186",
"sig": "3044022000a0856075820b29361a83fb332c190048ad5f4a81f9b993765e5c76b6de462302200433ebf787caebb7d549fc93636e7e79b347a97fd56826f75adb69af01654efe01",
"privkey": "c235de75530efcf7c8bf08e3b3b69c13d5a306364172617f61c20d2d02d4b768"
},
{
"msg": "de8f24d7924433bb1868e48a92aa49020c464140c1c69d36f8268b38798b1171",
"sig": "3045022100fbcc16baf92400595a5df863680c76388ff152e4e6ca3efb26d041f6126b51db022069c8c6ba124306ac55a3f5b5b95988fc45166aced7265d9fffdec77113cf572201",
"privkey": "231913cd2deed9aa0483d2a23719d9dc7a9354518ce5eea88f4d2de219891888"
},
{
"msg": "3f87a3f5199d729f5683d90b1977e1403afab944a8a107abe8aeab1c2bbc4710",
"sig": "304402200e816369dc132b4331713cc481258cbe9a4526a767aeed50dd9c00d3cd5f321602200a592715b5538fe25713a179334dc0e275b710f74f16e11c599b79d397f1d01e01",
"privkey": "5b274ede3c80bcee4d5c1cf02f5b9f76adb95667a0369418370aa81530c28064"
},
{
"msg": "12bb4666adc2cede1826b582085caed6fb64438a5462f74010eea04b4f2fb5fb",
"sig": "30450221008258561ae898aa8e689b6a8a878704020d1025d7ae835985eaac27a555996627022006bdaec9eaea8dc2eefcd197e1a10828e26f9114c394d1f2d161cfcc7e3d1cd401",
"privkey": "4fc83d5a7155af0810791a6db59e307295f0897682a1a6b958fd699f3ef9cb53"
},
{
"msg": "1ac99db7e7ef6ee4af2016dd0c71b2a6d2995c1a2029c13959ddea0a4af1e839",
"sig": "30440220110722d507a7da0dc7a520ce7efe0e1fb42790c00ee8d565e0c7c8c4292cbcea0220267ae97ea9a2b1ef08239553cef818f625ed1e3e87ef766e8b6063f21a9daf9901",
"privkey": "f1fcd239bad3e3ef1483e10f3753283b88df5b8603f9bab20d66e00e81cef441"
},
{
"msg": "b5d1b36d95311a86e450f507a0dea0805eaefb68c89f222d8a3d4761e5619b9d",
"sig": "3044022053a91f2c657aed63d265aa6249b3c0db90844210d828980b6ddf885b4e98b0840220325ba1809427c15527da92751f4fbe6e56230533ad7afccd91a244ff7c25ecb901",
"privkey": "ae74253a454718f1c08b4bc3b9673e2b084b1cd0b4c3bbc324da8329d5bced7c"
},
{
"msg": "fb710ffc70334a93c4052be5e229875f55aa3f3067e6c493d53f115e39ba387a",
"sig": "304502210099b8afbdecefb8e2b5a3e2acdb7fb28da7d7f24c6ed6eb88e43c423b67954ebf022050050a3e69fbdfa91fa16d9ad669720c65b2fabe7e011ecab9336e92d18be19401",
"privkey": "40e53957385d806936ffba31637c7bcbc353616d896b6cda0e20d56e16baabaa"
},
{
"msg": "b27b1bbaf48f7d3c38ce061542054b2fb19cce7a40a779253ece58169caa6efb",
"sig": "30450221009fccc94220c12ef508bfbe9a0d1a592875272e4213bdb78baa290d5a01054b1a02204101988977098b835b4b1ceff4e6af9925a92b7f879718a60340083679bbb63401",
"privkey": "67ff6b87850ab1fc1f8f7c0ddc606610fedd027e926fbed60f280abd2972a440"
},
{
"msg": "433955be0f609ee6685e49229652c1311b6141f4b85a4f018e2f9b2ac49a4b54",
"sig": "304402202ccf1a22e503d11bad88fb90da3a5b3547397de3f125b86334ead3497fcd1ca302207065bdd03323de65b784384926fb26f637094774837b8368f59a191cf50b6f9101",
"privkey": "7befa50da27667bc46825f960dec45e461940da6a2267d8da6ce4b04bf4888c4"
},
{
"msg": "577650e585efa3b2c2aa04f5c561306524178f0643c9208ec7034923a6949492",
"sig": "30450221008b75fcfac6277b160a555bbbb2dcb477c2509967946edfb0106f8d142fa1543c0220442de5a96c7e8f670398164a4380b97f8066304c62f5f7fef8b86e05941e94d301",
"privkey": "8cfe9d574c49070e41fc473352c4029547bba2299a2a61770fedb87d32de2edd"
},
{
"msg": "a2fc75d302dadb11fc4bce7bafeb90406b9a367e368d0cb7a885e0b96d695fa6",
"sig": "30450221009ab4c7be6d7bebfbb9bdafa5abd628c8874b56872d77d04171209e692128b7ba022048f66d9206126e8a2a48a8cacb44dc7a6a660d04998b3f6d07d88481e4f230b301",
"privkey": "a1ab7d29541f45b96ccb881522f7dd45901765ac1160ebbabc50e2947b8853ef"
},
{
"msg": "9acd7c5fedc120d69095eb7ce77684aae974cf7b48cfc806baece4dd812d560a",
"sig": "3045022100e8fb2e2817d7f481e059ccee51e8449f550f1488634ac012811aece52e5e23d502203d8d06125a037af6e32c0a0cd7032dbc12c7ca84f5d3952afb58857685c68fad01",
"privkey": "e2bccf63d91102cd90d519b18463ecdf41378c9f9b0e1d5a1ed58a837be11afa"
},
{
"msg": "23ecbc3ed373e19e84d3d8e6420613d6e759b3e5d606e6ba9700234beaa7ae8d",
"sig": "3044022013b03a0a39a56f9241b21ee74acf83d93b5b6a81bcf254f7558648e686fc300e022065a5999b37b2fd7294f853b5c312cbf62c12a1db58f0d95041e7b7dd157cce7f01",
"privkey": "61dc64fb0590b9615bd5f381b0a301316857dd32f0b214c2e814f35e5fe956f2"
},
{
"msg": "aea4c1124be7afa6c25af9f542b79997370ff6cd870e185a20c7be78c9c24b84",
"sig": "3045022100adac0cbb49e7d492b9f877a5f842860e0cbbce99fb4592558dee58f8e3cc44a4022074caa58d7edf18f2ed5c436930a5b8dd3a48a6024aa2c038b2f56c1187ab28b201",
"privkey": "0b31aea8e0af9a18f02e9cd4e06530e9ec9c4cab1e6a3bd52fdca5183617fc66"
},
{
"msg": "f793e37b0dc14ffae24d6e5a3477aaf23cc3bba1ca939ccd0c4a4bc3f1943e68",
"sig": "304402200096eeb7256f916c256ae3884df5416bfac00143bcfb46a501cc0eee45ee432602200ba266f42639556de6a0f7c9f0bc2ee14d80cc035965c7fad9bd57c04826684601",
"privkey": "3fe28fcb15f00c93c5d628b4ae942beb2fb73e5f2c28f05dfd98998824c115c9"
},
{
"msg": "85e774c6574ca6ae8f30af0ba108bbc487835a6ab9b9d7e00d17f1e710b3bde1",
"sig": "3045022100bb5a0cfb531d6bf5b817c1f6a17db02e7b592111a2a572a6ee4bf31e9de1ccd402202afab1acafd825fb8a51d801cb20564c67fa42a33afa5d7526f0d9f57535b5da01",
"privkey": "3902f9706403006e3fbc35d12b06fc78670509aa50b552544d708ab5dc5f5b79"
},
{
"msg": "671db247e553158156e7c670136e9fd299a9d1fc33c394ee593752b0a1cc1f03",
"sig": "304402206d9f228584074ab3eafccffe240a1fbb448e8125836461da7423def37313aa1802205d076e6066caab751e95323be6761215e2fc5b69f2c9392b571e66a8f12ce2cb01",
"privkey": "2bc7499a1da26f836ed93be9834f9cfef1120e9512f3bc90c6d57c3ce366c58d"
},
{
"msg": "d069674f48c2038bbb0dadcb18a9b18795eb71cc16cb34e91b4cbca86aec61d2",
"sig": "3045022100d1260fdebd27eed66d577b77a1f299cc42ac137227aa7730e2035077b71161da02204a8522a2f2eb8cc78e7ea11ad56f463f7d8f08c6e4e9a7db0cec3ad6779ff38d01",
"privkey": "0fc62bc36495f5f9b0d23145d0ee1983c29f822c7c60e22239959c13acec8da9"
},
{
"msg": "e9a4c69779c44c72858e580297452f3ed488849a0cf204d75de42e591844f008",
"sig": "3045022100849c6e7b4d66ac63540a2784620c43ac1b558f7a1432237965949be3624af1d10220674f15f7779e4f0677f4c4cf66f85a5f7ca6a8b966f17c05ac1dd38e4664f0d801",
"privkey": "1229ade4f8919c0e61a5221c6cc37e7a2da7dcfc22eaf6d58b8e995d38a830c0"
},
{
"msg": "183b7c41bb27526528ba72277a92ff7d39241539f6616f024e4389e76696db65",
"sig": "3045022100ba80e06c2a798b0dc206eb44b99703a31536ccc930eb0500a043f241aec21d1702200ce955a1627c9a073f8f49072afd5aa289e544bc90e5983b093c06c5c67e51a201",
"privkey": "08ece7a61cc766fee43dce42570d418d7509d63cc293a15e2292bef473e5c49a"
},
{
"msg": "a119183cedb4d2385c204482f6f6aad863947f4dc336810a2cd494d73a7d63e6",
"sig": "3045022100bd8fe449160c9ec8029bb6f554f225fa985db131e2a7f56cda04d48d7133f8c10220060a2e95874ffddee22ce3e1a47bf15360922c73fb7c2a9ffe267447bbbd24d301",
"privkey": "70ea418b73f35a4d5fa241c97661be9e88d4e773478fc9ad59602e0d18d7499b"
},
{
"msg": "e53804e86688bfb3e2d7a72d9a07d0b76c8d043472a70375f04bc26e5175d380",
"sig": "3044022076927896b56154a8eec11decbe729aa0a2543979cb388ceee3570b35e511e1ff0220730367ce5443b1522e61d990b5f0fe7c3e14d62fecf141d189da51285a65938e01",
"privkey": "4d2da431e0b77707cf388cc9d44f067d3fb82a3e544a436c2c94abfd0bd1a8eb"
},
{
"msg": "c0a7969a9bd9689925f5b801e3937772fce4c20a238acf58e6baa4ddd68f958e",
"sig": "30440220700c5e64229194d774b222c34e436673c69aa8f1c9a18865895c05fccd02bf3a0220384b60122c477d03bc5ecfae58908dfc195dd94f09ae7e2eb18e14d54314982901",
"privkey": "7253a7b52381bce33b2502dd8026c6c242f66d75dbef89c6e47e8983a373941e"
},
{
"msg": "d767a2f44d17543cb9833a4f5aa792f12064bcb1b7882feedd014cb9aeaba94c",
"sig": "3045022100d6cbcf05a476a5e05b92acf93c2ed41c97af666fc03f9a45e797af67f6f6eaf302202485861dd6538828e6ef0fe17f4e41c25053f4a2f28b017e181c0f364b44867f01",
"privkey": "90fb55d3cd1b87138b2983581f5f65efd7dc444c06438f492621e99311840805"
},
{
"msg": "47d6db6d8e2a9aae31ade5ae2b1ae6ed17c25b7b74be25fbb6ea590046cf2d97",
"sig": "3044022054d1dd346604659a1ae9905a375f52124c066938bdd19200aa6598fe3cda676202202671b0da6d94702269909d2481347c328d789d052ff43b6821686fa65117627101",
"privkey": "cdcf9bb9730b0b88669876bc0692393a5dabaa75f78ca68372098a81374dee4e"
},
{
"msg": "3e54cafef15a961d757071aee94b690280aad8201af7582aa81fafb64b748527",
"sig": "304402200e9cd509a33cc07318ac8e8c61c6e35a4825361bf255b47996ac6a6c45252a98022071092aee8df6e329303b5483c2e8fc6292b51df5e48ebef6548f043c11ad298201",
"privkey": "3b829c6c16002db5ba3323ac1ca6745cd1f6d1f67eb9c8f5f11b48df08d3fa75"
},
{
"msg": "ff7482425542c945e2b83931583e2f516682dd24b2bac632ce00b0bf95f3764a",
"sig": "304402204ac0df04b0b83d87938c7d9591095acdcb6e0c6edaeb99a0ea40a1951f77470102201a40cd8a308c3a752cfb8c3741d6fec79b410a6bc4a3c64c4c377ea5b9bfddbe01",
"privkey": "1c1d11ed9739251c3e065db25ac10fd6413a54d8f9e553be3c67f4eb86bbdb08"
},
{
"msg": "b5c1a15c2c219f845d5253f64947d49f94519a57aa484b6005517e0a8f933a58",
"sig": "3045022100c17a386ef1263ce5c1816e17504ccf8cbcdaf5f09ba00f141099c990ce2cc30002201d64bf0ad8da6d1b3fa02191145c19a94fb1011865933c2a8aaec4728fa5e06501",
"privkey": "df972b1d45f99fd4dbcb5e7354d6292b56b4a0f25f6432f9e1d7a318eecb2120"
},
{
"msg": "bd15aac26ece339e81248e364dcc66dcbaadd6bac3f94047d161f0e71f44758c",
"sig": "30440220035a4c4bb28381cb4ed4f6f5714cb34bab019339299212fcc86ae90f83725ea502204f63ae13c03dc80e320b4274f9bd403f4966fde7c89c21328264a6305ee8c42701",
"privkey": "66eaec33187b285b3c604973aaacab3ae8d383a075dfd996c4cc3ac4cd16d0fd"
},
{
"msg": "85fc198a649ee134d2116a2e0b189faf1a4d15c3afbb182033032f9ac322e1bd",
"sig": "3045022100aa128e5391a4bec3181d4a2127bd45fb38bc142993c967af8d7de33e90e3c03e022034eef4d80133c0002671027d55a1e10eaa12cd7e24f62d037077d1dd0e90775801",
"privkey": "5a6331ff79f2930f95df8a4747cdf56b0475eeae453af8da9257982f68fe66f4"
},
{
"msg": "8b66547716aee0c7bcce9bc93051bd2babbcefaaed51a94605506f6ab6492744",
"sig": "3045022100bdadcc9d82b6bce0d4c453001e06481ba48b92ea2a8ed81b9186ceb247a6bb1e022005b30ff42cb05defa923dc09a9727eea67cbbaf1b5e5b561ea4d854b67e8208001",
"privkey": "994f92698ef865cc782429f13e47040ece8b95a2d6dc30fd8c6a9188db655668"
},
{
"msg": "54fe0067ad6b4c7f4314802d40ab01896237015a466439d35ae986d81a6e5dbf",
"sig": "304402207b4f7d5bd15f520aabc9dabda7b8e73c660f10cca48c7e8ab5533a69137badc702204cd239932e7932d768bd65b55da2147ac527e61567f45bb14a953b0338211d3701",
"privkey": "21664545b76332766ec8959baedc77b7c842379d4400ce7f5f30417e5a1760e1"
},
{
"msg": "438bafa3b8dbead8b2eeac1b9fd6527b9510d56d5bc09a2ae2a51b67e64ea8a9",
"sig": "30450221009d3fa71c0f2f7b015fff020316c81476930ed4d4f6fe3fdc348cae358d70206302202e2e69d6ca559ee5eea309b72c13bf22c643660e27cc7799d99bc807a28fbe3401",
"privkey": "dba5a15df6ef7b060b7e9a4ee819a431bd2c3146430e5d90b15c8c7f34fc5d9f"
},
{
"msg": "2560b38e6a265f413fd762a88c4c492d46270b007e18cc844feb1dc06429a110",
"sig": "30440220361980512e7d7f6da1b37fb225c336801092d9ed05cf72b7723d7205de1b2baa02205cdf459c367d1f274b8067d008c533385c6c4330fd6376c4d330005312d4834b01",
"privkey": "d384f6a007cadf556e10c1bb59eb3e1e7dd940aae5ec6d305b64a6dbbe73ff64"
},
{
"msg": "bf1d36ee509e65f04d78be03e0fa0d5ceae29397a33d9efad93332cb47ba0155",
"sig": "3045022100be83c754e4426893b698437baef7fe19329df4cd46f5cf05b33ed1090be2b4fa02202986f9ceb8ea9d2a30876b2a3e4c2e495d9716cc21c66018c91726955ea4b82201",
"privkey": "7f2776e0a044ff802d622f6ac37637ae83b4e2d83dbbf83c681f3606c46a7a8e"
},
{
"msg": "fb75554ed0cc5485d2559c29f6510b6ef60dacb5f17d81564d25a87e79ac826e",
"sig": "304402207ab3815aae1a99a367489a31bf7a94661ee086e887641ebac2e455871994db3702204f6f8b7677bb30efb5c4602169f2541274b8f51e1938a2f84a828b9da0137ee201",
"privkey": "4c6f22a57c553e05a0a7a35adf46e1cb4c4d004a984e5af88bb2d2188ba7ab88"
},
{
"msg": "6d18019673f7a984b0a222b7299b35e61622681cad5161748040c5375c951505",
"sig": "3044022034375c54a58c8562889c8e41f9c299f7f85704459f8d11f317dd52038ce7e29d02203e8a421f7f4d9d3dbad692dc81ce89ae060b734a01e9c048526ffb0eee908edb01",
"privkey": "0c0b3289b2c6fc93986902fab4457f42d22b0b461c5e5a53a5ec727051586fa7"
},
{
"msg": "7e1e2a99702c16bed9055d399af557c2a63da0a5083292adeb3897af6b802564",
"sig": "3045022100c85073b669d65fa197cb73e4fc7a90c65b11cf195b8d718e998b22be071bd3c302207e7def3e6fe2e72aec48855ce06f9425c712fb874baa94484be96f9b9f472d3101",
"privkey": "4d1c0ae59c723633336f8dcc6bde9b358f9b75603e45168e406807212252b112"
},
{
"msg": "a33b04ec26e5cbc6558c43abeed149ae35391bcccef36b684d345ff13496ca9b",
"sig": "3045022100f09854120ef83925f0a865aed3b256c5f0efef8f35f2bcf91384545d4ab6315e02205e9ff2aba9fe7270a73281f176d4675163a26b52e71819ac18f001cd5c93225401",
"privkey": "b2eef7149d49c01b51ee926e926e2e26f73c25bbf74371c990617eef8b50ecfe"
},
{
"msg": "fa01a5e23fa06dd60c852d89edeb778f94ce904182a8b9d8d1ca9fa6634f9662",
"sig": "304402204cd469bb017d011fabb29cceb655148b0462c666dd940a2442176f4a02f5b02702207c64b92d62db3390facc8db753acbd05a9a1b63896ff4b27dbe47f256502bfad01",
"privkey": "7a572657b960cbeef0c13fd97855fd61147e896093d160fdb1191fe2849bf8e1"
},
{
"msg": "14a93f4e03431f95877f6dc9f41f59bc967686bc8401ae10527483e1cdcfebf0",
"sig": "3045022100e502a90aa2908a903d45d5077d718812fd7341b551519f96fa7af94e66f39ef902201bef0e0b54a6fbc28e011d8ecefd0f33f6c7283cc2227ae7ae847b12b873e01001",
"privkey": "d661888426cf1c65cba5f96ec26314b55f421cd447ced732809e32220f28c246"
},
{
"msg": "b6ec194ce825fc8ebee69325abfa2acb952d45495ab351455122d4901d4f64bb",
"sig": "304402205edce4c4ab58df2c58efeef2f12975a3a3ad38d6da9d4f18d76b086d5fc4d69d022074844f4cb83eae0aa01f409fbb27bccc32b44b0bca12b614831cfaea711edd9f01",
"privkey": "27cdce4f1e5ffa46fbbfe615bc1d1599db6869404714f0cc46300901b767383a"
},
{
"msg": "9b86e708eb9574a8c3ded5d3932a6de43ae4982dcbdca3269af14e967c639b7f",
"sig": "30440220557f81e8f67ed361d2289aec02013731f75248350ecec55ac8dfb14418da68c202202598c35a9c0e062bc48d1ccb9494630a5daae324595be83c473fbaf2b3e7bdd201",
"privkey": "8d6fa8a66bc4684b35d9eb3226d352c7300452dd9b3d548d7a2d947459bc5a0f"
},
{
"msg": "170a2926a37a37dbe2e406e2d5a3923973bae98e82ab55e26864a1dcf1785da1",
"sig": "3045022100fc7726b77976e58fd1f8a48c9232747edc40359eb1f6b393540608de72e2b4b5022005c22000c2c1c719c6f4f43ba81ba6ed4643a8645a34ec50619a4945849bd50a01",
"privkey": "339699b552be47df9e751d7bbd53fa052d953738d851741e656bba90de4a53b5"
},
{
"msg": "90de053a840eb83db882433d067a2451bfc81f58db606d4e411a6b8fd82c953a",
"sig": "3045022100ae765968d1add07797a390b99ddb7faad3451e922a2e8f38adee56c654a3274902201f992b0f3605c54a6ae60d8604c7260b9a4db93be2512ad64937be4f0b3ad55501",
"privkey": "8b0377d0b6e665a0c6072009b50044c6891cec9316bfac8fc9b6a5a34e4eabb1"
},
{
"msg": "38d14fe6dd85bdb8748f5cb23e1fb2e58df2e8bf841f1e1c68bd4d20dc94cfc5",
"sig": "30450221008e35cd8d034a2fc8234d9638f5baa6fe2bd96570df09b7b15ccd007f5c05a93e022041ae8101af3721d99668f87a743bad7bebfa3e0fbfb1a84d6e0f2e73e1d053a601",
"privkey": "6e99a1772417ee7deb91d0e3762d2642d7278f2f7431a4f659da50d43af879b8"
},
{
"msg": "00ed851dc354b6df5a3e3bab543ee399b02f3600c595aa3e5ca6a1483465b155",
"sig": "3045022100deeb14e5b93035c0658f20aa05b87cb132609978bfa5ec008a3ca9502961244102205d0aef23a1f146edcda709137a5c5a376bb0f75abd031ba12128c4578ab93d8401",
"privkey": "56580e7ac5163e4e6579ab0e772f2a3848a80af534588e70f230a18158953803"
},
{
"msg": "4d46ab40f75ab52c1fd8a7974e06ff684c01bf3e746977e811a1a442bf2912fd",
"sig": "3044022062aa9538861667b57609b750f7260df90373c01523b1341b7f841f3f53dafa0202200a3296141e23dec3292ae553a28c001efcdef18eca50ef09a0b4795b6d4b61b201",
"privkey": "3d38b60f2a844fb43dea0262aac32301ead58568074ca9915c6498155cb47f13"
},
{
"msg": "9dd253813dd4ea8902617a09cfdcf060dd062849b76f3c1e556500d13d77170f",
"sig": "3045022100dccc41da7fdac14735bb98a2c59aae91d26284244f4cbc0beedb7851172a444a02206c5ac076f60a7f5243ef4e1630c51f411a03cdf57049d4b92a055ff90160ce8101",
"privkey": "80ac1ff9b4219c1aea37fa937299dfa946e48d23c858d463eafa1bd8d986d9e8"
},
{
"msg": "c783fcc63873a8b39563fd0d39ded5453d9c7737e32a0946bc62ce4f6a4773bc",
"sig": "3045022100d782b60cca256c5b7918a62c3f6759588ed8bc3bad7b704dd8de3fe6e720a36802206d163563810897555f0a90c969d476f6c0452cc7a3027ab4ceaf8aafce1cb5a501",
"privkey": "527f7b367a63d977568bd25593860ae36bc3ba4b65f43b121f1af776c995d224"
},
{
"msg": "4519ef8ca61e50159ee43d921a679ca78ab70784167ebe656112c2017f1e2a8e",
"sig": "3045022100dd23d3fee7e8fc4bac8c82378aee98fd7d3efa9140f18c1949b83f13654a7f8202201aabe8f08204e36e414d2a1cc42d76a7ba46bc3e4907dddae30944f14107b17a01",
"privkey": "e13d124062e954974d5e5918bf1409a7a5d1d20ad4f4217006e2d5612a255da3"
},
{
"msg": "a3a2d23da4f1a6c4031879ba02e11952bd05209863f90907606615edc6dce871",
"sig": "3045022100983403797071adeae9cf36b3541580903d4fe20bbc29d7c85da3d5e86ebfbac202202b1cbdefdfa24e3c53b066b5bba6491f4117ab2b378c04552a4c1297d397670a01",
"privkey": "1f25a034e5df2a5ae72f91d63be72497c3a1df79300ce195ee73e4cfeeda37a6"
},
{
"msg": "0b34440573c1ea6ea03e4b5500307948698f229b5a1315f81a5c622fdf660ddf",
"sig": "3045022100a5a3d9ffc866c3a747ad2a015f306d8a6c98540c7622f2bd0409e7a909924a7402201d0606df93f8f423fc5559623a829ae81632c6205af9a69e86965b1aafe9f7f101",
"privkey": "2dfc3b63b1c8f04643f550281371a846a1d31fa651fb861f7e6ae9db88122041"
},
{
"msg": "88dde95676e529d3bd4422e8a50d106a4bbd465e8623b37d09228ff66c9dd275",
"sig": "30440220411a5d0613c89a246f08d1cf3db4b5d94b3c7de70a2464a0c6b930bd179db38702206253cc6df480e8fcc3716aa2e2c3cd10990fa73c6f2347e8aa7a499528ef2dec01",
"privkey": "d2f35b4f8e5f9db7e884ab4bcb64f84dc4d87a8d4b9055995df62b759e7ba4aa"
},
{
"msg": "3617b55b4aed94d2fddf0f96f9c8c9f4359f948a2b902b76f0d9474a9e549710",
"sig": "3045022100ae0f294fbc13c28259019d000a9a9817173febfb37fb0a273511add46af4226102202d2a8b8b0e058179a0baf190dc76f649075a8d3ab3832d3be859159cbe1a9ae701",
"privkey": "66dc7feb6d7c733005c5d8716b22f38819738bd1538a40f46205f3f3be191efc"
}
]
}

1749
tests/data/pubkey.json

File diff suppressed because it is too large

50
tests/samples.py

@ -1,50 +0,0 @@
PRIVATE_KEY_BYTES = b'\xc2\x8a\x9f\x80s\x8fw\rRx\x03\xa5f\xcfo\xc3\xed\xf6\xce\xa5\x86\xc4\xfcJR#\xa5\xady~\x1a\xc3'
PRIVATE_KEY_DER = (
b'0\x81\x84\x02\x01\x000\x10\x06\x07*\x86H\xce=\x02\x01\x06'
b'\x05+\x81\x04\x00\n\x04m0k\x02\x01\x01\x04 \xc2\x8a\x9f'
b'\x80s\x8fw\rRx\x03\xa5f\xcfo\xc3\xed\xf6\xce\xa5\x86\xc4'
b'\xfcJR#\xa5\xady~\x1a\xc3\xa1D\x03B\x00\x04=\\(u\xc9\xbd'
b"\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03\x9b\x1d\x93'"
b'\x82H\x91\x80C4v\xa45**\xdd\x00\xeb\xb0\xd5\xc9LQ[r\xeb'
b'\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3'
)
PRIVATE_KEY_HEX = 'c28a9f80738f770d527803a566cf6fc3edf6cea586c4fc4a5223a5ad797e1ac3'
PRIVATE_KEY_NUM = 87993618360805341115891506172036624893404292644470266399436498750715784469187
PRIVATE_KEY_PEM = (
b'-----BEGIN PRIVATE KEY-----\n'
b'MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgwoqfgHOPdw1SeAOlZs9v\n'
b'w+32zqWGxPxKUiOlrXl+GsOhRANCAAQ9XCh1yb0RaHWnGl22TP/LEzlrFj0Dmx2T\n'
b'J4JIkYBDNHakNSoq3QDrsNXJTFFbcusQ8f2PPwO0L0orJVv8mqnj\n'
b'-----END PRIVATE KEY-----\n'
)
PUBLIC_KEY_COMPRESSED = b"\x03=\\(u\xc9\xbd\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03\x9b\x1d\x93'\x82H\x91\x80C4"
PUBLIC_KEY_UNCOMPRESSED = (
b'\x04=\\(u\xc9\xbd\x11hu\xa7\x1a]\xb6L\xff\xcb\x139k\x16=\x03'
b"\x9b\x1d\x93'\x82H\x91\x80C4v\xa45**\xdd\x00\xeb\xb0\xd5\xc9"
b'LQ[r\xeb\x10\xf1\xfd\x8f?\x03\xb4/J+%[\xfc\x9a\xa9\xe3'
)
PUBLIC_KEY_X = 27753912938952041417634381842191885283234814940840273460372041880794577257268
PUBLIC_KEY_Y = 53663045980837260634637807506183816949039230809110041985901491152185762425315
MESSAGE = (
b'\xdfw\xeb)\t2R8\xda5\x02\xadE\xdd\xce\xd2\xe0\xb4\xf1\x81\xe7\xdf'
b':\xce\x82m\xcf\x99\xf3o\x9d\xe6\xfb\xe4\x98O\x88\xcfh\xbe\xfd\xc2'
b'{\xafm\xb3\xff\xb4QR\xffPu$\xfc>A\'\x03t\xc5\xf9\xd8\xf3I,\xaa"*'
b"\xd7q\xfe\xb7]\x11\xa9uB'd\x89\x03\'3\xb8/\x80\xa2#\x00\xa2\xfe"
b'\xff\xae\xb0\x86\xc1/ o\xc8]?\xa05L\xff8\x8az\x92\xc9\xab\x9fg0|'
b'\\5\x98\xfaG\x9b#\xec\x1a\xc5\x10\xd6\x08\x9c:\x01"\x0c\x812O/i'
b'\xc4WI\x0c\r\xd8\x81-m1_\x14]$\xf8\x16\xef\x1e\x1d\xb0"Q\x1a\xcf'
b'`R\xae\x0c"r2\x9a\xa3\xdb\xc4W}<c\xd8\x0e\xb5\x96\x99\x87\xdeU'
b'\x84\x1a?No\x10T\xf8\xb8\xd3\x18\xa4\xaf'
)
SIGNATURE = (
b'0E\x02!\x00\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13'
b"\xad`\xc1\x06[\xe0\x821\x96\xe29\x80'\x02 \r\x02\x13\xd2\xaf?\x92G"
b'\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad\xe4J\x9c-\n'
)
RECOVERABLE_SIGNATURE = (
b'\xee$\x1b\x0e@fa\xd4<\x17)\xa7\n\xd0\xd7\xef\x90\xcd\x13'
b"\xad`\xc1\x06[\xe0\x821\x96\xe29\x80'\r\x02\x13\xd2\xaf?"
b'\x92G\x80&8\x1cVz%2\xb0\x8a\xd0l\x0b4\x9c~\x93\x18\xad'
b'\xe4J\x9c-\n\x00'
)

53
tests/test_bench.py

@ -1,53 +0,0 @@
from coincurve import PrivateKey, PublicKey, verify_signature
from .samples import MESSAGE, PRIVATE_KEY_BYTES, PUBLIC_KEY_COMPRESSED, SIGNATURE
def test_verify_signature_util(benchmark):
benchmark(verify_signature, SIGNATURE, MESSAGE, PUBLIC_KEY_COMPRESSED)
def test_private_key_new(benchmark):
benchmark(PrivateKey)
def test_private_key_load(benchmark):
benchmark(PrivateKey, PRIVATE_KEY_BYTES)
def test_private_key_sign(benchmark):
private_key = PrivateKey(PRIVATE_KEY_BYTES)
benchmark(private_key.sign, MESSAGE)
def test_private_key_sign_recoverable(benchmark):
private_key = PrivateKey(PRIVATE_KEY_BYTES)
benchmark(private_key.sign_recoverable, MESSAGE)
def test_private_key_ecdh(benchmark):
private_key = PrivateKey(PRIVATE_KEY_BYTES)
benchmark(private_key.ecdh, PUBLIC_KEY_COMPRESSED)
def test_public_key_load(benchmark):
benchmark(PublicKey, PUBLIC_KEY_COMPRESSED)
def test_public_key_load_from_valid_secret(benchmark):
benchmark(PublicKey.from_valid_secret, PRIVATE_KEY_BYTES)
def test_public_key_format(benchmark):
public_key = PublicKey(PUBLIC_KEY_COMPRESSED)
benchmark(public_key.format)
def test_public_key_point(benchmark):
public_key = PublicKey(PUBLIC_KEY_COMPRESSED)
benchmark(public_key.point)
def test_public_key_verify(benchmark):
public_key = PublicKey(PUBLIC_KEY_COMPRESSED)
benchmark(public_key.verify, SIGNATURE, MESSAGE)

7
tests/test_ecdsa.py

@ -1,7 +0,0 @@
from coincurve.ecdsa import cdata_to_der, der_to_cdata
from .samples import SIGNATURE
def test_der():
assert cdata_to_der(der_to_cdata(SIGNATURE)) == SIGNATURE

148
tests/test_keys.py

@ -1,148 +0,0 @@
from hashlib import sha512
from os import urandom
import pytest
from coincurve.ecdsa import deserialize_recoverable, recover
from coincurve.keys import PrivateKey, PublicKey
from coincurve.utils import bytes_to_int, int_to_bytes_padded, verify_signature
from .samples import (
MESSAGE,
PRIVATE_KEY_BYTES,
PRIVATE_KEY_DER,
PRIVATE_KEY_HEX,
PRIVATE_KEY_NUM,
PRIVATE_KEY_PEM,
PUBLIC_KEY_COMPRESSED,
PUBLIC_KEY_UNCOMPRESSED,
PUBLIC_KEY_X,
PUBLIC_KEY_Y,
RECOVERABLE_SIGNATURE,
SIGNATURE,
)
G = PublicKey(
b'\x04y\xbef~\xf9\xdc\xbb\xacU\xa0b\x95\xce\x87\x0b\x07\x02\x9b'
b'\xfc\xdb-\xce(\xd9Y\xf2\x81[\x16\xf8\x17\x98H:\xdaw&\xa3\xc4e'
b']\xa4\xfb\xfc\x0e\x11\x08\xa8\xfd\x17\xb4H\xa6\x85T\x19\x9cG'
b'\xd0\x8f\xfb\x10\xd4\xb8'
)
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
class TestPrivateKey:
def test_public_key(self):
assert PrivateKey(PRIVATE_KEY_BYTES).public_key.format() == PUBLIC_KEY_COMPRESSED
def test_signature_correct(self):
private_key = PrivateKey()
public_key = private_key.public_key
message = urandom(200)
signature = private_key.sign(message)
assert verify_signature(signature, message, public_key.format(compressed=True))
assert verify_signature(signature, message, public_key.format(compressed=False))
def test_signature_deterministic(self):
assert PrivateKey(PRIVATE_KEY_BYTES).sign(MESSAGE) == SIGNATURE
def test_signature_invalid_hasher(self):
with pytest.raises(ValueError):
PrivateKey().sign(MESSAGE, lambda x: sha512(x).digest())
def test_signature_recoverable(self):
private_key = PrivateKey(PRIVATE_KEY_BYTES)
assert (
private_key.public_key.format()
== PublicKey(recover(MESSAGE, deserialize_recoverable(private_key.sign_recoverable(MESSAGE)))).format()
)
def test_to_hex(self):
assert PrivateKey(PRIVATE_KEY_BYTES).to_hex() == PRIVATE_KEY_HEX
def test_to_int(self):
assert PrivateKey(PRIVATE_KEY_BYTES).to_int() == PRIVATE_KEY_NUM
def test_to_pem(self):
assert PrivateKey(PRIVATE_KEY_BYTES).to_pem() == PRIVATE_KEY_PEM
def test_to_der(self):
assert PrivateKey(PRIVATE_KEY_BYTES).to_der() == PRIVATE_KEY_DER
def test_from_hex(self):
assert PrivateKey.from_hex(PRIVATE_KEY_HEX).secret == PRIVATE_KEY_BYTES
def test_from_int(self):
assert PrivateKey.from_int(PRIVATE_KEY_NUM).secret == PRIVATE_KEY_BYTES
def test_from_pem(self):
assert PrivateKey.from_pem(PRIVATE_KEY_PEM).secret == PRIVATE_KEY_BYTES
def test_from_der(self):
assert PrivateKey.from_der(PRIVATE_KEY_DER).secret == PRIVATE_KEY_BYTES
def test_ecdh(self):
a = PrivateKey()
b = PrivateKey()
assert a.ecdh(b.public_key.format()) == b.ecdh(a.public_key.format())
def test_add(self):
assert PrivateKey(b'\x01').add(b'\x09').to_int() == 10
def test_add_update(self):
private_key = PrivateKey(b'\x01')
new_private_key = private_key.add(b'\x09', update=True)
assert new_private_key.to_int() == 10
assert private_key is new_private_key
def test_multiply(self):
assert PrivateKey(b'\x05').multiply(b'\x05').to_int() == 25
def test_multiply_update(self):
private_key = PrivateKey(b'\x05')
new_private_key = private_key.multiply(b'\x05', update=True)
assert new_private_key.to_int() == 25
assert private_key is new_private_key
class TestPublicKey:
def test_from_secret(self):
assert PublicKey.from_secret(PRIVATE_KEY_BYTES).format() == PUBLIC_KEY_COMPRESSED
def test_from_point(self):
assert PublicKey.from_point(PUBLIC_KEY_X, PUBLIC_KEY_Y).format() == PUBLIC_KEY_COMPRESSED
def test_from_signature_and_message(self):
assert (
PublicKey.from_secret(PRIVATE_KEY_BYTES).format()
== PublicKey.from_signature_and_message(RECOVERABLE_SIGNATURE, MESSAGE).format()
)
def test_format(self):
assert PublicKey(PUBLIC_KEY_UNCOMPRESSED).format(compressed=True) == PUBLIC_KEY_COMPRESSED
assert PublicKey(PUBLIC_KEY_COMPRESSED).format(compressed=False) == PUBLIC_KEY_UNCOMPRESSED
def test_point(self):
assert PublicKey(PUBLIC_KEY_COMPRESSED).point() == (PUBLIC_KEY_X, PUBLIC_KEY_Y)
def test_verify(self):
public_key = PublicKey(PUBLIC_KEY_COMPRESSED)
assert public_key.verify(SIGNATURE, MESSAGE)
def test_transform(self):
x = urandom(32)
k = urandom(32)
point = G.multiply(x)
assert point.add(k) == G.multiply(int_to_bytes_padded((bytes_to_int(x) + bytes_to_int(k)) % n))
def test_combine(self):
a = PrivateKey().public_key
b = PrivateKey().public_key
assert PublicKey.combine_keys([a, b]) == a.combine([b])

106
tests/test_utils.py

@ -1,106 +0,0 @@
from os import urandom
import pytest
from coincurve.utils import (
GROUP_ORDER,
ZERO,
bytes_to_int,
chunk_data,
der_to_pem,
get_valid_secret,
int_to_bytes,
int_to_bytes_padded,
pad_scalar,
pem_to_der,
validate_secret,
verify_signature,
)
from .samples import MESSAGE, PRIVATE_KEY_DER, PUBLIC_KEY_COMPRESSED, PUBLIC_KEY_UNCOMPRESSED, SIGNATURE
class TestPadScalar:
def test_correct(self):
assert pad_scalar(b'\x01') == b'\x00' * 31 + b'\x01'
def test_pad_limit(self):
n = urandom(32)
assert len(pad_scalar(n)) == len(n)
def test_empty_scalar(self):
assert len(pad_scalar(b'')) == 32
def test_get_valid_secret():
secret = get_valid_secret()
assert len(secret) == 32 and ZERO < secret < GROUP_ORDER
class TestValidateSecret:
def test_valid(self):
secret = validate_secret(b'\x01')
assert len(secret) == 32 and ZERO < secret < GROUP_ORDER
def test_bytes_greater_than_group_order(self):
secret = (
b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
b'\xff\xff\xfe\xba\xae\xdc\xe6\xafH\xa0;\xbf\xd2^\x8d'
)
assert secret > GROUP_ORDER
secret = validate_secret(secret)
assert len(secret) == 32 and ZERO < secret < GROUP_ORDER
def test_out_of_range(self):
with pytest.raises(ValueError):
validate_secret(ZERO)
with pytest.raises(ValueError):
validate_secret(GROUP_ORDER)
def test_bytes_int_conversion():
bytestr = b'\x00' + urandom(31)
assert pad_scalar(int_to_bytes(bytes_to_int(bytestr))) == bytestr
def test_bytes_int_conversion_padded():
bytestr = b'\x00' + urandom(31)
assert int_to_bytes_padded(bytes_to_int(bytestr)) == bytestr
def test_der_conversion():
assert pem_to_der(der_to_pem(PRIVATE_KEY_DER)) == PRIVATE_KEY_DER
def test_verify_signature():
assert verify_signature(SIGNATURE, MESSAGE, PUBLIC_KEY_COMPRESSED)
assert verify_signature(SIGNATURE, MESSAGE, PUBLIC_KEY_UNCOMPRESSED)
def test_chunk_data():
assert list(chunk_data('4fadd1977328c11efc1c1d8a781aa6b9677984d3e0b', 2)) == [
'4f',
'ad',
'd1',
'97',
'73',
'28',
'c1',
'1e',
'fc',
'1c',
'1d',
'8a',
'78',
'1a',
'a6',
'b9',
'67',
'79',
'84',
'd3',
'e0',
'b',
]

95
tox.ini

@ -1,95 +0,0 @@
[tox]
skip_missing_interpreters = true
envlist =
3.7
3.8
3.9
3.10
pypy3
bench
lint
fmt
typing
docs
[testenv]
passenv = *
deps =
-rrequirements-dev.txt
commands =
python -c "import shutil; shutil.move('coincurve', '_coincurve')"
coverage run --parallel-mode -m pytest -v --benchmark-skip {posargs}
python -c "import shutil; shutil.move('_coincurve', 'coincurve')"
coverage combine
coverage report -m
[testenv:bench]
skip_install = true
envdir = {toxworkdir}/{env:PYTHON_VERSION:bench}
commands =
python -c "import shutil; shutil.move('coincurve', '_coincurve')"
pytest -v --benchmark-only --benchmark-sort=name --benchmark-cprofile=tottime
python -c "import shutil; shutil.move('_coincurve', 'coincurve')"
[testenv:lint]
envdir = {toxworkdir}/lint
skip_install = true
deps =
flake8>=3.9
flake8-bugbear>=20.1.4
flake8-quotes>=3.2.0
black>=21.12b0
isort[pyproject]>=5
commands =
flake8 .
black --check --diff .
isort --check-only --diff .
[testenv:fmt]
envdir = {[testenv:lint]envdir}
skip_install = true
deps = {[testenv:lint]deps}
commands =
isort .
black .
{[testenv:lint]commands}
[testenv:typing]
skip_install = true
deps =
mypy==0.790
commands =
mypy coincurve
[testenv:docs]
usedevelop = true
setenv =
; Pretty __repr__ for defaults of complex types
COINCURVE_BUILDING_DOCS=true
; Use a set timestamp for reproducible builds.
; See https://reproducible-builds.org/specs/source-date-epoch/
SOURCE_DATE_EPOCH=1580601600
deps =
mkdocs~=1.2.2
; theme
mkdocs-material~=7.3.1
; plugins
mkdocs-minify-plugin~=0.4.1
mkdocs-git-revision-date-localized-plugin~=0.10.0
mkdocstrings~=0.16.2
; Extensions
pymdown-extensions~=9.0
mkdocs-material-extensions~=1.0.3
mkpatcher~=1.0.2
; Necessary for syntax highlighting in code blocks
Pygments~=2.10.0
commands =
python -m mkdocs {posargs}
[testenv:docs-ci]
setenv = {[testenv:docs]setenv}
deps = {[testenv:docs]deps}
commands =
python -c "import shutil; shutil.move('coincurve', '_coincurve')"
{[testenv:docs]commands}
python -c "import shutil; shutil.move('_coincurve', 'coincurve')"

1
users/index.html

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save