Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add test utils wasm package #164

Merged
merged 2 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/actions/setup-dfx/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ description: Setup DFX
runs:
using: 'composite'
steps:
- name: Get DFX version
shell: bash
run: echo "dfx_version=$(cat dfx.json | jq -r .dfx)" >> "$GITHUB_ENV"

- name: Cache DFX
uses: actions/cache@v3
with:
Expand All @@ -22,7 +18,7 @@ runs:
echo "DFX restored from cache"
else
echo "DFX not restored from cache, running install script:"
DFX_VERSION=${{ env.dfx_version }} sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)"
DFX_VERSION=0.14.2 sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)"
nathanosdev marked this conversation as resolved.
Show resolved Hide resolved
fi
echo "DFX version"
dfx --version
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ jobs:
- name: Build NPM packages
run: pnpm build

- name: Test NPM packages
run: pnpm test

- name: Test Cargo crates
run: cargo test

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ members = [
# these projects need wasm32-unknown-unknown as their target
exclude = [
"examples/certified-counter/src/backend",
"packages/ic-response-verification-wasm"
"packages/ic-response-verification-wasm",
"packages/ic-certification-test-utils-wasm",
]

[profile.release]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,7 @@ See [Conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) for m
| Project | Command | Description |
| ----------------------------------- | ----------------------------------------------------------- | ------------------------------------------ |
| All | `pnpm build` | Build all NPM projects |
| `@dfinity/certificate-verification` | `pnpm run --filter @dfinity/certificate-verification build` | Build certificate verification |
| `@dfinity/certificate-verification` | `pnpm run --filter @dfinity/certificate-verification test` | Test certificate verification |
| `@dfinity/certification-test-utils` | `pnpm run --filter @dfinity/certification-test-utils build` | Build certification test utils |
| `@dfinity/response-verification` | `pnpm run --filter @dfinity/response-verification build` | Build the response verification JS library |
14 changes: 7 additions & 7 deletions examples/certified-counter/src/frontend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ buttonElement.addEventListener('click', async event => {

const agent = new HttpAgent();
await agent.fetchRootKey();
const tree = await verifyCertification(
Principal.fromText(canisterId),
new Uint8Array(certificate).buffer,
new Uint8Array(witness).buffer,
agent.rootKey,
50000,
);
const tree = await verifyCertification({
nathanosdev marked this conversation as resolved.
Show resolved Hide resolved
canisterId: Principal.fromText(canisterId),
encodedCertificate: new Uint8Array(certificate).buffer,
encodedTree: new Uint8Array(witness).buffer,
rootKey: agent.rootKey,
maxCertificateTimeOffsetMs: 50000,
});

const treeHash = lookup_path(['count'], tree);
if (!treeHash) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"scripts": {
"build": "pnpm run -r build",
"format": "prettier --write .",
"format:check": "prettier --check ."
"format:check": "prettier --check .",
"test": "pnpm run -r test"
},
"engines": {
"node": "^18",
Expand Down
14 changes: 7 additions & 7 deletions packages/certificate-verification-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ Check [ic-certified-map](https://github.com/dfinity/cdk-rs/tree/main/library/ic-
```javascript
const { data, certificate, witness } = await canister.get_data();

const tree = await verifyCertification(
Principal.fromText(canisterId),
new Uint8Array(certificate).buffer,
new Uint8Array(witness).buffer,
agent.rootKey,
50000,
);
const tree = await verifyCertification({
canisterId: Principal.fromText(canisterId),
encodedCertificate: new Uint8Array(certificate).buffer,
encodedTree: new Uint8Array(witness).buffer,
rootKey: agent.rootKey,
maxCertificateTimeOffsetMs: 50000,
});

const treeDataHash = lookup_path(['count'], tree);
const responseDataHash = calculateDataHash(data);
Expand Down
3 changes: 3 additions & 0 deletions packages/certificate-verification-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
"@dfinity/agent": "~0.15.7",
"@dfinity/candid": "~0.15.7",
"@dfinity/principal": "~0.15.7"
},
"devDependencies": {
"@dfinity/certification-test-utils": "workspace:*"
}
}
49 changes: 49 additions & 0 deletions packages/certificate-verification-js/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { describe, expect, it } from 'vitest';
import { HashTree, reconstruct, Cbor } from '@dfinity/agent';
import { CertificateBuilder } from '@dfinity/certification-test-utils';
import { Principal } from '@dfinity/principal';
import { createHash, webcrypto } from 'node:crypto';
import { verifyCertification } from './index';

globalThis.crypto = webcrypto as Crypto;

describe('verifyCertification', () => {
it('should verify a valid certificate with delegation', async () => {
const userId = '1234';

const username = 'testuser';
const usernameHash = new Uint8Array(
createHash('sha256').update(username).digest(),
);

const hashTree: HashTree = [
2,
new Uint8Array(Buffer.from(userId)),
[3, usernameHash],
];
const rootHash = await reconstruct(hashTree);
const cborEncodedTree = Cbor.encode(hashTree);

const canisterId = Principal.fromUint8Array(
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]),
);
const time = BigInt(Date.now());

const certificate = new CertificateBuilder(
canisterId.toString(),
new Uint8Array(rootHash),
)
.withTime(time)
.withDelegation(123n, [{ high: 10, low: 0 }])
.build();

const decodedHashTree = await verifyCertification({
canisterId,
encodedCertificate: certificate.cborEncodedCertificate,
encodedTree: cborEncodedTree,
maxCertificateTimeOffsetMs: 5000,
rootKey: certificate.rootKey,
});
expect(decodedHashTree).toEqual(hashTree);
});
});
22 changes: 15 additions & 7 deletions packages/certificate-verification-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ import { Principal } from '@dfinity/principal';
import { PipeArrayBuffer, lebDecode } from '@dfinity/candid';
import { CertificateTimeError, CertificateVerificationError } from './error';

export async function verifyCertification(
canisterId: Principal,
encodedCertificate: ArrayBuffer,
encodedTree: ArrayBuffer,
rootKey: ArrayBuffer,
maxCertificateTimeOffsetMs: number,
): Promise<HashTree> {
export interface CertificationParams {
nathanosdev marked this conversation as resolved.
Show resolved Hide resolved
canisterId: Principal;
encodedCertificate: ArrayBuffer;
encodedTree: ArrayBuffer;
rootKey: ArrayBuffer;
maxCertificateTimeOffsetMs: number;
}

export async function verifyCertification({
canisterId,
encodedCertificate,
encodedTree,
rootKey,
maxCertificateTimeOffsetMs,
}: CertificationParams): Promise<HashTree> {
const certificate = await Certificate.create({
certificate: encodedCertificate,
canisterId,
Expand Down
Loading