supranational / blst Goto Github PK
View Code? Open in Web Editor NEWMultilingual BLS12-381 signature library
License: Apache License 2.0
Multilingual BLS12-381 signature library
License: Apache License 2.0
Given the significant speed increase (~20% for high level signing/verifying) provided by BMI2 and ADX support (for MULX, ADCX, ADOX instructions) (bench: status-im/nim-blst#1)
It would probably worthwhile to autodetect CPU support for those instructions at runtime.
This is especially interesting because the CPUs are now widespread (Broadwell, 2015 for Intel and Ryzen 2017 for AMD).
Cloudflare BN256 does that for example https://github.com/cloudflare/bn256/blob/3cac37b6/gfp_amd64.s#L108-L129
I've been working to create portable versions of Lighthouse, which has meant vendoring openssl
as a static library.
During linking I get the following error from cargo
, which indicates duplicate symbols between openssl (already defined) and blst:
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.0.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.1.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.10.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.11.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.12.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.13.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.14.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.15.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.2.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.3.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.4.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.5.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.6.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.7.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.8.rcgu.o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.build_script_build.5xlfh9ot-cgu.9.rcgu.o" "-o" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1" "/target/release/build/eth2_testnet_config-f80d9826a04c3cd1/build_script_build-f80d9826a04c3cd1.3505t472p1rxx8d9.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/target/release/deps" "-L" "/target/release/build/blst-9371ea9d4f785b6a/out" "-L" "/target/release/build/ring-2576dc4f14a87596/out" "-L" "/target/release/build/libsqlite3-sys-028045c599cbd948/out" "-L" "/target/release/build/openssl-sys-b8f5860d05172a46/out/openssl-build/install/lib" "-L" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/target/release/deps/libreqwest-8554af7f94b086ee.rlib" "/target/release/deps/libhyper_tls-85c3f52119d8e093.rlib" "/target/release/deps/libipnet-a7fb6f02dcdb374c.rlib" "/target/release/deps/libtokio_tls-2bafd832aa83b03a.rlib" "/target/release/deps/libencoding_rs-f47002981754d86e.rlib" "/target/release/deps/libserde_urlencoded-0beb76c71f0f9b89.rlib" "/target/release/deps/libbase64-81fb7a3de7920337.rlib" "/target/release/deps/libmime_guess-0fce326879fca279.rlib" "/target/release/deps/libunicase-22c5590a75454b10.rlib" "/target/release/deps/libmime-9028ffd6b66d5a7a.rlib" "/target/release/deps/libnative_tls-f87010ecba179e74.rlib" "/target/release/deps/libopenssl_probe-c94d77228ca05eeb.rlib" "/target/release/deps/libopenssl-0382c8b8a815da34.rlib" "/target/release/deps/libopenssl_sys-ac675114625945ad.rlib" "/target/release/deps/libforeign_types-e6850f3f6ab87d8d.rlib" "/target/release/deps/libforeign_types_shared-514f271abd9dcb1d.rlib" "/target/release/deps/libhyper-5472c2bf7440e591.rlib" "/target/release/deps/libhttparse-0b84b879b01ace27.rlib" "/target/release/deps/libwant-2f95fb59033dc3cc.rlib" "/target/release/deps/libtry_lock-3fcfb9a79f999690.rlib" "/target/release/deps/libh2-fc76a0624648478f.rlib" "/target/release/deps/libindexmap-97a6c9a28c898ae9.rlib" "/target/release/deps/libhashbrown-1c75b6870c81d067.rlib" "/target/release/deps/libtokio_util-fd20f3c0dc0057ee.rlib" "/target/release/deps/libsocket2-527ba7744fe478af.rlib" "/target/release/deps/libtower_service-9d14a18aa9ec401f.rlib" "/target/release/deps/libtracing-bb64b643ab3ab47c.rlib" "/target/release/deps/libtracing_core-c16b67022a9bc9e2.rlib" "/target/release/deps/libtokio-53b210f35bd8ead5.rlib" "/target/release/deps/libsignal_hook_registry-307f62036afe760e.rlib" "/target/release/deps/libarc_swap-08b842736ed53d42.rlib" "/target/release/deps/libmio_uds-f1b01f66f1a6d177.rlib" "/target/release/deps/libmio-572e635e562870bc.rlib" "/target/release/deps/libiovec-4d3855f43e6ae4df.rlib" "/target/release/deps/libnet2-a96c450616b7ff39.rlib" "/target/release/deps/libpin_project_lite-26d68186f2482f16.rlib" "/target/release/deps/libhttp_body-2678c6cea2a1f74e.rlib" "/target/release/deps/libfutures_util-926b97d1a3e51a08.rlib" "/target/release/deps/libmemchr-fa9b7adacce34692.rlib" "/target/release/deps/libproc_macro_nested-ebcc1646b95e9e82.rlib" "/target/release/deps/libfutures-1e51387ca0ed956e.rlib" "/target/release/deps/libfutures_io-ec5b8a96624282f2.rlib" "/target/release/deps/libslab-e1b177a90421fcb5.rlib" "/target/release/deps/libfutures_channel-a06e86628c520166.rlib" "/target/release/deps/libpin_project-5888f93c514d4c4f.rlib" "/target/release/deps/libfutures_sink-f5a2e83e5606de49.rlib" "/target/release/deps/libfutures_task-6dee730c29d08740.rlib" "/target/release/deps/libonce_cell-4f89fede75132748.rlib" "/target/release/deps/libparking_lot-008820c471764ac5.rlib" "/target/release/deps/libparking_lot_core-6a8d5aac23394d22.rlib" "/target/release/deps/liblock_api-bc84e94bb6be3b36.rlib" "/target/release/deps/libpin_utils-abc99c3ae697a3d7.rlib" "/target/release/deps/libfutures_core-7394af138f43fd8e.rlib" "/target/release/deps/liburl-fd13b2968901b466.rlib" "/target/release/deps/libpercent_encoding-beb548f7fbaa198d.rlib" "/target/release/deps/libidna-619be24928d079c4.rlib" "/target/release/deps/libunicode_normalization-301d5ba88b28b166.rlib" "/target/release/deps/libtinyvec-1ea3f44ee5fc5858.rlib" "/target/release/deps/libunicode_bidi-e08f9552f9f382a4.rlib" "/target/release/deps/libmatches-8cd9af4a7f899158.rlib" "/target/release/deps/libhttp-d56db25500e32e7d.rlib" "/target/release/deps/libfnv-32aea7382b61848c.rlib" "/target/release/deps/libhandlebars-b08252ca284e3d53.rlib" "/target/release/deps/libpest-c9cf2d5a9dcebfd8.rlib" "/target/release/deps/libucd_trie-9376a72a54b14696.rlib" "/target/release/deps/libserde_json-3ebf8e5838f343ff.rlib" "/target/release/deps/libryu-fce13a80f1ff55e4.rlib" "/target/release/deps/libitoa-e8be65b96c1c4287.rlib" "/target/release/deps/libquick_error-414a73e455c6dbdd.rlib" "/target/release/deps/libeth2_config-b98313cbba557eaa.rlib" "/target/release/deps/libtypes-9922c132c755a3d2.rlib" "/target/release/deps/libslog-91b967d4301de7ab.rlib" "/target/release/deps/libcompare_fields-3d9c36773428e99a.rlib" "/target/release/deps/libdirs-061a3e8953d7b9a1.rlib" "/target/release/deps/libdirs_sys-0ddc1d62db5c4685.rlib" "/target/release/deps/librusqlite-f7ae25b21ba8b62e.rlib" "/target/release/deps/libtime-2cf742b08c31dbdf.rlib" "/target/release/deps/libbitflags-c74b1b8d1e8f9660.rlib" "/target/release/deps/libfallible_streaming_iterator-0ac1ce980e2d8ebc.rlib" "/target/release/deps/libfallible_iterator-12cc4918bbe1bf48.rlib" "/target/release/deps/liblru_cache-0988af52d825971e.rlib" "/target/release/deps/liblibsqlite3_sys-2587f56b8c60d5b9.rlib" "/target/release/deps/libswap_or_not_shuffle-ce9ba8310597e235.rlib" "/target/release/deps/libcached_tree_hash-e3269ddc876e285b.rlib" "/target/release/deps/libssz_types-f8e12236cc72e1c7.rlib" "/target/release/deps/libtypenum-972aadf3a52fcf7a.rlib" "/target/release/deps/librand_xorshift-b7beef0ae4da1a1d.rlib" "/target/release/deps/libeth2_interop_keypairs-98348466bfd611a7.rlib" "/target/release/deps/libserde_yaml-8147d4a7df260ce2.rlib" "/target/release/deps/libdtoa-a00da8193e23dc72.rlib" "/target/release/deps/libyaml_rust-b1132581acd8da15.rlib" "/target/release/deps/liblinked_hash_map-6585ebdbeac56aed.rlib" "/target/release/deps/libnum_bigint-2cc3c04e0fb19dc4.rlib" "/target/release/deps/libnum_integer-82310229b4a02121.rlib" "/target/release/deps/libnum_traits-fdea96309b91f98a.rlib" "/target/release/deps/liblog-2d4953f5690c3429.rlib" "/target/release/deps/libbls-f8fb8a157a1e5f73.rlib" "/target/release/deps/libmilagro_bls-378037218fcbbd41.rlib" "/target/release/deps/libamcl-2a75d0291c07f714.rlib" "/target/release/deps/libhex-cb9304af7205c48f.rlib" "/target/release/deps/libblst-f24ffced809e69d4.rlib" "/target/release/deps/libthreadpool-3f53d1bf42699f77.rlib" "/target/release/deps/libzeroize-15e0634389e4352b.rlib" "/target/release/deps/libssz-241fb120a8f7667a.rlib" "/target/release/deps/libserde_hex-b3f7ec2ba6bcb33e.rlib" "/target/release/deps/libhex-01e4031a68a52844.rlib" "/target/release/deps/libtree_hash-f510e2f95c45f4dc.rlib" "/target/release/deps/libsmallvec-be015730e60a1d5f.rlib" "/target/release/deps/librayon-439da60135725620.rlib" "/target/release/deps/librayon_core-e5bcb1180adc1be2.rlib" "/target/release/deps/libnum_cpus-df749efb73077f5f.rlib" "/target/release/deps/libcrossbeam_deque-a8b5f613ba1adc75.rlib" "/target/release/deps/libcrossbeam_epoch-3287268bfdc33002.rlib" "/target/release/deps/libscopeguard-981e0fd01390580f.rlib" "/target/release/deps/libmemoffset-e35e5516b0a74720.rlib" "/target/release/deps/libcrossbeam_queue-ef4de43db3543d2b.rlib" "/target/release/deps/libcrossbeam_utils-df47abda0d2411cd.rlib" "/target/release/deps/libmaybe_uninit-221c27a634e131c5.rlib" "/target/release/deps/libeither-277d2d8fb6dd8acf.rlib" "/target/release/deps/libmerkle_proof-88a6a6a415f087d8.rlib" "/target/release/deps/libsafe_arith-e6488697dafac224.rlib" "/target/release/deps/libethereum_types-24de5876b3fb154f.rlib" "/target/release/deps/libethbloom-fc3f1b2a32546fd5.rlib" "/target/release/deps/libtiny_keccak-c5ab25563b70a73e.rlib" "/target/release/deps/libprimitive_types-1c91ce6b1f45fff8.rlib" "/target/release/deps/libimpl_codec-19eea1bb4ceb871f.rlib" "/target/release/deps/libparity_scale_codec-42c213969c9c54f7.rlib" "/target/release/deps/libbyte_slice_cast-81b414f4afcce7e2.rlib" "/target/release/deps/libarrayvec-6e24743649c361b9.rlib" "/target/release/deps/libuint-17fc075c0c0f1515.rlib" "/target/release/deps/libcrunchy-61d5f9ffa08e7808.rlib" "/target/release/deps/libimpl_serde-e82472131d2d37fe.rlib" "/target/release/deps/libserde-be0a196a4cfea052.rlib" "/target/release/deps/libimpl_rlp-2a6de41817dac32e.rlib" "/target/release/deps/librlp-a03224ccba6b4199.rlib" "/target/release/deps/libfixed_hash-e71d48d5abff73b1.rlib" "/target/release/deps/librand-0b1da1fbe4932acc.rlib" "/target/release/deps/librand_chacha-618e4ef498dbe97f.rlib" "/target/release/deps/libppv_lite86-0feb83f6519fdc19.rlib" "/target/release/deps/librand_core-0d70a91769289afc.rlib" "/target/release/deps/libgetrandom-b4fb2a9bd67ca6b2.rlib" "/target/release/deps/libcfg_if-b54bd1f3a94e0e76.rlib" "/target/release/deps/librustc_hex-43614664506e6dcb.rlib" "/target/release/deps/libbyteorder-fb4a30392f846b17.rlib" "/target/release/deps/libstatic_assertions-f0e656d75f7dd446.rlib" "/target/release/deps/libeth2_hashing-c69517f0367e772b.rlib" "/target/release/deps/libring-00e4bf62b6678855.rlib" "/target/release/deps/liblazy_static-d64e9aa0f0de57b3.rlib" "/target/release/deps/libspin-ad732aaaa7d97aa6.rlib" "/target/release/deps/liblibc-636aca7798be1458.rlib" "/target/release/deps/libuntrusted-45d6058bac1acda1.rlib" "/target/release/deps/libint_to_bytes-8b87d8a5d3b49e80.rlib" "/target/release/deps/libbytes-f26916b0b8c43cfa.rlib" "-Wl,--start-group" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8bb11f807a7b6b4c.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-ca8087507780d964.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-259c92b387c1c166.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-16e0a2fbbb8e14b3.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-8a1651b8e23d2aaf.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-23bdd98b0574083e.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-855a92055ec33e2e.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-24c70dd44fbacdfb.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-b326273841bae587.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-ac3c1f0e16507051.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-a5729542b65954aa.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-09bd1119ab1cad7d.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-9a787681bfbeaf61.rlib" "-Wl,--end-group" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-5a0398ee67f74664.rlib" "-Wl,-Bdynamic" "-lutil" "-ldl" "-lutil" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-ldl" "-lutil"
= note: /target/release/deps/libblst-f24ffced809e69d4.rlib(assembly.o): In function `sha256_block_data_order':
(.text+0x4c0): multiple definition of `sha256_block_data_order'
/target/release/deps/libopenssl_sys-ac675114625945ad.rlib(sha256-x86_64.o):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
I can resolve this issue and produce a binary if I use the following commit of blst: sigp@284f705. This is basically s/sha256_block_data_order/blst_sha256_block_data_order
across this project.
Linking is not my domain, so I open to more elegant solutions that my previous commit. Thank you :)
I tried to import this as a go module, but it could not find some methods.
For example blst.P1Affine is missing the "From" method and blst.P2Affine is missing the "Sign" method.
So then I decided to see if the blst.go file was outdated, therefore I cloned this repo,
run go get golang.org/x/tools/cmd/goimports
run .generate.py
And there I noticed that blst.go is also failing with many missing methods for the types declared, for example:
sk.Zeroize undefined (type *_Ctype_struct___6 has no field or method Zeroize)compilerMissingFieldOrMethod
Is there something else I'm missing to use the example from the README.md ?
sha256.h - & should probably be && on line 67
build.sh
fails on MacOS with the following warnings (as errors):
nashatyrev@MacBook-Pro blst % ./build.sh
+ cc -O -fno-builtin-memcpy -fPIC -Wall -Wextra -Werror -mno-avx -c ./src/server.c
In file included from ./src/server.c:19:
./src/bulk_addition.c:147:1: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
ADDITION_BTREE(POINTonE2, 384x, fp2, BLS12_381_Rx.p2)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/bulk_addition.c:113:49: note: expanded from macro 'ADDITION_BTREE'
#define ADDITION_BTREE(ptype, bits, field, one) \
^
./src/bulk_addition.c:57:37: note: expanded from macro '\
HEAD'
static const vec##bits zero = { 0 }; \
^
In file included from ./src/server.c:20:
./src/multi_scalar.c:192:1: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
MULT_SCALAR_WBITS_IMPL(POINTonE1, 384, fp, BLS12_381_Rx.p)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/multi_scalar.c:101:46: note: expanded from macro 'MULT_SCALAR_WBITS_IMPL'
static const ptype##_affine infinity = { 0 }; \
^
./src/multi_scalar.c:196:1: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
MULT_SCALAR_WBITS_IMPL(POINTonE2, 384x, fp2, BLS12_381_Rx.p2)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/multi_scalar.c:101:46: note: expanded from macro 'MULT_SCALAR_WBITS_IMPL'
static const ptype##_affine infinity = { 0 }; \
^
./src/multi_scalar.c:196:1: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
MULT_SCALAR_WBITS_IMPL(POINTonE2, 384x, fp2, BLS12_381_Rx.p2)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/multi_scalar.c:101:46: note: expanded from macro 'MULT_SCALAR_WBITS_IMPL'
static const ptype##_affine infinity = { 0 }; \
^
4 errors generated.
This is due to commit 46be9ea
Adding -Wno-missing-braces
option to build.sh
solves the problem
I noticed that in Python example (run.me
) different affine used for the signature construction from binary data:
########################################################################
# at this point 'pk_for_wire', 'sig_for_wire' and 'msg' are
# "sent over network," so now on "receiver" side
sig = blst.P1_Affine(sig_for_wire)
pk = blst.P2_Affine(pk_for_wire)
########################################################################
# from https://github.com/supranational/blst/issues/5
pk_for_wire = bytes.fromhex("ab10fc693d038b73d67279127501a05f0072cbb7147c68650ef6ac4e0a413e5cabd1f35c8711e1f7d9d885bbc3b8eddc")
sig_for_wire = bytes.fromhex("a44158c08c8c584477770feec2afa24d5a0b0bab2800414cb9efbb37c40339b6318c9349dad8de27ae644376d71232580ff5102c7a8579a6d2627c6e40b0ced737a60c66c7ebd377c04bf5ac957bf05bc8b6b09fbd7bdd2a7fa1090b5a0760bb")
msg = bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000")
DST = bytes.fromhex("424c535f5349475f424c53313233383147325f584d443a5348412d3235365f535357555f524f5f504f505f")
sig = blst.P2_Affine(sig_for_wire)
pk = blst.P1_Affine(pk_for_wire)
In first case P1_Affine
was used and for the second case P2_Affine
. Is it correct?
The function blst_keygen
hashes the salt before using the HKDF, which is not the case in the specification. Is there any reason?
When writing an OCaml binding (available here), I tried to use the test vectors available in bls_sigs_ref. The test vectors use the seed to generate the sk and therefore the tests were not passing. While removing the hash, all the test vectors are fine (without any surprise ofc).
If anyone else would like to use the test vectors generated by bls_sigs_ref, I regenerated the correct signature for the current version (3f7d97e) of keygen. The MR history should be enough clear to be convinced the values are correct. The files can also be regenerated from the original as described in the MR.
When decompression a point each specific field point should be strictly less than the field modulus.
For example a min PublicKey should have the x coordinate strictly less than the field modulus. PublicKey.X < P
If this is not enforced, signature malleability may occur by taking Signature.X[0]
from a valid signature and doing Signature.X[0] + P
which will equate to the same point thus providing signature malleability.
I think this check out be easiest to do on the limbs just after converting bytes to words. That is in src/vect.h::limbs_from_be_bytes()
. That way a simple loop can be made checking each word from the most significant word is less than, equal to or greater than the equivalent word in the field modulus.
This could break the loop if a word is less than, error/exit if a word is greater than and continue if a word is equal to the field modulus word.
If you look at the implementation here https://github.com/zkcrypto/bls12_381/blob/master/src/g2.rs#L517-L518 there is the need to check if either both points are infinity, or both points are not, in addition to the currently executed check
We need to use blst in order to perform a signature in our project, but it fails using blst_sign_pk_in_g1
function, specifically in POINTonE2_mult_gls
. It has been built using arm-none-eabi-gcc from GNU Arm Embedded Toolchain as cross compiler and it's used in a nRF5340 board. Last working version was this one.
Any plans to add an api for performing blind signatures?
As of aae0c7d ,
AggegateVerify
will verify a message signed by a zero key as valid. This will only be triggered if there are
multiple messages/pubkeys to verify. In the event the message and pubkey are singluar verification fails correctly.
https://github.com/supranational/blst/blob/master/bindings/go/blst.go#L282
To illustrate here is a test case for it:
func TestSignVerifyAggregateValidatesInfinitePubkey(t *testing.T) {
size := 20
sks, msgs, _, pubks, _, err :=
generateBatchTestDataUncompressedMinPk(size)
if err {
t.Errorf("Error generating test data")
return
}
// All signers sign the same message
sigs := make([]*SignatureMinPk, 0)
for i := 0; i < size; i++ {
sigs = append(sigs, new(SignatureMinPk).Sign(sks[i], msgs[i],
dstMinPk))
}
// Infinite pubkeys and signature
zeroKey := new(PublicKeyMinPk)
zeroSig := new(SignatureMinPk)
agProj := new(AggregateSignatureMinPk).Aggregate([]*SignatureMinPk{zeroSig})
if agProj == nil {
t.Errorf("Aggregate unexpectedly returned nil")
return
}
agSig := agProj.ToAffine()
if !agSig.AggregateVerify([]*PublicKeyMinPk{zeroKey}, [][]byte{msgs[0]}, dstMinPk) {
t.Errorf("failed to verify signature")
}
// Replace firstkey with infinite pubkey.
pubks[0] = zeroKey
sigs[0] = zeroSig
agProj = new(AggregateSignatureMinPk).Aggregate(sigs)
if agProj == nil {
t.Errorf("Aggregate unexpectedly returned nil")
return
}
agSig = agProj.ToAffine()
if !agSig.AggregateVerify(pubks, msgs, dstMinPk) {
t.Errorf("failed to verify signature")
}
}
The first test case correctly fails, while the second test case actually passes.
Didn't found any tests on core_verify_pk_in_g1
function and thought it probably could be a library bug.
PrivateKey (bigendian serialized) = 0x2793e28525ec30c29f3ff05f9ebd5449c79f180c442496ccef9294bd9850662c
Public key (compressed p1_affine) = 0xab10fc693d038b73d67279127501a05f0072cbb7147c68650ef6ac4e0a413e5cabd1f35c8711e1f7d9d885bbc3b8eddc
Message = 0x0000000000000000000000000000000000000000000000000000000000000000
Message hash (compressed p2_affine, DST=0x424c535f5349475f424c53313233383147325f584d443a5348412d3235365f535357555f524f5f504f505f , aug =[]):
0x97502412bcfc3f1d88b71f1ad9b60fa37c332d19466fba1dc991d42bcd09bcd9f1c22a562646ffce0922793b6c69938b076e5cd6cfb3c361fc767e5f40ce05486e1668825ffeecab89d7daa455a179736a387ae93b9b15d283d45ffa14cd4af7
Signature (compressed p2_affine) = 0xa44158c08c8c584477770feec2afa24d5a0b0bab2800414cb9efbb37c40339b6318c9349dad8de27ae644376d71232580ff5102c7a8579a6d2627c6e40b0ced737a60c66c7ebd377c04bf5ac957bf05bc8b6b09fbd7bdd2a7fa1090b5a0760bb
Just compare all the values to the current Java Milagro library and all of them are the same, but Milagro verifies the signature while core_verify_pk_in_g1
doesn't. The signature has the same value when signing by both our current Milagro implementation and by Blst based code.
Would be super if you could check this case. Any other help in finding the root cause is also much appreciated!
Thanks again for this great library!
When implementing blst
in Lighthouse (Eth2 impl) I noticed that the core structs (e.g., PublicKey
, Signature
, etc) are missing some typical and useful impls. In particular:
Clone
PartialEq
Eq
(if it adheres to the definition here)As you can see in our code, I've added some wrapper structs to Lighthouse and made my own custom implementations. It would be great if these were included in the library by default.
If the implementations I've used (see previous link) are good, I'm happy to make a PR to this repository. However I suspect that you might know faster or more elegant ways to achieve these things.
Following our exchanges, you can accelerate the scalar multiplication via:
Method 1 has a patent that expires on September 2020.
Implementation follow closely Algorithm 1 and 2 from paper
The Lattice decompositions for BN and BLS curve families follow chapter 6 from
The FourQ draft also mentions this: https://tools.ietf.org/html/draft-ladd-cfrg-4q-00#section-4.3
For variable point, on G1, we can accelerate via an efficient endomorphism, field multiplication by a cube root of unity:
For variable point, on G2 you can combine the cube root of unity endomorphism with the Frobenius endomorphism to divide by 4 the number of doubling.
I think only MCL and MIRACL are using those at the moment.
The decomposition lattice is available in the guide to pairing based cryptography. I also have sage scripts for G1 decomposition for vectors (incomplete, the last assert fails even though in my production code it's working so I probably have bit issues with Python):
The paper mentions LSB Set decomposition has being more efficient if the point is known at compile-time. CIRCL and Snowshoe also implement this technique.
Looking into aggregate.c it's clear what blst_pairing_aggregate_pk_in_g1
is for but blst_pairing_mul_n_aggregate_pk_in_g1
is not documented.
Lines 7 to 34 in 6d6dec3
It seems like it's computing ฮป0 e(PK0, H(msg0)) ฮป1 e(PK1, H(msg1)) ...
with ฮปi != 1
This is a placeholder issue to track swig/swig#1746, which adds node.js v12+ support to swig. And to provide a download point for pre-generated wrapper, blst_wrap.cpp, for those who don't want to experiment with swig compilation.
Can this library be used as a signature for filecoin?
The current implementation of inversion follows closely @pornin's paper and uses an inner loop with 4 31-bit integers stored in 2 64-bit registers:
blst/src/asm/ctx_inverse_mod_384-x86_64.pl
Lines 904 to 912 in 575c3dd
https://github.com/pornin/bingcd/blob/700cc4d/src/gf25519.c#L1098-L1145
Instead it's possible to store 4 62-bit integers in 2 128-bit SIMD which are available in x86-64 (which implies SSE2) and ARM Neon.
This allows the inner loop to use 62 iterations instead of 31 and actually should remove the need for 2 distinct loops.
The main benefits would be:
However I do not know if in pure SSE2 it's possible to emulate CMOV efficiently and conditional swap.
In terms of use-cases:
Sagnificant performance degradation for aggregate method in jblst.
This was noticed while benchmark tests for BLS aggregation method in jblst. The library from v0.1.0-RELEASE showed ~150MB/sec performance on my 6 core Rysen 5. I decided to upgrade to the latest jblst v 0.3.3-1. After this the same test showed ~3.5MB/sec. The benchmark test is published in github repo here: https://github.com/RiV-chain/riv-benchmark/blob/main/src/main/java/org/riv/SigningTest.java#L29
I could find the part of Java code and compare what difference in the native methods invokation:
v0.1.0-RELEASE
public static BlstSignature aggregate(List<BlstSignature> signatures) {
List<BlstSignature> finiteSignatures =
signatures.stream().filter(sig -> !sig.isInfinity()).collect(Collectors.toList());
Optional<BlstSignature> invalidSignature =
finiteSignatures.stream().filter(s -> !s.isValid).findFirst();
if (invalidSignature.isPresent()) {
throw new IllegalArgumentException(
"Can't aggregate invalid signature: " + invalidSignature.get());
}
p2 sum = new p2();
try {
blst.p2_from_affine(sum, finiteSignatures.get(0).ec2Point);
for (int i = 1; i < finiteSignatures.size(); i++) {
blst.p2_add_affine(sum, sum, finiteSignatures.get(i).ec2Point);
}
p2_affine res = new p2_affine();
blst.p2_to_affine(res, sum);
return new BlstSignature(res, true);
} finally {
sum.delete();
}
}
v0.3.3-1
public static BlstSignature aggregate(List<BlstSignature> signatures) {
Optional<BlstSignature> invalidSignature =
signatures.stream().filter(s -> !s.isValid).findFirst();
if (invalidSignature.isPresent()) {
throw new IllegalArgumentException(
"Can't aggregate invalid signature: " + invalidSignature.get());
}
P2 sum = new P2();
for (BlstSignature finiteSignature : signatures) {
sum.aggregate(finiteSignature.ec2Point);
}
return new BlstSignature(sum.to_affine(), true);
}
Current NodeJS bindings are not able to run in a multi-threaded setup with worker_threads reliably. Most of the times the parent process crashes with a segmentation fault. I'm working on creating a minimal reproducible POC that always crashes, but it's proving very difficult.
First of all, could you say if current SWIG NodeJS bindings are safe to multi-thread? There's some directions about to load the same bindings in multiple threads in the NodeJS docs. I wonder if the current SWIG setup achieves any of this directions. https://nodejs.org/api/addons.html#addons_worker_support
In our particular case I would be happy with a threaded setup where threads don't share any resources and only communicate with the main thread through messages.
As of time of writing, polkadot's substrate does not use any impl of BLS, since a part of runtime is compiled to wasm and current bls crates are to slow for it.
Do you have some plans to add support for wasm target in clang?
First, thanks again for producing this library!
During integration I noticed some odd behaviour and I tracked it down to a difference between compiling in release/debug.
For example:
cargo test
: all tests pass.cargo test --release
: some tests fail.Run cargo test --release
in bindings/rust/
.
cargo test --release
Finished release [optimized] target(s) in 0.02s
Running target/release/deps/blst-a42debb43dd162a7
running 19 tests
test bindgen_test_layout_blst_fp ... ok
test bindgen_test_layout_blst_fp12 ... ok
test bindgen_test_layout_blst_fp2 ... ok
test bindgen_test_layout_blst_fp6 ... ok
test bindgen_test_layout_blst_fr ... ok
test bindgen_test_layout_blst_p1 ... ok
test bindgen_test_layout_blst_p1_affine ... ok
test bindgen_test_layout_blst_p2 ... ok
test bindgen_test_layout_blst_p2_affine ... ok
test bindgen_test_layout_blst_pairing ... ok
test bindgen_test_layout_blst_scalar ... ok
test min_pk::tests::test_serialization ... ok
test min_sig::tests::test_serialization ... ok
test min_sig::tests::test_sign ... FAILED
test min_pk::tests::test_sign ... FAILED
test min_sig::tests::test_aggregate ... FAILED
test min_sig::tests::test_multiple_agg_sigs ... FAILED
test min_pk::tests::test_aggregate ... FAILED
test min_pk::tests::test_multiple_agg_sigs ... FAILED
failures:
---- min_sig::tests::test_sign stdout ----
thread 'min_sig::tests::test_sign' panicked at 'assertion failed: `(left == right)`
left: `BLST_VERIFY_FAIL`,
right: `BLST_SUCCESS`', src/lib.rs:1340:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- min_pk::tests::test_sign stdout ----
thread 'min_pk::tests::test_sign' panicked at 'assertion failed: `(left == right)`
left: `BLST_VERIFY_FAIL`,
right: `BLST_SUCCESS`', src/lib.rs:1300:5
---- min_sig::tests::test_aggregate stdout ----
thread 'min_sig::tests::test_aggregate' panicked at 'assertion failed: `(left == right)`
left: `[BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL]`,
right: `[BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS]`', src/lib.rs:1340:5
---- min_sig::tests::test_multiple_agg_sigs stdout ----
thread 'min_sig::tests::test_multiple_agg_sigs' panicked at 'assertion failed: `(left == right)`
left: `[BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL]`,
right: `[BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS]`', src/lib.rs:1340:5
---- min_pk::tests::test_aggregate stdout ----
thread 'min_pk::tests::test_aggregate' panicked at 'assertion failed: `(left == right)`
left: `[BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL]`,
right: `[BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS]`', src/lib.rs:1300:5
---- min_pk::tests::test_multiple_agg_sigs stdout ----
thread 'min_pk::tests::test_multiple_agg_sigs' panicked at 'assertion failed: `(left == right)`
left: `[BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL, BLST_VERIFY_FAIL]`,
right: `[BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS, BLST_SUCCESS]`', src/lib.rs:1300:5
failures:
min_pk::tests::test_aggregate
min_pk::tests::test_multiple_agg_sigs
min_pk::tests::test_sign
min_sig::tests::test_aggregate
min_sig::tests::test_multiple_agg_sigs
min_sig::tests::test_sign
test result: FAILED. 13 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--lib'
In the api calls, like
pub fn blst_fp_sqr(ret: *mut blst_fp, a: *const blst_fp);
does ret
need to be cleared, or can it contain another value, and will be automatically be cleared?
In the Rust bindings, in order to use Signature::verify_multiple_aggregate_signatures
you must initialize some blst_scalar
values.
AFAIK, the only way to do this is via the unsafe blst_scalar_from_*
functions.
It would be great if the bindings could wrap these in a non-unsafe
function, if they are indeed as safe as all the other times we call the unsafe extern "C"
functions.
export CC="clang"
export CFLAGS="-fsanitize=fuzzer-no-link"
git clone --depth 1 https://github.com/supranational/blst
cd blst/
./build.sh
echo -e "#include \"bindings/blst.h\"\n int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) { blst_fp12_one(); return 0; }" >f.c
$CC $CFLAGS -fsanitize=fuzzer f.c libblst.a
This used to work but since commit 54e2be4 this now produces many errors such as:
libblst.a(blst.o):(.data._ZN11__sanitizer15IOCTL_KDGKBSENTE+0x0): multiple definition of `__sanitizer::IOCTL_KDGKBSENT'
/usr/lib/llvm-11/lib/clang/11.1.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a(sanitizer_platform_limits_posix.cpp.o):(.data._ZN11__sanitizer15IOCTL_KDGKBSENTE+0x0): first defined here
libblst.a(blst.o): In function `__sanitizer::StartReportDeadlySignal()':
(.text._ZN11__sanitizer23StartReportDeadlySignalEv+0x0): multiple definition of `__sanitizer::StartReportDeadlySignal()'
/usr/lib/llvm-11/lib/clang/11.1.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a(sanitizer_symbolizer_report.cpp.o):(.text._ZN11__sanitizer23StartReportDeadlySignalEv+0x0): first defined here
libblst.a(blst.o): In function `__sanitizer::SetAlternateSignalStack()':
(.text._ZN11__sanitizer23SetAlternateSignalStackEv+0x0): multiple definition of `__sanitizer::SetAlternateSignalStack()'
/usr/lib/llvm-11/lib/clang/11.1.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a(sanitizer_posix_libcdep.cpp.o):(.text._ZN11__sanitizer23SetAlternateSignalStackEv+0x0): first defined here
libblst.a(blst.o): In function `__sanitizer::ThreadRegistry::JoinThread(unsigned int, void*)':
(.text._ZN11__sanitizer14ThreadRegistry10JoinThreadEjPv+0x0): multiple definition of `__sanitizer::ThreadRegistry::JoinThread(unsigned int, void*)'
/usr/lib/llvm-11/lib/clang/11.1.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a(sanitizer_thread_registry.cpp.o):(.text._ZN11__sanitizer14ThreadRegistry10JoinThreadEjPv+0x0): first defined here
Is there anything we can do about this?
Is the addition chain to exponentiate by a^((p^2-9)/16) faster than the method mentioned in
Adj, G. and F. Rodriguez-Henriquez, "Square Root Computation over Even Extension Fields",
DOI 10.1109/TC.2013.145, pages 2829-2841, In IEEE
Transactions on Computers. vol 63 issue 11, November 2014,
https://doi.org/10.1109/TC.2013.145.
https://eprint.iacr.org/2012/685.pdf
In Nim, assuming we have sqrt_invsqrt
which returns both the sqrt and inverse sqrt on Fp
func sqrt_if_square*(a: var QuadraticExt): SecretBool =
## If ``a`` is a square, compute the square root of ``a``
## if not, ``a`` is unmodified.
##
## The square root, if it exist is multivalued,
## i.e. both xยฒ == (-x)ยฒ
## This procedure returns a deterministic result
#
# Implementation via the complex method (which confusingly does not require a complex field)
# We make it constant-time via conditional copies
mixin fromComplexExtension # TODO: relax this
static: doAssert a.fromComplexExtension()
var t1{.noInit.}, t2{.noInit.}, t3{.noInit.}: typeof(a.c0)
t1.square(a.c0) # a0ยฒ
t2.square(a.c1) # - ฮฒ a1ยฒ with ฮฒ = ๐ยฒ in a complex extension field
t1 += t2 # a0 - (-1) a1ยฒ
result = t1.sqrt_if_square()
t2.sum(a.c0, t1)
t2.div2()
t3.diff(a.c0, t1)
t3.div2()
let quadResidTest = t2.isSquare()
t2.ccopy(t3, not quadResidTest)
sqrt_invsqrt(sqrt = t1, invsqrt = t3, t2)
a.c0.ccopy(t1, result)
t3.div2()
t3 *= a.c1
a.c1.ccopy(t3, result)
The Eth2 test vectors contain a test that requires the infinity signature to represent a valid signature by the infinity pubkey across any message:
input: {pubkey: '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
message: '0xabababababababababababababababababababababababababababababababab', signature: '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'}
output: true
The output: true
here means that we should consider this pubkey/message/signature combination to be valid.
Presently blst
will return output: false
for the above test vector. I'm wondering if this project would expect to change their behaviour to match the Eth2 spec or if it plans to leave it as-is?
Thank you for your time :)
Throughout CPP API the DST
is defined as const std::string
Was it done intentionally?
Cause C API defines it as const byte*
and the spec also defines it as octet string
:
Domain separation is enforced with a domain separation tag (DST),
which is an octet string.
The header file that describes the function uses a different type than the actual implementation - this may lead to miscompiles / optimization errors as there may be subtle differences between bool
and limb_t
.
Line 142 in a8398ed
Line 244 in a8398ed
blst/bindings/blst_aux.h:17:6: warning: type of โblst_p1_affine_is_equalโ does not match original declaration [-Wlto-type-mismatch]
17 | bool blst_p1_affine_is_equal(const blst_p1_affine *a, const blst_p1_affine *b);
| ^
blst/src/exports.c:241:8: note: return value type mismatch
241 | limb_t blst_p1_affine_is_equal(const POINTonE1_affine *a,
| ^
blst/src/exports.c:241:8: note: type โlimb_tโ should match type โ_Boolโ
blst/src/exports.c:241:8: note: โblst_p1_affine_is_equalโ was previously declared here
blst/src/exports.c:241:8: note: code may be misoptimized unless โ-fno-strict-aliasingโ is used
Hello,
Great Library !
Do you plan to migrate to hash to curve v9?
https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09
thanks
Is there any chance of getting hash to scalar implemented?
https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.html#section-5-4
The hash_to_field function is also suitable for securely hashing to scalars. For example, when hashing to scalars for an elliptic curve (sub)group with prime order r, it suffices to instantiate hash_to_curve with target field GF(r).
I've been working on adding it but wanted to check the viability of this change before going too much further with it.
FYI, BLST is incompatible with the following GCC flag: -ftree-loop-vectorize
This causes the scalar multiplication to miscompile and easily noticeable on blst_sk_to_pk_in_g1
function.
Unfortunately it is automatically activated with -O3
. You might want to have a note about not compiling with -O3
or using -fno-tree-loop-vectorize
to deactivate the offending flag.
Tested with GCC v10.1.0
Clang works fine (v10.0.1)
Blst currently supports x86_64 and ARMv8 through the asm routines. This is a feature request to add asm routines to enable Blst for the IBMz aka s390x architecture and demonstrate appropriate, good performance.
A financial bounty from IBM is open for discussion.
The rust bindings uncompress()
and deserialize()
for each point object do not ensure the correct number of bytes are supplied before calling.
This is an issue if someone calls uncompress(&[])
with an empty array. The c code assumes it was passed a 48 byte array and will read the next sections of memory.
I think this will have to be checked in the rust uncompress()
/ deserialize()
functions.
For uncompress()
maybe something along the lines of pk_comp.len() == $pk_comp_size
.
It's generally safe to do a strict check on length to prevent signature malleability by appending bytes.
A little more challenging for deserialize()
as we have to handle the compressed and uncompressed byte lengths. But a check of the compression bit should do the trick.
Thought I'd open the issue to get the current status of subgroup checks for signatures and public keys in the rust bindings and hopefully reach a conclusion.
A quick summary of previous discussions (sorry if I've forgotten any):
Check subgroups on deserialisation
Note: I believe this is currently what the go bindings do?
Pros - simple, secure, if points are cached in BLST format the subgroup check is done once per point.
Cons - if the same signature / public key is deserialised/not cached in BLST format, there are unnecessary subgroup checks
Always check signatures, skip public keys only on PoPVerified public keys (e.g. when calling fast_aggregate_verify()
public keys are always PoPVerified).
Pros - Faster deserialisation times, public keys will only be checked once
Cons - Wasteful if we verify signatures then aggregate them, slower if we use public keys multiple times for non-PoPVerified methods.
Always check signatures and publickeys
Pros - this matches the BLS Spec
Cons - wasteful as points will have the subgroup checked during every use and public keys are likely used numerous times.
Personally I'm leaning towards option 1 to match the go bindings and for it's simplicity. Option 2 has a few edge cases to be weary of such as if we do fast_aggregate_verify_multiple()
which multiplies a signature by random integer so we'd have to do subgroup checks before multiplication and aggregating signatures into an which individually aren't in the correct subgroup but aggregated are.
When cross-compiling for aarch64 from x86_64, I'm receiving a linking error about missing functions (below).
I'm using a commit descended from 5c41509, specifically the head of #26
Compiling in portable mode resolves the issue (as the polyfills are used instead).
note: /target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_affine_Serialize_BE':
server.c:(.text.POINTonE1_affine_Serialize_BE+0x50): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE1_affine_Serialize_BE+0xa0): undefined reference to `fromx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `reciprocal_fp':
server.c:(.text.reciprocal_fp+0x98): undefined reference to `sqrx_mont_384'
server.c:(.text.reciprocal_fp+0xc4): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0xe4): undefined reference to `sqrx_mont_384'
server.c:(.text.reciprocal_fp+0x108): undefined re```ference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x130): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x154): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x184): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x1a8): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.reciprocal_fp+0x1d4): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `reciprocal_fp':
server.c:(.text.reciprocal_fp+0x2ac): undefined reference to `sqrx_mont_384'
server.c:(.text.rec<details><summary>Backtrace</summary>
<p>
<code>iprocal_fp+0x2d0): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x2f4): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x318): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp+0x340): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.reciprocal_fp+0x368): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.reciprocal_fp+0x390): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.reciprocal_fp+0x3b8): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.reciprocal_fp+0x3e0): undefined reference to `sqrx_n_mul_mont_383'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.reciprocal_fp+0x408): more undefined references to `sqrx_n_mul_mont_383' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `recip_sqrt_fp_3mod4':
server.c:(.text.recip_sqrt_fp_3mod4+0x98): undefined reference to `sqrx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0xc8): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0xe8): undefined reference to `sqrx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x10c): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x134): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x158): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x188): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x1ac): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.recip_sqrt_fp_3mod4+0x1d8): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `recip_sqrt_fp_3mod4':
server.c:(.text.recip_sqrt_fp_3mod4+0x2b0): undefined reference to `sqrx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x2d4): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x2f8): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x31c): undefined reference to `mulx_mont_384'
server.c:(.text.recip_sqrt_fp_3mod4+0x344): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.recip_sqrt_fp_3mod4+0x36c): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.recip_sqrt_fp_3mod4+0x394): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.recip_sqrt_fp_3mod4+0x3bc): undefined reference to `sqrx_n_mul_mont_383'
server.c:(.text.recip_sqrt_fp_3mod4+0x3e4): undefined reference to `sqrx_n_mul_mont_383'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.recip_sqrt_fp_3mod4+0x40c): more undefined references to `sqrx_n_mul_mont_383' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `recip_sqrt_fp_3mod4':
server.c:(.text.recip_sqrt_fp_3mod4+0xda0): undefined reference to `sqrx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqrt_fp':
server.c:(.text.sqrt_fp+0x68): undefined reference to `mulx_mont_384'
server.c:(.text.sqrt_fp+0x88): undefined reference to `sqrx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_fp_times_Zz':
server.c:(.text.map_fp_times_Zz+0x70): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sigma':
server.c:(.text.sigma+0x34): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `line_by_Px2':
server.c:(.text.line_by_Px2+0x44): undefined reference to `mulx_mont_384'
server.c:(.text.line_by_Px2+0x60): undefined reference to `mulx_mont_384'
server.c:(.text.line_by_Px2+0x78): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.line_by_Px2+0x9c): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_affine_Compress_BE':
server.c:(.text.POINTonE1_affine_Compress_BE+0x48): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE1_affine_Compress_BE+0x90): undefined reference to `sgn0x_pty_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_fp':
server.c:(.text.map_fp+0x64): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `isogeny_map_to_E1':
server.c:(.text.isogeny_map_to_E1+0x7c): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0xa4): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0xc8): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0xe8): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x110): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x130): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x158): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x180): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x1a8): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x1c8): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x1f0): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x210): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x238): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x258): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x288): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x2d0): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x378): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x3b4): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x404): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.isogeny_map_to_E1+0x474): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `isogeny_map_to_E1':
server.c:(.text.isogeny_map_to_E1+0x528): undefined reference to `sqrx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x54c): undefined reference to `mulx_mont_384'
server.c:(.text.isogeny_map_to_E1+0x570): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_Uncompress':
server.c:(.text.POINTonE1_Uncompress+0x1a0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_Uncompress+0x1c0): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_Uncompress+0x1e4): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_Uncompress+0x24c): undefined reference to `sgn0x_pty_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `reciprocal_fp2':
server.c:(.text.reciprocal_fp2+0x60): undefined reference to `sqrx_mont_384'
server.c:(.text.reciprocal_fp2+0x80): undefined reference to `sqrx_mont_384'
server.c:(.text.reciprocal_fp2+0xc8): undefined reference to `mulx_mont_384'
server.c:(.text.reciprocal_fp2+0xec): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_double':
server.c:(.text.POINTonE1_double+0x60): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_double+0x8c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_double+0xac): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_double+0xe4): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_double+0x150): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_double+0x1b4): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_double+0x1fc): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_add':
server.c:(.text.POINTonE1_add+0x7c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add+0xa0): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add+0xcc): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x100): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x130): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x15c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x184): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.POINTonE1_add+0x1b0): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_add':
server.c:(.text.POINTonE1_add+0x200): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add+0x228): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x280): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x2a0): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add+0x318): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x340): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add+0x39c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add+0x3e8): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_dadd':
server.c:(.text.POINTonE1_dadd+0x94): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0xd8): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0xf8): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0x11c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x14c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0x178): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x1c0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x1e8): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x20c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x230): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.POINTonE1_dadd+0x254): more undefined references to `mulx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_dadd':
server.c:(.text.POINTonE1_dadd+0x334): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0x358): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x37c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x3a0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x3c4): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x3e4): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd+0x430): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd+0x468): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `hash_to_field':
server.c:(.text.hash_to_field+0x3b0): undefined reference to `redcx_mont_384'
server.c:(.text.hash_to_field+0x3cc): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_affine_Serialize_BE':
server.c:(.text.POINTonE2_affine_Serialize_BE+0x54): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE2_affine_Serialize_BE+0xa4): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE2_affine_Serialize_BE+0xf4): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE2_affine_Serialize_BE+0x148): undefined reference to `fromx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_fp2_times_Zz':
server.c:(.text.map_fp2_times_Zz+0x70): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `qi_x_iwsc':
server.c:(.text.qi_x_iwsc+0x50): undefined reference to `mulx_mont_384x'
server.c:(.text.qi_x_iwsc+0x68): undefined reference to `mulx_mont_384'
server.c:(.text.qi_x_iwsc+0x80): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `qi_y_iwsc':
server.c:(.text.qi_y_iwsc+0x60): undefined reference to `mulx_mont_384x'
server.c:(.text.qi_y_iwsc+0xb8): undefined reference to `mulx_mont_384'
server.c:(.text.qi_y_iwsc+0xdc): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `psi':
server.c:(.text.psi+0x68): undefined reference to `sqrx_mont_384x'
server.c:(.text.psi+0x90): undefined reference to `mulx_mont_384x'
server.c:(.text.psi+0xc4): undefined reference to `mulx_mont_384x'
server.c:(.text.psi+0x108): undefined reference to `mulx_mont_384x'
server.c:(.text.psi+0x138): undefined reference to `mulx_mont_384x'
server.c:(.text.psi+0x15c): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.psi+0x184): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `psi':
server.c:(.text.psi+0x1a4): undefined reference to `sqrx_mont_384x'
server.c:(.text.psi+0x1c8): undefined reference to `mulx_mont_384x'
server.c:(.text.psi+0x1ec): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_affine_Compress_BE':
server.c:(.text.POINTonE2_affine_Compress_BE+0x54): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE2_affine_Compress_BE+0xa4): undefined reference to `fromx_mont_384'
server.c:(.text.POINTonE2_affine_Compress_BE+0xf0): undefined reference to `sgn0x_pty_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_affine_on_curve':
server.c:(.text.POINTonE2_affine_on_curve+0x58): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_affine_on_curve+0x7c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_affine_on_curve+0xb4): undefined reference to `sqrx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_Deserialize_BE':
server.c:(.text.POINTonE2_Deserialize_BE+0x2a8): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE2_Deserialize_BE+0x2cc): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE2_Deserialize_BE+0x2f0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE2_Deserialize_BE+0x314): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_fp2':
server.c:(.text.map_fp2+0x64): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqr_n_mul_fp2':
server.c:(.text.sqr_n_mul_fp2+0x4c): undefined reference to `sqrx_mont_382x'
server.c:(.text.sqr_n_mul_fp2+0x8c): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `recip_sqrt_fp2_9mod16':
server.c:(.text.recip_sqrt_fp2_9mod16+0x98): undefined reference to `sqrx_mont_384x'
server.c:(.text.recip_sqrt_fp2_9mod16+0xd0): undefined reference to `mulx_mont_384x'
server.c:(.text.recip_sqrt_fp2_9mod16+0xf4): undefined reference to `mulx_mont_384x'
server.c:(.text.recip_sqrt_fp2_9mod16+0x118): undefined reference to `mulx_mont_384x'
server.c:(.text.recip_sqrt_fp2_9mod16+0x13c): undefined reference to `mulx_mont_384x'
server.c:(.text.recip_sqrt_fp2_9mod16+0x160): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.recip_sqrt_fp2_9mod16+0x184): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_add':
server.c:(.text.POINTonE2_add+0x7c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add+0xa0): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add+0xcc): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x100): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x130): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x15c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x184): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.POINTonE2_add+0x1b0): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_add':
server.c:(.text.POINTonE2_add+0x200): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add+0x228): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x280): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x2a0): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add+0x318): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x340): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add+0x39c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add+0x3e8): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `line_add':
server.c:(.text.line_add+0x7c): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_add+0xac): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0xdc): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x100): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x140): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_add+0x194): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x1f4): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x214): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_add+0x278): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x2b4): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x314): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_add+0x364): undefined reference to `mulx_mont_384x'
server.c:(.text.line_add+0x38c): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_dadd':
server.c:(.text.POINTonE2_dadd+0x94): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0xd8): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0xf8): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x11c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x14c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x178): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x1c0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x1e8): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x20c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x230): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.POINTonE2_dadd+0x254): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_dadd':
server.c:(.text.POINTonE2_dadd+0x334): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x358): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x37c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x3a0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x3c4): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x3e4): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x430): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd+0x468): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_double':
server.c:(.text.POINTonE2_double+0x60): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_double+0x8c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_double+0xac): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_double+0xe4): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_double+0x150): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_double+0x1b4): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_double+0x1fc): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `line_dbl':
server.c:(.text.line_dbl+0x78): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_dbl+0xa8): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_dbl+0xd4): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_dbl+0xfc): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_dbl+0x130): undefined reference to `sqrx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.line_dbl+0x1a8): more undefined references to `sqrx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `line_dbl':
server.c:(.text.line_dbl+0x294): undefined reference to `mulx_mont_384x'
server.c:(.text.line_dbl+0x2c8): undefined reference to `sqrx_mont_384x'
server.c:(.text.line_dbl+0x358): undefined reference to `mulx_mont_384x'
server.c:(.text.line_dbl+0x37c): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `frobenius_map_fp6':
server.c:(.text.frobenius_map_fp6+0xf0): undefined reference to `mulx_mont_384x'
server.c:(.text.frobenius_map_fp6+0x120): undefined reference to `mulx_mont_384'
server.c:(.text.frobenius_map_fp6+0x158): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `frobenius_map_fp12':
server.c:(.text.frobenius_map_fp12+0x78): undefined reference to `mulx_mont_384x'
server.c:(.text.frobenius_map_fp12+0x90): undefined reference to `mulx_mont_384x'
server.c:(.text.frobenius_map_fp12+0xb8): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_from_Jacobian':
server.c:(.text.POINTonE2_from_Jacobian+0x8c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_from_Jacobian+0xb0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_from_Jacobian+0xd4): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_from_Jacobian+0xf8): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_from_Jacobian':
server.c:(.text.POINTonE1_from_Jacobian+0x8c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_from_Jacobian+0xb0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_from_Jacobian+0xd4): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_from_Jacobian+0xf8): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqr_fp4':
server.c:(.text.sqr_fp4+0x5c): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp4+0x74): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp4+0x100): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp4+0x120): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp4+0x130): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp4+0x1a0): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp4+0x1c0): undefined reference to `redcx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqr_fp6':
server.c:(.text.sqr_fp6+0x64): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp6+0x88): undefined reference to `mulx_382x'
server.c:(.text.sqr_fp6+0xc4): undefined reference to `mulx_382x'
server.c:(.text.sqr_fp6+0xfc): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp6+0x140): undefined reference to `sqrx_382x'
server.c:(.text.sqr_fp6+0x214): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp6+0x234): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp6+0x2a8): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp6+0x2c8): undefined reference to `redcx_mont_384'
server.c:(.text.sqr_fp6+0x344): undefined reference to `redcx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.sqr_fp6+0x364): more undefined references to `redcx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `mul_by_xy0_fp6x2':
server.c:(.text.mul_by_xy0_fp6x2+0x5c): undefined reference to `mulx_382x'
server.c:(.text.mul_by_xy0_fp6x2+0x80): undefined reference to `mulx_382x'
server.c:(.text.mul_by_xy0_fp6x2+0x9c): undefined reference to `mulx_382x'
server.c:(.text.mul_by_xy0_fp6x2+0x148): undefined reference to `mulx_382x'
server.c:(.text.mul_by_xy0_fp6x2+0x1bc): undefined reference to `mulx_382x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.mul_by_xy00z0_fp12+0x74): more undefined references to `mulx_382x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `mul_by_xy00z0_fp12':
server.c:(.text.mul_by_xy00z0_fp12+0x2b0): undefined reference to `redcx_mont_384'
server.c:(.text.mul_by_xy00z0_fp12+0x2d0): undefined reference to `redcx_mont_384'
server.c:(.text.mul_by_xy00z0_fp12+0x2f0): undefined reference to `redcx_mont_384'
server.c:(.text.mul_by_xy00z0_fp12+0x310): undefined reference to `redcx_mont_384'
server.c:(.text.mul_by_xy00z0_fp12+0x330): undefined reference to `redcx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.mul_by_xy00z0_fp12+0x350): more undefined references to `redcx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqrt_align_fp2':
server.c:(.text.sqrt_align_fp2+0x6c): undefined reference to `sqrx_mont_384x'
server.c:(.text.sqrt_align_fp2+0x2d8): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `sqrt_fp2':
server.c:(.text.sqrt_fp2+0x5c): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_Uncompress':
server.c:(.text.POINTonE2_Uncompress+0x224): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE2_Uncompress+0x24c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE2_Uncompress+0x26c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_Uncompress+0x290): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_Uncompress+0x2f8): undefined reference to `sgn0x_pty_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_add_affine':
server.c:(.text.POINTonE2_add_affine+0x9c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0xc0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0xf4): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x118): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x158): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x1b4): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x210): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x238): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x298): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x2d8): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_add_affine+0x33c): undefined reference to `sqrx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_add_affine':
server.c:(.text.POINTonE1_add_affine+0x98): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add_affine+0xbc): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0xf0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x114): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x154): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x1b0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x20c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x234): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x294): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x2d4): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_add_affine+0x338): undefined reference to `sqrx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE2_dadd_affine':
server.c:(.text.POINTonE2_dadd_affine+0x8c): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0xdc): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x104): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x128): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x14c): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x1b0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x274): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x2a0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x2cc): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x2f0): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x314): undefined reference to `mulx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x338): undefined reference to `sqrx_mont_384x'
server.c:(.text.POINTonE2_dadd_affine+0x384): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `POINTonE1_dadd_affine':
server.c:(.text.POINTonE1_dadd_affine+0x8c): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0xdc): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x104): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x128): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x14c): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x1b0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x274): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x2a0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x2cc): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x2f0): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x314): undefined reference to `mulx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x338): undefined reference to `sqrx_mont_384'
server.c:(.text.POINTonE1_dadd_affine+0x384): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_to_isogenous_E1':
server.c:(.text.map_to_isogenous_E1+0x70): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x98): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0xb8): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x108): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x12c): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x154): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x1ec): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x210): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x238): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x260): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x298): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x2c0): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x2f4): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x31c): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x340): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x370): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x390): undefined reference to `sqrx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x400): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x428): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x44c): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x470): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x4e4): undefined reference to `sgn0x_pty_mont_384'
server.c:(.text.map_to_isogenous_E1+0x504): undefined reference to `sgn0x_pty_mont_384'
server.c:(.text.map_to_isogenous_E1+0x540): undefined reference to `mulx_mont_384'
server.c:(.text.map_to_isogenous_E1+0x564): undefined reference to `mulx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `mul_fp6x2':
server.c:(.text.mul_fp6x2+0x58): undefined reference to `mulx_382x'
server.c:(.text.mul_fp6x2+0x88): undefined reference to `mulx_382x'
server.c:(.text.mul_fp6x2+0xb8): undefined reference to `mulx_382x'
server.c:(.text.mul_fp6x2+0x110): undefined reference to `mulx_382x'
server.c:(.text.mul_fp6x2+0x210): undefined reference to `mulx_382x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.mul_fp6x2+0x304): more undefined references to `mulx_382x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `mul_fp12':
server.c:(.text.mul_fp12+0x230): undefined reference to `redcx_mont_384'
server.c:(.text.mul_fp12+0x250): undefined reference to `redcx_mont_384'
server.c:(.text.mul_fp12+0x270): undefined reference to `redcx_mont_384'
server.c:(.text.mul_fp12+0x290): undefined reference to `redcx_mont_384'
server.c:(.text.mul_fp12+0x2b0): undefined reference to `redcx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.mul_fp12+0x2d0): more undefined references to `redcx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `inverse_fp12':
server.c:(.text.inverse_fp12+0x104): undefined reference to `sqrx_mont_384x'
server.c:(.text.inverse_fp12+0x128): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x16c): undefined reference to `sqrx_mont_384x'
server.c:(.text.inverse_fp12+0x1a0): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x1dc): undefined reference to `sqrx_mont_384x'
server.c:(.text.inverse_fp12+0x208): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x240): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x26c): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x2b8): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x2f4): undefined reference to `sqrx_mont_384'
server.c:(.text.inverse_fp12+0x31c): undefined reference to `sqrx_mont_384'
server.c:(.text.inverse_fp12+0x374): undefined reference to `mulx_mont_384'
server.c:(.text.inverse_fp12+0x3a0): undefined reference to `mulx_mont_384'
server.c:(.text.inverse_fp12+0x3e0): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x40c): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x430): undefined reference to `mulx_mont_384x'
server.c:(.text.inverse_fp12+0x464): undefined reference to `redcx_mont_384'
server.c:(.text.inverse_fp12+0x484): undefined reference to `redcx_mont_384'
server.c:(.text.inverse_fp12+0x4a4): undefined reference to `redcx_mont_384'
server.c:(.text.inverse_fp12+0x4c4): undefined reference to `redcx_mont_384'
server.c:(.text.inverse_fp12+0x4e4): undefined reference to `redcx_mont_384'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.inverse_fp12+0x504): more undefined references to `redcx_mont_384' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_to_isogenous_E2':
server.c:(.text.map_to_isogenous_E2+0x74): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0xa0): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0xc0): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x110): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x134): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x15c): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x1fc): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x224): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x24c): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x26c): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x2a4): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x2cc): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x30c): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x330): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x354): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x38c): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x3d0): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x3f8): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.map_to_isogenous_E2+0x41c): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_to_isogenous_E2':
server.c:(.text.map_to_isogenous_E2+0x52c): undefined reference to `sgn0x_pty_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x54c): undefined reference to `sgn0x_pty_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x5a0): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_isogenous_E2+0x5c4): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_to_g2':
server.c:(.text.map_to_g2+0xb0): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_g2+0xd4): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_g2+0xf8): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_g2+0x13c): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_g2+0x1f0): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_g2+0x234): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_g2+0x288): undefined reference to `mulx_mont_384x'
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o):server.c:(.text.map_to_g2+0x2f4): more undefined references to `mulx_mont_384x' follow
/target/aarch64-unknown-linux-gnu/release/deps/libblst-4cbca568cdce9a19.rlib(server.o): In function `map_to_g2':
server.c:(.text.map_to_g2+0x3ac): undefined reference to `sqrx_mont_384x'
server.c:(.text.map_to_g2+0x3d4): undefined reference to `mulx_mont_384x'
server.c:(.text.map_to_g2+0x3fc): undefined reference to `mulx_mont_384x'
collect2: error: ld returned 1 exit status
I want to set threshold = 2, total = 3. There are two signatures to complete.
language: golang
As said in the title why is (0, 2)
mapped to the point at infinity?
/*
* Even though (0,2) is formally a point on E1 curve it's turned to
* infinity...
*/
Environment: Windows, MinGW-64 GCC compiler, cygwin
or msys2
shell.
When compiling blst_wrap.cpp
via bindings/java/run.me
the following error appears:
blst_wrap.cpp:194:21: error: 'long long long' is too long for GCC
194 | typedef long long __int64;
Just commenting that line in generated blst_wrap.cpp
does the trick - everything builds fine
Here is what found out:
MinGW GCC has the header _mingw.h
which does #define __int64 long long
The above breaks that some very old SWIG tweak (it was added more than 16 years ago):
/* Fix for jlong on some versions of gcc on Windows */
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
typedef long long __int64;
#endif
The above code comes from the SWIG javahead.swg
include
FYI: the _mingw.h
is included via the following dependencies:
. ../blst.hpp
.. E:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/string
... E:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/char_traits.h
.... E:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/postypes.h
..... E:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/cwchar
...... E:/TDM-GCC-64/x86_64-w64-mingw32/include/wchar.h
....... E:/TDM-GCC-64/x86_64-w64-mingw32/include/corecrt.h
........ E:/TDM-GCC-64/x86_64-w64-mingw32/include/_mingw.h
It actually looks more like a SWIG issue. They should probably add something like && !defined(__int64)
to their macro condition.
Though I'd like to ask you guys first as C/C++ gurus if we can fix/workaround this on Blst or our Teku side?
It would be nice to be able to provide a custom hash routine to support other algorithms, such as "BLS12381G1_XMD:BLAKE2B_SSWU_RO_" for BBS+. OpenSSL includes support for "blake2b512".
Also looks like blake2b might make it into both Ethereum and Zcash. My interest is more around BBS+ though.
ethereum/EIPs#2129
Whatever the case, an option to use blake2b512 would be a nice addition.
Looking over expand_message_xmd in https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.html
I have tried to integrate blst_fp2_sqrt
into blstrs
, but have run into an issue with this test case:
https://github.com/filecoin-project/blstrs/blob/master/src/fp2.rs#L935-L978
It fails with
left: `Fp2 {
c0: Fp(0x090a7bae7eacfad4c30069b48d39ec66d6f82c12b68250ebfa02f6bba490b7a1afb4216bc88d749c794c664d8fbd51e6),
c1: Fp(0x112941eaa55e8369a6526cae32ee3b2df8f2209a00d547a43e8ec2f2249f063ca83ba6b84bec9bb7f965acb03df5c359)
}`,
right: `Fp2 {
c0: Fp(0x10f6963bbad2ebc5881b3e01b611c0708d7f1f723d02c1d36d2ddbe552203e826ef7de92e8c68b6340b299b2704258c5),
c1: Fp(0x08d7cfff94216330a4c93b08105d71a96b852aeaf2afcb1b28a20faed211efe77670594665676447c099534fc209e752)
}`', src/fp2.rs:946:9
all other test cases pass strangely enough.
There is a new paper https://eprint.iacr.org/2021/1130.pdf from M. Scott, which allows to speedup group membership checks considerably. Could be very useful to implement
It would be great to see how fast the lib is, from README
Quoting @Nashatyrev in #54.
- (codestyle nit not directly related to this PR) there are methods like
class P1 { P1 add(P1 a); }
which modify and returnthis
instance. From my perspective they could be erroneously interpreted as that a new instance is returned andthis
instance is left unmodified. Not sure about common C++ patterns, but Java dev would likely misinterpret this. Does it make sense to returnvoid
from these methods to avoid such misuse?
This has been reported by a few of our users prysmaticlabs/prysm#7312 . We just released a new release of our client with support for blst
. However a few users running on ARM64
have failed with the above error and also a user running on debian 10 (x86_64) have also reported getting the above error.
Below is an example snapshot of the stack trace.
SIGILL: illegal instruction
PC=0x146f2a1 m=3 sigcode=2
goroutine 0 [idle]:
runtime: unknown pc 0x146f2a1
stack: frame={sp:0x7f8db214ecf0, fp:0x0} stack=[0x7f8db194f288,0x7f8db214ee88)
00007f8db214ebf0: 000000000044d420 <runtime.(*pageAlloc).update+1296> 00007f8db2963e00
00007f8db214ec00: 000000000000000d 00007f8db214ed38
00007f8db214ec10: 000000000048c991 <runtime.goexit+1> 00000000000eaf57
00007f8db214ec20: 00000000013df594 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).Start+5236> 000008f800aec26f
00007f8db214ec30: 00000000013db920 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).processFetchedData+1088> ffffffff00aeae53
00007f8db214ec40: 00000000013da864 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).roundRobinSync+1124> ffffffff00aeab55
00007f8db214ec50: 00000000013df593 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).Start+5235> ffffffff00aeca1a
00007f8db214ec60: 0000000000000000 0000000000000000
00007f8db214ec70: 00000000013da865 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).roundRobinSync+1125> 0000070000aea68a
00007f8db214ec80: 00000000013dda36 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).processBatchedBlocks+1942> ffffffff00aebd4e
00007f8db214ec90: 0000000001013f0a <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ExecuteStateTransitionNoVerifyAnySig+458> ffffffff008776b6
00007f8db214eca0: 0000000000b9460d <github.com/prysmaticlabs/prysm/beacon-chain/state.NewFieldTrie+877> 000000c00055156f
00007f8db214ecb0: 0000000001015139 <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ProcessSlots+937> ffffffff008780e7
00007f8db214ecc0: 0000000000000000 0000000000000000
00007f8db214ecd0: 000000000101486d <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ProcessSlot+461> ffffffff00877beb
00007f8db214ece0: 0000000000431b59 <runtime.profilealloc+89> 00000018000ab8b0
00007f8db214ecf0: <89f3fffcfffcfffd 000000000146ccd7
00007f8db214ed00: 0000000000b9460c <github.com/prysmaticlabs/prysm/beacon-chain/state.NewFieldTrie+876> 00007f8db214eda0
00007f8db214ed10: 00007f8db214ed70 0000000001d4f400
00007f8db214ed20: 0000000000000080 000000c00c29ba40
00007f8db214ed30: 00007f8db214ee00 0000000001441333
00007f8db214ed40: 07d369807fd6a51e 5ce681b849ad9b70
00007f8db214ed50: 350427e9f5d63260 ddf4455750c7b9ff
00007f8db214ed60: 9c7e600381e7002a 00bdb40b883e391c
00007f8db214ed70: 07d369807fd6a51e 5ce681b849ad9b70
00007f8db214ed80: 350427e9f5d63260 ddf4455750c7b9ff
00007f8db214ed90: 9c7e600381e7002a 00bdb40b883e391c
00007f8db214eda0: 0000000002a6b408 00007f8da84751a8
00007f8db214edb0: 0000000000000001 00007f8da84751a8
00007f8db214edc0: 0000000000000000 000000c016f7c000
00007f8db214edd0: 00007f8db214ee18 000000c0116f3fb8
00007f8db214ede0: ffffffffffffffff 000000c0116f6000
runtime: unknown pc 0x146f2a1
stack: frame={sp:0x7f8db214ecf0, fp:0x0} stack=[0x7f8db194f288,0x7f8db214ee88)
00007f8db214ebf0: 000000000044d420 <runtime.(*pageAlloc).update+1296> 00007f8db2963e00
00007f8db214ec00: 000000000000000d 00007f8db214ed38
00007f8db214ec10: 000000000048c991 <runtime.goexit+1> 00000000000eaf57
00007f8db214ec20: 00000000013df594 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).Start+5236> 000008f800aec26f
00007f8db214ec30: 00000000013db920 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).processFetchedData+1088> ffffffff00aeae53
00007f8db214ec40: 00000000013da864 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).roundRobinSync+1124> ffffffff00aeab55
00007f8db214ec50: 00000000013df593 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).Start+5235> ffffffff00aeca1a
00007f8db214ec60: 0000000000000000 0000000000000000
00007f8db214ec70: 00000000013da865 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).roundRobinSync+1125> 0000070000aea68a
00007f8db214ec80: 00000000013dda36 <github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync.(*Service).processBatchedBlocks+1942> ffffffff00aebd4e
00007f8db214ec90: 0000000001013f0a <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ExecuteStateTransitionNoVerifyAnySig+458> ffffffff008776b6
00007f8db214eca0: 0000000000b9460d <github.com/prysmaticlabs/prysm/beacon-chain/state.NewFieldTrie+877> 000000c00055156f
00007f8db214ecb0: 0000000001015139 <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ProcessSlots+937> ffffffff008780e7
00007f8db214ecc0: 0000000000000000 0000000000000000
00007f8db214ecd0: 000000000101486d <github.com/prysmaticlabs/prysm/beacon-chain/core/state.ProcessSlot+461> ffffffff00877beb
00007f8db214ece0: 0000000000431b59 <runtime.profilealloc+89> 00000018000ab8b0
00007f8db214ecf0: <89f3fffcfffcfffd 000000000146ccd7
00007f8db214ed00: 0000000000b9460c <github.com/prysmaticlabs/prysm/beacon-chain/state.NewFieldTrie+876> 00007f8db214eda0
00007f8db214ed10: 00007f8db214ed70 0000000001d4f400
00007f8db214ed20: 0000000000000080 000000c00c29ba40
00007f8db214ed30: 00007f8db214ee00 0000000001441333
00007f8db214ed40: 07d369807fd6a51e 5ce681b849ad9b70
00007f8db214ed50: 350427e9f5d63260 ddf4455750c7b9ff
00007f8db214ed60: 9c7e600381e7002a 00bdb40b883e391c
00007f8db214ed70: 07d369807fd6a51e 5ce681b849ad9b70
00007f8db214ed80: 350427e9f5d63260 ddf4455750c7b9ff
00007f8db214ed90: 9c7e600381e7002a 00bdb40b883e391c
00007f8db214eda0: 0000000002a6b408 00007f8da84751a8
00007f8db214edb0: 0000000000000001 00007f8da84751a8
00007f8db214edc0: 0000000000000000 000000c016f7c000
00007f8db214edd0: 00007f8db214ee18 000000c0116f3fb8
00007f8db214ede0: ffffffffffffffff 000000c0116f6000
goroutine 248 [syscall]:
runtime.cgocall(0x143df10, 0xc0116f3fb8, 0x4b65ab3d1e582b89)
GOROOT/src/runtime/cgocall.go:133 +0x5b fp=0xc0116f3f88 sp=0xc0116f3f50 pc=0x427acb
github.com/supranational/blst/bindings/go._Cfunc_blst_p1_uncompress(0xc00c29ba40, 0xc0164d0750, 0xc000000000)
_cgo_gotypes.go:520 +0x4d fp=0xc0116f3fb8 sp=0xc0116f3f88 pc=0xbadbbd
github.com/supranational/blst/bindings/go.(*_Ctype_struct___4).Uncompress(0xc00c29ba40, 0xc0164d0750, 0x30, 0x30, 0x0)
blst.go:1392 +0x48 fp=0xc0116f3fe0 sp=0xc0116f3fb8 pc=0xbb3cd8
github.com/prysmaticlabs/prysm/shared/bls/blst.PublicKeyFromBytes(0xc0164d0750, 0x30, 0x30, 0xc00c0dce00, 0x1c, 0x8, 0xc000074700)
shared/bls/blst/public_key.go:39 +0x1d2 fp=0xc0116f40d0 sp=0xc0116f3fe0 pc=0xbb8882
github.com/prysmaticlabs/prysm/shared/bls.PublicKeyFromBytes(0xc0164d0750, 0x30, 0x30, 0xc00c0dce00, 0x20, 0xc018cef140, 0xc0116f41f4)
shared/bls/bls.go:24 +0x70 fp=0xc0116f4168 sp=0xc0116f40d0 pc=0xbcc010
github.com/prysmaticlabs/prysm/beacon-chain/core/helpers.RetrieveBlockSignatureSet(0xc0089259d0, 0xc0164d0750, 0x30, 0x30, 0xc009ca64e0, 0x60, 0x60, 0xc018cef100, 0x20, 0x20, ...)
This fails the moment we decompress a pubkey in the cgo call.
The provided ARM64 binary is compiled on a host linux x86_64 system using these instructions:
https://github.com/prysmaticlabs/prysm/blob/master/third_party/blst/blst.BUILD#L12
In line with what was used over here:
https://github.com/supranational/blst/blob/master/bindings/go/blst.go#L13
Are there any other flags we might be missing here ?
They were all running the commit from here:
This commit is about a month back, so was wondering if it might already be fixed in master
That issue is not directly related to blst
code, but rather a general SWIG question.
I've simplified the code for experiments:
test.h
:
typedef struct { uint64_t arr[4]; } scalar;
void fun1(scalar *ret);
void fun2(scalar s);
test.swg
:
%module "test"
%include "test.h";
The SWIG 4.0 Windows
was used for experiments.
If I generate the wrapper in this simple case with swig.exe test.swg
(result) or swig.exe -DSWIGWORDSIZE64 test.swg
(result) I've got opaque SWIGTYPE_p_uint64_t.java which is unusable
Some SO article led me to the following solution:
test.swg
:
%module "test"
%include "stdint.i";
%include "arrays_java.i";
%include "test.h";
with swig.exe test.swg
I've got the same result as earlier.
However with swig.exe -DSWIGWORDSIZE64 test.swg
I've finally got ability to pass the uint64_t
with java long[]
:
void setArr(long[] value)
But! As we run with -DSWIGWORDSIZE64
option the SWIG generated C wrapper code which uses unsigned long
to refer uint64_t
when copying Java arrays :
https://github.com/Nashatyrev/swig.test/blob/master/case.4/build/test_wrap.c#L810
if (!SWIG_JavaArrayInUlong(jenv, &jarr2, (unsigned long **)&arg2, jarg2)) return ;
On Windows unsigned long
is 32-bit so the code works incorrectly.
(btw on Linux the same generated code should work)
If you have some SWIG experience may be you can give me a hint how to handle this situation?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.