Skip to content

Commit

Permalink
Bbs updates to draft 3 (#85)
Browse files Browse the repository at this point in the history
* Refactoring fixtures to generate draft-irtf-cfrg-bbs-signatures-03 examples.

- Switched from older MATTR library to @mattrglobal/pairing-crypto. Currently requires a packaged build since it isn't in upstream npm.
- Refactored examples to input from a template directory, output to build directory
- Split out key generation, just in case we can get stable examples.

* Move Node.js package.json to the root to take advantage of i-d-template support. Wire up build/clean

* modify text to use operations from BBS draft 3

* Change algorithms to specifically refer to draft 3 of the bbs signatures work

* Apply suggestions from code review

Co-authored-by: Michael B. Jones <michael_b_jones@hotmail.com>

* Some text restructuring/cleanup in BBS section to space out the figures, added acknowledgement of MATTR library used for BBS examples

---------

Co-authored-by: Michael B. Jones <michael_b_jones@hotmail.com>
  • Loading branch information
dwaite and selfissued authored Oct 20, 2023
1 parent 43eb204 commit 22690c1
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 476 deletions.
100 changes: 0 additions & 100 deletions .circleci/config.yml

This file was deleted.

10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
SUBDIRS = fixtures
LIBDIR := lib
include $(LIBDIR)/main.mk

.PHONY: $(SUBDIRS)
fixtures:
cd fixtures; node bbs-keygen.mjs; node bbs-fixtures.mjs

$(drafts_xml): fixtures

$(LIBDIR)/main.mk:
ifneq (,$(shell grep "path *= *$(LIBDIR)" .gitmodules 2>/dev/null))
git submodule sync
Expand All @@ -9,3 +16,6 @@ else
git clone -q --depth 10 $(CLONE_ARGS) \
-b main https://github.com/martinthomson/i-d-template $(LIBDIR)
endif

clean::
rm -r fixtures/build
263 changes: 48 additions & 215 deletions draft-ietf-jose-json-proof-algorithms.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion fixtures/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.DS_Store
.vscode
node_modules/
package-lock.json
build/
81 changes: 81 additions & 0 deletions fixtures/bbs-fixtures.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import fs from "fs/promises";

import pairing from "@mattrglobal/pairing-crypto";
import { encode } from 'jose/util/base64url';

import { keyRead } from './bbs-keyread.mjs';

import protectedHeaderJSON from "./template/bbs-issuer-protected-header.json" assert {type: "json"};
import presentationHeaderJSON from "./template/bbs-prover-presentation-header.json" assert {type: "json"};
import payloadsJSON from "./template/bbs-issuer-payloads.json" assert {type: "json"};

// load/massage data
const keyPair = await keyRead();
const protectedHeader = Buffer.from(JSON.stringify(protectedHeaderJSON), "UTF-8");
const payloads = payloadsJSON.map((item)=>Buffer.from(JSON.stringify(item), "UTF-8"));
const presentationHeader = Buffer.from(JSON.stringify(presentationHeaderJSON), "UTF-8");

// calculate signature
const signature = await pairing.bbs.bls12381_sha256.sign({
publicKey: keyPair.publicKey,
secretKey: keyPair.secretKey,
header: protectedHeader,
payloads: payloads
});

await fs.writeFile("build/bbs-issuer-proof.base64url", encode(signature), {encoding: "UTF-8"});

// Compact Serialization
const compactSerialization = [
encode(protectedHeader),
payloads.map((item)=>encode(item)).join("~"),
encode(signature)
].join(".");
await fs.writeFile("build/bbs-issuer.compact.jwp", compactSerialization, {encoding: "UTF-8"});

// JSON Serialization
const jsonSerialziation = {
issuer: encode(protectedHeader),
payloads: payloads.map((item)=>encode(item)),
proof: encode(signature)
};

await fs.writeFile("build/bbs-issuer.json.jwp", JSON.stringify(jsonSerialziation, null, 2), {encoding: "UTF-8"});

// Generate proof, selectively disclosing only name and age
var proof = await pairing.bbs.bls12381_sha256.deriveProof({
publicKey: keyPair.publicKey,
header: protectedHeader,
presentationHeader: presentationHeader,
signature: signature,
verifySignature: false,
messages: [
{ value: payloads[0], reveal: true },
{ value: payloads[1], reveal: true },
{ value: payloads[2], reveal: false },
{ value: payloads[3], reveal: true }
]
});
await fs.writeFile("build/bbs-prover-proof.base64url", encode(proof), {encoding: "UTF-8"});

// go ahead and modify payloads in place for final output
payloads[2] = null; // remove email

// Compact Serialization
const compactProverSerialization = [
encode(presentationHeader),
encode(protectedHeader),
payloads.map((item)=>encode(item || "")).join("~"),
encode(proof)
].join(".");
await fs.writeFile("build/bbs-prover.compact.jwp", compactProverSerialization, {encoding: "UTF-8"});

// JSON Serialization
const jsonProverSerialization = {
presentation: encode(presentationHeader),
issuer: encode(protectedHeader),
payloads: payloads.map((item)=> item && encode(item)),
proof: encode(proof)
};

await fs.writeFile("build/bbs-prover.json.jwp", JSON.stringify(jsonProverSerialization, null, 2), {encoding: "UTF-8"});
30 changes: 30 additions & 0 deletions fixtures/bbs-keygen.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// generate two files (public-key.jwk and private-key.jwk)
// containing a BLS curve key pair usable for issuance, based on
// https://www.ietf.org/archive/id/draft-ietf-cose-bls-key-representations-02.html
import {bbs} from "@mattrglobal/pairing-crypto"
import {encode} from "jose/util/base64url"
import fs from "fs/promises";

var keys = await bbs.bls12381_sha256.generateKeyPair();

// create "build" directory if doesn't exist
try { await fs.mkdir("build"); } catch (e) { /* ignore */ }

await fs.writeFile("build/private-key.jwk",
JSON.stringify({
kty: "OKP",
alg: "BBS-DRAFT-3",
use: "proof",
crv: "BLs12381G2",
x: encode(keys.publicKey),
d: encode(keys.secretKey)
}, null, 2));

await fs.writeFile("build/public-key.jwk",
JSON.stringify({
kty: "OKP",
alg: "BBS-DRAFT-3",
use: "proof",
crv: "BLs12381G2",
x: encode(keys.publicKey)
}, null, 2));
12 changes: 12 additions & 0 deletions fixtures/bbs-keyread.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// read the previous generated key from build/private-key.jwk

import {decode} from "jose/util/base64url"
import fs from "fs/promises";

export async function keyRead() {
let jwk = JSON.parse(await fs.readFile("build/private-key.jwk"));
return {
secretKey: decode(jwk.d),
publicKey: decode(jwk.x)
};
}
Loading

0 comments on commit 22690c1

Please sign in to comment.