Skip to content

Commit

Permalink
switch from wasm-based hpke-dispatch to hpke-js
Browse files Browse the repository at this point in the history
  • Loading branch information
jbr committed Aug 23, 2023
1 parent 7951178 commit 9ea361c
Show file tree
Hide file tree
Showing 11 changed files with 682 additions and 975 deletions.
1,071 changes: 410 additions & 661 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"scripts": {
"test": "npm test -ws --if-present",
"build": "npm run -ws --if-present build",
"build:clean": "npm run -ws --if-present build:clean",
"test:coverage": "c8 npm test",
"lint": "npm run -ws --if-present lint",
"clean": "npm run -ws clean",
Expand All @@ -31,7 +32,6 @@
"@typescript-eslint/parser": "^6.4.1",
"c8": "^8.0.1",
"chai": "^4.3.7",
"esbuild": "^0.19.2",
"eslint": "^8.47.0",
"eslint-config-prettier": "^9.0.0",
"mocha": "^10.2.0",
Expand All @@ -44,4 +44,4 @@
"typescript": "^5.0.4",
"typescript-eslint-language-service": "^5.0.5"
}
}
}
13 changes: 6 additions & 7 deletions packages/dap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,26 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"source": "src/index.ts",
"module": "dist/module.js",
"browser": "dist/browser.js",
"type": "module",
"license": "MPL-2.0",
"scripts": {
"clean": "rm -rf dist/*",
"build:clean": "npm run clean && npm run build",
"build": "npm run build:web && npm run build:node",
"build:web": "esbuild browser=src/index.ts --bundle --loader:.wasm=binary --format=esm --outdir=dist --sourcemap --minify",
"build:node": "tsc -p ./tsconfig.json",
"build": "tsc -p ./tsconfig.json",
"docs": "typedoc src",
"test": "mocha \"src/**/*.spec.ts\"",
"lint": "eslint src --ext .ts && prettier -c src",
"format": "prettier -w src",
"check": "tsc --noEmit -p ./tsconfig.json",
"format": "prettier -w src",
"test:coverage": "c8 npm test"
},
"dependencies": {
"@divviup/common": "^0.1.0",
"@divviup/prio3": "^0.1.0",
"@divviup/vdaf": "^0.1.0",
"hpke": "^0.5.0"
"@hpke/chacha20poly1305": "^1.2.2",
"@hpke/core": "^1.2.2",
"@hpke/dhkem-x25519": "^1.2.2",
"hpke-js": "^1.2.2"
}
}
60 changes: 33 additions & 27 deletions packages/dap/src/aggregator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Aggregator } from "./aggregator";
import assert from "assert";
import { Role } from "./constants";
import { HpkeConfig, HpkeConfigList } from "./hpkeConfig";
import { Aead, Kdf, Kem, Keypair } from "hpke";
import {
InputShareAad,
InputShareInfo,
Expand All @@ -11,12 +10,14 @@ import {
} from "./report";
import { TaskId } from "./taskId";
import { ReportId } from "./reportId";
import { KdfId, AeadId } from "hpke-js";
import { DhkemP256HkdfSha256 } from "@hpke/core";

describe("DAP Aggregator", () => {
it("should append a trailing slash on construction from a string", () => {
const aggregator = new Aggregator(
"http://example.com/aggregator",
Role.Leader,
Role.Leader
);

assert.equal(aggregator.url.toString(), "http://example.com/aggregator/");
Expand All @@ -25,7 +26,7 @@ describe("DAP Aggregator", () => {
it("should append a trailing slash on construction from a URL", () => {
const aggregator = new Aggregator(
new URL("http://example.com/aggregator"),
Role.Leader,
Role.Leader
);

assert.equal(aggregator.url.toString(), "http://example.com/aggregator/");
Expand All @@ -34,60 +35,65 @@ describe("DAP Aggregator", () => {
it("has a convenience method to build helper aggregator", () => {
assert.deepEqual(
Aggregator.helper("http://example.com"),
new Aggregator("http://example.com", Role.Helper),
new Aggregator("http://example.com", Role.Helper)
);
});

it("has a convenience method to build leader aggregator", () => {
assert.deepEqual(
Aggregator.leader("http://example.com"),
new Aggregator("http://example.com", Role.Leader),
new Aggregator("http://example.com", Role.Leader)
);
});

it("performs a hpke seal with the first valid hpke config", () => {
it("performs a hpke seal with the first valid hpke config", async () => {
const aggregator = Aggregator.leader("https://example.com");
const kem = Kem.DhP256HkdfSha256;
const { public_key, private_key } = new Keypair(kem);
const kem = new DhkemP256HkdfSha256();
const { publicKey, privateKey } = await kem.generateKeyPair();
const key = await kem.serializePublicKey(publicKey);

const hpkeConfig = new HpkeConfig(
1,
kem,
Kdf.Sha256,
Aead.AesGcm128,
Buffer.from(public_key),
kem.id,
KdfId.HkdfSha256,
AeadId.Aes128Gcm,
Buffer.from(key)
);

aggregator.hpkeConfigList = new HpkeConfigList([hpkeConfig]);
const inputShare = new PlaintextInputShare([], Buffer.from("payload"));
const aad = new InputShareAad(
TaskId.random(),
new ReportMetadata(ReportId.random(), Date.now() / 1000),
Buffer.alloc(0),
Buffer.alloc(0)
);
const cipherText = aggregator.seal(inputShare, aad);
const cipherText = await aggregator.seal(inputShare, aad);

const open = hpkeConfig
.config()
.base_mode_open(
private_key,
cipherText.encapsulatedContext,
new InputShareInfo(Role.Leader).encode(),
cipherText.payload,
aad.encode(),
);
const open = await hpkeConfig.cipherSuite().open(
{
recipientKey: privateKey,
enc: cipherText.encapsulatedContext,
info: new InputShareInfo(Role.Leader).encode(),
},
cipherText.payload,
aad.encode()
);

assert.deepEqual(Buffer.from(open), inputShare.encode());
assert.deepEqual(
Buffer.from(open).toString("hex"),
inputShare.encode().toString("hex")
);
});

it("throws when hpke seal is called without a hpke config list", () => {
it("throws when hpke seal is called without a hpke config list", async () => {
const aggregator = Aggregator.leader("https://example.com");
const inputShare = new PlaintextInputShare([], Buffer.from("payload"));
const aad = new InputShareAad(
TaskId.random(),
new ReportMetadata(ReportId.random(), Date.now() / 1000),
Buffer.alloc(0),
Buffer.alloc(0)
);

assert.throws(() => aggregator.seal(inputShare, aad));
await assert.rejects(aggregator.seal(inputShare, aad));
});
});
7 changes: 5 additions & 2 deletions packages/dap/src/aggregator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ export class Aggregator {
return new Aggregator(url, Role.Leader);
}

seal(inputShare: PlaintextInputShare, aad: InputShareAad): HpkeCiphertext {
async seal(
inputShare: PlaintextInputShare,
aad: InputShareAad,
): Promise<HpkeCiphertext> {
if (!this.hpkeConfigList) {
throw new Error(
"Attempted to call Aggregator#seal before fetching a hpkeConfigList.",
);
}
return this.hpkeConfigList
return await this.hpkeConfigList
.selectConfig()
.seal(
new InputShareInfo(this.role).encode(),
Expand Down
Loading

0 comments on commit 9ea361c

Please sign in to comment.