Skip to content

Commit

Permalink
remove MIRACL Core backend (#170)
Browse files Browse the repository at this point in the history
EIP-4844 requires BLST via `nim-kzg4844`; MIRACL Core is not supported.
Furthermore, BLST now has fallback for generic CPU architectures.
Therefore, remove support for the MIRACL Core backend.
  • Loading branch information
etan-status committed Feb 22, 2024
1 parent 1002533 commit d091a57
Show file tree
Hide file tree
Showing 74 changed files with 13 additions and 27,897 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "miracl-core"]
path = vendor/miracl-core
url = https://github.com/miracl/core
[submodule "vendor/blst"]
path = vendor/blst
url = https://github.com/supranational/blst
13 changes: 1 addition & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,11 @@ v9 and v7 are protocol compatible but have cosmetic changes (naming variables, p
## Backend

This library uses:
- [SupraNational BLST](https://github.com/supranational/blst) on x86-64 and ARM64
- [MIRACL Core](https://github.com/miracl/core) on all other platforms.
- [SupraNational BLST](https://github.com/supranational/blst) on all platforms.

BLST uses SSSE3 by default, if supported on the host. To disable that, when building
binaries destined for older CPUs, pass `-d:BLSTuseSSSE3=0` to the Nim compiler.

### Keeping track of upstream

To keep track of upstream MIRACL Core:

- Update the submodule.
- Execute `nim e miracl.nims vendor/miracl-core/c blscurve/miracl/csources`
- Test
- Commit

### Executing the test suite

We recommend working within the nimbus build environment described here:
Expand Down Expand Up @@ -117,4 +107,3 @@ at your option. These files may not be copied, modified, or distributed except a
### Dependencies

- SupraNational BLST is distributed under the Apache License, Version 2.0
- MIRACL Core is distributed under the Apache License, Version 2.0
3 changes: 0 additions & 3 deletions benchmarks/bench_all.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ separator()
# Pairings
when BLS_BACKEND == BLST:
benchBLSTPairing(1000)
else:
benchMiraclPairingViaDoublePairing(1000)
benchMiraclPairingViaMultiPairing(1000)
separator()

# Hash-to-curve implementation
Expand Down
102 changes: 0 additions & 102 deletions benchmarks/bls12381_curve.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import
when BLS_BACKEND == BLST:
import
../blscurve/blst/blst_abi
else:
import
../blscurve/miracl/[common, miracl],
../blscurve/miracl/hash_to_curve

# ############################################################
#
Expand All @@ -43,18 +39,6 @@ proc benchScalarMultG1*(iters: int) =

bench("Scalar multiplication G1 (255-bit, constant-time)", iters):
x.blst_p1_mult(x, scalar, 255)
else:
var x = generator1()
var scal{.noinit.}: array[32, byte]
for val in scal.mitems:
val = byte benchRNG.rand(0xFF)

var scalar{.noinit.}: BIG_384
doAssert scalar.fromBytes(scal)
scalar.BIG_384_mod(CURVE_Order)

bench("Scalar multiplication G1 (255-bit, constant-time)", iters):
x.mul(scalar)

proc benchScalarMultG2*(iters: int) =
when BLS_BACKEND == BLST:
Expand All @@ -70,18 +54,6 @@ proc benchScalarMultG2*(iters: int) =

bench("Scalar multiplication G2 (255-bit, constant-time)", iters):
x.blst_p2_mult(x, scalar, 255)
else:
var x = generator2()
var scal{.noinit.}: array[32, byte]
for val in scal.mitems:
val = byte benchRNG.rand(0xFF)

var scalar{.noinit.}: BIG_384
doAssert scalar.fromBytes(scal)
scalar.BIG_384_mod(CURVE_Order)

bench("Scalar multiplication G2 (255-bit, constant-time)", iters):
x.mul(scalar)

proc benchECAddG1*(iters: int) =
when BLS_BACKEND == BLST:
Expand All @@ -91,12 +63,6 @@ proc benchECAddG1*(iters: int) =

bench("EC add G1 (constant-time)", iters):
x.blst_p1_add_or_double(x, y)
else:
var x = generator1()
var y = generator1()

bench("EC add G1 (constant-time)", iters):
x.add(y)

proc benchECAddG2*(iters: int) =
when BLS_BACKEND == BLST:
Expand All @@ -106,12 +72,6 @@ proc benchECAddG2*(iters: int) =

bench("EC add G2 (constant-time)", iters):
x.blst_p2_add_or_double(x, y)
else:
var x = generator2()
var y = generator2()

bench("EC add G2 (constant-time)", iters):
x.add(y)

when BLS_BACKEND == BLST:

Expand Down Expand Up @@ -173,65 +133,6 @@ when BLS_BACKEND == BLST:
let valid = ctx[].blst_pairing_finalverify(nil) # Final Exponentiation
# doAssert bool valid

else:

proc benchMiraclPairingViaDoublePairing*(iters: int) =
## Builtin Miracl Double-Pairing implementation
# Ideally we don't depend on the bls_signature_scheme but it's much simpler
let (pubkey, seckey) = block:
var pk: PublicKey
var sk: SecretKey
var ikm: array[32, byte]
ikm[0] = 0x12
discard ikm.keyGen(pk, sk)
(cast[ECP_BLS12381](pk), cast[BIG_384](sk))
let msg = "Mr F was here"
const domainSepTag = "BLS_SIG_BLS12381G2-SHA256-SSWU-RO_POP_"

# Signing
var sig = hashToG2(msg, domainSepTag)
sig.mul(seckey)

# Verification
let generator = generator1()
let Q = hashToG2(msg, domainSepTag)
# Pairing: e(Q, xP) == e(R, P)
bench("Pairing (Miracl builtin double pairing)", iters):
let valid = doublePairing(
Q, pubkey,
sig, generator
)
# doAssert valid

proc benchMiraclPairingViaMultiPairing*(iters: int) =
## MultiPairing implementation
## Using deferred Miller loop + Final Exponentiation
# Ideally we don't depend on the bls_signature_scheme but it's much simpler
let (pubkey, seckey) = block:
var pk: PublicKey
var sk: SecretKey
var ikm: array[32, byte]
ikm[0] = 0x12
discard ikm.keyGen(pk, sk)
(cast[ECP_BLS12381](pk), cast[BIG_384](sk))
let msg = "Mr F was here"
const domainSepTag = "BLS_SIG_BLS12381G2-SHA256-SSWU-RO_POP_"

# Signing
var sig = hashToG2(msg, domainSepTag)
sig.mul(seckey)

# Verification
let generator = generator1()
let Q = hashToG2(msg, domainSepTag)
# Pairing: e(Q, xP) == e(R, P)
bench("Pairing (Multi-Pairing with delayed Miller and Exp)", iters):
let valid = multiPairing(
Q, pubkey,
sig, generator
)
# doAssert valid

when isMainModule:
benchScalarMultG1(1000)
benchScalarMultG2(1000)
Expand All @@ -240,6 +141,3 @@ when isMainModule:

when BLS_BACKEND == BLST:
benchBLSTPairing(5000)
else:
benchMiraclPairingViaDoublePairing(1000)
benchMiraclPairingViaMultiPairing(1000)
9 changes: 0 additions & 9 deletions benchmarks/hash_to_curve.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import
when BLS_BACKEND == BLST:
import
../blscurve/blst/blst_abi
else:
import
../blscurve/miracl/[common, miracl],
../blscurve/miracl/hash_to_curve

# ############################################################
#
Expand All @@ -43,11 +39,6 @@ proc benchHashToG2*(iters: int) =
aug = ""
)
Paff.blst_p2_to_affine(P)
else:
var point: ECP2_BLS12381

bench("Hash to G2 (Draft #9)", iters):
point = hashToG2(msg, dst)

when isMainModule:
benchHashToG2(1000)
2 changes: 1 addition & 1 deletion benchmarks/platforms/x86.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Cpu Name
# -------------------------------------------------------

{.passc:"-std=gnu99".} # TODO may conflict with miracl "-std=c99"
{.passc:"-std=gnu99".}

proc cpuID(eaxi, ecxi: int32): tuple[eax, ebx, ecx, edx: int32] =
when defined(vcc):
Expand Down
19 changes: 3 additions & 16 deletions blscurve.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,16 @@ proc run(args, path: string) =

### tasks
task test, "Run all tests":
# Debug - test intermediate computations
# run "", "blscurve/miracl/hkdf.nim"
# run "", "blscurve/miracl/draft_v5/hash_to_curve_draft_v5.nim"
# run "", "blscurve/miracl/hash_to_curve.nim"

# Internal BLS API - IETF standard
# run "", "tests/hash_to_curve_v7.nim"

# Serialization
run "-d:BLS_FORCE_BACKEND=miracl", "tests/serialization.nim"
run "-d:BLS_FORCE_BACKEND=blst", "tests/serialization.nim"
# Public BLS API - IETF standard / Ethereum2.0 v1.0.0
run "-d:BLS_FORCE_BACKEND=miracl", "tests/eth2_vectors.nim"
run "-d:BLS_FORCE_BACKEND=blst", "tests/eth2_vectors.nim"
# key Derivation - EIP 2333
run "-d:BLS_FORCE_BACKEND=miracl", "tests/eip2333_key_derivation.nim"
# Secret key to pubkey
run "-d:BLS_FORCE_BACKEND=miracl", "tests/priv_to_pub.nim"

run "-d:BLS_FORCE_BACKEND=blst", "tests/serialization.nim"
# run "-d:BLS_FORCE_BACKEND=blst", "tests/eth2_vectors.nim"
run "-d:BLS_FORCE_BACKEND=blst", "tests/eip2333_key_derivation.nim"
# Secret key to pubkey
run "-d:BLS_FORCE_BACKEND=blst", "tests/priv_to_pub.nim"

# Internal SHA256
Expand All @@ -79,9 +69,6 @@ task test, "Run all tests":
# on 32-bit for asm volatile, this might be due to
# incorrect RDTSC call in benchmark
when defined(arm64) or defined(amd64):
run "--threads:on -d:BLS_FORCE_BACKEND=miracl -d:danger --warnings:off",
"benchmarks/bench_all.nim"

run "--threads:on -d:BLS_FORCE_BACKEND=blst -d:danger --warnings:off",
"benchmarks/bench_all.nim"

Expand Down
10 changes: 1 addition & 9 deletions blscurve/bls_backend.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
const BLS_FORCE_BACKEND*{.strdefine.} = "auto"

static: doAssert BLS_FORCE_BACKEND == "auto" or
BLS_FORCE_BACKEND == "miracl" or
BLS_FORCE_BACKEND == "blst",
"""Only "auto", "blst" and "miracl" backends are valid."""
"""Only "auto" and "blst" backends are valid."""

type BlsBackendKind* = enum
BLST
Miracl

const UseBLST = BLS_FORCE_BACKEND == "auto" or BLS_FORCE_BACKEND == "blst"

Expand All @@ -29,13 +27,7 @@ when UseBLST:
# WASM and others - no specialised assembly code available
{.passc: "-D__BLST_NO_ASM__".}
const BLS_BACKEND* = BLST
else:
# Miracl
const BLS_BACKEND* = Miracl

when BLS_BACKEND == BLST:
import ./blst/[blst_min_pubkey_sig_core, blst_recovery]
export blst_min_pubkey_sig_core, blst_recovery
else:
import ./miracl/miracl_min_pubkey_sig_core
export miracl_min_pubkey_sig_core
3 changes: 1 addition & 2 deletions blscurve/bls_batch_verifier.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ when compileOption("threads"):
# - message = 32B (assuming sha256 hashed)
# hence 176B only
#
# TODO: Once ContextMultiAggregateVerify is implemented
# for Miracl, this wouldn't need to be in the BLST specific file
# TODO: This wouldn't need to be in the BLST specific file

type
SignatureSet* = tuple[pubkey: PublicKey, message: array[32, byte], signature: Signature]
Expand Down
1 change: 0 additions & 1 deletion blscurve/bls_public_exports.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export
fromHex, fromBytes, fromBytesKnownOnCurve,
toHex, serialize, exportRaw

# TODO - MIRACL implementation
when BLS_BACKEND == BLST:
export
exportUncompressed, subtractAll,
Expand Down
6 changes: 2 additions & 4 deletions blscurve/blst/blst_min_pubkey_sig_core.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
# approach, since the size of (PK_1, ..., PK_n, signature) is
# dominated by the public keys even for small n.

# We expose the same API as MIRACL
#
# Design:
# - We check public keys and signatures at deserialization
# - non-zero
Expand Down Expand Up @@ -401,8 +399,8 @@ func finish*(ctx: var ContextCoreAggregateVerify, signature: Signature or Aggreg
# Ultimately this can be merged with the internal ContextCoreAggregateVerify
# but:
# - The previous code was audited
# - For now we only support BLST
# though MIRACL is straightforward, context merge is just a FP12 multiplication
# - For now we only support BLST but other backends may be straightforward,
# context merge is just a FP12 multiplication
# since GT is a multiplicative group.
# - we need to hold cryptographycally secure
# random bytes to protect against forged signatures
Expand Down

0 comments on commit d091a57

Please sign in to comment.