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.BLS381Lets 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 * GGenerate 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 benchPerformance 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
SysTestto protect your use-case.
- PoC finished (missing Windows)
- Add
.travis.ymland improveREADME.mdso 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.mdchapter about performance -
README.mdchapter about configuration -
README.mdchapter to contributors - Tested on Windows
- Tested 32-bit Linux
- Fix
TODOs in code - Add
gmp-seclibs for timing resistance. - Use timing resistent
FP,EP, andPPconfigs 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)