Skip to content

Commit

Permalink
Merge pull request #26 from kwantam/nonzero_sk
Browse files Browse the repository at this point in the history
KeyGen and KeyValidate updates
  • Loading branch information
hoeteck authored Sep 8, 2020
2 parents 6ea058e + 36da837 commit 03a1d2d
Showing 1 changed file with 44 additions and 24 deletions.
68 changes: 44 additions & 24 deletions draft-irtf-cfrg-bls-signature.md
Original file line number Diff line number Diff line change
Expand Up @@ -574,18 +574,16 @@ In addition, the following primitives are determined by the above parameters:

## KeyGen {#keygen}

The KeyGen algorithm generates a secret key SK deterministically from
a secret octet string IKM.
The KeyGen procedure described in this section generates a secret key SK
deterministically from a secret octet string IKM.
SK is guaranteed to be nonzero, as required by KeyValidate ((#keyvalidate)).

KeyGen uses HKDF [@RFC5869] instantiated with the hash function H.

For security, IKM MUST be infeasible to guess, e.g.,
generated by a trusted source of randomness.
IKM MUST be at least 32 bytes long, but it MAY be longer.

Because KeyGen is deterministic, implementations MAY choose either to store
the resulting SK or to store IKM and call KeyGen to derive SK when necessary.

KeyGen takes an optional parameter, key\_info.
This parameter MAY be used to derive multiple independent keys from the same IKM.
By default, key\_info is the empty string.
Expand All @@ -597,7 +595,7 @@ Inputs:
- IKM, a secret octet string. See requirements above.
Outputs:
- SK, a uniformly random integer such that 0 <= SK < r.
- SK, a uniformly random integer such that 1 <= SK < r.
Parameters:
- key_info, an optional octet string.
Expand All @@ -611,28 +609,32 @@ Definitions:
- "BLS-SIG-KEYGEN-SALT-" is an ASCII string comprising 20 octets.
Procedure:
1. PRK = HKDF-Extract("BLS-SIG-KEYGEN-SALT-", IKM || I2OSP(0, 1))
2. OKM = HKDF-Expand(PRK, key_info || I2OSP(L, 2), L)
3. SK = OS2IP(OKM) mod r
4. return SK
1. salt = "BLS-SIG-KEYGEN-SALT-"
2. SK = 0
3. while SK == 0:
4. salt = H(salt)
5. PRK = HKDF-Extract(salt, IKM || I2OSP(0, 1))
6. OKM = HKDF-Expand(PRK, key_info || I2OSP(L, 2), L)
7. SK = OS2IP(OKM) mod r
8. return SK
~~~

KeyGen is the RECOMMENDED way of generating secret keys, but its use is not
required for compatibility, and implementations MAY use a different KeyGen
procedure. For security, such an alternative KeyGen procedure MUST output SK
that is statistically close to uniformly random in the range 1 <= SK < r.

## SkToPk {#sktopk}

The SkToPk algorithm takes a secret key SK and outputs the corresponding
public key PK.

SK MUST be indistinguishable from uniformly random modulo r ((#coreparams))
and infeasible to guess, e.g., generated using a trusted source of randomness.
KeyGen ((#keygen)) outputs SK meeting these requirements.
Other key generation approaches meeting these requirements MAY also be used;
details of such methods are beyond the scope of this document.
(#keygen) discusses requirements for SK.

~~~
PK = SkToPk(SK)
Inputs:
- SK, a secret integer such that 0 <= SK < r.
- SK, a secret integer such that 1 <= SK < r.
Outputs:
- PK, a public key encoded as an octet string.
Expand All @@ -646,6 +648,9 @@ Procedure:
## KeyValidate {#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 (#pubkeyvalid) for further discussion.

As an optimization, implementations MAY cache the result of KeyValidate
in order to avoid unnecessarily repeating validation for known keys.
Expand All @@ -662,8 +667,9 @@ Outputs:
Procedure:
1. xP = pubkey_to_point(PK)
2. If xP is INVALID, return INVALID
3. If pubkey_subgroup_check(xP) is INVALID, return INVALID
4. return VALID
3. If xP is the identity element, return INVALID
4. If pubkey_subgroup_check(xP) is INVALID, return INVALID
5. return VALID
~~~

## CoreSign {#coresign}
Expand Down Expand Up @@ -1218,7 +1224,25 @@ is REQUIRED.
For the proof of possession scheme, each public key MUST be accompanied by
a proof of possession, and use of PopVerify is REQUIRED.

## Skipping membership check
KeyValidate requires all public keys to represent valid, non-identity points
in the correct subgroup.
A valid point and subgroup membership are required to ensure that the pairing
operation is defined ((#membershipcheck)).

A non-identity point is required because the identity public key has the
property that the corresponding secret key is equal to zero, which means
that the identity point is the unique valid signature for every message
under this key.
A malicious signer could take advantage of this fact to equivocate about
which message he signed.
While non-equivocation is not a required property for a signature scheme,
equivocation is infeasible for BLS signatures under any nonzero secret key
because it would require finding colliding inputs to the hash\_to\_point
function, which is assumed to be collision resistant.
Prohibiting SK == 0 eliminates the exceptional case, which may help to prevent
equivocation-related security issues in protocols that use BLS signatures.

## Skipping membership check {#membershipcheck}

Some existing implementations skip the signature\_subgroup\_check invocation
in CoreVerify ((#coreverify)), whose purpose is ensuring that the signature
Expand Down Expand Up @@ -1257,10 +1281,6 @@ One possibility is to generate IKM from a trusted source of randomness.
Guidelines on constructing such a source are outside the scope of this
document.

Secret keys MAY be generated using other methods; in this case they MUST
be infeasible to guess and MUST be indistinguishable from uniformly random
modulo r.

## Implementing hash\_to\_point and hash\_pubkey\_to\_point

The security analysis models hash\_to\_point and hash\_pubkey\_to\_point
Expand Down

0 comments on commit 03a1d2d

Please sign in to comment.