Skip to content

Commit

Permalink
Update function to check VC validity, add check: whether the attester…
Browse files Browse the repository at this point in the history
…'s sequence is the same in proof
  • Loading branch information
jonathanxuu committed Aug 26, 2023
1 parent d61c738 commit dfd33dc
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 19 deletions.
16 changes: 15 additions & 1 deletion protocol/did/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { DidUrl, VerificationMethodType } from '@zcloak/did-resolver/types';
import type { KeypairType } from '@zcloak/keyring/types';

import { stringToU8a, u8aConcat } from '@polkadot/util';
import { isArray, stringToU8a, u8aConcat } from '@polkadot/util';

import { parseDid } from '@zcloak/did-resolver/parseDid';

Expand All @@ -19,6 +19,20 @@ export function isSameUri(didUrl1: DidUrl, didUrl2: DidUrl): boolean {
return did1 === did2;
}

export function isAttester(value: unknown, version: string): boolean {
if (typeof value === 'string' && (version === '0' || version === '1')) {
return isDidUrl(value)
} else if (isArray(value) && value.length !== 0 && version === '2'){
let check = true;
for (const item of value) {
check = isDidUrl(item) && check;
}
return check;
} else {
throw new Error(`The attester is not valid`);

This comment has been minimized.

Copy link
@jonathanxuu

jonathanxuu Aug 26, 2023

Author Collaborator

Remove throw new Error, change to return false in check function
Already removed in the next commit

}
}

