mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Squashed 'src/dashbls/' changes from 22b066020c..9329803969
9329803969 wip: fix FromBytesUnchecked (#68) 767713de3d feat: js bindings in camel case (#66) 06df92693a chore(release): bump version (#64) 73593feefd fix: the JS bundle script and bindings (#47) 38a8f768c6 Merge pull request #61 from kittywhiskers/compat_support d9b375145e ci: ensure that CMakeFiles are compatible with LTS-bundled cmake 5ba1b520cc build: restore CMake 3.14.0 compatibility d1c1b66e5f backport: merge bls-signatures#332 (Python 3.11) git-subtree-dir: src/dashbls git-subtree-split: 9329803969fd325dc0d5c9029ab15669d658ed5d
This commit is contained in:
parent
8bf0c812f5
commit
c1992c149e
9
.github/workflows/build-binds.yml
vendored
9
.github/workflows/build-binds.yml
vendored
@ -24,14 +24,13 @@ jobs:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
golang: [ '1.17' ]
|
||||
python: ['3.7', '3.8', '3.9', '3.10']
|
||||
python: ['3.7', '3.8', '3.9', '3.10', '3.11']
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
- uses: chia-network/actions/setup-python@main
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
@ -60,9 +59,7 @@ jobs:
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -qq --yes snap libgmp-dev
|
||||
sudo apt-get remove --purge cmake -y
|
||||
sudo snap install cmake --classic
|
||||
sudo apt-get install -qq --yes valgrind libgmp-dev cmake
|
||||
hash -r
|
||||
cmake --version
|
||||
|
||||
|
6
.github/workflows/build-test.yaml
vendored
6
.github/workflows/build-test.yaml
vendored
@ -38,9 +38,7 @@ jobs:
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -qq --yes valgrind snap libgmp-dev libsodium-dev
|
||||
sudo apt-get remove --purge cmake -y
|
||||
sudo snap install cmake --classic
|
||||
sudo apt-get install -qq --yes valgrind libgmp-dev cmake
|
||||
hash -r
|
||||
cmake --version
|
||||
|
||||
@ -49,7 +47,7 @@ jobs:
|
||||
run: |
|
||||
ls -l
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.14
|
||||
brew install autoconf automake gmp
|
||||
brew install autoconf automake gmp pkg-config
|
||||
|
||||
- name: Build library using CMake
|
||||
if: startsWith(matrix.builder, 'cmake')
|
||||
|
33
.github/workflows/build-wheels.yml
vendored
33
.github/workflows/build-wheels.yml
vendored
@ -43,16 +43,34 @@ jobs:
|
||||
python:
|
||||
- major-dot-minor: '3.7'
|
||||
cibw-build: 'cp37-*'
|
||||
manylinux:
|
||||
arch: manylinux2014
|
||||
intel: manylinux2010
|
||||
matrix: '3.7'
|
||||
- major-dot-minor: '3.8'
|
||||
cibw-build: 'cp38-*'
|
||||
manylinux:
|
||||
arch: manylinux2014
|
||||
intel: manylinux2010
|
||||
matrix: '3.8'
|
||||
- major-dot-minor: '3.9'
|
||||
cibw-build: 'cp39-*'
|
||||
manylinux:
|
||||
arch: manylinux2014
|
||||
intel: manylinux2010
|
||||
matrix: '3.9'
|
||||
- major-dot-minor: '3.10'
|
||||
cibw-build: 'cp310-*'
|
||||
manylinux:
|
||||
arch: manylinux2014
|
||||
intel: manylinux2010
|
||||
matrix: '3.10'
|
||||
- major-dot-minor: '3.11'
|
||||
cibw-build: 'cp311-*'
|
||||
manylinux:
|
||||
arch: manylinux2014
|
||||
intel: manylinux2014
|
||||
matrix: '3.11'
|
||||
arch:
|
||||
- name: ARM
|
||||
matrix: arm
|
||||
@ -114,25 +132,24 @@ jobs:
|
||||
- name: Install pipx
|
||||
run: |
|
||||
pip install pipx
|
||||
|
||||
- name: Build and test
|
||||
uses: pypa/cibuildwheel@v2.7.0
|
||||
with:
|
||||
output-dir: dist
|
||||
env:
|
||||
CIBW_PRERELEASE_PYTHONS: True
|
||||
CIBW_BUILD_VERBOSITY_MACOS: 0
|
||||
CIBW_BUILD_VERBOSITY_LINUX: 0
|
||||
CIBW_BUILD_VERBOSITY_WINDOWS: 0
|
||||
CIBW_BUILD: ${{ matrix.python.cibw-build }}
|
||||
CIBW_SKIP: '*-manylinux_i686 *-win32 *-musllinux_*'
|
||||
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2010
|
||||
CIBW_ENVIRONMENT_LINUX: "PATH=/project/cmake-3.17.3-Linux-`uname -m`/bin:$PATH"
|
||||
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.python.manylinux['arm'] }}
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.python.manylinux['intel'] }}
|
||||
CIBW_ENVIRONMENT_LINUX: "PATH=/project/cmake-3.14.3-Linux-`uname -m`/bin:$PATH"
|
||||
CIBW_BEFORE_ALL_LINUX: >
|
||||
yum -y install epel-release
|
||||
&& echo "epel-release installed"
|
||||
&& yum -y install lzip
|
||||
&& echo "lzip installed"
|
||||
&& curl -L https://github.com/Kitware/CMake/releases/download/v3.17.3/cmake-3.17.3-Linux-`uname -m`.sh > cmake.sh
|
||||
&& curl -L https://github.com/Kitware/CMake/releases/download/v3.14.3/cmake-3.14.3-Linux-`uname -m`.sh > cmake.sh
|
||||
&& yes | sh cmake.sh | cat
|
||||
&& rm -f /usr/bin/cmake
|
||||
&& curl -L https://gmplib.org/download/gmp/gmp-6.2.1.tar.lz | tar x --lzip
|
||||
@ -176,6 +193,8 @@ jobs:
|
||||
&& cp {wheel} {dest_dir}
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
CIBW_TEST_COMMAND: py.test -v {project}/python-bindings/test.py
|
||||
run:
|
||||
pipx run --spec='cibuildwheel==2.9.0' cibuildwheel --output-dir dist 2>&1
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
|
@ -8,7 +8,6 @@ project(
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
|
||||
set(
|
||||
${PROJECT_NAME}_HEADERS
|
||||
catch2/catch.hpp
|
||||
@ -22,6 +21,11 @@ list(
|
||||
add_library(
|
||||
${PROJECT_NAME}
|
||||
INTERFACE
|
||||
)
|
||||
|
||||
target_sources(
|
||||
${PROJECT_NAME}
|
||||
INTERFACE
|
||||
"${${PROJECT_NAME}_HEADERS}"
|
||||
)
|
||||
|
||||
|
@ -41,7 +41,7 @@ class BLS {
|
||||
|
||||
static void SetSecureAllocator(Util::SecureAllocCallback allocCb, Util::SecureFreeCallback freeCb);
|
||||
|
||||
static void CheckRelicErrors();
|
||||
static void CheckRelicErrors(bool should_throw = true);
|
||||
};
|
||||
} // end namespace bls
|
||||
|
||||
|
@ -13,24 +13,26 @@ include_directories(
|
||||
file(GLOB_RECURSE WRAP_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/wrappers/*.h)
|
||||
file(GLOB_RECURSE WRAP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/wrappers/*.cpp)
|
||||
|
||||
add_executable(blsjs ${CMAKE_CURRENT_SOURCE_DIR}/jsbindings.cpp
|
||||
add_executable(blsjstmp ${CMAKE_CURRENT_SOURCE_DIR}/jsbindings.cpp
|
||||
${WRAP_HEADERS} ${WRAP_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/helpers.h ${CMAKE_CURRENT_SOURCE_DIR}/helpers.cpp
|
||||
)
|
||||
add_custom_target(install_npm_dependencies npm ci)
|
||||
add_dependencies(blsjs install_npm_dependencies)
|
||||
target_link_libraries(blsjs PRIVATE dashbls)
|
||||
add_dependencies(blsjstmp install_npm_dependencies)
|
||||
target_link_libraries(blsjstmp PRIVATE dashbls)
|
||||
|
||||
# Copy necessary files for the npm package
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/package.json package.json COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/package-lock.json package-lock.json COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/blsjs.d.ts blsjs.d.ts COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README.md README.md COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bundle_wasm_for_web.js bundle_wasm_for_web.js COPYONLY)
|
||||
|
||||
# Copy test files
|
||||
file(GLOB JS_BINDINGS_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/tests/ ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.js ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.ts)
|
||||
file(GLOB JS_BINDINGS_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/tests/ ${CMAKE_CURRENT_SOURCE_DIR}/tests/*)
|
||||
foreach(file ${JS_BINDINGS_TESTS})
|
||||
message(FILE ${file})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/${file} tests/${file} COPYONLY)
|
||||
endforeach()
|
||||
|
||||
set_target_properties(blsjs PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1")
|
||||
set_target_properties(blsjstmp PROPERTIES LINK_FLAGS "--bind -Oz --closure 1 -s MODULARIZE=1 -s NODEJS_CATCH_EXIT=1 -s NODEJS_CATCH_REJECTION=1")
|
||||
add_custom_command(TARGET blsjstmp POST_BUILD COMMAND npm run build:web)
|
||||
|
74
js-bindings/blsjs.d.ts
vendored
74
js-bindings/blsjs.d.ts
vendored
@ -1,95 +1,95 @@
|
||||
export declare class AugSchemeMPL {
|
||||
static sk_to_g1(sk: PrivateKey): G1Element;
|
||||
static key_gen(msg: Uint8Array): PrivateKey;
|
||||
static skToG1(sk: PrivateKey): G1Element;
|
||||
static keyGen(msg: Uint8Array): PrivateKey;
|
||||
static sign(sk: PrivateKey, msg: Uint8Array): G2Element;
|
||||
static sign_prepend(sk: PrivateKey, msg: Uint8Array, prependPk: G1Element): G2Element;
|
||||
static signPrepend(sk: PrivateKey, msg: Uint8Array, prependPk: G1Element): G2Element;
|
||||
static verify(pk: G1Element, msg: Uint8Array, sig: G2Element): boolean;
|
||||
static aggregate(g2Elements: G2Element[]): G2Element;
|
||||
static aggregate_verify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static derive_child_sk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_sk_unhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_pk_unhardened(pk: G1Element, index: number): G1Element;
|
||||
static aggregateVerify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static deriveChildSk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildSkUnhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildPkUnhardened(pk: G1Element, index: number): G1Element;
|
||||
}
|
||||
|
||||
export declare class BasicSchemeMPL {
|
||||
static sk_to_g1(sk: PrivateKey): G1Element;
|
||||
static key_gen(msg: Uint8Array): PrivateKey;
|
||||
static skToG1(sk: PrivateKey): G1Element;
|
||||
static keyGen(msg: Uint8Array): PrivateKey;
|
||||
static sign(sk: PrivateKey, msg: Uint8Array): G2Element;
|
||||
static verify(pk: G1Element, msg: Uint8Array, sig: G2Element): boolean;
|
||||
static aggregate(g2Elements: G2Element[]): G2Element;
|
||||
static aggregate_verify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static derive_child_sk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_sk_unhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_pk_unhardened(pk: G1Element, index: number): G1Element;
|
||||
static aggregateVerify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static deriveChildSk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildSkUnhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildPkUnhardened(pk: G1Element, index: number): G1Element;
|
||||
}
|
||||
|
||||
export declare class PopSchemeMPL {
|
||||
static sk_to_g1(sk: PrivateKey): G1Element;
|
||||
static key_gen(msg: Uint8Array): PrivateKey;
|
||||
static skToG1(sk: PrivateKey): G1Element;
|
||||
static keyGen(msg: Uint8Array): PrivateKey;
|
||||
static sign(sk: PrivateKey, msg: Uint8Array): G2Element;
|
||||
static verify(pk: G1Element, msg: Uint8Array, sig: G2Element): boolean;
|
||||
static aggregate(g2Elements: G2Element[]): G2Element;
|
||||
static aggregate_verify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static derive_child_sk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_sk_unhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static derive_child_pk_unhardened(pk: G1Element, index: number): G1Element;
|
||||
static pop_prove(sk: PrivateKey): G2Element;
|
||||
static pop_verify(pk: G1Element, signatureProof: G2Element): boolean;
|
||||
static fast_aggregate_verify(pks: G1Element[], msg: Uint8Array, sig: G2Element): boolean;
|
||||
static aggregateVerify(pks: G1Element[], msgs: Uint8Array[], sig: G2Element): boolean;
|
||||
static deriveChildSk(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildSkUnhardened(sk: PrivateKey, index: number): PrivateKey;
|
||||
static deriveChildPkUnhardened(pk: G1Element, index: number): G1Element;
|
||||
static popProve(sk: PrivateKey): G2Element;
|
||||
static popVerify(pk: G1Element, signatureProof: G2Element): boolean;
|
||||
static fastAggregateVerify(pks: G1Element[], msg: Uint8Array, sig: G2Element): boolean;
|
||||
}
|
||||
|
||||
export declare class G1Element {
|
||||
static SIZE: number;
|
||||
static from_bytes(bytes: Uint8Array): G1Element;
|
||||
static fromBytes(bytes: Uint8Array): G1Element;
|
||||
static generator(): G2Element;
|
||||
serialize(): Uint8Array;
|
||||
negate(): G1Element;
|
||||
deepcopy(): G1Element;
|
||||
get_fingerprint(): number;
|
||||
getFingerprint(): number;
|
||||
add(el: G1Element): G1Element;
|
||||
mul(bn: Bignum): G1Element;
|
||||
equal_to(el: G1Element): boolean;
|
||||
equalTo(el: G1Element): boolean;
|
||||
delete(): void;
|
||||
}
|
||||
|
||||
export declare class G2Element {
|
||||
static SIZE: number;
|
||||
static from_bytes(bytes: Uint8Array): G2Element;
|
||||
static from_g2(sk: G2Element): G2Element;
|
||||
static aggregate_sigs(sigs: G2Element[]): G2Element;
|
||||
static fromBytes(bytes: Uint8Array): G2Element;
|
||||
static fromG2(sk: G2Element): G2Element;
|
||||
static aggregateSigs(sigs: G2Element[]): G2Element;
|
||||
static generator(): G2Element;
|
||||
serialize(): Uint8Array;
|
||||
negate(): G2Element;
|
||||
deepcopy(): G2Element;
|
||||
add(el: G2Element): G2Element;
|
||||
mul(bn: Bignum): G2Element;
|
||||
equal_to(el: G2Element): boolean;
|
||||
equalTo(el: G2Element): boolean;
|
||||
delete(): void;
|
||||
}
|
||||
|
||||
export declare class PrivateKey {
|
||||
static PRIVATE_KEY_SIZE: number;
|
||||
static from_bytes(bytes: Uint8Array, modOrder: boolean): PrivateKey;
|
||||
static fromBytes(bytes: Uint8Array, modOrder: boolean): PrivateKey;
|
||||
static aggregate(pks: PrivateKey[]): PrivateKey;
|
||||
deepcopy(): PrivateKey;
|
||||
serialize(): Uint8Array;
|
||||
get_g1(): G1Element;
|
||||
get_g2(): G2Element;
|
||||
mul_g1(el: G1Element): G1Element;
|
||||
mul_g2(el: G2Element): G2Element;
|
||||
equal_to(key: PrivateKey): boolean;
|
||||
getG1(): G1Element;
|
||||
getG2(): G2Element;
|
||||
mulG1(el: G1Element): G1Element;
|
||||
mulG2(el: G2Element): G2Element;
|
||||
equalTo(key: PrivateKey): boolean;
|
||||
delete(): void;
|
||||
}
|
||||
|
||||
export declare class Bignum {
|
||||
static from_string(s: string, radix: number): Bignum;
|
||||
static fromString(s: string, radix: number): Bignum;
|
||||
toString(radix: number): string;
|
||||
delete(): void;
|
||||
}
|
||||
|
||||
export declare class Util {
|
||||
static hash256(msg: Uint8Array): Uint8Array;
|
||||
static hex_str(msg: Uint8Array): string;
|
||||
static hexStr(msg: Uint8Array): string;
|
||||
}
|
||||
|
||||
export interface ModuleInstance {
|
||||
|
37
js-bindings/bundle_wasm_for_web.js
Normal file
37
js-bindings/bundle_wasm_for_web.js
Normal file
@ -0,0 +1,37 @@
|
||||
// The code manipulation from this file needs to be done for Chrome, as
|
||||
// it requires wasm to be loaded asynchronously, and it doesn't
|
||||
// work when bundling complex projects. With this solution, wasm is
|
||||
// included right into the bundle itself in a form of base64 string
|
||||
// and compiled asynchronously, just as Chrome requires
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const outputPath = './blsjs.js';
|
||||
|
||||
const wasm = fs.readFileSync('./blsjstmp.wasm');
|
||||
const wasmBase = wasm.toString('base64');
|
||||
|
||||
const codeToPrepend = `
|
||||
if (typeof window === "object") {
|
||||
var buf = Buffer.from("${wasmBase}", "base64");
|
||||
var blob = new Blob([buf], { type: "application/wasm" });
|
||||
var wasmUrl = URL.createObjectURL(blob);
|
||||
}
|
||||
`;
|
||||
|
||||
const originalSourceCode = fs.readFileSync('./blsjstmp.js', 'utf-8');
|
||||
const modifiedSourceCode = originalSourceCode
|
||||
.replace(/fetch\(.,/g, "fetch(wasmUrl,");
|
||||
|
||||
const modifiedSourceBuffer = Buffer.from(modifiedSourceCode, 'utf-8');
|
||||
|
||||
const bundleFileDescriptor = fs.openSync(outputPath, 'w+');
|
||||
|
||||
const bufferToPrepend = Buffer.from(codeToPrepend);
|
||||
|
||||
fs.writeSync(bundleFileDescriptor, bufferToPrepend, 0, bufferToPrepend.length, 0);
|
||||
fs.writeSync(bundleFileDescriptor, modifiedSourceBuffer, 0, modifiedSourceBuffer.length, bufferToPrepend.length);
|
||||
|
||||
fs.close(bundleFileDescriptor, (err) => {
|
||||
if (err) throw err;
|
||||
});
|
@ -22,92 +22,88 @@ using namespace emscripten;
|
||||
namespace js_wrappers {
|
||||
EMSCRIPTEN_BINDINGS(blsjs) {
|
||||
class_<AugSchemeMPLWrapper>("AugSchemeMPL")
|
||||
.class_function("sk_to_g1", &AugSchemeMPLWrapper::SkToG1)
|
||||
.class_function("key_gen", &AugSchemeMPLWrapper::KeyGen)
|
||||
.class_function("skToG1", &AugSchemeMPLWrapper::SkToG1)
|
||||
.class_function("keyGen", &AugSchemeMPLWrapper::KeyGen)
|
||||
.class_function("sign", &AugSchemeMPLWrapper::Sign)
|
||||
.class_function("sign_prepend", &AugSchemeMPLWrapper::SignPrepend)
|
||||
.class_function("signPrepend", &AugSchemeMPLWrapper::SignPrepend)
|
||||
.class_function("verify", &AugSchemeMPLWrapper::Verify)
|
||||
.class_function("aggregate", &AugSchemeMPLWrapper::Aggregate)
|
||||
.class_function("aggregate_verify", &AugSchemeMPLWrapper::AggregateVerify)
|
||||
.class_function("derive_child_sk", &AugSchemeMPLWrapper::DeriveChildSk)
|
||||
.class_function("derive_child_sk_unhardened", &AugSchemeMPLWrapper::DeriveChildSkUnhardened)
|
||||
.class_function("derive_child_pk_unhardened", &AugSchemeMPLWrapper::DeriveChildPkUnhardened);
|
||||
.class_function("aggregateVerify", &AugSchemeMPLWrapper::AggregateVerify)
|
||||
.class_function("deriveChildSk", &AugSchemeMPLWrapper::DeriveChildSk)
|
||||
.class_function("deriveChildSkUnhardened", &AugSchemeMPLWrapper::DeriveChildSkUnhardened)
|
||||
.class_function("deriveChildPkUnhardened", &AugSchemeMPLWrapper::DeriveChildPkUnhardened);
|
||||
|
||||
class_<SchemeMPLWrapper<BasicSchemeMPL>>("BasicSchemeMPL")
|
||||
.class_function("sk_to_g1", &SchemeMPLWrapper<BasicSchemeMPL>::SkToG1)
|
||||
.class_function("key_gen", &SchemeMPLWrapper<BasicSchemeMPL>::KeyGen)
|
||||
.class_function("skToG1", &SchemeMPLWrapper<BasicSchemeMPL>::SkToG1)
|
||||
.class_function("keyGen", &SchemeMPLWrapper<BasicSchemeMPL>::KeyGen)
|
||||
.class_function("sign", &SchemeMPLWrapper<BasicSchemeMPL>::Sign)
|
||||
.class_function("verify", &SchemeMPLWrapper<BasicSchemeMPL>::Verify)
|
||||
.class_function("aggregate", &SchemeMPLWrapper<BasicSchemeMPL>::Aggregate)
|
||||
.class_function("aggregate_verify", &SchemeMPLWrapper<BasicSchemeMPL>::AggregateVerify)
|
||||
.class_function("derive_child_sk", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSk)
|
||||
.class_function("derive_child_sk_unhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSkUnhardened)
|
||||
.class_function("derive_child_pk_unhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildPkUnhardened);
|
||||
.class_function("aggregateVerify", &SchemeMPLWrapper<BasicSchemeMPL>::AggregateVerify)
|
||||
.class_function("deriveChildSk", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSk)
|
||||
.class_function("deriveChildSkUnhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildSkUnhardened)
|
||||
.class_function("deriveChildPkUnhardened", &SchemeMPLWrapper<BasicSchemeMPL>::DeriveChildPkUnhardened);
|
||||
|
||||
class_<PopSchemeMPLWrapper>("PopSchemeMPL")
|
||||
.class_function("sk_to_g1", &PopSchemeMPLWrapper::SkToG1)
|
||||
.class_function("key_gen", &PopSchemeMPLWrapper::KeyGen)
|
||||
.class_function("skToG1", &PopSchemeMPLWrapper::SkToG1)
|
||||
.class_function("keyGen", &PopSchemeMPLWrapper::KeyGen)
|
||||
.class_function("sign", &PopSchemeMPLWrapper::Sign)
|
||||
.class_function("verify", &PopSchemeMPLWrapper::Verify)
|
||||
.class_function("aggregate", &PopSchemeMPLWrapper::Aggregate)
|
||||
.class_function("aggregate_verify", &PopSchemeMPLWrapper::AggregateVerify)
|
||||
.class_function("derive_child_sk", &PopSchemeMPLWrapper::DeriveChildSk)
|
||||
.class_function("derive_child_sk_unhardened", &PopSchemeMPLWrapper::DeriveChildSkUnhardened)
|
||||
.class_function("derive_child_pk_unhardened", &PopSchemeMPLWrapper::DeriveChildPkUnhardened)
|
||||
.class_function("pop_prove", &PopSchemeMPLWrapper::PopProve)
|
||||
.class_function("pop_verify", &PopSchemeMPLWrapper::PopVerify)
|
||||
.class_function("fast_aggregate_verify", &PopSchemeMPLWrapper::FastAggregateVerify);
|
||||
.class_function("aggregateVerify", &PopSchemeMPLWrapper::AggregateVerify)
|
||||
.class_function("deriveChildSk", &PopSchemeMPLWrapper::DeriveChildSk)
|
||||
.class_function("deriveChildSkUnhardened", &PopSchemeMPLWrapper::DeriveChildSkUnhardened)
|
||||
.class_function("deriveChildPkUnhardened", &PopSchemeMPLWrapper::DeriveChildPkUnhardened)
|
||||
.class_function("popProve", &PopSchemeMPLWrapper::PopProve)
|
||||
.class_function("popVerify", &PopSchemeMPLWrapper::PopVerify)
|
||||
.class_function("fastAggregateVerify", &PopSchemeMPLWrapper::FastAggregateVerify);
|
||||
|
||||
|
||||
class_<G1ElementWrapper>("G1Element")
|
||||
.class_property("SIZE", &G1ElementWrapper::SIZE)
|
||||
.constructor<>()
|
||||
.class_function("fromBytes", &G1ElementWrapper::FromBytes) // Not removing this for compatibility
|
||||
.class_function("from_bytes", &G1ElementWrapper::FromBytes)
|
||||
.class_function("fromBytes", &G1ElementWrapper::FromBytes)
|
||||
.class_function("generator", &G2ElementWrapper::Generator)
|
||||
.function("serialize", &G1ElementWrapper::Serialize)
|
||||
.function("negate", &G1ElementWrapper::Negate)
|
||||
.function("deepcopy", &G1ElementWrapper::Deepcopy)
|
||||
.function("get_fingerprint", &G1ElementWrapper::GetFingerprint)
|
||||
.function("getFingerprint", &G1ElementWrapper::GetFingerprint)
|
||||
.function("add", &G1ElementWrapper::Add)
|
||||
.function("mul", &G1ElementWrapper::Mul)
|
||||
.function("equal_to", &G1ElementWrapper::EqualTo);
|
||||
.function("equalTo", &G1ElementWrapper::EqualTo);
|
||||
|
||||
class_<G2ElementWrapper>("G2Element")
|
||||
.class_property("SIZE", &G2ElementWrapper::SIZE)
|
||||
.constructor<>()
|
||||
.class_function("fromBytes", &G2ElementWrapper::FromBytes) // Not removing this for compatibility
|
||||
.class_function("from_bytes", &G2ElementWrapper::FromBytes)
|
||||
.class_function("from_g2", &G2ElementWrapper::FromG2Element)
|
||||
.class_function("aggregate_sigs", &G2ElementWrapper::AggregateSigs)
|
||||
.class_function("fromBytes", &G2ElementWrapper::FromBytes)
|
||||
.class_function("fromG2", &G2ElementWrapper::FromG2Element)
|
||||
.class_function("aggregateSigs", &G2ElementWrapper::AggregateSigs)
|
||||
.class_function("generator", &G2ElementWrapper::Generator)
|
||||
.function("serialize", &G2ElementWrapper::Serialize)
|
||||
.function("negate", &G2ElementWrapper::Negate)
|
||||
.function("deepcopy", &G2ElementWrapper::Deepcopy)
|
||||
.function("add", &G2ElementWrapper::Add)
|
||||
.function("mul", &G2ElementWrapper::Mul)
|
||||
.function("equal_to", &G2ElementWrapper::EqualTo);
|
||||
.function("equalTo", &G2ElementWrapper::EqualTo);
|
||||
|
||||
class_<PrivateKeyWrapper>("PrivateKey")
|
||||
.class_property("PRIVATE_KEY_SIZE", &PrivateKeyWrapper::PRIVATE_KEY_SIZE)
|
||||
.class_function("fromBytes", &PrivateKeyWrapper::FromBytes) // Not removing this for compatibility
|
||||
.class_function("from_bytes", &PrivateKeyWrapper::FromBytes)
|
||||
.class_function("fromBytes", &PrivateKeyWrapper::FromBytes)
|
||||
.class_function("aggregate", &PrivateKeyWrapper::Aggregate)
|
||||
.function("deepcopy", &PrivateKeyWrapper::Deepcopy)
|
||||
.function("serialize", &PrivateKeyWrapper::Serialize)
|
||||
.function("get_g1", &PrivateKeyWrapper::GetG1)
|
||||
.function("get_g2", &PrivateKeyWrapper::GetG2)
|
||||
.function("mul_g1", &PrivateKeyWrapper::MulG1)
|
||||
.function("mul_g2", &PrivateKeyWrapper::MulG2)
|
||||
.function("equal_to", &PrivateKeyWrapper::EqualTo);
|
||||
.function("getG1", &PrivateKeyWrapper::GetG1)
|
||||
.function("getG2", &PrivateKeyWrapper::GetG2)
|
||||
.function("mulG1", &PrivateKeyWrapper::MulG1)
|
||||
.function("mulG2", &PrivateKeyWrapper::MulG2)
|
||||
.function("equalTo", &PrivateKeyWrapper::EqualTo);
|
||||
|
||||
class_<BignumWrapper>("Bignum")
|
||||
.class_function("fromString", &BignumWrapper::FromString) // Not removing this for compatibility
|
||||
.class_function("from_string", &BignumWrapper::FromString)
|
||||
.class_function("fromString", &BignumWrapper::FromString)
|
||||
.function("toString", &BignumWrapper::ToString);
|
||||
|
||||
class_<UtilWrapper>("Util")
|
||||
.class_function("hash256", &UtilWrapper::Hash256)
|
||||
.class_function("hex_str", &UtilWrapper::HexStr);
|
||||
.class_function("hexStr", &UtilWrapper::HexStr);
|
||||
};
|
||||
} // namespace js_wrappers
|
||||
|
4474
js-bindings/package-lock.json
generated
4474
js-bindings/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,28 +1,31 @@
|
||||
{
|
||||
"name": "bls-signatures",
|
||||
"version": "0.2.1-beta.0",
|
||||
"name": "@dashevo/bls",
|
||||
"version": "1.0.0-beta.3",
|
||||
"description": "The most advanced BLS library for JavaScript",
|
||||
"main": "blsjs.js",
|
||||
"types": "blsjs.d.ts",
|
||||
"files": [
|
||||
"blsjs.js",
|
||||
"blsjs.wasm",
|
||||
"blsjstmp.wasm",
|
||||
"blsjs.d.ts"
|
||||
],
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"scripts": {
|
||||
"build:web": "node bundle_wasm_for_web.js",
|
||||
"test": "npm run test:node && npm run test:browser",
|
||||
"test:typings": "tsc --esModuleInterop ./tests/typings.spec.ts",
|
||||
"test:node": "npm run test:typings && mocha ./tests/*.spec.js",
|
||||
"test:browser": "npm run test:typings && ./node_modules/.bin/karma start ./tests/karma.conf.js --single-run"
|
||||
"test:typings": "tsc ./tests/typings.spec.ts",
|
||||
"test:node": "mocha ./tests/*.spec.js",
|
||||
"test:browser": "npm run test:typings && karma start ./tests/karma.conf.js --single-run",
|
||||
"webpack": "webpack --config=./webpack.config.js",
|
||||
"rollup": "rollup -c"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:Chia-Network/bls-signatures.git"
|
||||
"url": "git@github.com:dashpay/bls-signatures.git"
|
||||
},
|
||||
"homepage": "https://github.com/Chia-Network/bls-signatures/tree/master/js-bindings",
|
||||
"homepage": "https://github.com/dashpay/bls-signatures/tree/main/js-bindings",
|
||||
"author": {
|
||||
"name": "Anton Suprunchuk",
|
||||
"email": "antouhou@gmail.com",
|
||||
|
@ -56,8 +56,8 @@ describe('PrivateKey', () => {
|
||||
const message1 = Uint8Array.from([1, 65, 254, 88, 90, 45, 22]);
|
||||
|
||||
const seed = Uint8Array.from([28, 20, 102, 229, 1, 157]);
|
||||
const sk1 = AugSchemeMPL.key_gen(getPkSeed());
|
||||
const pk1 = AugSchemeMPL.sk_to_g1(sk1);
|
||||
const sk1 = AugSchemeMPL.keyGen(getPkSeed());
|
||||
const pk1 = AugSchemeMPL.skToG1(sk1);
|
||||
const sig1 = AugSchemeMPL.sign(sk1, message1);
|
||||
|
||||
assert(AugSchemeMPL.verify(pk1, message1, sig1));
|
||||
@ -67,7 +67,7 @@ describe('PrivateKey', () => {
|
||||
it('Should create a private key from a seed', () => {
|
||||
const {AugSchemeMPL, PrivateKey} = blsSignatures;
|
||||
|
||||
const pk = AugSchemeMPL.key_gen(getPkSeed());
|
||||
const pk = AugSchemeMPL.keyGen(getPkSeed());
|
||||
assert(pk instanceof PrivateKey);
|
||||
assert.deepStrictEqual(pk.serialize(), getPkBuffer());
|
||||
});
|
||||
@ -77,14 +77,14 @@ describe('PrivateKey', () => {
|
||||
it('Should create a private key from a Buffer', () => {
|
||||
const {PrivateKey, Util} = blsSignatures;
|
||||
|
||||
const pk = PrivateKey.from_bytes(getPkBuffer(), false);
|
||||
const pk = PrivateKey.fromBytes(getPkBuffer(), false);
|
||||
assert(pk instanceof PrivateKey);
|
||||
assert.deepStrictEqual(pk.serialize(), getPkBuffer());
|
||||
});
|
||||
it('Should create a private key from a Uint8Array', () => {
|
||||
const {PrivateKey, Util} = blsSignatures;
|
||||
|
||||
const pk = PrivateKey.from_bytes(getPkUint8Array(), false);
|
||||
const pk = PrivateKey.fromBytes(getPkUint8Array(), false);
|
||||
assert(pk instanceof PrivateKey);
|
||||
assert.deepStrictEqual(pk.serialize(), getPkBuffer());
|
||||
});
|
||||
@ -94,7 +94,7 @@ describe('PrivateKey', () => {
|
||||
it('Should serialize key to a Buffer', () => {
|
||||
const {AugSchemeMPL, PrivateKey} = blsSignatures;
|
||||
|
||||
const pk = AugSchemeMPL.key_gen(getPkSeed());
|
||||
const pk = AugSchemeMPL.keyGen(getPkSeed());
|
||||
const serialized = pk.serialize();
|
||||
assert(serialized instanceof Uint8Array);
|
||||
assert.deepStrictEqual(serialized, getPkBuffer());
|
||||
@ -106,7 +106,7 @@ describe('PrivateKey', () => {
|
||||
const {AugSchemeMPL, PrivateKey, G2Element} = blsSignatures;
|
||||
|
||||
const pk = PrivateKey.fromBytes(getPkBuffer(), false);
|
||||
const pubkey = AugSchemeMPL.sk_to_g1(pk);
|
||||
const pubkey = AugSchemeMPL.skToG1(pk);
|
||||
const message = 'Hello world';
|
||||
const messageBuffer = Uint8Array.from(Buffer.from(message, 'utf8'));
|
||||
const signature = AugSchemeMPL.sign(pk, messageBuffer);
|
||||
@ -119,10 +119,10 @@ describe('PrivateKey', () => {
|
||||
it('Should return a public key with a verifiable fingerprint', () => {
|
||||
const {AugSchemeMPL, PrivateKey, G1Element} = blsSignatures;
|
||||
|
||||
const pk = AugSchemeMPL.key_gen(getPkSeed());
|
||||
const publicKey = AugSchemeMPL.sk_to_g1(pk);
|
||||
const pk = AugSchemeMPL.keyGen(getPkSeed());
|
||||
const publicKey = AugSchemeMPL.skToG1(pk);
|
||||
assert(publicKey instanceof G1Element);
|
||||
assert.strictEqual(publicKey.get_fingerprint(), getSeedAndFinferprint().fingerprint);
|
||||
assert.strictEqual(publicKey.getFingerprint(), getSeedAndFinferprint().fingerprint);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -41,11 +41,11 @@ before((done) => {
|
||||
});
|
||||
|
||||
describe('G1Element', () => {
|
||||
describe('.from_bytes', () => {
|
||||
describe('.fromBytes', () => {
|
||||
it('Should create a public key from bytes', () => {
|
||||
const {G1Element, Util} = blsSignatures;
|
||||
|
||||
const pk = G1Element.from_bytes(getPublicKeyFixture().buffer);
|
||||
const pk = G1Element.fromBytes(getPublicKeyFixture().buffer);
|
||||
assert(pk instanceof G1Element);
|
||||
});
|
||||
});
|
||||
@ -54,12 +54,12 @@ describe('G1Element', () => {
|
||||
it('Should aggregate keys if keys array contains more than one key', () => {
|
||||
const {G1Element} = blsSignatures;
|
||||
|
||||
const pks = getPublicKeysArray().map(buf => G1Element.from_bytes(buf));
|
||||
let first_pk = pks[0];
|
||||
const pks = getPublicKeysArray().map(buf => G1Element.fromBytes(buf));
|
||||
let firstPk = pks[0];
|
||||
for (var i = 1; i < pks.length; i++) {
|
||||
first_pk = first_pk.add(pks[i]);
|
||||
firstPk = firstPk.add(pks[i]);
|
||||
}
|
||||
assert(first_pk instanceof G1Element);
|
||||
assert(firstPk instanceof G1Element);
|
||||
});
|
||||
});
|
||||
|
||||
@ -67,7 +67,7 @@ describe('G1Element', () => {
|
||||
it('Should serialize key to the same buffer', () => {
|
||||
const {G1Element} = blsSignatures;
|
||||
|
||||
const pk = G1Element.from_bytes(getPublicKeyFixture().buffer);
|
||||
const pk = G1Element.fromBytes(getPublicKeyFixture().buffer);
|
||||
const serialized = pk.serialize();
|
||||
assert.deepStrictEqual(Buffer.from(serialized).toString('hex'), getPublicKeyFixtureHex());
|
||||
});
|
||||
@ -77,8 +77,8 @@ describe('G1Element', () => {
|
||||
it('Should get correct fingerprint', () => {
|
||||
const {G1Element} = blsSignatures;
|
||||
|
||||
const pk = G1Element.from_bytes(getPublicKeyFixture().buffer);
|
||||
const fingerprint = pk.get_fingerprint();
|
||||
const pk = G1Element.fromBytes(getPublicKeyFixture().buffer);
|
||||
const fingerprint = pk.getFingerprint();
|
||||
assert.strictEqual(fingerprint, getPublicKeyFixture().fingerprint);
|
||||
});
|
||||
});
|
||||
|
@ -38,13 +38,13 @@ describe('Signature', () => {
|
||||
const seed2 = makehash(Uint8Array.from([3, 4, 5, 6, 7]));
|
||||
const seed3 = makehash(Uint8Array.from([4, 5, 6, 7, 8]));
|
||||
|
||||
const privateKey1 = BasicSchemeMPL.key_gen(seed1);
|
||||
const privateKey2 = BasicSchemeMPL.key_gen(seed2);
|
||||
const privateKey3 = BasicSchemeMPL.key_gen(seed3);
|
||||
const privateKey1 = BasicSchemeMPL.keyGen(seed1);
|
||||
const privateKey2 = BasicSchemeMPL.keyGen(seed2);
|
||||
const privateKey3 = BasicSchemeMPL.keyGen(seed3);
|
||||
|
||||
const publicKey1 = BasicSchemeMPL.sk_to_g1(privateKey1);
|
||||
const publicKey2 = BasicSchemeMPL.sk_to_g1(privateKey2);
|
||||
const publicKey3 = BasicSchemeMPL.sk_to_g1(privateKey3);
|
||||
const publicKey1 = BasicSchemeMPL.skToG1(privateKey1);
|
||||
const publicKey2 = BasicSchemeMPL.skToG1(privateKey2);
|
||||
const publicKey3 = BasicSchemeMPL.skToG1(privateKey3);
|
||||
|
||||
const sig1 = BasicSchemeMPL.sign(privateKey1, message);
|
||||
const sig2 = BasicSchemeMPL.sign(privateKey2, message);
|
||||
@ -89,14 +89,14 @@ describe('Signature', () => {
|
||||
it('Should aggregate signature', () => {
|
||||
const {AugSchemeMPL, G2Element, PrivateKey} = blsSignatures;
|
||||
|
||||
const sk = AugSchemeMPL.key_gen(makehash(Uint8Array.from([1, 2, 3])));
|
||||
const pk = AugSchemeMPL.sk_to_g1(sk);
|
||||
const sk = AugSchemeMPL.keyGen(makehash(Uint8Array.from([1, 2, 3])));
|
||||
const pk = AugSchemeMPL.skToG1(sk);
|
||||
const msg1 = Uint8Array.from([3, 4, 5]);
|
||||
const msg2 = Uint8Array.from([6, 7, 8]);
|
||||
const sig1 = AugSchemeMPL.sign(sk, msg1);
|
||||
const sig2 = AugSchemeMPL.sign(sk, msg2);
|
||||
const aggregatedSig = G2Element.aggregate_sigs([sig1, sig2]);
|
||||
assert.strictEqual(AugSchemeMPL.aggregate_verify([pk, pk], [msg1, msg2], aggregatedSig), true);
|
||||
const aggregatedSig = G2Element.aggregateSigs([sig1, sig2]);
|
||||
assert.strictEqual(AugSchemeMPL.aggregateVerify([pk, pk], [msg1, msg2], aggregatedSig), true);
|
||||
|
||||
sk.delete();
|
||||
pk.delete();
|
||||
@ -109,7 +109,7 @@ describe('Signature', () => {
|
||||
it('Should serialize signature to Buffer', () => {
|
||||
const {AugSchemeMPL, G2Element, PrivateKey} = blsSignatures;
|
||||
|
||||
const sk = AugSchemeMPL.key_gen(makehash(Uint8Array.from([1, 2, 3, 4, 5])));
|
||||
const sk = AugSchemeMPL.keyGen(makehash(Uint8Array.from([1, 2, 3, 4, 5])));
|
||||
const sig = AugSchemeMPL.sign(sk, Uint8Array.from([100, 2, 254, 88, 90, 45, 23]));
|
||||
assert(sig instanceof G2Element);
|
||||
assert.deepStrictEqual(Buffer.from(sig.serialize()).toString('hex'), getSignatureHex());
|
||||
@ -125,15 +125,15 @@ describe('Signature', () => {
|
||||
const message = Uint8Array.from(Buffer.from('Message'));
|
||||
const seed1 = makehash(Buffer.from([1, 2, 3, 4, 5]));
|
||||
const seed2 = makehash(Buffer.from([1, 2, 3, 4, 6]));
|
||||
const sk1 = AugSchemeMPL.key_gen(seed1);
|
||||
const sk2 = AugSchemeMPL.key_gen(seed2);
|
||||
const pk1 = AugSchemeMPL.sk_to_g1(sk1);
|
||||
const pk2 = AugSchemeMPL.sk_to_g1(sk2);
|
||||
const sk1 = AugSchemeMPL.keyGen(seed1);
|
||||
const sk2 = AugSchemeMPL.keyGen(seed2);
|
||||
const pk1 = AugSchemeMPL.skToG1(sk1);
|
||||
const pk2 = AugSchemeMPL.skToG1(sk2);
|
||||
const sig1 = AugSchemeMPL.sign(sk1, message);
|
||||
const sig2 = AugSchemeMPL.sign(sk2, message);
|
||||
const sig = AugSchemeMPL.aggregate([sig1, sig2]);
|
||||
|
||||
assert(AugSchemeMPL.aggregate_verify([pk1, pk2], [message, message], sig));
|
||||
assert(AugSchemeMPL.aggregateVerify([pk1, pk2], [message, message], sig));
|
||||
|
||||
sk1.delete();
|
||||
sk2.delete();
|
||||
@ -149,8 +149,8 @@ describe('Signature', () => {
|
||||
const message1 = Uint8Array.from(Buffer.from('Message'));
|
||||
const message2 = Uint8Array.from(Buffer.from('Nessage'));
|
||||
const seed = makehash(Buffer.from([1, 2, 3, 4, 5]));
|
||||
const sk = AugSchemeMPL.key_gen(seed);
|
||||
const pk = AugSchemeMPL.sk_to_g1(sk);
|
||||
const sk = AugSchemeMPL.keyGen(seed);
|
||||
const pk = AugSchemeMPL.skToG1(sk);
|
||||
const sig = AugSchemeMPL.sign(sk, message1);
|
||||
assert.strictEqual(AugSchemeMPL.verify(pk, message2, sig), false);
|
||||
|
||||
|
@ -50,7 +50,7 @@ blsjs().then((blsjs) => {
|
||||
Util
|
||||
} = blsjs;
|
||||
|
||||
function test_schemes() {
|
||||
function testSchemes() {
|
||||
var seedArray = [
|
||||
0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6,
|
||||
220, 18, 102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22
|
||||
@ -59,8 +59,8 @@ blsjs().then((blsjs) => {
|
||||
|
||||
const msg = Buffer.from([100, 2, 254, 88, 90, 45, 23]);
|
||||
const msg2 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
const sk = BasicSchemeMPL.key_gen(seed);
|
||||
const pk = sk.get_g1();
|
||||
const sk = BasicSchemeMPL.keyGen(seed);
|
||||
const pk = sk.getG1();
|
||||
|
||||
//assert(sk == PrivateKey.fromBytes(sk.serialize(), false));
|
||||
//assert(pk == G1Element.fromBytes(pk.serialize()));
|
||||
@ -72,49 +72,49 @@ blsjs().then((blsjs) => {
|
||||
});
|
||||
|
||||
var seed = Buffer.concat([Buffer.from([1]), seed.slice(1)]);
|
||||
const sk1 = BasicSchemeMPL.key_gen(seed);
|
||||
const pk1 = sk1.get_g1();
|
||||
const sk1 = BasicSchemeMPL.keyGen(seed);
|
||||
const pk1 = sk1.getG1();
|
||||
var seed = Buffer.concat([Buffer.from([2]), seed.slice(1)]);
|
||||
const sk2 = BasicSchemeMPL.key_gen(seed);
|
||||
const pk2 = sk2.get_g1();
|
||||
const sk2 = BasicSchemeMPL.keyGen(seed);
|
||||
const pk2 = sk2.getG1();
|
||||
|
||||
[BasicSchemeMPL, AugSchemeMPL, PopSchemeMPL].map((Scheme) => {
|
||||
// Aggregate same message
|
||||
const agg_pk = pk1.add(pk2);
|
||||
const aggPk = pk1.add(pk2);
|
||||
var sig1, sig2;
|
||||
if (Scheme === AugSchemeMPL) {
|
||||
sig1 = Scheme.sign_prepend(sk1, msg, agg_pk);
|
||||
sig2 = Scheme.sign_prepend(sk2, msg, agg_pk);
|
||||
sig1 = Scheme.signPrepend(sk1, msg, aggPk);
|
||||
sig2 = Scheme.signPrepend(sk2, msg, aggPk);
|
||||
} else {
|
||||
sig1 = Scheme.sign(sk1, msg);
|
||||
sig2 = Scheme.sign(sk2, msg);
|
||||
}
|
||||
|
||||
var agg_sig = Scheme.aggregate([sig1, sig2]);
|
||||
assert(Scheme.verify(agg_pk, msg, agg_sig));
|
||||
var aggSig = Scheme.aggregate([sig1, sig2]);
|
||||
assert(Scheme.verify(aggPk, msg, aggSig));
|
||||
|
||||
// Aggregate different message
|
||||
sig1 = Scheme.sign(sk1, msg)
|
||||
sig2 = Scheme.sign(sk2, msg2)
|
||||
agg_sig = Scheme.aggregate([sig1, sig2])
|
||||
assert(Scheme.aggregate_verify([pk1, pk2], [msg, msg2], agg_sig));
|
||||
aggSig = Scheme.aggregate([sig1, sig2])
|
||||
assert(Scheme.aggregateVerify([pk1, pk2], [msg, msg2], aggSig));
|
||||
|
||||
// HD keys
|
||||
const child = Scheme.derive_child_sk(sk1, 123);
|
||||
const childU = Scheme.derive_child_sk_unhardened(sk1, 123);
|
||||
const childUPk = Scheme.derive_child_pk_unhardened(pk1, 123);
|
||||
const child = Scheme.deriveChildSk(sk1, 123);
|
||||
const childU = Scheme.deriveChildSkUnhardened(sk1, 123);
|
||||
const childUPk = Scheme.deriveChildPkUnhardened(pk1, 123);
|
||||
|
||||
const sig_child = Scheme.sign(child, msg);
|
||||
assert(Scheme.verify(child.get_g1(), msg, sig_child));
|
||||
const sigChild = Scheme.sign(child, msg);
|
||||
assert(Scheme.verify(child.getG1(), msg, sigChild));
|
||||
|
||||
const sigU_child = Scheme.sign(childU, msg);
|
||||
assert(Scheme.verify(childUPk, msg, sigU_child));
|
||||
const sigUChild = Scheme.sign(childU, msg);
|
||||
assert(Scheme.verify(childUPk, msg, sigUChild));
|
||||
});
|
||||
}
|
||||
|
||||
function test_vectors_invalid() {
|
||||
function testVectorsInvalid() {
|
||||
// Invalid inputs from https://github.com/algorand/bls_sigs_ref/blob/master/python-impl/serdesZ.py
|
||||
const invalid_inputs_1 = [
|
||||
const invalidInputs1 = [
|
||||
// infinity points: too short
|
||||
"c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
// infinity points: not all zeros
|
||||
@ -131,7 +131,7 @@ blsjs().then((blsjs) => {
|
||||
// invalid elm of Fp --- equal to p (must be strictly less)
|
||||
"9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
|
||||
]
|
||||
const invalid_inputs_2 = [
|
||||
const invalidInputs2 = [
|
||||
// infinity points: too short
|
||||
"c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
// infinity points: not all zeros
|
||||
@ -151,36 +151,36 @@ blsjs().then((blsjs) => {
|
||||
"9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
|
||||
];
|
||||
|
||||
let g1_exn_count = 0;
|
||||
let g2_exn_count = 0;
|
||||
let g1ExnCount = 0;
|
||||
let g2ExnCount = 0;
|
||||
|
||||
invalid_inputs_1.map((s) => {
|
||||
invalidInputs1.map((s) => {
|
||||
const bytes_ = binascii.unhexlify(s);
|
||||
try {
|
||||
const g1 = G1Element(bytes_);
|
||||
console.log(`Failed to disallow creation of G1 element for string ${s}`);
|
||||
assert(false);
|
||||
} catch(e) {
|
||||
g1_exn_count++;
|
||||
g1ExnCount++;
|
||||
}
|
||||
});
|
||||
|
||||
invalid_inputs_2.map((s) => {
|
||||
invalidInputs2.map((s) => {
|
||||
const bytes_ = binascii.unhexlify(s);
|
||||
try {
|
||||
const g2 = G2Element(bytes_);
|
||||
console.log(`Failed to disallow creation of G2 element for string ${s}`);
|
||||
assert(false);
|
||||
} catch(e) {
|
||||
g2_exn_count++;
|
||||
g2ExnCount++;
|
||||
}
|
||||
});
|
||||
|
||||
assert(g1_exn_count == invalid_inputs_1.length);
|
||||
assert(g2_exn_count == invalid_inputs_2.length);
|
||||
assert(g1ExnCount == invalidInputs1.length);
|
||||
assert(g2ExnCount == invalidInputs2.length);
|
||||
}
|
||||
|
||||
function test_vectors_valid() {
|
||||
function testVectorsValid() {
|
||||
// The following code was used to generate these vectors
|
||||
//
|
||||
// from py_ecc.bls import (
|
||||
@ -191,8 +191,8 @@ blsjs().then((blsjs) => {
|
||||
//
|
||||
// secret1 = bytes([1] * 32)
|
||||
// secret2 = bytes([x * 314159 % 256 for x in range(32)])
|
||||
// sk1 = int.from_bytes(secret1, 'big')
|
||||
// sk2 = int.from_bytes(secret2, 'big')
|
||||
// sk1 = int.fromBytes(secret1, 'big')
|
||||
// sk2 = int.fromBytes(secret2, 'big')
|
||||
// msg = bytes([3, 1, 4, 1, 5, 9])
|
||||
// pk1 = G2Basic.SkToPk(sk1)
|
||||
// pk2 = G2Basic.SkToPk(sk2)
|
||||
@ -207,15 +207,15 @@ blsjs().then((blsjs) => {
|
||||
//
|
||||
// Javascript version converts these strings to binascii
|
||||
|
||||
const ref_sig1Basic = bytes('96ba34fac33c7f129d602a0bc8a3d43f9abc014eceaab7359146b4b150e57b808645738f35671e9e10e0d862a30cab70074eb5831d13e6a5b162d01eebe687d0164adbd0a864370a7c222a2768d7704da254f1bf1823665bc2361f9dd8c00e99');
|
||||
const ref_sig2Basic = bytes('a402790932130f766af11ba716536683d8c4cfa51947e4f9081fedd692d6dc0cac5b904bee5ea6e25569e36d7be4ca59069a96e34b7f700758b716f9494aaa59a96e74d14a3b552a9a6bc129e717195b9d6006fd6d5cef4768c022e0f7316abf');
|
||||
const ref_sigABasic = bytes('987cfd3bcd62280287027483f29c55245ed831f51dd6bd999a6ff1a1f1f1f0b647778b0167359c71505558a76e158e66181ee5125905a642246b01e7fa5ee53d68a4fe9bfb29a8e26601f0b9ad577ddd18876a73317c216ea61f430414ec51c5');
|
||||
const ref_sig1Aug = bytes('8180f02ccb72e922b152fcedbe0e1d195210354f70703658e8e08cbebf11d4970eab6ac3ccf715f3fb876df9a9797abd0c1af61aaeadc92c2cfe5c0a56c146cc8c3f7151a073cf5f16df38246724c4aed73ff30ef5daa6aacaed1a26ecaa336b');
|
||||
const ref_sig2Aug = bytes('99111eeafb412da61e4c37d3e806c6fd6ac9f3870e54da9222ba4e494822c5b7656731fa7a645934d04b559e9261b86201bbee57055250a459a2da10e51f9c1a6941297ffc5d970a557236d0bdeb7cf8ff18800b08633871a0f0a7ea42f47480');
|
||||
const ref_sigAAug = bytes('8c5d03f9dae77e19a5945a06a214836edb8e03b851525d84b9de6440e68fc0ca7303eeed390d863c9b55a8cf6d59140a01b58847881eb5af67734d44b2555646c6616c39ab88d253299acc1eb1b19ddb9bfcbe76e28addf671d116c052bb1847');
|
||||
const ref_sig1Pop = bytes('9550fb4e7f7e8cc4a90be8560ab5a798b0b23000b6a54a2117520210f986f3f281b376f259c0b78062d1eb3192b3d9bb049f59ecc1b03a7049eb665e0df36494ae4cb5f1136ccaeefc9958cb30c3333d3d43f07148c386299a7b1bfc0dc5cf7c');
|
||||
const ref_sig2Pop = bytes('a69036bc11ae5efcbf6180afe39addde7e27731ec40257bfdc3c37f17b8df68306a34ebd10e9e32a35253750df5c87c2142f8207e8d5654712b4e554f585fb6846ff3804e429a9f8a1b4c56b75d0869ed67580d789870babe2c7c8a9d51e7b2a');
|
||||
const ref_sigAPop = bytes('a4ea742bcdc1553e9ca4e560be7e5e6c6efa6a64dddf9ca3bb2854233d85a6aac1b76ec7d103db4e33148b82af9923db05934a6ece9a7101cd8a9d47ce27978056b0f5900021818c45698afdd6cf8a6b6f7fee1f0b43716f55e413d4b87a6039');
|
||||
const refSig1Basic = bytes('96ba34fac33c7f129d602a0bc8a3d43f9abc014eceaab7359146b4b150e57b808645738f35671e9e10e0d862a30cab70074eb5831d13e6a5b162d01eebe687d0164adbd0a864370a7c222a2768d7704da254f1bf1823665bc2361f9dd8c00e99');
|
||||
const refSig2Basic = bytes('a402790932130f766af11ba716536683d8c4cfa51947e4f9081fedd692d6dc0cac5b904bee5ea6e25569e36d7be4ca59069a96e34b7f700758b716f9494aaa59a96e74d14a3b552a9a6bc129e717195b9d6006fd6d5cef4768c022e0f7316abf');
|
||||
const refSigABasic = bytes('987cfd3bcd62280287027483f29c55245ed831f51dd6bd999a6ff1a1f1f1f0b647778b0167359c71505558a76e158e66181ee5125905a642246b01e7fa5ee53d68a4fe9bfb29a8e26601f0b9ad577ddd18876a73317c216ea61f430414ec51c5');
|
||||
const refSig1Aug = bytes('8180f02ccb72e922b152fcedbe0e1d195210354f70703658e8e08cbebf11d4970eab6ac3ccf715f3fb876df9a9797abd0c1af61aaeadc92c2cfe5c0a56c146cc8c3f7151a073cf5f16df38246724c4aed73ff30ef5daa6aacaed1a26ecaa336b');
|
||||
const refSig2Aug = bytes('99111eeafb412da61e4c37d3e806c6fd6ac9f3870e54da9222ba4e494822c5b7656731fa7a645934d04b559e9261b86201bbee57055250a459a2da10e51f9c1a6941297ffc5d970a557236d0bdeb7cf8ff18800b08633871a0f0a7ea42f47480');
|
||||
const refSigAAug = bytes('8c5d03f9dae77e19a5945a06a214836edb8e03b851525d84b9de6440e68fc0ca7303eeed390d863c9b55a8cf6d59140a01b58847881eb5af67734d44b2555646c6616c39ab88d253299acc1eb1b19ddb9bfcbe76e28addf671d116c052bb1847');
|
||||
const refSig1Pop = bytes('9550fb4e7f7e8cc4a90be8560ab5a798b0b23000b6a54a2117520210f986f3f281b376f259c0b78062d1eb3192b3d9bb049f59ecc1b03a7049eb665e0df36494ae4cb5f1136ccaeefc9958cb30c3333d3d43f07148c386299a7b1bfc0dc5cf7c');
|
||||
const refSig2Pop = bytes('a69036bc11ae5efcbf6180afe39addde7e27731ec40257bfdc3c37f17b8df68306a34ebd10e9e32a35253750df5c87c2142f8207e8d5654712b4e554f585fb6846ff3804e429a9f8a1b4c56b75d0869ed67580d789870babe2c7c8a9d51e7b2a');
|
||||
const refSigAPop = bytes('a4ea742bcdc1553e9ca4e560be7e5e6c6efa6a64dddf9ca3bb2854233d85a6aac1b76ec7d103db4e33148b82af9923db05934a6ece9a7101cd8a9d47ce27978056b0f5900021818c45698afdd6cf8a6b6f7fee1f0b43716f55e413d4b87a6039');
|
||||
|
||||
const secret1 = Buffer.from(repeat(32,1));
|
||||
const secret2 = Buffer.from(range(32).map((x) => x * 314159 % 256));
|
||||
@ -233,18 +233,18 @@ blsjs().then((blsjs) => {
|
||||
const sig2Pop = PopSchemeMPL.sign(sk2, msg)
|
||||
const sigAPop = PopSchemeMPL.aggregate([sig1Pop, sig2Pop])
|
||||
|
||||
assert(Buffer.from(sig1Basic.serialize()).equals(ref_sig1Basic));
|
||||
assert(Buffer.from(sig2Basic.serialize()).equals(ref_sig2Basic));
|
||||
assert(Buffer.from(sigABasic.serialize()).equals(ref_sigABasic));
|
||||
assert(Buffer.from(sig1Aug.serialize()).equals(ref_sig1Aug));
|
||||
assert(Buffer.from(sig2Aug.serialize()).equals(ref_sig2Aug));
|
||||
assert(Buffer.from(sigAAug.serialize()).equals(ref_sigAAug));
|
||||
assert(Buffer.from(sig1Pop.serialize()).equals(ref_sig1Pop));
|
||||
assert(Buffer.from(sig2Pop.serialize()).equals(ref_sig2Pop));
|
||||
assert(Buffer.from(sigAPop.serialize()).equals(ref_sigAPop));
|
||||
assert(Buffer.from(sig1Basic.serialize()).equals(refSig1Basic));
|
||||
assert(Buffer.from(sig2Basic.serialize()).equals(refSig2Basic));
|
||||
assert(Buffer.from(sigABasic.serialize()).equals(refSigABasic));
|
||||
assert(Buffer.from(sig1Aug.serialize()).equals(refSig1Aug));
|
||||
assert(Buffer.from(sig2Aug.serialize()).equals(refSig2Aug));
|
||||
assert(Buffer.from(sigAAug.serialize()).equals(refSigAAug));
|
||||
assert(Buffer.from(sig1Pop.serialize()).equals(refSig1Pop));
|
||||
assert(Buffer.from(sig2Pop.serialize()).equals(refSig2Pop));
|
||||
assert(Buffer.from(sigAPop.serialize()).equals(refSigAPop));
|
||||
}
|
||||
|
||||
function test_readme() {
|
||||
function testReadme() {
|
||||
let seed = Buffer.from(
|
||||
[
|
||||
0,
|
||||
@ -281,8 +281,8 @@ blsjs().then((blsjs) => {
|
||||
22,
|
||||
]
|
||||
);
|
||||
let sk = AugSchemeMPL.key_gen(seed);
|
||||
let pk = sk.get_g1();
|
||||
let sk = AugSchemeMPL.keyGen(seed);
|
||||
let pk = sk.getG1();
|
||||
|
||||
const message = Buffer.from([1, 2, 3, 4, 5]);
|
||||
let signature = AugSchemeMPL.sign(sk, message);
|
||||
@ -290,107 +290,107 @@ blsjs().then((blsjs) => {
|
||||
let ok = AugSchemeMPL.verify(pk, message, signature);
|
||||
assert(ok);
|
||||
|
||||
const sk_bytes = sk.serialize(); // 32 bytes
|
||||
const pk_bytes = pk.serialize(); // 48 bytes
|
||||
const signature_bytes = signature.serialize(); // 96 bytes
|
||||
const skBytes = sk.serialize(); // 32 bytes
|
||||
const pkBytes = pk.serialize(); // 48 bytes
|
||||
const signatureBytes = signature.serialize(); // 96 bytes
|
||||
|
||||
console.log(Buffer.from(sk_bytes).toString('hex'), Buffer.from(pk_bytes).toString('hex'), Buffer.from(signature_bytes).toString('hex'));
|
||||
console.log(Buffer.from(skBytes).toString('hex'), Buffer.from(pkBytes).toString('hex'), Buffer.from(signatureBytes).toString('hex'));
|
||||
|
||||
sk = PrivateKey.fromBytes(sk_bytes, false);
|
||||
pk = G1Element.fromBytes(pk_bytes);
|
||||
signature = G2Element.fromBytes(signature_bytes);
|
||||
sk = PrivateKey.fromBytes(skBytes, false);
|
||||
pk = G1Element.fromBytes(pkBytes);
|
||||
signature = G2Element.fromBytes(signatureBytes);
|
||||
|
||||
seed = Buffer.concat([Buffer.from([1]), seed.slice(1)]);
|
||||
const sk1 = AugSchemeMPL.key_gen(seed);
|
||||
const sk1 = AugSchemeMPL.keyGen(seed);
|
||||
seed = Buffer.concat([Buffer.from([2]), seed.slice(1)]);
|
||||
const sk2 = AugSchemeMPL.key_gen(seed);
|
||||
const sk2 = AugSchemeMPL.keyGen(seed);
|
||||
const message2 = Buffer.from([1, 2, 3, 4, 5, 6, 7]);
|
||||
|
||||
const pk1 = sk1.get_g1();
|
||||
const pk1 = sk1.getG1();
|
||||
const sig1 = AugSchemeMPL.sign(sk1, message);
|
||||
|
||||
const pk2 = sk2.get_g1();
|
||||
const pk2 = sk2.getG1();
|
||||
const sig2 = AugSchemeMPL.sign(sk2, message2);
|
||||
|
||||
const agg_sig = AugSchemeMPL.aggregate([sig1, sig2]);
|
||||
const aggSig = AugSchemeMPL.aggregate([sig1, sig2]);
|
||||
|
||||
ok = AugSchemeMPL.aggregate_verify([pk1, pk2], [message, message2], agg_sig);
|
||||
ok = AugSchemeMPL.aggregateVerify([pk1, pk2], [message, message2], aggSig);
|
||||
assert(ok);
|
||||
|
||||
seed = Buffer.concat([Buffer.from([3]), seed.slice(1)]);
|
||||
const sk3 = AugSchemeMPL.key_gen(seed);
|
||||
const pk3 = sk3.get_g1();
|
||||
const sk3 = AugSchemeMPL.keyGen(seed);
|
||||
const pk3 = sk3.getG1();
|
||||
const message3 = Buffer.from([100, 2, 254, 88, 90, 45, 23]);
|
||||
const sig3 = AugSchemeMPL.sign(sk3, message3);
|
||||
|
||||
const agg_sig_final = AugSchemeMPL.aggregate([agg_sig, sig3]);
|
||||
ok = AugSchemeMPL.aggregate_verify(
|
||||
[pk1, pk2, pk3], [message, message2, message3], agg_sig_final
|
||||
const aggSigFinal = AugSchemeMPL.aggregate([aggSig, sig3]);
|
||||
ok = AugSchemeMPL.aggregateVerify(
|
||||
[pk1, pk2, pk3], [message, message2, message3], aggSigFinal
|
||||
);
|
||||
assert(ok);
|
||||
|
||||
const pop_sig1 = PopSchemeMPL.sign(sk1, message);
|
||||
const pop_sig2 = PopSchemeMPL.sign(sk2, message);
|
||||
const pop_sig3 = PopSchemeMPL.sign(sk3, message);
|
||||
const pop1 = PopSchemeMPL.pop_prove(sk1);
|
||||
const pop2 = PopSchemeMPL.pop_prove(sk2);
|
||||
const pop3 = PopSchemeMPL.pop_prove(sk3);
|
||||
const popSig1 = PopSchemeMPL.sign(sk1, message);
|
||||
const popSig2 = PopSchemeMPL.sign(sk2, message);
|
||||
const popSig3 = PopSchemeMPL.sign(sk3, message);
|
||||
const pop1 = PopSchemeMPL.popProve(sk1);
|
||||
const pop2 = PopSchemeMPL.popProve(sk2);
|
||||
const pop3 = PopSchemeMPL.popProve(sk3);
|
||||
|
||||
ok = PopSchemeMPL.pop_verify(pk1, pop1);
|
||||
ok = PopSchemeMPL.popVerify(pk1, pop1);
|
||||
assert(ok);
|
||||
ok = PopSchemeMPL.pop_verify(pk2, pop2);
|
||||
ok = PopSchemeMPL.popVerify(pk2, pop2);
|
||||
assert(ok);
|
||||
ok = PopSchemeMPL.pop_verify(pk3, pop3);
|
||||
ok = PopSchemeMPL.popVerify(pk3, pop3);
|
||||
assert(ok);
|
||||
|
||||
const pop_sig_agg = PopSchemeMPL.aggregate([pop_sig1, pop_sig2, pop_sig3]);
|
||||
const popSigAgg = PopSchemeMPL.aggregate([popSig1, popSig2, popSig3]);
|
||||
|
||||
ok = PopSchemeMPL.fast_aggregate_verify([pk1, pk2, pk3], message, pop_sig_agg);
|
||||
ok = PopSchemeMPL.fastAggregateVerify([pk1, pk2, pk3], message, popSigAgg);
|
||||
assert(ok);
|
||||
|
||||
const pop_agg_pk = pk1.add(pk2).add(pk3);
|
||||
assert(Buffer.from(pop_agg_pk.serialize()).toString('hex') == '8ffb2a3c4a6ce516febdf1f2a5140c6974cce2530ebc1b56629f078c25d538aa3d8f0cf694516b4bfc8d344bbea829d3');
|
||||
const t_pop_agg_pk_1 = pk1.add(pk2.add(pk3));
|
||||
assert(Buffer.from(pop_agg_pk.serialize()).equals(Buffer.from(t_pop_agg_pk_1.serialize())));
|
||||
const popAggPk = pk1.add(pk2).add(pk3);
|
||||
assert(Buffer.from(popAggPk.serialize()).toString('hex') == '8ffb2a3c4a6ce516febdf1f2a5140c6974cce2530ebc1b56629f078c25d538aa3d8f0cf694516b4bfc8d344bbea829d3');
|
||||
const tPopAggPk1 = pk1.add(pk2.add(pk3));
|
||||
assert(Buffer.from(popAggPk.serialize()).equals(Buffer.from(tPopAggPk1.serialize())));
|
||||
|
||||
assert(Buffer.from(pop_sig_agg.serialize()).toString('hex') == 'b3115327c21286b043cf972db56cefe0a745a8091482c9eec47fe5c0dbdb2ffc4d05ae54e7ee45e209135e6c81e8af2212465abffe8ab3166d3f4d5ed1f4d98cb65323d8d1fc210311c7e46a5f637ef7d90b7f3206708dc4bb32a2e1549a3060');
|
||||
ok = PopSchemeMPL.verify(pop_agg_pk, message, pop_sig_agg);
|
||||
assert(Buffer.from(popSigAgg.serialize()).toString('hex') == 'b3115327c21286b043cf972db56cefe0a745a8091482c9eec47fe5c0dbdb2ffc4d05ae54e7ee45e209135e6c81e8af2212465abffe8ab3166d3f4d5ed1f4d98cb65323d8d1fc210311c7e46a5f637ef7d90b7f3206708dc4bb32a2e1549a3060');
|
||||
ok = PopSchemeMPL.verify(popAggPk, message, popSigAgg);
|
||||
assert(ok);
|
||||
|
||||
const pop_agg_sk = PrivateKey.aggregate([sk1, sk2, sk3]);
|
||||
ok = Buffer.from(PopSchemeMPL.sign(pop_agg_sk, message).serialize()).equals(Buffer.from(pop_sig_agg.serialize()));
|
||||
const popAggSk = PrivateKey.aggregate([sk1, sk2, sk3]);
|
||||
ok = Buffer.from(PopSchemeMPL.sign(popAggSk, message).serialize()).equals(Buffer.from(popSigAgg.serialize()));
|
||||
assert(ok);
|
||||
|
||||
const master_sk = AugSchemeMPL.key_gen(seed);
|
||||
const child = AugSchemeMPL.derive_child_sk(master_sk, 152);
|
||||
const grandchild = AugSchemeMPL.derive_child_sk(child, 952);
|
||||
const masterSk = AugSchemeMPL.keyGen(seed);
|
||||
const child = AugSchemeMPL.deriveChildSk(masterSk, 152);
|
||||
const grandchild = AugSchemeMPL.deriveChildSk(child, 952);
|
||||
|
||||
const master_pk = master_sk.get_g1();
|
||||
const child_u = AugSchemeMPL.derive_child_sk_unhardened(master_sk, 22);
|
||||
const grandchild_u = AugSchemeMPL.derive_child_sk_unhardened(child_u, 0);
|
||||
const masterPk = masterSk.getG1();
|
||||
const childU = AugSchemeMPL.deriveChildSkUnhardened(masterSk, 22);
|
||||
const grandchildU = AugSchemeMPL.deriveChildSkUnhardened(childU, 0);
|
||||
|
||||
const child_u_pk = AugSchemeMPL.derive_child_pk_unhardened(master_pk, 22);
|
||||
const grandchild_u_pk = AugSchemeMPL.derive_child_pk_unhardened(child_u_pk, 0);
|
||||
const childUPk = AugSchemeMPL.deriveChildPkUnhardened(masterPk, 22);
|
||||
const grandchildUPk = AugSchemeMPL.deriveChildPkUnhardened(childUPk, 0);
|
||||
|
||||
ok = Buffer.from(grandchild_u_pk.serialize()).equals(Buffer.from(grandchild_u.get_g1().serialize()));
|
||||
ok = Buffer.from(grandchildUPk.serialize()).equals(Buffer.from(grandchildU.getG1().serialize()));
|
||||
assert(ok);
|
||||
}
|
||||
|
||||
function test_aggregate_verify_zero_items() {
|
||||
assert(AugSchemeMPL.aggregate_verify([], [], new G2Element()));
|
||||
function testAggregateVerifyZeroItems() {
|
||||
assert(AugSchemeMPL.aggregateVerify([], [], new G2Element()));
|
||||
}
|
||||
|
||||
function test_bignum() {
|
||||
function testBignum() {
|
||||
const mersenne = Bignum.fromString('162259276829213363391578010288127', 10);
|
||||
assert(mersenne.toString(16).toLowerCase() == '7ffffffffffffffffffffffffff');
|
||||
}
|
||||
|
||||
test_schemes();
|
||||
test_vectors_invalid();
|
||||
test_vectors_valid();
|
||||
test_readme();
|
||||
test_aggregate_verify_zero_items();
|
||||
test_bignum();
|
||||
testSchemes();
|
||||
testVectorsInvalid();
|
||||
testVectorsValid();
|
||||
testReadme();
|
||||
testAggregateVerifyZeroItems();
|
||||
testBignum();
|
||||
}).then(function() {
|
||||
console.log("\nAll tests passed.");
|
||||
});
|
||||
|
@ -70,9 +70,9 @@ createBlsSignaturesModule().then((blsSignatures) => {
|
||||
describe('typings', () => {
|
||||
it('PrivateKey', () => {
|
||||
strictEqual(PrivateKey.PRIVATE_KEY_SIZE, 32);
|
||||
const sk = AugSchemeMPL.key_gen(getSkSeed());
|
||||
const sk = AugSchemeMPL.keyGen(getSkSeed());
|
||||
const aggSk = PrivateKey.aggregate([sk]);
|
||||
const pk = sk.get_g1();
|
||||
const pk = sk.getG1();
|
||||
const bytes: Uint8Array = sk.serialize();
|
||||
const sig = AugSchemeMPL.sign(sk, getMessageBytes());
|
||||
ok(AugSchemeMPL.verify(pk, getMessageBytes(), sig));
|
||||
@ -83,9 +83,9 @@ createBlsSignaturesModule().then((blsSignatures) => {
|
||||
|
||||
it('G1Element', () => {
|
||||
strictEqual(G1Element.SIZE, 48);
|
||||
const pk = G1Element.from_bytes(getPkBytes());
|
||||
const pk = G1Element.fromBytes(getPkBytes());
|
||||
const aggPk = pk.add(pk);
|
||||
const fingerprint: number = pk.get_fingerprint();
|
||||
const fingerprint: number = pk.getFingerprint();
|
||||
const bytes: Uint8Array = pk.serialize();
|
||||
pk.delete();
|
||||
aggPk.delete();
|
||||
@ -93,10 +93,10 @@ createBlsSignaturesModule().then((blsSignatures) => {
|
||||
|
||||
it('G2Element', () => {
|
||||
strictEqual(G2Element.SIZE, 96);
|
||||
const pk = G1Element.from_bytes(getPkBytes());
|
||||
const sig = G2Element.from_bytes(getSignatureBytes());
|
||||
const pk = G1Element.fromBytes(getPkBytes());
|
||||
const sig = G2Element.fromBytes(getSignatureBytes());
|
||||
const aggSig = AugSchemeMPL.aggregate([sig]);
|
||||
const sig2 = G2Element.from_bytes(getSignatureBytes());
|
||||
const sig2 = G2Element.fromBytes(getSignatureBytes());
|
||||
const isValid: boolean =
|
||||
AugSchemeMPL.verify(pk, getMessageBytes(), sig);
|
||||
const serialized: Uint8Array = sig.serialize();
|
||||
|
18
js_build_docker.sh
Executable file
18
js_build_docker.sh
Executable file
@ -0,0 +1,18 @@
|
||||
DOCKER_IMAGE=emscripten/emsdk
|
||||
|
||||
git submodule update --init --recursive
|
||||
mkdir js_build
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
-v $(pwd):/src \
|
||||
-w="/src/js_build" \
|
||||
$DOCKER_IMAGE \
|
||||
emcmake cmake /src
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
-v $(pwd):/src \
|
||||
-w="/src/js_build" \
|
||||
$DOCKER_IMAGE \
|
||||
cmake --build . -- -j10
|
@ -3,7 +3,7 @@ include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11.git
|
||||
GIT_TAG v2.9.1
|
||||
GIT_TAG v2.10.0
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
|
||||
|
4
setup.py
4
setup.py
@ -196,8 +196,8 @@ if platform.system() == "Windows":
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/Chia-Network/bls-signatures",
|
||||
python_requires=">=3.7",
|
||||
setup_requires=["pybind11>=2.5.0"],
|
||||
install_requires=["pybind11>=2.5.0"],
|
||||
setup_requires=["pybind11>=2.10.0"],
|
||||
install_requires=["pybind11>=2.10.0"],
|
||||
ext_modules=ext_modules,
|
||||
cmdclass={"build_ext": BuildExt},
|
||||
zip_safe=False,
|
||||
|
@ -78,15 +78,17 @@ void BLS::SetSecureAllocator(
|
||||
}
|
||||
|
||||
|
||||
void BLS::CheckRelicErrors()
|
||||
void BLS::CheckRelicErrors(bool should_throw)
|
||||
{
|
||||
if (!core_get()) {
|
||||
throw std::runtime_error("Library not initialized properly. Call BLS::Init()");
|
||||
}
|
||||
if (core_get()->code != RLC_OK) {
|
||||
core_get()->code = RLC_OK;
|
||||
if (should_throw) {
|
||||
throw std::invalid_argument("Relic library error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace bls
|
||||
|
@ -82,9 +82,7 @@ G1Element G1Element::FromBytesUnchecked(Bytes const bytes, bool fLegacy)
|
||||
}
|
||||
}
|
||||
g1_read_bin(ele.p, buffer, G1Element::SIZE + 1);
|
||||
if (!fLegacy) {
|
||||
BLS::CheckRelicErrors();
|
||||
}
|
||||
BLS::CheckRelicErrors(!fLegacy);
|
||||
return ele;
|
||||
}
|
||||
|
||||
@ -293,9 +291,7 @@ G2Element G2Element::FromBytesUnchecked(Bytes const bytes, const bool fLegacy)
|
||||
}
|
||||
|
||||
g2_read_bin(ele.q, buffer, G2Element::SIZE + 1);
|
||||
if (!fLegacy) {
|
||||
BLS::CheckRelicErrors();
|
||||
}
|
||||
BLS::CheckRelicErrors(!fLegacy);
|
||||
return ele;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user