status-im / nim-blscurve

Nim implementation of BLS signature scheme (Boneh-Lynn-Shacham) over Barreto-Lynn-Scott (BLS) curve BLS12-381
Apache License 2.0
26 stars 11 forks source link

Miracl backend: Accelerate "KeyValidate" #90

Closed mratsim closed 3 years ago

mratsim commented 3 years ago

Currently verification incurs a significant scalar multiplication overhead due to the repeated need of validating public key.

https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-2.5

2.5.  KeyValidate

   The KeyValidate algorithm ensures that a public key is valid.  In
   particular, it ensures that a public key represents a valid, non-
   identity point that is in the correct subgroup.  See Section 5.1 for
   further discussion.

   As an optimization, implementations MAY cache the result of
   KeyValidate in order to avoid unnecessarily repeating validation for
   known keys.

   result = KeyValidate(PK)

   Inputs:
   - PK, a public key in the format output by SkToPk.

   Outputs:
   - result, either VALID or INVALID

   Procedure:
   1. xP = pubkey_to_point(PK)
   2. If xP is INVALID, return INVALID
   3. If xP is the identity element, return INVALID
   4. If pubkey_subgroup_check(xP) is INVALID, return INVALID
   5. return VALID

The pubkey_subgroup_check is costly https://github.com/status-im/nim-blscurve/blob/70cbdd16e00d15a6556e84552012b9a368cacb56/blscurve/miracl/bls_signature_scheme.nim#L98-L104

We have 2 solutions:

  1. Instead of using scalar multiplication, use Bowe19 for Miracl backend, like what BLST does, see https://github.com/pairingwg/bls_standard/issues/21
    
    subgroup_test_g2(P)

Input: a point P Output: True if P is in the order-q subgroup of E2, else False

Constants:

Steps:

  1. pP = psi(P)

  2. pP = psi(pP)

  3. Q = P - pP

  4. pP = psi(pP)

  5. pP = z * pP

  6. Q = Q + pP

  7. return Q == point_at_infinity_E2

    
    `psi` is already defined for clearCofactor
  8. We can cache the result of "KeyValidate" as suggested in the spec, probably by introducing a CheckedPublicKey type. Note that BLST doesn't offer verification primitives that skip the subgroup check.

tersec commented 3 years ago

Would miracl skipping the subgroup check be faster at verifying than BLST without skipping the subgroup check?

mratsim commented 3 years ago

No it won't.

mratsim commented 3 years ago

Note: subgroup check caching was implemented for BLST in #99. As soon we won't need Miracl for ARM32, x86_32, MIPS, PPC, Riscv5 ... this is considered low-priority.

mratsim commented 3 years ago

Implemented in #100