export function isDidUrl(value: unknown): value is DidUrl {
if (typeof value !== 'string') return false;

Expand Down
20 changes: 10 additions & 10 deletions protocol/vc/src/credential/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ describe('VerifiableCredential', (): void => {
digestHashType: 'Keccak256'
});

const vc = await vcBuilder.build(issuer);

const vc = await vcBuilder.build(issuer, false);
console.log(vc)

This comment has been minimized.

Copy link
@jonathanxuu

jonathanxuu Aug 26, 2023

Author Collaborator

Already removed the console.logs in the next commit

expect(isPrivateVC(vc)).toBe(true);

expect(vc).toMatchObject({
Expand All @@ -120,7 +120,7 @@ describe('VerifiableCredential', (): void => {
ctype: ctype.$id,
issuanceDate: now,
credentialSubject: CONTENTS,
issuer: issuer.id,
issuer: [issuer.id],
holder: holder.id,
hasher: ['RescuePrime', 'Keccak256'],
proof: [
Expand Down Expand Up @@ -153,7 +153,7 @@ describe('VerifiableCredential', (): void => {
digestHashType: 'Keccak256'
});

const vc = await vcBuilder.build(issuer);
const vc = await vcBuilder.build(issuer, false);

expect(isPrivateVC(vc)).toBe(true);

Expand All @@ -163,7 +163,7 @@ describe('VerifiableCredential', (): void => {
ctype: ctype.$id,
issuanceDate: now,
credentialSubject: CONTENTS,
issuer: issuer.id,
issuer: [issuer.id],
holder: holder.id,
hasher: ['RescuePrime', 'Keccak256'],
proof: [
Expand Down Expand Up @@ -196,17 +196,17 @@ describe('VerifiableCredential', (): void => {
digestHashType: 'Keccak256'
});

const vc = await vcBuilder.build(issuer);

expect(isPrivateVC(vc)).toBe(true);
const vc = await vcBuilder.build(issuer, false,["did:zk:0xFeDE01Ff4402e35c6f6d20De9821d64bDF4Ba563"]);
console.log(vc)

This comment has been minimized.

Copy link
@jonathanxuu

jonathanxuu Aug 26, 2023

Author Collaborator

Already removed the console.logs in the next commit

expect(isPrivateVC(vc)).toBe(false);

expect(vc).toMatchObject({
'@context': DEFAULT_CONTEXT,
version: DEFAULT_VC_VERSION,
ctype: ctype.$id,
issuanceDate: now,
credentialSubject: CONTENTS,
issuer: issuer.id,
issuer: [issuer.id, "did:zk:0xFeDE01Ff4402e35c6f6d20De9821d64bDF4Ba563"],
holder: holder.id,
hasher: ['RescuePrimeOptimized', 'Keccak256'],
proof: [
Expand Down Expand Up @@ -256,7 +256,7 @@ describe('VerifiableCredential', (): void => {
ctype: ctype.$id,
issuanceDate: now,
credentialSubject: CONTENTS,
issuer: issuer.id,
issuer: [issuer.id],
holder: holder.id,
hasher: ['RescuePrime', 'Keccak256'],
proof: [
Expand Down
2 changes: 1 addition & 1 deletion protocol/vc/src/credential/vc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class VerifiableCredentialBuilder {
if (isPublic) {
rootHashResult = calcRoothash(this.raw.contents, this.raw.hashType, this.version);
} else {
rootHashResult = calcRoothash(this.raw.contents, this.raw.hashType, this.version,{});
rootHashResult = calcRoothash(this.raw.contents, this.raw.hashType, this.version, {});
}

const digestPayload: DigestPayload<VerifiableCredentialVersion> = {
Expand Down
38 changes: 35 additions & 3 deletions protocol/vc/src/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import type {
import { isArray, isHex, isJsonObject, isNull, isNumber, isString, isUndefined } from '@polkadot/util';

import { isBase32, isBase58, isBase64 } from '@zcloak/crypto';
import { isDidUrl } from '@zcloak/did/utils';
import { isAttester, isDidUrl } from '@zcloak/did/utils';

import { ALL_HASH_TYPES, ALL_SIG_TYPES, ALL_VP_TYPES } from './defaults';
import { parseDid } from '@zcloak/did-resolver/parseDid';

/**
* @name isHashType
Expand Down Expand Up @@ -61,6 +62,37 @@ export function isProof(input: unknown): input is Proof {
);
}

/**
* @name isAttesterMapping
* @description
* check the `attester` is the same in [[Proof]]
*/
export function isAttesterMapping(issuer: unknown, proof: unknown): boolean {
if (isProof(proof)) {
const issuerInProof = parseDid(proof.verificationMethod).did;
return issuer === issuerInProof;
} else return false;
}

/**
* @name isAttesterProof
* @description
* check the Proof is qualified or not
*/
export function isAttesterProof(issuer: unknown, proof: unknown): boolean {
// version 0 & version 1, only one attester and one proof
if (typeof issuer === 'string' && isArray(proof) && proof.length === 1) {
return isAttesterMapping(issuer, proof);
} else if (isArray(issuer) && isArray(proof) && issuer.length === proof.length) {
let check = true;
for (let i = 0; i < issuer.length; i++) {
check = isAttesterMapping(issuer[i], proof[i]) && check;
}
return check;
} else {
return false;
}
}
/**
* @name isRawCredential
* @description
Expand Down Expand Up @@ -118,10 +150,10 @@ export function isVC(input: unknown): input is VerifiableCredential<boolean> {
isString(input.version) &&
isNumber(input.issuanceDate) &&
(isUndefined(input.expirationDate) || isNull(input.expirationDate) || isNumber(input.expirationDate)) &&
isDidUrl(input.issuer) &&
isAttester(input.issuer, input.version as string) &&

This comment has been minimized.

Copy link
@jonathanxuu

jonathanxuu Aug 26, 2023

Author Collaborator

Modify this function in the next commit (remove as string)

isHex(input.digest) &&
isArray(input.proof) &&
!input.proof.map((p) => isProof(p)).includes(false) &&
isAttesterProof(input.issuer, input.proof) &&
isHex(input.ctype) &&
(isJsonObject(input.credentialSubject) || isHex(input.credentialSubject)) &&
isDidUrl(input.holder) &&
Expand Down
29 changes: 28 additions & 1 deletion protocol/vc/src/rootHash.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { HexString } from '@polkadot/util/types';
import { initCrypto } from '@zcloak/crypto';
import { initCrypto, keccak256AsHex } from '@zcloak/crypto';

import { calcRoothash } from './rootHash';
import { encodeAsSol } from './utils';
Expand Down Expand Up @@ -122,6 +122,7 @@ describe('calcRoothash', (): void => {
expect(rootHash).toEqual('0x2cbd72a75cf5797fb6893b222a45de60eaa2ddf2e5d435d67e5ed8067efb76e3');
});
});

describe('calcContentAsSolidity', () => {
it('calcRoothash', (): void => {
const input = {
Expand All @@ -138,4 +139,30 @@ describe('calcRoothash', (): void => {
]);
});
});

describe('calc Roothash with version 2', () => {
it('calcRoothash', (): void => {
const input = {
name: 'zCloak',
age: 111,
number_array: [11, 12, 13],
isUser: true,
string_array: ["zCloak", "database"]
};
const values = Object.values(input);
const encodedClaimHashes: HexString[] = values.map((values) => encodeAsSol(values));

expect(encodedClaimHashes).toEqual(["0x28cb5b00333a3266fa3d92f3426ad4ef1d20018b44dd64913578d43438b4051a", "0x39f2babe526038520877fc7c33d81accf578af4a06c5fa6b0d038cae36e12711", "0x8d20824cd86ad1c5673537a4b5d1ee68bd9265b7d357e82bc76483ae879322c2", "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2", "0x69ab0c29dcf9256886435d72272bceee1f0a0b2cee41865d3b56f9726e7fe0a3",
]);

const { rootHash } = calcRoothash(input, 'Keccak256', '2', {'0x28cb5b00333a3266fa3d92f3426ad4ef1d20018b44dd64913578d43438b4051a': '0xcd769c703ecfdc6798d56711af8b3a7918973524db6c6c0901209fd396f3a61b',
'0x39f2babe526038520877fc7c33d81accf578af4a06c5fa6b0d038cae36e12711': '0xc5bd9417c2dd820e8c074086acb0e1a785c5f9aa59022ca74606f4f6f32338bb',
'0x8d20824cd86ad1c5673537a4b5d1ee68bd9265b7d357e82bc76483ae879322c2': '0x9895d1010a3c7ae796bfdb2bff52febcfb21d8c71a0fb465a02d8a2a0ad857bd',
'0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2': '0xddb361f768d83f2f8eabd4f51517adb8d92aef33ce627127311bad01bac41710',
'0x69ab0c29dcf9256886435d72272bceee1f0a0b2cee41865d3b56f9726e7fe0a3': '0x51c09e0512047698103565fc9c2aca963eb3af6cf99b9201fc6be1331e4649e5'
});
console.log(rootHash)
expect(rootHash).toEqual('0x8e94d639398a25f0484ba8f40feff5e694b084164118af84ffece25c68be4342');
});
});
});
1 change: 0 additions & 1 deletion protocol/vc/src/rootHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export function rootHashFromMerkle(
}

const leave = HASHER[hashType](nonceMap ? u8aConcat(encode, nonceMap[encode]) : encode);

leaves.push(leave);
}

Expand Down
3 changes: 1 addition & 2 deletions protocol/vc/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ export function encodeAsSol(input: NativeType | NativeTypeWithOutNull[]): HexStr
return web3.utils.soliditySha3({ type: 'int256[]', value: input });
} else throw new Error(`This object can not be encoded ${input}`);
default:
const check: never = input;
return check;
throw new Error(`Can not encode this type: ${input}`)
}
}

Expand Down

0 comments on commit dfd33dc

Please sign in to comment.