Skip to content

Commit

Permalink
modify text to use operations from BBS draft 3
Browse files Browse the repository at this point in the history
  • Loading branch information
dwaite committed Oct 13, 2023
1 parent 7ec2d37 commit 49d0892
Showing 1 changed file with 38 additions and 217 deletions.
255 changes: 38 additions & 217 deletions draft-ietf-jose-json-proof-algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,256 +219,77 @@ See the example in the appendix of the JSON Web Proof draft.

The BBS Signature Scheme [@!I-D.irtf-cfrg-bbs-signatures] is under active development within the CRFG. Prior to this effort work was done under the DIF [Applied Cryptography Working Group](https://identity.foundation/working-groups/crypto.html), an effort to clarify and bring best practices to early prototypes leveraged by multiple early stage decentralized identity projects.

This JSON Proof Algorithm definition for BBS is based on the already released implementation and relies on the provided software API. A future definition with a different `alg` value will be created to succeed this version as the BBS standardization effort progresses.

This algorithm supports both selective disclosure and unlinkability, enabling the holder to generate multiple presentations from one issued JWP without any verifier being able to correlate those presentations together.

### BLS Curve

The pairing friendly elliptic curve used for the BBS software implementation is part of the BLS family with an embedding degree of 12 over a 381-bit prime field. For this JPA, only the group G2 is used.
### Algorithm

In the implementation the method used to generate the key pairs is `generateBls12381G2KeyPair()`.
The `BBS` "alg" parameter value corresponds to a ciphersuite identifier of `BBS_BLS12381G1_XMD:SHA-256_SSWU_RO_H2G_HM2S_` in a JWP in issuance form, while `BBS-PROOF` corresponds to the same ciphersuite in presentation form.

### Messages
### Key format

BBS is a multi-message scheme and operates on an array of individual messages for signing and proof generation. Each message is a single binary octet string. The BBS implementation uses a hash-to-curve method to map each message to a point.
A `BBS` key is an elliptic curve-based key pair, specifically against the G_2 subgroup of a pairing friendly curve. Additional details on key generation can be found in [@!I-D.irtf-cfrg-bbs-signatures, section 3.3]

### Issuer Protected Header
The JWK form of this key is an `OKP` type with a curve of `BLS12381G2`, with `x` being the BASE64URL-encoded form of the output of `point_to_octets_g2`.

The UTF-8 octet string of the issuer protected header is the first message in the input array at index 0.

### Payloads

The octet strings of each payload are placed into the BBS message array following the issuer protected header message. For example, the first payload is at index 1 of the array and the last payload is always the last message in the array.

In future versions of this algorithm, there will be additional methods defined for transforming a payload into a point such that additional Zero-Knowledge Proof types can be supported by the holder such as range and membership predicates.
<{{./fixtures/build/private-key.jwk}}
Figure: BBS private key in JWK format

### Issuance

The issuer's BLS12-381 G2 Stable Key is used to sign the completed message array input containing the octet strings of the issuer protected header and every payload. The result is a signature octet string that is used as the initial JWP proof value.
Issuance is performed using the `Sign` operation from [@!I-D.irtf-cfrg-bbs-signatures, section 3.4.1], using the issuer's BLS12-381 G2 key pair (as `SK` and `PK`), along with desired protected header and payloads (as the octets header and the octets array messages).

In the implementation, the method used to perform the signing is `blsSign({keyPair, [header, payload1, payload2, ...]})` and returns a binary signature value.
The octets result of this operation forms the issuance proof, to be used along with the protected header and payloads to serialize the JWP.

### Presentation
For example, the following figures show an issued JWP:

The holder must decode the issuer protected header and payload values in order to generate the identical message array that the issuer used.
<{{./fixtures/template/bbs-issuer-protected-header.json}}
Figure: Issuer protected header

To generate a presented JWP for a verifier, the holder must use a cryptographic nonce that is provided by that verifier as input. This nonce MUST be a 32-byte octet string that the verifier generated by a secure RNG. How this nonce value is communicated to the holder is out of scope of this presentation. The `nonce` claim in the presentation protected header is used to store the verifier's given nonce value.
<{{./fixtures/template/bbs-issuer-payloads.json}}
Figure: Issuer payloads (formatted as JSON array)

The holder also applies selective disclosure preferences by creating an array of indices of which messages in the input array are to be revealed to the verifier. The revealed indices MUST include the value `0` so that the issuer protected header message is always revealed to the verifier.
<{{./fixtures/build/bbs-issuer.json.jwp}}
Figure: Issued JWP (JSON serialization)

The result of creating a proof is an octet string that is used as the presented JWP proof value.
<{{./fixtures/build/bbs-issuer.compact.jwp}}
Figure: Issued JWP (compact serialization)

In the implementation, the method used to generate the proof is `blsCreateProof({signedProof, publicKey, [issuer_header, payload1, payload2, ...], presentation_header, [0, 2, ...])`.
### Issuance proof verification

### Verification
Holder verification of the signature on issuance form is performed using the `Verify` operation from [@!I-D.irtf-cfrg-bbs-signatures, section 3.4.2].

The verifier decodes the JWP issuer protected header and payload values into a messages array, skipping any non-revealed payloads. The current BBS implementation embeds the revealed indices into the output proof value, so the verification messages array only needs to include the disclosed messages.
This operation utilizes the issuer's public key as `PK`, the proof as `signature`, the protected header octets as `header` and the array of payload octets as `messages`).

In the implementation, the method used to verify the proof is `blsVerifyProof({verifyProof, publicKey, [issuer_header, payload2, ...], presentation_header)`.
### Presentation

### JPA Registration
Derivation of a presentation is done by the holder using the `ProofGen` operation from [@!I-D.irtf-cfrg-bbs-signatures, section 3.4.3].

Proposed JWP `alg` value for BBS based on the software implementation is "BBS-X".
This operation utilizes the issuer's public key as `PK`, the issuer protected header as `header`, the issuance proof as `signature`, the issuance payloads as `messages`, and the holder's presentation protected header as `ph`.

### Example
The operation also takes a vector of indexes into `messages`, describing which payloads the holder wishes to disclose.

The following example uses the given BLS12-384 key-pair:
The output of this operation is the presentation proof.

Public:
```json
[179, 209, 122, 60, 230, 37, 188, 86, 19, 19, 4, 36, 240, 230, 79,
178, 230, 147, 9, 60, 239, 41, 233, 167, 190, 252, 154, 35, 39, 201,
238, 73, 77, 228, 20, 47, 109, 174, 15, 168, 187, 145, 126, 85, 83,
151, 48, 30, 13, 237, 92, 179, 124, 181, 211, 204, 187, 222, 229,
234, 182, 94, 60, 157, 19, 148, 162, 48, 185, 134, 177, 168, 68,
115, 167, 48, 92, 181, 168, 53, 52, 246, 201, 112, 103, 23, 159,
138, 225, 13, 165, 171, 251, 112, 163, 96]
```
Figure: bbs-issuer-public-octets
Presentation serialization leverages the two protected headers and presentation proof, along with the disclosed payloads. Non-disclosed payloads are represented with the absent value of `null` in JSON serialization and a zero-length string in compact serialization.

Private:
```json
[72, 125, 227, 97, 150, 148, 186, 145, 110, 46, 135, 232, 104, 204,
128, 242, 73, 151, 72, 162, 0, 54, 139, 146, 221, 137, 34, 74, 1,
42, 140, 206]
```
Figure: bbs-issuer-private-octets
For example, the following figures show a presented JWP:

The protected header used is:
```json
{
"iss": "https://issuer.example",
"claims": [
"family_name",
"given_name",
"email",
"age"
],
"typ": "JPT",
"alg": "BBS-X"
}
```
Figure: bbs-issuer-protected-header
<{{./fixtures/template/bbs-prover-presentation-header.json}}
Figure: Holder presentation header

The first payload is the string `"Doe"` with the octet sequence of `[ 34, 68, 111, 101, 34 ]` and base64url-encoded as `IkRvZSI`.
<{{./fixtures/build/bbs-prover.json.jwp}}
Figure: Presentation JWP (JSON serialization)

The second payload is the string `"Jay"` with the octet sequence of `[ 34, 74, 97, 121, 34 ]` and base64url-encoded as `IkpheSI`.
<{{./fixtures/build/bbs-prover.compact.jwp}}
Figure: Presentation JWP (compact serialization)

The third payload is the string `"jaydoe@example.org"` with the octet sequence of `[ 34, 106, 97, 121, 100, 111, 101, 64, 101, 120, 97, 109, 112, 108, 101, 46, 111, 114, 103, 34 ]` and base64url-encoded as `ImpheWRvZUBleGFtcGxlLm9yZyI`.

The fourth payload is the string `42` with the octet sequence of `[ 52, 50 ]` and base64url-encoded as `NDI`.
### Presentation verification

The message array used as an input to the BLS implementation is:
Verification of a presentation is done by the holder using the `ProofVerify` operation from [@!I-D.irtf-cfrg-bbs-signatures, section 3.4.4].

```json
[
[123, 34, 105, 115, 115, 34, 58, 34, 104, 116, 116, 112, 115, 58,
47, 47, 105, 115, 115, 117, 101, 114, 46, 101, 120, 97, 109, 112,
108, 101, 34, 44, 34, 99, 108, 97, 105, 109, 115, 34, 58, 91, 34,
102, 97, 109, 105, 108, 121, 95, 110, 97, 109, 101, 34, 44, 34,
103, 105, 118, 101, 110, 95, 110, 97, 109, 101, 34, 44, 34, 101,
109, 97, 105, 108, 34, 44, 34, 97, 103, 101, 34, 93, 44, 34, 116,
121, 112, 34, 58, 34, 74, 80, 84, 34, 44, 34, 97, 108, 103, 34, 58,
34, 66, 66, 83, 45, 88, 34, 125],
[ 34, 68, 111, 101, 34 ],
[ 34, 74, 97, 121, 34 ],
[34, 106, 97, 121, 100, 111, 101, 64, 101, 120, 97, 109, 112, 108,
101, 46, 111, 114, 103, 34], [ 52, 50 ]
]
```
Figure: bbs-issuer-messages

Using the above inputs, the output of the `blsSign()` call is the octet string:
```json
[180, 3, 66, 254, 9, 205, 20, 88, 175, 82, 90, 34, 26, 178, 80, 225,
91, 209, 120, 23, 185, 159, 76, 73, 189, 236, 115, 141, 31, 83, 43,
42, 186, 247, 196, 236, 70, 19, 123, 80, 249, 146, 237, 172, 48,
208, 193, 62, 100, 59, 154, 22, 52, 165, 184, 250, 71, 52, 106, 233,
26, 240, 251, 214, 122, 133, 61, 241, 70, 127, 83, 240, 112, 130,
181, 151, 160, 214, 43, 213, 83, 211, 238, 191, 1, 65, 135, 147,
226, 197, 24, 104, 183, 9, 141, 207, 21, 106, 136, 161, 115, 142, 3,
196, 155, 52, 174, 205, 212, 13, 174, 220]
```
Figure: bbs-issuer-signature

The resulting signed JWP in JSON serialization is:
```json
{
"protected": "eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiY2xhaW1z
IjpbImZhbWlseV9uYW1lIiwiZ2l2ZW5fbmFtZSIsImVtYWlsIiwiYWdlIl0sInR5cC
I6IkpQVCIsImFsZyI6IkJCUy1YIn0",
"payloads": [
"IkRvZSI",
"IkpheSI",
"ImpheWRvZUBleGFtcGxlLm9yZyI",
"NDI"
],
"proof": "tANC_gnNFFivUloiGrJQ4VvReBe5n0xJvexzjR9TKyq698TsRhN7UPmS
7aww0ME-ZDuaFjSluPpHNGrpGvD71nqFPfFGf1PwcIK1l6DWK9VT0-6_AUGHk-LFGG
i3CY3PFWqIoXOOA8SbNK7N1A2u3A"
}
```
Figure: bbs-issued-jwp

The same JWP in compact serialization:
```text
ImV5SnBjM01pT2lKb2RIUndjem92TDJsemMzVmxjaTVsZUdGdGNHeGxJaXdpWTJ4aGFX
MXpJanBiSW1aaGJXbHNlVjl1WVcxbElpd2laMmwyWlc1ZmJtRnRaU0lzSW1WdFlXbHNJ
aXdpWVdkbElsMHNJblI1Y0NJNklrcFFWQ0lzSW1Gc1p5STZJa0pDVXkxWUluMCI.IkRv
ZSI~IkpheSI~ImpheWRvZUBleGFtcGxlLm9yZyI~NDI.tANC_gnNFFivUloiGrJQ4VvR
eBe5n0xJvexzjR9TKyq698TsRhN7UPmS7aww0ME-ZDuaFjSluPpHNGrpGvD71nqFPfFG
f1PwcIK1l6DWK9VT0-6_AUGHk-LFGGi3CY3PFWqIoXOOA8SbNK7N1A2u3A
```
Figure: bbs-issued-compact

For verification, a nonce is needed:
```json
[137, 103, 248, 147, 211, 133, 97, 190, 130, 157, 110, 64, 244, 250,
100, 151, 7, 36, 164, 109, 146, 195, 190, 75, 32, 255, 6, 128, 44,
128, 96, 9]
```
Figure: bbs-present-nonce

To generate a proof, the `blsCreateProof()` method is used with a revealed indexes array argument of `[ 0, 2, 4 ]` and results in the octet string:
```json
[0, 5, 21, 169, 73, 242, 49, 111, 234, 26, 186, 194, 204, 174, 241,
30, 165, 50, 117, 236, 144, 95, 147, 186, 219, 190, 135, 205, 66,
179, 227, 86, 151, 246, 174, 234, 204, 46, 171, 249, 225, 198, 135,
81, 131, 225, 141, 217, 47, 217, 127, 176, 15, 98, 110, 233, 74,
220, 230, 27, 201, 117, 114, 211, 41, 183, 44, 64, 185, 45, 140,
153, 49, 73, 199, 93, 208, 248, 212, 175, 106, 199, 83, 255, 128,
77, 152, 250, 166, 101, 78, 248, 10, 106, 236, 24, 238, 21, 34, 134,
128, 186, 132, 153, 123, 86, 88, 156, 246, 203, 23, 253, 248, 217,
233, 1, 168, 208, 12, 193, 222, 142, 90, 28, 223, 241, 130, 164,
144, 83, 0, 15, 165, 25, 156, 145, 243, 39, 88, 249, 246, 185, 152,
3, 220, 72, 180, 0, 0, 0, 116, 133, 180, 58, 53, 105, 120, 124, 227,
160, 78, 229, 74, 209, 111, 164, 101, 183, 86, 122, 212, 126, 90,
23, 228, 109, 184, 73, 75, 114, 177, 142, 178, 89, 107, 100, 189,
187, 74, 143, 167, 218, 186, 193, 189, 247, 14, 134, 40, 0, 0, 0, 2,
5, 130, 120, 86, 255, 28, 33, 145, 20, 149, 195, 8, 4, 200, 212,
178, 67, 147, 230, 174, 192, 9, 158, 94, 179, 144, 63, 60, 82, 255,
216, 4, 85, 108, 209, 194, 209, 177, 106, 69, 215, 235, 177, 83,
244, 1, 195, 102, 135, 99, 20, 121, 7, 252, 26, 187, 206, 16, 250,
134, 1, 255, 197, 92, 130, 105, 241, 175, 35, 22, 210, 101, 158,
113, 214, 222, 3, 4, 168, 188, 251, 34, 213, 211, 224, 150, 147, 38,
164, 229, 151, 226, 223, 188, 181, 180, 204, 228, 58, 107, 55, 232,
148, 180, 199, 42, 181, 127, 59, 233, 234, 188, 0, 0, 0, 4, 93, 196,
31, 38, 151, 105, 231, 46, 228, 46, 86, 196, 136, 212, 175, 170, 83,
21, 78, 19, 224, 211, 122, 7, 92, 71, 17, 171, 66, 122, 56, 130, 45,
19, 172, 217, 65, 63, 246, 39, 6, 30, 77, 132, 86, 36, 41, 3, 234,
72, 146, 200, 101, 150, 159, 108, 140, 15, 195, 57, 249, 154, 191,
204, 91, 30, 159, 32, 157, 24, 3, 110, 90, 102, 99, 206, 42, 58, 1,
181, 215, 85, 29, 32, 131, 46, 76, 25, 5, 43, 203, 32, 215, 167,
169, 108, 56, 174, 146, 51, 174, 40, 190, 22, 37, 93, 156, 245,
208, 26, 55, 180, 135, 115, 70, 96, 106, 243, 213, 131, 196, 63,
165, 42, 157, 22, 94, 46]
```
Figure: bbs-present-proof

The resulting verifiable JWP in JSON serialization is:
```json
{
"protected": "eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiY2xhaW1z
IjpbImZhbWlseV9uYW1lIiwiZ2l2ZW5fbmFtZSIsImVtYWlsIiwiYWdlIl0sInR5cC
I6IkpQVCIsImFsZyI6IkJCUy1YIn0",
"payloads": [
null,
"IkpheSI",
null,
"NDI"
],
"proof": "AAUVqUnyMW_qGrrCzK7xHqUydeyQX5O6276HzUKz41aX9q7qzC6r-eHG
h1GD4Y3ZL9l_sA9ibulK3OYbyXVy0ym3LEC5LYyZMUnHXdD41K9qx1P_gE2Y-qZlTv
gKauwY7hUihoC6hJl7Vlic9ssX_fjZ6QGo0AzB3o5aHN_xgqSQUwAPpRmckfMnWPn2
uZgD3Ei0AAAAdIW0OjVpeHzjoE7lStFvpGW3VnrUfloX5G24SUtysY6yWWtkvbtKj6
fausG99w6GKAAAAAIFgnhW_xwhkRSVwwgEyNSyQ5PmrsAJnl6zkD88Uv_YBFVs0cLR
sWpF1-uxU_QBw2aHYxR5B_wau84Q-oYB_8VcgmnxryMW0mWecdbeAwSovPsi1dPglp
MmpOWX4t-8tbTM5DprN-iUtMcqtX876eq8AAAABF3EHyaXaecu5C5WxIjUr6pTFU4T
4NN6B1xHEatCejiCLROs2UE_9icGHk2EViQpA-pIkshllp9sjA_DOfmav8xbHp8gnR
gDblpmY84qOgG111UdIIMuTBkFK8sg16epbDiukjOuKL4WJV2c9dAaN7SHc0ZgavPV
g8Q_pSqdFl4u"
}
```
Figure: bbs-present-jwp

The same JWP in compact serialization:
```text
ImV5SnBjM01pT2lKb2RIUndjem92TDJsemMzVmxjaTVsZUdGdGNHeGxJaXdpWTJ4aGFX
MXpJanBiSW1aaGJXbHNlVjl1WVcxbElpd2laMmwyWlc1ZmJtRnRaU0lzSW1WdFlXbHNJ
aXdpWVdkbElsMHNJblI1Y0NJNklrcFFWQ0lzSW1Gc1p5STZJa0pDVXkxWUluMCI.~Ikp
heSI~~NDI.AAUVqUnyMW_qGrrCzK7xHqUydeyQX5O6276HzUKz41aX9q7qzC6r-eHGh1
GD4Y3ZL9l_sA9ibulK3OYbyXVy0ym3LEC5LYyZMUnHXdD41K9qx1P_gE2Y-qZlTvgKau
wY7hUihoC6hJl7Vlic9ssX_fjZ6QGo0AzB3o5aHN_xgqSQUwAPpRmckfMnWPn2uZgD3E
i0AAAAdIW0OjVpeHzjoE7lStFvpGW3VnrUfloX5G24SUtysY6yWWtkvbtKj6fausG99w
6GKAAAAAIFgnhW_xwhkRSVwwgEyNSyQ5PmrsAJnl6zkD88Uv_YBFVs0cLRsWpF1-uxU_
QBw2aHYxR5B_wau84Q-oYB_8VcgmnxryMW0mWecdbeAwSovPsi1dPglpMmpOWX4t-8tb
TM5DprN-iUtMcqtX876eq8AAAABF3EHyaXaecu5C5WxIjUr6pTFU4T4NN6B1xHEatCej
iCLROs2UE_9icGHk2EViQpA-pIkshllp9sjA_DOfmav8xbHp8gnRgDblpmY84qOgG111
UdIIMuTBkFK8sg16epbDiukjOuKL4WJV2c9dAaN7SHc0ZgavPVg8Q_pSqdFl4u
```
Figure: bbs-present-compact
This operation utilizes the issuer's public key as `PK`, the issuer protected header as `header`, the issuance proof as `signature`, the holder's presentation protected header as `ph`, and the payloads as `disclosed_messages`.

In addition, the `disclosed_indexes` vector value is calculated from the payloads. For each absent value in payloads (`null` in JSON serialization or a zero-length string in compact serialization), the index of that payload is added to this vector.

## Message Authentication Code

Expand Down

0 comments on commit 49d0892

Please sign in to comment.