GithubHelp home page GithubHelp logo

supranational / blst Goto Github PK

View Code? Open in Web Editor NEW
437.0 21.0 157.0 1.88 MB

Multilingual BLS12-381 signature library

License: Apache License 2.0

C 13.75% Assembly 70.62% Go 5.21% Python 2.68% Rust 4.13% Batchfile 0.03% Shell 0.32% C++ 1.61% Java 0.06% JavaScript 0.07% TypeScript 0.17% Makefile 0.04% C# 1.28% HTML 0.04%
blst-library signatures blst eth2 filecoin bls12-381 hash-to-curve bls-signature

blst's People

Contributors

ajsutton avatar alinush avatar cemozerr avatar dannywillems avatar dapplion avatar dot-asm avatar gyuho avatar hellosupranational avatar huitseeker avatar jtraglia avatar kirk-baird avatar kwantam avatar michaelsproul avatar mratsim avatar nano-o avatar patrick-ogrady avatar paulhauner avatar sean-sn avatar simonatsn avatar stephenbuttolph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blst's Issues

missing methods proposed by the README.md when used in hello-word app with go 1.16

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 ?

EIP-2333

This is just a question.

The KeyGen function directly derive a secretKey from a seed and optional parameters. I guess this might be compliant with EIP-2333, but not very sure.

Would anyone please confirm it does, or how we derive masterKey and child keys with the provided functions? Thanks.

[Optim] SIMD for Pornin's GCD inverse

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:

$code.=<<___;
.type __inner_loop_31,\@abi-omnipotent
.align 32
__inner_loop_31: ################# by Thomas Pornin
mov \$0x7FFFFFFF80000000, $fg0 # |f0|=1, |g0|=0
mov \$0x800000007FFFFFFF, $fg1 # |f1|=0, |g1|=1
mov \$0x7FFFFFFF7FFFFFFF, $bias
.Loop_31:

https://github.com/pornin/bingcd/blob/700cc4d/src/gf25519.c#L1098-L1145

image

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:

  • for variable time inversion since we could eliminate more than 31 0 bits in a single iteration.
  • reducing bookkeeping since the hot loop is bigger and there is no more slow loop.
  • reducing general register pressure on x86-64 (if it was an issue).

However I do not know if in pure SSE2 it's possible to emulate CMOV efficiently and conditional swap.

In terms of use-cases:

  • inversion is used once for pairing but only represent a small portion of the total cost
  • inversion will likely be used for polynomial commitments for inverse FFTs

Python example question

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?

Rust bindings: add typical impls

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.

[doc] Aggregate - pairing_mul_n

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.

blst/src/aggregate.c

Lines 7 to 34 in 6d6dec3

/*
* Usage pattern on single-processor system is
*
* blst_pairing_init(ctx);
* blst_pairing_aggregate_pk_in_g1(ctx, PK1, aggregated_signature, message1);
* blst_pairing_aggregate_pk_in_g1(ctx, PK2, NULL, message2);
* ...
* blst_pairing_commit(ctx);
* blst_pairing_finalverify(ctx, NULL);
*
***********************************************************************
* Usage pattern on multi-processor system is
*
* blst_pairing_init(pk0);
* blst_pairing_init(pk1);
* ...
* start threads each processing a slice of PKs and messages:
* blst_pairing_aggregate_pk_in_g1(pkx, PK[], NULL, message[]);
* blst_pairing_commit(pkx);
* ...
* blst_fp12 gtsig;
* blst_aggregated_in_g2(&gtsig, aggregated_signature);
* join threads and merge their contexts:
* blst_pairing_merge(pk0, pk1);
* blst_pairing_merge(pk0, pk2);
* ...
* blst_pairing_finalverify(pk0, gtsig);
*/

It seems like it's computing λ0 e(PK0, H(msg0)) λ1 e(PK1, H(msg1)) ... with λi != 1

SWIG Java uint64_t binding on Windows

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?

wasm32 support

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?

Point Decompression does not handle invalid byte lengths

What is the issue?

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.

What needs to be done?

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.

Infinity pubkey and signature

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 :)

Running in ARM64 Fails with SIGILL: illegal instruction

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:

d75dab4

This commit is about a month back, so was wondering if it might already be fixed in master

Symbol collision with openssl

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 :)

Java binding issue with MinGW GCC on Windows

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?

GCC optimization flag incompatibility

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)

