Julia Wrapper for the Relic Toolkit.
The goal is to facilitate a user-friendly, secure, and performant PBC lib for Julia.
- Supports multiple Curves (BLS381 and BN254)
- Single-line (
using ...
) changes curve - Supports both 32 and 64 bit machines
- Supports common operative systems (Linux, Mac, Windows)
- State-of-the art performance
- Production Ready (timing, side-channel resistance)
So lets implement the simplest possible BLS signature scheme in 10 lines of code!
The symbols (e.g. pk
, H(m)
) below were chosen to be consistent with this excellent blog.
using Pkg
Pkg.add(PackageSpec(url="https://github.com/blenessy/RelicToolkit.jl"))
Import the Curve functions you want to use (BLS381
and BN254
are currently supported):
using RelicToolkit.BLS381
Lets start by defining the following functions to remain consistent with Stepan's blog:
# a.k.a. hash to curve function
H(m) = curve_map(EP2, Vector{UInt8}(m))
# a.k.a. pairing function
e(P::EP, Q::EP2) = field_final_exp(curve_miller(P, Q))
Create a random private key:
pk = mod(rand(BN), curve_order(EP))
Generate a public key from the private key:
G = curve_gen(EP)
P = pk * G
Generate a public key from the private key:
P = pk * curve_gen(EP)
Sign a hashed message:
S = pk * H("foo")
Validate the signature:
@assert e(P, H("foo")) == e(G, S)
You can run the performance tests with:
make CURVE=BLS381 bench
Performance is state of the art (on par with C). You should get something like this on a 4-5 year old 2.2GHz Core i7:
...
[PP][field_final_exp]: 947.266 μs (alloc: 1, mem: 624 bytes, gc: 0.000 ns)
[PP][curve_miller]: 1.734 ms (alloc: 1, mem: 624 bytes, gc: 0.000 ns)
...
Since the pairing function is defined as field_final_exp(curve_miller(P, Q))
you can estimate
its performance by adding these times together.
Cofiguration is done through environment variables. The number of configuration possibilities should be limited for simplicity.
Key | Default | Description |
---|---|---|
RELIC_TOOLKIT_CURVE | (all curves are loaded) | Used for limiting, which curve is loaded (saves memory) at startup. Possible values are: BN254 and BLS381 . |
Contributions are welcome! If you are unsure where to chip in, please see the roadmap below.
Currect code coverage is 100% and the author would like to keep it that way.
Test | Purpose |
---|---|
UnitTests |
Make sure the ccall are working and do not crash Julia. |
SysTests |
Protect complete features from breaking |
PerfTests |
Fair benchmarks for performance awareness |
Just create a PR (as usual in GitHub) and make sure that the code coverage stays at 100%.
- Please start by creating an issue and explain your use-case and goal.
- Create a PR (as usual in GitHub) with the implementation and add a new
SysTest
to protect your use-case.
- PoC finished (missing Windows)
- Add
.travis.yml
and improveREADME.md
so that the community can help - Add conversion from Integer
- Add syntactic sugar by overloading applicable operators (e.g. +, -, *, //, ^)
- Use BN(undef) and FP(undef) where safe to save some clock cycles
- Remove function name prefix from lib - it just make it harder to switch
- Make it possible to instantiate both libs in one session
- Implement zero and one functions
- Unit tests for EPX
- BLS Schema System Test and example in README.md
-
README.md
chapter about performance -
README.md
chapter about configuration -
README.md
chapter to contributors - Tested on Windows
- Tested 32-bit Linux
- Fix
TODO
s in code - Add
gmp-sec
libs for timing resistance. - Use timing resistent
FP
,EP
, andPP
configs and functions. - Add tests that measure time, CPU, Memory usage consistency over time.
- Julia 1.3.x and multi-thread support
- Implement all logical operators for BN, FP, and FPX
- Support all ARCH/OS combos that Julia and the Relic Toolkit has in common
- Support (signed) integers where BN is supported with FP and EP
- BN should extend Signed and should be automatically convertible/promotable to BigInt
- Academic/security audits (help needed)