[$] Enable and optimize for Linux on Z (s390x)

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.

core_verify_pk_in_g1 fails to verify valid signature

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!

Rust Subgroup Checks

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):

  1. 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

  2. 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.

  3. 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.

Rust unit tests fail in release

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.

Steps to reproduce

Run cargo test --release in bindings/rust/.

Logs

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'

Point Decompression does not enforce field points are less than field modulus.

What is the issue?

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.

What needs to be done?

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.

Linking errors on aarch64

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

AggregateVerify Verifies for Infinite Pubkeys

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.

[Optim] Accelerated scalar multiplication

Following our exchanges, you can accelerate the scalar multiplication via:

  • GLV endomorphism on G1, which divides the number of doubling by 2.
  • GLV endomorphism + GLS endomorphism on G2 which divides the number of doublings by 4.

Method 1 has a patent that expires on September 2020.

References

Implementation follow closely Algorithm 1 and 2 from paper

  • Efficient and Secure Algorithms for GLV-Based Scalar
    Multiplication and their Implementation on GLV-GLS
    Curves (Extended Version)
    Armando Faz-Hernández, Patrick Longa, Ana H. Sánchez, 2013
    https://eprint.iacr.org/2013/158.pdf

The Lattice decompositions for BN and BLS curve families follow chapter 6 from

  • Guide to Pairing-based Cryptography
    Chapter 6: Scalar Multiplication and Exponentiation in Pairing Groups
    Joppe Bos, Craig Costello, Michael Naehrig

Extra

The FourQ draft also mentions this: https://tools.ietf.org/html/draft-ladd-cfrg-4q-00#section-4.3

Implementation

Variable point

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):

Fixed points like generators

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.

Sagnificant performance degradation for aggregate method in jblst

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);
  }

NodeJS multi-thread support

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.

Type mismatches in exports and headers

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.

bool blst_fp12_is_equal(const blst_fp12 *a, const blst_fp12 *b);

limb_t blst_p1_affine_is_equal(const POINTonE1_affine *a,

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

"BLS12381G1_XMD:BLAKE2B_SSWU_RO_"

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

To "this" or not to "this"...

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 return this instance. From my perspective they could be erroneously interpreted as that a new instance is returned and this instance is left unmodified. Not sure about common C++ patterns, but Java dev would likely misinterpret this. Does it make sense to return void from these methods to avoid such misuse?

Error while performing signature

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.

keygen: salt is hashed

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.

[Optim] Square root on Fp2

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

image

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)

Rust bindings: expose safe blst_scalar constructors

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.

Fp2 Sqrt missmatch

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.

[Optim] Runtime detection of MULX and ADX support

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

Hash to scalar

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.

DTS as std::string in CPP binding

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.

MacOS build fails

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

Unable to compile with instrumentation since recent commit

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?

node.js v12+

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.

[low priority] Use C fallback on non-ARM non-x86 platforms

We can use the no_asm.h fallback for 32-bit also as a fallback for non-ARM, non-x86 platforms by changing the #if in

  • Assembly.S

    blst/build/assembly.S

    Lines 112 to 115 in 7cda6fa

    #elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__==4
    /* inaccurate way to detect a 32-bit processor, but it's close enough */
    #else
    # error "unsupported platform"
  • vect.h

    blst/src/vect.h

    Lines 11 to 35 in 7cda6fa

    #if defined(__x86_64__) || defined(__aarch64__) || defined(__mips64) || \
    defined(__ia64) || (defined(__VMS) && !defined(__vax))
    /* These are available even in ILP32 flavours, but even then they are
    * capable of performing 64-bit operations as efficiently as in *P64. */
    typedef unsigned long long limb_t;
    # define LIMB_T_BITS 64
    #elif defined(_WIN64) /* Win64 is P64 */
    typedef unsigned __int64 limb_t;
    # define LIMB_T_BITS 64
    #elif defined(__wasm64__)
    typedef unsigned int limb_t;
    # define LIMB_T_BITS 32
    # define __BLST_NO_ASM__
    # else /* 32 bits on 32-bit platforms, 64 - on 64-bit */
    typedef unsigned long limb_t;
    # ifdef _LP64
    # define LIMB_T_BITS 64
    # else
    # define LIMB_T_BITS 32
    # define __BLST_NO_ASM__
    # endif
    #endif

Tagging low-priority as we don't have a use case, at least yet but FWIW we had our PowerPC CI failing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.