From b9292ba4eeda71bb0ce4773d356b3ae76e79a3a5 Mon Sep 17 00:00:00 2001 From: lovesh Date: Mon, 4 Mar 2024 20:24:52 +0530 Subject: [PATCH] Add KVAC Signed-off-by: lovesh --- .eslintrc.js | 1 + package.json | 11 +- src/Pseudonym.ts | 2 +- src/accumulator/accumulator.ts | 48 +-- src/accumulator/accumulatorWitness.ts | 48 +-- src/accumulator/params-and-keys.ts | 2 +- src/accumulator/proof.ts | 32 +- .../blinded-credential-builder.ts | 44 ++- .../blinded-credential-request-builder.ts | 55 ++- .../blinded-credential-request.ts | 33 +- .../blinded-credential.ts | 55 ++- .../credential-builder-common.ts | 6 +- .../credential-builder.ts | 36 +- src/anonymous-credentials/credential.ts | 60 ++- src/anonymous-credentials/delegated-proof.ts | 54 +++ .../presentation-builder.ts | 65 ++-- src/anonymous-credentials/presentation.ts | 231 ++++++++---- src/anonymous-credentials/types-and-consts.ts | 45 ++- src/anonymous-credentials/util.ts | 186 ++++++++-- src/bbs-plus/keys.ts | 2 +- src/bbs-plus/params.ts | 2 +- src/bbs-plus/proof.ts | 2 +- src/bbs-plus/signature.ts | 2 +- src/bbs/keys.ts | 2 +- src/bbs/params.ts | 4 +- src/bbs/proof.ts | 2 +- src/bbs/signature.ts | 4 +- src/bddt16-mac/index.ts | 3 + src/bddt16-mac/keys.ts | 11 + src/bddt16-mac/mac.ts | 234 ++++++++++++ src/bddt16-mac/params.ts | 139 +++++++ src/bound-check/index.ts | 2 +- src/composite-proof/proof-spec.ts | 14 +- src/composite-proof/proof.ts | 71 +++- src/composite-proof/setup-param.ts | 13 +- src/composite-proof/statement.ts | 199 ++++++++-- src/composite-proof/witness.ts | 19 +- src/delegated-proofs.ts | 22 ++ src/encoder.ts | 2 +- src/frost-dkg.ts | 2 +- src/index.ts | 2 +- src/init.ts | 16 + src/legosnark/index.ts | 2 +- src/ped-com.ts | 2 +- src/ps/keys.ts | 4 +- src/ps/params.ts | 4 +- src/ps/proof.ts | 2 +- src/ps/signature.ts | 4 +- src/r1cs/circom-circuit.ts | 2 +- src/r1cs/file.ts | 2 +- src/r1cs/setup.ts | 2 +- src/saver/chunked-commitment.ts | 2 +- src/saver/ciphertext.ts | 2 +- src/saver/decryptor.ts | 2 +- src/sign-verify-js-objs.ts | 31 +- src/threshold-sigs/base-ot.ts | 2 +- src/threshold-sigs/bbs-plus.ts | 2 +- src/threshold-sigs/bbs.ts | 2 +- src/threshold-sigs/common.ts | 2 +- src/util.ts | 2 +- tests/accumulator.spec.ts | 21 +- .../blind-issuance.spec.ts | 71 ++-- .../anonymous-credentials/credential.spec.ts | 73 ++-- .../delegated-proofs.spec.ts | 208 +++++++++++ .../presentation-circom.spec.ts | 40 +- ...resentation-multiple-bounds-and-ve.spec.ts | 14 +- .../presentation-multiple-sig-types.spec.ts | 53 ++- .../presentation.spec.ts | 226 +++++++----- tests/anonymous-credentials/schema.spec.ts | 2 +- .../serialized-credential.spec.ts | 10 +- .../serialized-presentation.spec.ts | 15 +- .../serialized-schema.spec.ts | 3 +- tests/anonymous-credentials/utils.ts | 86 ++++- tests/bound-check.spec.ts | 2 +- .../composite-proofs/blind-signature.spec.ts | 28 +- tests/composite-proofs/bound-check.spec.ts | 161 ++++---- .../composite-proofs/many-signatures.spec.ts | 85 +++-- .../msg-js-obj/accumulator.spec.ts | 82 +++-- ...h-attribute-equality-and-pseudonym.spec.ts | 104 +++--- .../msg-js-obj/blind-sig.spec.ts | 56 ++- .../msg-js-obj/blood-group.spec.ts | 60 ++- .../msg-js-obj/bound-check.spec.ts | 113 +++--- .../msg-js-obj/cities.spec.ts | 58 ++- .../r1cs/all_receipts_different.spec.ts | 72 ++-- .../r1cs/assets-liabilities.spec.ts | 106 +++--- .../msg-js-obj/r1cs/blood-group.spec.ts | 76 ++-- .../msg-js-obj/r1cs/grade.spec.ts | 62 ++-- .../msg-js-obj/r1cs/mimc-hash.spec.ts | 56 +-- .../msg-js-obj/r1cs/vaccination.spec.ts | 60 ++- .../msg-js-obj/r1cs/yearly-income.spec.ts | 62 ++-- .../composite-proofs/msg-js-obj/saver.spec.ts | 43 ++- .../msg-js-obj/scheme.spec.ts | 178 ++++----- .../composite-proofs/msg-js-obj/util.spec.ts | 24 +- tests/composite-proofs/msg-js-obj/util.ts | 71 ++++ tests/composite-proofs/pseudonyms.spec.ts | 139 ++++--- .../r1cs/less_than_greater_than.spec.ts | 65 ++-- .../r1cs/set-membership.spec.ts | 39 +- tests/composite-proofs/saver.spec.ts | 78 ++-- .../signature-and-accumulator.spec.ts | 70 ++-- .../composite-proofs/single-signature.spec.ts | 60 ++- tests/composite-proofs/social-kyc.spec.ts | 63 ++-- .../variable-number-of-messages.spec.ts | 41 +-- tests/demo.spec.ts | 223 +++++------ tests/frost-dkg.spec.ts | 3 +- tests/prefilled-positive-accumulator.spec.ts | 12 +- tests/r1cs.spec.ts | 4 +- tests/saver.spec.ts | 2 +- tests/scheme.spec.ts | 348 +++++++++--------- tests/scheme.ts | 65 +++- tests/threshold-sigs.spec.ts | 39 +- tests/utils.ts | 35 +- yarn.lock | 41 ++- 112 files changed, 3586 insertions(+), 1976 deletions(-) create mode 100644 src/anonymous-credentials/delegated-proof.ts create mode 100644 src/bddt16-mac/index.ts create mode 100644 src/bddt16-mac/keys.ts create mode 100644 src/bddt16-mac/mac.ts create mode 100644 src/bddt16-mac/params.ts create mode 100644 src/delegated-proofs.ts create mode 100644 src/init.ts create mode 100644 tests/anonymous-credentials/delegated-proofs.spec.ts create mode 100644 tests/composite-proofs/msg-js-obj/util.ts diff --git a/.eslintrc.js b/.eslintrc.js index 3ad09a83..8b5e8551 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,6 +7,7 @@ module.exports = { }, plugins: [ '@typescript-eslint', + 'unused-imports' ], extends: [ 'eslint:recommended', diff --git a/package.json b/package.json index d625f2c5..76cf6d4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/crypto-wasm-ts", - "version": "0.50.0", + "version": "0.52.0", "description": "Typescript abstractions over Dock's Rust crypto library's WASM wrapper", "homepage": "https://github.com/docknetwork/crypto-wasm-ts", "main": "lib/index.js", @@ -16,7 +16,8 @@ "test-bbs": "TEST_SIGNATURE_SCHEME=BBS yarn jest", "test-bbs+": "TEST_SIGNATURE_SCHEME=BBS+ yarn jest", "test-ps": "TEST_SIGNATURE_SCHEME=PS yarn jest", - "test-all": "TEST_SIGNATURE_SCHEME=BBS yarn jest; TEST_SIGNATURE_SCHEME=BBS+ yarn jest; TEST_SIGNATURE_SCHEME=PS yarn jest" + "test-bddt16": "TEST_SIGNATURE_SCHEME=BDDT16 yarn jest", + "test-all": "TEST_SIGNATURE_SCHEME=BBS yarn jest; TEST_SIGNATURE_SCHEME=BBS+ yarn jest; TEST_SIGNATURE_SCHEME=PS yarn jest; TEST_SIGNATURE_SCHEME=BDDT16 yarn jest" }, "license": "Apache-2.0", "private": false, @@ -27,10 +28,11 @@ "lib": "lib" }, "dependencies": { - "@docknetwork/crypto-wasm": "0.23.0", "@types/flat": "^5.0.2", "@types/lodash": "^4.14.195", "bs58": "5.0.0", + "crypto-wasm-new": "npm:@docknetwork/crypto-wasm@0.24.0", + "crypto-wasm-old": "npm:@docknetwork/crypto-wasm@0.23.0", "flat": "^5.0.2", "json-pointer": "^0.6.2", "json-stringify-deterministic": "^1.0.11", @@ -48,6 +50,7 @@ "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-unused-imports": "^3.1.0", "husky": "^7.0.4", "jest": "^29.1.0", "jsonld": "6.0.0", @@ -56,6 +59,6 @@ "r1csfile": "^0.0.41", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "5.1.3" + "typescript": "5.3.3" } } diff --git a/src/Pseudonym.ts b/src/Pseudonym.ts index d79c006b..a4ba8b9f 100644 --- a/src/Pseudonym.ts +++ b/src/Pseudonym.ts @@ -1,4 +1,4 @@ -import { pedersenCommitmentG1, generateRandomG1Element } from '@docknetwork/crypto-wasm'; +import { pedersenCommitmentG1, generateRandomG1Element } from 'crypto-wasm-new'; import { BytearrayWrapper } from './bytearray-wrapper'; import { base58ToBytearray, bytearrayToBase58 } from './util'; diff --git a/src/accumulator/accumulator.ts b/src/accumulator/accumulator.ts index a407ee42..b06227f2 100644 --- a/src/accumulator/accumulator.ts +++ b/src/accumulator/accumulator.ts @@ -29,8 +29,8 @@ import { universalAccumulatorRemoveBatch, universalAccumulatorVerifyMembership, universalAccumulatorVerifyNonMembership -} from '@docknetwork/crypto-wasm'; -import { MembershipWitness, NonMembershipWitness } from './accumulatorWitness'; +} from 'crypto-wasm-new'; +import { VBMembershipWitness, VBNonMembershipWitness } from './accumulatorWitness'; import { getUint8ArraysFromObject } from '../util'; import { IAccumulatorState, IUniversalAccumulatorState } from './IAccumulatorState'; import { IInitialElementsStore } from './IInitialElementsStore'; @@ -261,7 +261,7 @@ export abstract class Accumulator { element: Uint8Array, secretKey?: AccumulatorSecretKey, state?: IAccumulatorState - ): Promise; + ): Promise; /** * Calculate the membership witnesses for the given batch of elements @@ -273,7 +273,7 @@ export abstract class Accumulator { elements: Uint8Array[], secretKey?: AccumulatorSecretKey, state?: IAccumulatorState - ): Promise; + ): Promise; /** * Verify the membership witness. @@ -284,7 +284,7 @@ export abstract class Accumulator { */ abstract verifyMembershipWitness( member: Uint8Array, - witness: MembershipWitness, + witness: VBMembershipWitness, pk: AccumulatorPublicKey, params?: AccumulatorParams ): boolean; @@ -508,11 +508,11 @@ export class PositiveAccumulator extends Accumulator { member: Uint8Array, secretKey?: AccumulatorSecretKey, state?: IAccumulatorState - ): Promise { + ): Promise { await this.ensurePresence(member, state); const sk = this.getSecretKey(secretKey); const wit = positiveAccumulatorMembershipWitness(this.value, member, sk.value); - return new MembershipWitness(wit); + return new VBMembershipWitness(wit); } /** @@ -526,11 +526,11 @@ export class PositiveAccumulator extends Accumulator { members: Uint8Array[], secretKey?: AccumulatorSecretKey, state?: IAccumulatorState - ): Promise { + ): Promise { await this.ensurePresenceOfBatch(members, state); const sk = this.getSecretKey(secretKey); return positiveAccumulatorMembershipWitnessesForBatch(this.value, members, sk.value).map( - (m) => new MembershipWitness(m) + (m) => new VBMembershipWitness(m) ); } @@ -544,7 +544,7 @@ export class PositiveAccumulator extends Accumulator { */ verifyMembershipWitness( member: Uint8Array, - witness: MembershipWitness, + witness: VBMembershipWitness, publicKey: AccumulatorPublicKey, params?: AccumulatorParams ): boolean { @@ -750,12 +750,12 @@ export class UniversalAccumulator extends Accumulator { secretKey?: AccumulatorSecretKey, state?: IAccumulatorState, initialElementsStore?: IInitialElementsStore - ): Promise { + ): Promise { await this.checkElementAcceptable(member, initialElementsStore); await this.ensurePresence(member, state); const sk = this.getSecretKey(secretKey); const wit = universalAccumulatorMembershipWitness(this.value, member, sk.value); - return new MembershipWitness(wit); + return new VBMembershipWitness(wit); } async membershipWitnessesForBatch( @@ -763,12 +763,12 @@ export class UniversalAccumulator extends Accumulator { secretKey?: AccumulatorSecretKey, state?: IAccumulatorState, initialElementsStore?: IInitialElementsStore - ): Promise { + ): Promise { await this.checkElementBatchAcceptable(members, initialElementsStore); await this.ensurePresenceOfBatch(members, state); const sk = this.getSecretKey(secretKey); return universalAccumulatorMembershipWitnessesForBatch(this.value, members, sk.value).map( - (m) => new MembershipWitness(m) + (m) => new VBMembershipWitness(m) ); } @@ -790,7 +790,7 @@ export class UniversalAccumulator extends Accumulator { params?: AccumulatorParams, initialElementsStore?: IInitialElementsStore, batchSize = 100 - ): Promise { + ): Promise { await this.checkElementAcceptable(nonMember, initialElementsStore); await this.ensureAbsence(nonMember, state); const sk = this.getSecretKey(secretKey); @@ -810,7 +810,7 @@ export class UniversalAccumulator extends Accumulator { } const d = universalAccumulatorCombineMultipleD(ds); const wit = universalAccumulatorNonMembershipWitness(this.value, d, nonMember, sk.value, params_.value); - return new NonMembershipWitness(wit); + return new VBNonMembershipWitness(wit); } /** @@ -830,13 +830,13 @@ export class UniversalAccumulator extends Accumulator { params?: AccumulatorParams, state?: IUniversalAccumulatorState, initialElementsStore?: IInitialElementsStore - ): Promise { + ): Promise { await this.checkElementAcceptable(nonMember, initialElementsStore); await this.ensureAbsence(nonMember, state); const sk = this.getSecretKey(secretKey); const params_ = this.getParams(params); const wit = universalAccumulatorNonMembershipWitness(this.value, d, nonMember, sk.value, params_.value); - return new NonMembershipWitness(wit); + return new VBNonMembershipWitness(wit); } /** @@ -856,7 +856,7 @@ export class UniversalAccumulator extends Accumulator { params?: AccumulatorParams, initialElementsStore?: IInitialElementsStore, batchSize = 100 - ): Promise { + ): Promise { await this.checkElementBatchAcceptable(nonMembers, initialElementsStore); await this.ensureAbsenceOfBatch(nonMembers, state); const sk = this.getSecretKey(secretKey); @@ -894,7 +894,7 @@ export class UniversalAccumulator extends Accumulator { ds[i] = universalAccumulatorCombineMultipleD(dsForAll[i]); } return universalAccumulatorNonMembershipWitnessesForBatch(this.value, ds, nonMembers, sk.value, params_.value).map( - (m) => new NonMembershipWitness(m) + (m) => new VBNonMembershipWitness(m) ); } @@ -915,19 +915,19 @@ export class UniversalAccumulator extends Accumulator { params?: AccumulatorParams, state?: IUniversalAccumulatorState, initialElementsStore?: IInitialElementsStore - ): Promise { + ): Promise { await this.checkElementBatchAcceptable(nonMembers, initialElementsStore); await this.ensureAbsenceOfBatch(nonMembers, state); const sk = this.getSecretKey(secretKey); const params_ = this.getParams(params); return universalAccumulatorNonMembershipWitnessesForBatch(this.value, d, nonMembers, sk.value, params_.value).map( - (m) => new NonMembershipWitness(m) + (m) => new VBNonMembershipWitness(m) ); } verifyMembershipWitness( member: Uint8Array, - witness: MembershipWitness, + witness: VBMembershipWitness, pk: AccumulatorPublicKey, params?: AccumulatorParams ): boolean { @@ -937,7 +937,7 @@ export class UniversalAccumulator extends Accumulator { verifyNonMembershipWitness( nonMember: Uint8Array, - witness: NonMembershipWitness, + witness: VBNonMembershipWitness, pk: AccumulatorPublicKey, params?: AccumulatorParams ): boolean { diff --git a/src/accumulator/accumulatorWitness.ts b/src/accumulator/accumulatorWitness.ts index 16c9c7b5..35a9f5aa 100644 --- a/src/accumulator/accumulatorWitness.ts +++ b/src/accumulator/accumulatorWitness.ts @@ -10,7 +10,7 @@ import { updateNonMembershipWitnessPostRemove, updateNonMembershipWitnessUsingPublicInfoAfterBatchUpdate, updateNonMembershipWitnessUsingPublicInfoAfterMultipleBatchUpdates -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { getUint8ArraysFromObject, jsonObjToUint8Array } from '../util'; import { AccumulatorSecretKey } from './params-and-keys'; import { BytearrayWrapper } from '../bytearray-wrapper'; @@ -28,17 +28,17 @@ export abstract class AccumulatorWitness { element: Uint8Array, additions: Uint8Array[], removals: Uint8Array[], - publicInfo: WitnessUpdatePublicInfo + publicInfo: VBWitnessUpdatePublicInfo ): void; abstract updateUsingPublicInfoPostMultipleBatchUpdates( element: Uint8Array, additions: Uint8Array[][], removals: Uint8Array[][], - publicInfo: WitnessUpdatePublicInfo[] + publicInfo: VBWitnessUpdatePublicInfo[] ): void; } -export class MembershipWitness extends AccumulatorWitness { +export class VBMembershipWitness extends AccumulatorWitness { // @ts-ignore value: Uint8Array; @@ -73,7 +73,7 @@ export class MembershipWitness extends AccumulatorWitness { member: Uint8Array, additions: Uint8Array[], removals: Uint8Array[], - publicInfo: WitnessUpdatePublicInfo + publicInfo: VBWitnessUpdatePublicInfo ) { this.value = updateMembershipWitnessUsingPublicInfoAfterBatchUpdate( this.value, @@ -96,7 +96,7 @@ export class MembershipWitness extends AccumulatorWitness { member: Uint8Array, additions: Uint8Array[][], removals: Uint8Array[][], - publicInfo: WitnessUpdatePublicInfo[] + publicInfo: VBWitnessUpdatePublicInfo[] ) { const info = publicInfo.map((i) => i.value); this.value = updateMembershipWitnessUsingPublicInfoAfterMultipleBatchUpdates( @@ -118,13 +118,13 @@ export class MembershipWitness extends AccumulatorWitness { * @param secretKey */ static updateMultiplePostBatchUpdates( - witnesses: MembershipWitness[], + witnesses: VBMembershipWitness[], members: Uint8Array[], additions: Uint8Array[], removals: Uint8Array[], accumulatorValueBeforeUpdates: Uint8Array, secretKey: AccumulatorSecretKey - ): MembershipWitness[] { + ): VBMembershipWitness[] { const wits = witnesses.map((m) => m.value); return updateMembershipWitnessesPostBatchUpdates( wits, @@ -133,7 +133,7 @@ export class MembershipWitness extends AccumulatorWitness { removals, accumulatorValueBeforeUpdates, secretKey.value - ).map((m) => new MembershipWitness(m)); + ).map((m) => new VBMembershipWitness(m)); } toJSON(): string { @@ -142,14 +142,14 @@ export class MembershipWitness extends AccumulatorWitness { }); } - static fromJSON(json: string): MembershipWitness { + static fromJSON(json: string): VBMembershipWitness { const obj = JSON.parse(json); const [value] = getUint8ArraysFromObject(obj, ['value']); - return new MembershipWitness(value); + return new VBMembershipWitness(value); } } -export class NonMembershipWitness extends AccumulatorWitness { +export class VBNonMembershipWitness extends AccumulatorWitness { // @ts-ignore value: { d: Uint8Array; C: Uint8Array }; @@ -184,7 +184,7 @@ export class NonMembershipWitness extends AccumulatorWitness { nonMember: Uint8Array, additions: Uint8Array[], removals: Uint8Array[], - publicInfo: WitnessUpdatePublicInfo + publicInfo: VBWitnessUpdatePublicInfo ) { this.value = updateNonMembershipWitnessUsingPublicInfoAfterBatchUpdate( this.value, @@ -207,7 +207,7 @@ export class NonMembershipWitness extends AccumulatorWitness { nonMember: Uint8Array, additions: Uint8Array[][], removals: Uint8Array[][], - publicInfo: WitnessUpdatePublicInfo[] + publicInfo: VBWitnessUpdatePublicInfo[] ) { const info = publicInfo.map((i) => i.value); this.value = updateNonMembershipWitnessUsingPublicInfoAfterMultipleBatchUpdates( @@ -229,13 +229,13 @@ export class NonMembershipWitness extends AccumulatorWitness { * @param secretKey */ static updateMultiplePostBatchUpdates( - witnesses: NonMembershipWitness[], + witnesses: VBNonMembershipWitness[], nonMembers: Uint8Array[], additions: Uint8Array[], removals: Uint8Array[], accumulatorValueBeforeUpdates: Uint8Array, secretKey: AccumulatorSecretKey - ): NonMembershipWitness[] { + ): VBNonMembershipWitness[] { const wits = witnesses.map((w) => w.value); return updateNonMembershipWitnessesPostBatchUpdates( wits, @@ -244,7 +244,7 @@ export class NonMembershipWitness extends AccumulatorWitness { removals, accumulatorValueBeforeUpdates, secretKey.value - ).map((m) => new NonMembershipWitness(m)); + ).map((m) => new VBNonMembershipWitness(m)); } toJSON(): string { @@ -253,25 +253,25 @@ export class NonMembershipWitness extends AccumulatorWitness { }); } - static fromJSON(json: string): NonMembershipWitness { + static fromJSON(json: string): VBNonMembershipWitness { const obj = JSON.parse(json); const [d, C] = getUint8ArraysFromObject(obj.value, ['d', 'C']); - return new NonMembershipWitness({ d, C }); + return new VBNonMembershipWitness({ d, C }); } } /** * Public info published by the accumulator manager used to update witnesses after several additions and removals. */ -export class WitnessUpdatePublicInfo extends BytearrayWrapper { +export class VBWitnessUpdatePublicInfo extends BytearrayWrapper { toJSON(): string { return JSON.stringify({ value: this.value }); } - fromJSON(json: string): WitnessUpdatePublicInfo { - return new WitnessUpdatePublicInfo(jsonObjToUint8Array(json)); + fromJSON(json: string): VBWitnessUpdatePublicInfo { + return new VBWitnessUpdatePublicInfo(jsonObjToUint8Array(json)); } /** @@ -286,8 +286,8 @@ export class WitnessUpdatePublicInfo extends BytearrayWrapper { additions: Uint8Array[], removals: Uint8Array[], sk: AccumulatorSecretKey - ): WitnessUpdatePublicInfo { + ): VBWitnessUpdatePublicInfo { const value = publicInfoForWitnessUpdate(accumulatorValueBeforeUpdates, additions, removals, sk.value); - return new WitnessUpdatePublicInfo(value); + return new VBWitnessUpdatePublicInfo(value); } } diff --git a/src/accumulator/params-and-keys.ts b/src/accumulator/params-and-keys.ts index cb070af0..36c0c376 100644 --- a/src/accumulator/params-and-keys.ts +++ b/src/accumulator/params-and-keys.ts @@ -9,7 +9,7 @@ import { generateNonMembershipProvingKey, isAccumulatorParamsValid, isAccumulatorPublicKeyValid -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; export class AccumulatorParams extends BytearrayWrapper { /** diff --git a/src/accumulator/proof.ts b/src/accumulator/proof.ts index 769dd2d5..ae72ed35 100644 --- a/src/accumulator/proof.ts +++ b/src/accumulator/proof.ts @@ -11,8 +11,8 @@ import { accumulatorInitializeNonMembershipProof, accumulatorVerifyMembershipProof, VerifyResult -} from '@docknetwork/crypto-wasm'; -import { MembershipWitness, NonMembershipWitness } from './accumulatorWitness'; +} from 'crypto-wasm-new'; +import { VBMembershipWitness, VBNonMembershipWitness } from './accumulatorWitness'; import { AccumulatorParams, AccumulatorPublicKey, @@ -21,15 +21,15 @@ import { } from './params-and-keys'; import { BytearrayWrapper } from '../bytearray-wrapper'; -export class MembershipProofProtocol extends BytearrayWrapper { +export class VBMembershipProofProtocol extends BytearrayWrapper { static initialize( member: Uint8Array, - witness: MembershipWitness, + witness: VBMembershipWitness, publicKey: AccumulatorPublicKey, params: AccumulatorParams, provingKey: MembershipProvingKey, blinding: Uint8Array = generateRandomFieldElement() - ): MembershipProofProtocol { + ): VBMembershipProofProtocol { const protocol = accumulatorInitializeMembershipProof( member, blinding, @@ -38,12 +38,12 @@ export class MembershipProofProtocol extends BytearrayWrapper { params.value, provingKey.value ); - return new MembershipProofProtocol(protocol); + return new VBMembershipProofProtocol(protocol); } - generateProof(challenge: Uint8Array): MembershipProof { + generateProof(challenge: Uint8Array): VBMembershipProof { const proof = accumulatorGenMembershipProof(this.value, challenge); - return new MembershipProof(proof); + return new VBMembershipProof(proof); } challengeContribution( @@ -62,15 +62,15 @@ export class MembershipProofProtocol extends BytearrayWrapper { } } -export class NonMembershipProofProtocol extends BytearrayWrapper { +export class VBNonMembershipProofProtocol extends BytearrayWrapper { static initialize( nonMember: Uint8Array, - witness: NonMembershipWitness, + witness: VBNonMembershipWitness, publicKey: AccumulatorPublicKey, params: AccumulatorParams, provingKey: NonMembershipProvingKey, blinding?: Uint8Array - ): MembershipProofProtocol { + ): VBMembershipProofProtocol { const b = blinding === undefined ? generateRandomFieldElement() : blinding; const protocol = accumulatorInitializeNonMembershipProof( nonMember, @@ -80,12 +80,12 @@ export class NonMembershipProofProtocol extends BytearrayWrapper { params.value, provingKey.value ); - return new MembershipProofProtocol(protocol); + return new VBMembershipProofProtocol(protocol); } - generateProof(challenge: Uint8Array): NonMembershipProof { + generateProof(challenge: Uint8Array): VBNonMembershipProof { const proof = accumulatorGenNonMembershipProof(this.value, challenge); - return new NonMembershipProof(proof); + return new VBNonMembershipProof(proof); } challengeContribution( @@ -104,7 +104,7 @@ export class NonMembershipProofProtocol extends BytearrayWrapper { } } -export class MembershipProof extends BytearrayWrapper { +export class VBMembershipProof extends BytearrayWrapper { verify( accumulated: Uint8Array, challenge: Uint8Array, @@ -138,7 +138,7 @@ export class MembershipProof extends BytearrayWrapper { } } -export class NonMembershipProof extends BytearrayWrapper { +export class VBNonMembershipProof extends BytearrayWrapper { verify( accumulated: Uint8Array, challenge: Uint8Array, diff --git a/src/anonymous-credentials/blinded-credential-builder.ts b/src/anonymous-credentials/blinded-credential-builder.ts index 9f9fcb32..d51a8bb5 100644 --- a/src/anonymous-credentials/blinded-credential-builder.ts +++ b/src/anonymous-credentials/blinded-credential-builder.ts @@ -2,14 +2,14 @@ import { CredentialBuilderCommon } from './credential-builder-common'; import { IBlindCredentialRequest } from './presentation-specification'; import { BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, - BBS_SIGNATURE_PARAMS_LABEL_BYTES, - SUBJECT_STR + BBS_SIGNATURE_PARAMS_LABEL_BYTES, BDDT16_MAC_PARAMS_LABEL_BYTES, } from './types-and-consts'; -import { BBSCredential, BBSPlusCredential } from './credential'; +import { BBSCredential, BBSPlusCredential, BDDT16Credential } from './credential'; import { BBSBlindSignature, BBSSecretKey, BBSSignatureParams } from '../bbs'; import { BBSPlusBlindSignatureG1, BBSPlusSecretKey, BBSPlusSignatureParamsG1 } from '../bbs-plus'; import { CredentialSchema } from './schema'; -import { BBSBlindedCredential, BBSPlusBlindedCredential } from './blinded-credential'; +import { BBSBlindedCredential, BBSPlusBlindedCredential, BDDT16BlindedCredential } from './blinded-credential'; +import { BDDT16BlindMac, BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; /** * Used by the signer to create a blinded credential. The signer will know only the unblinded attributes @@ -104,3 +104,39 @@ export class BBSPlusBlindedCredentialBuilder extends BlindedCredentialBuilder { ); } } + +export class BDDT16BlindedCredentialBuilder extends BlindedCredentialBuilder { + protected applyDefaultProofMetadataIfNeeded(s: object) { + BDDT16Credential.applyDefaultProofMetadataIfNeeded(s); + } + + /** + * Blind sign a credential + * @param secretKey + * @param sigParams + * @returns + */ + sign( + secretKey: BDDT16MacSecretKey, + sigParams: Uint8Array | BDDT16MacParams = BDDT16_MAC_PARAMS_LABEL_BYTES + ): BDDT16BlindedCredential { + const [totalAttrs, encodedAttrs] = this.getTotalAttributesAndEncodedKnownAttributes(); + const params = BDDT16MacParams.getMacParamsOfRequiredSize(totalAttrs, sigParams); + const sig = BDDT16BlindMac.generate( + this.blindedCredReq.commitment, + encodedAttrs, + secretKey, + params, + false + ); + return new BDDT16BlindedCredential( + this.version, + this.schema as CredentialSchema, + // @ts-ignore + this.subject, + this._topLevelFields, + sig, + this.credStatus + ); + } +} \ No newline at end of file diff --git a/src/anonymous-credentials/blinded-credential-request-builder.ts b/src/anonymous-credentials/blinded-credential-request-builder.ts index c53544ca..bf750a62 100644 --- a/src/anonymous-credentials/blinded-credential-request-builder.ts +++ b/src/anonymous-credentials/blinded-credential-request-builder.ts @@ -9,7 +9,7 @@ import { BBSCredential, BBSPlusCredential, PSCredential } from './credential'; import { AttributeEquality, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, - BBS_SIGNATURE_PARAMS_LABEL_BYTES, + BBS_SIGNATURE_PARAMS_LABEL_BYTES, BDDT16_MAC_PARAMS_LABEL_BYTES, BlindedAttributeEquality, BlindSignatureType, BoundCheckParamType, @@ -29,8 +29,12 @@ import { SaverProvingKey, SaverProvingKeyUncompressed } from '../saver'; -import { generateRandomFieldElement, R1CS } from '@docknetwork/crypto-wasm'; -import { BBSBlindedCredentialRequest, BBSPlusBlindedCredentialRequest } from './blinded-credential-request'; +import { generateRandomFieldElement, R1CS } from 'crypto-wasm-new'; +import { + BBSBlindedCredentialRequest, + BBSPlusBlindedCredentialRequest, + BDDT16BlindedCredentialRequest +} from './blinded-credential-request'; import { unflatten } from 'flat'; import { BBSSignatureParams } from '../bbs'; import { BBSPlusSignatureParamsG1 } from '../bbs-plus'; @@ -43,6 +47,7 @@ import { import { Presentation } from './presentation'; import { getR1CS, ParsedR1CSFile } from '../r1cs/file'; import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { BDDT16MacParams } from '../bddt16-mac'; type Credential = BBSCredential | BBSPlusCredential | PSCredential; @@ -509,6 +514,50 @@ export class BBSPlusBlindedCredentialRequestBuilder extends BlindedCredentialReq } } +export class BDDT16BlindedCredentialRequestBuilder extends BlindedCredentialRequestBuilder { + private readonly blinding: Uint8Array; + + constructor() { + super(); + this.blinding = generateRandomFieldElement(); + } + + /** + * Create the request to be sent to the signer and the blinding to be kept to later unblind the credential + * @param sigParams + * @returns + */ + finalize( + sigParams: Uint8Array | BDDT16MacParams = BDDT16_MAC_PARAMS_LABEL_BYTES + ): [BDDT16BlindedCredentialRequest, BDDT16Blinding] { + return [ + new BDDT16BlindedCredentialRequest(this.version, super.createPresentation(sigParams)), + new BDDT16Blinding(this.blinding) + ]; + } + + getBlinding(): Uint8Array { + return this.blinding; + } + + computeCommitment( + encodedSubject: Map, + totalAttributes: number, + labelOrParams: Uint8Array | BDDT16MacParams = BDDT16_MAC_PARAMS_LABEL_BYTES + ): Uint8Array { + const sigParams = BDDT16MacParams.getMacParamsOfRequiredSize(totalAttributes, labelOrParams); + this.sigParams = sigParams; + const [commitment] = sigParams.commitToMessages(encodedSubject, false, this.blinding); + return commitment; + } + + static getSigType(): BlindSignatureType { + return BlindSignatureType.Bddt16; + } +} + export class BBSPlusBlinding extends BytearrayWrapper {} +export class BDDT16Blinding extends BytearrayWrapper {} + // TODO: Add for PS as well diff --git a/src/anonymous-credentials/blinded-credential-request.ts b/src/anonymous-credentials/blinded-credential-request.ts index 3adab922..03558198 100644 --- a/src/anonymous-credentials/blinded-credential-request.ts +++ b/src/anonymous-credentials/blinded-credential-request.ts @@ -1,9 +1,13 @@ import { Versioned } from './versioned'; import { Presentation } from './presentation'; -import { PredicateParamType, PublicKey, VERSION_STR } from './types-and-consts'; +import { CredentialVerificationParam, PredicateParamType, PublicKey, VERSION_STR } from './types-and-consts'; import { AccumulatorPublicKey } from '../accumulator'; -import { VerifyResult } from '@docknetwork/crypto-wasm'; -import { BBSBlindedCredentialBuilder, BBSPlusBlindedCredentialBuilder } from './blinded-credential-builder'; +import { VerifyResult } from 'crypto-wasm-new'; +import { + BBSBlindedCredentialBuilder, + BBSPlusBlindedCredentialBuilder, + BDDT16BlindedCredentialBuilder +} from './blinded-credential-builder'; /** * A request for getting a blinded credential. Sent by the user to the signer who will verify it and then sign a blinded credential @@ -23,7 +27,7 @@ export abstract class BlindedCredentialRequest extends Versioned { } verify( - publicKeys: PublicKey[], + publicKeys: Map | CredentialVerificationParam[], accumulatorPublicKeys?: Map, predicateParams?: Map, circomOutputs?: Map, @@ -112,3 +116,24 @@ export class BBSPlusBlindedCredentialRequest extends BlindedCredentialRequest { return new BBSPlusBlindedCredentialRequest(version, Presentation.fromJSON(presentation)); } } + +export class BDDT16BlindedCredentialRequest extends BlindedCredentialRequest { + constructor(version: string, presentation: Presentation) { + super(version, presentation); + } + + /** + * Return the blinded credential builder which will be used to create the blinded credential + * @returns + */ + generateBlindedCredentialBuilder(): BDDT16BlindedCredentialBuilder { + // @ts-ignore + return new BDDT16BlindedCredentialBuilder(this.presentation.spec.blindCredentialRequest); + } + + static fromJSON(j: object): BDDT16BlindedCredentialRequest { + // @ts-ignore + const { version, presentation } = j; + return new BDDT16BlindedCredentialRequest(version, Presentation.fromJSON(presentation)); + } +} diff --git a/src/anonymous-credentials/blinded-credential.ts b/src/anonymous-credentials/blinded-credential.ts index 41431fbf..75e00d86 100644 --- a/src/anonymous-credentials/blinded-credential.ts +++ b/src/anonymous-credentials/blinded-credential.ts @@ -1,17 +1,18 @@ import { BBSPlusBlindSignatureG1 } from '../bbs-plus'; import { BBSBlindSignature, BBSSignature } from '../bbs'; -import { BBSCredential, BBSPlusCredential } from './credential'; -import { BBSPlusBlinding } from './blinded-credential-request-builder'; +import { BBSCredential, BBSPlusCredential, BDDT16Credential } from './credential'; +import { BBSPlusBlinding, BDDT16Blinding } from './blinded-credential-request-builder'; import * as _ from 'lodash'; import { CredentialCommon } from './credential-common'; import { BBS_BLINDED_CRED_PROOF_TYPE, BBS_CRED_PROOF_TYPE, BBS_PLUS_BLINDED_CRED_PROOF_TYPE, - BBS_PLUS_CRED_PROOF_TYPE, + BBS_PLUS_CRED_PROOF_TYPE, BDDT16_BLINDED_CRED_PROOF_TYPE, BDDT16_CRED_PROOF_TYPE, PROOF_STR, TYPE_STR } from './types-and-consts'; +import { BDDT16BlindMac } from '../bddt16-mac'; /** * A blinded credential created by the signer. Has to be converted to a (unblinded) credential @@ -48,7 +49,7 @@ export abstract class BlindedCredential extends CredentialCommon { + /** + * Convert to unblinded credential which can be verified with the secret key + * @param blindedSubject + * @param blinding - blinding used while creating the request + * @returns + */ + toCredential(blindedSubject: object | object[], blinding: BDDT16Blinding): BDDT16Credential { + const updatedSubject = this.getUpdatedSubject(blindedSubject); + const unblindedSig = this.signature.unblind(blinding.value); + const topLevelFields = this.updateProofType(BDDT16_CRED_PROOF_TYPE); + return new BDDT16Credential( + this.version, + this.schema, + updatedSubject, + topLevelFields, + unblindedSig, + this.credentialStatus + ); + } + + static fromJSON(j: object, proofValue?: string): BDDT16BlindedCredential { + const [cryptoVersion, credentialSchema, credentialSubject, topLevelFields, sig, credentialStatus] = this.parseJSON( + j, + proofValue + ); + + return new this( + cryptoVersion, + credentialSchema, + credentialSubject, + topLevelFields, + new BDDT16BlindMac(sig), + credentialStatus + ); + } + + static applyDefaultProofMetadataIfNeeded(s: object) { + if (!s[PROOF_STR]) { + s[PROOF_STR] = { + type: BDDT16_BLINDED_CRED_PROOF_TYPE + }; + } + } +} diff --git a/src/anonymous-credentials/credential-builder-common.ts b/src/anonymous-credentials/credential-builder-common.ts index 3049474d..264c9dff 100644 --- a/src/anonymous-credentials/credential-builder-common.ts +++ b/src/anonymous-credentials/credential-builder-common.ts @@ -11,7 +11,7 @@ import { SCHEMA_STR, STATUS_STR, SUBJECT_STR, - TYPE_STR + TYPE_STR, MEM_CHECK_KV_STR } from './types-and-consts'; /** @@ -60,8 +60,8 @@ export abstract class CredentialBuilderCommon extends Versioned { } setCredentialStatus(registryId: string, revCheck: string, memberValue: unknown) { - if (revCheck !== MEM_CHECK_STR && revCheck !== NON_MEM_CHECK_STR) { - throw new Error(`Revocation check should be either ${MEM_CHECK_STR} or ${NON_MEM_CHECK_STR} but was ${revCheck}`); + if (revCheck !== MEM_CHECK_STR && revCheck !== NON_MEM_CHECK_STR && revCheck !== MEM_CHECK_KV_STR) { + throw new Error(`Revocation check should be either ${MEM_CHECK_STR} or ${NON_MEM_CHECK_STR} or ${MEM_CHECK_KV_STR} but was ${revCheck}`); } this._credStatus = { [TYPE_STR]: RevocationStatusProtocol.Vb22, diff --git a/src/anonymous-credentials/credential-builder.ts b/src/anonymous-credentials/credential-builder.ts index cd9b8ac0..8731cc18 100644 --- a/src/anonymous-credentials/credential-builder.ts +++ b/src/anonymous-credentials/credential-builder.ts @@ -3,9 +3,9 @@ import { SCHEMA_STR, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, BBS_SIGNATURE_PARAMS_LABEL_BYTES, - PS_SIGNATURE_PARAMS_LABEL_BYTES + PS_SIGNATURE_PARAMS_LABEL_BYTES, BDDT16_MAC_PARAMS_LABEL_BYTES } from './types-and-consts'; -import { BBSCredential, BBSPlusCredential, Credential, PSCredential } from './credential'; +import { BBSCredential, BBSPlusCredential, BDDT16Credential, Credential, PSCredential } from './credential'; import { flatten } from 'flat'; import { areArraysEqual } from '../util'; import { BBSPublicKey, BBSSecretKey, BBSSignature, BBSSignatureParams } from '../bbs'; @@ -19,6 +19,7 @@ import { import { PSPublicKey, PSSecretKey, PSSignature, PSSignatureParams } from '../ps'; import { SignedMessages } from '../types'; import { CredentialBuilderCommon } from './credential-builder-common'; +import { BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; export interface ISigningOpts { // Whether the credential should contain exactly the same fields (object keys, array items, literals) as the @@ -231,3 +232,34 @@ export class PSCredentialBuilder extends CredentialBuilder { + protected signMessageObject( + messages: Object, + secretKey: BDDT16MacSecretKey, + labelOrParams: Uint8Array | BDDT16MacParams = BDDT16_MAC_PARAMS_LABEL_BYTES, + encoder: Encoder + ): SignedMessages { + return BDDT16Mac.signMessageObject(messages, secretKey, labelOrParams, encoder); + } + + protected newCredential( + version: string, + schema: CredentialSchema, + subject: object, + topLevelFields: Map, + sig: BDDT16Mac, + credStatus?: object + ): BDDT16Credential { + return new BDDT16Credential(version, schema, subject, topLevelFields, sig, credStatus); + } + + protected applyDefaultProofMetadataIfNeeded(s: object) { + BDDT16Credential.applyDefaultProofMetadataIfNeeded(s); + } +} diff --git a/src/anonymous-credentials/credential.ts b/src/anonymous-credentials/credential.ts index 40646c32..53c2a137 100644 --- a/src/anonymous-credentials/credential.ts +++ b/src/anonymous-credentials/credential.ts @@ -11,13 +11,15 @@ import { PS_SIGNATURE_PARAMS_LABEL_BYTES, SCHEMA_STR, STATUS_STR, - SUBJECT_STR + SUBJECT_STR, BDDT16_CRED_PROOF_TYPE, BDDT16_MAC_PARAMS_LABEL_BYTES } from './types-and-consts'; -import { VerifyResult } from '@docknetwork/crypto-wasm'; +import { VerifyResult } from 'crypto-wasm-new'; import { BBSPublicKey, BBSSignature, BBSSignatureParams } from '../bbs'; import { PSPublicKey, PSSignature, PSSignatureParams } from '../ps'; import { BBSPlusPublicKeyG2, BBSPlusSignatureG1, BBSPlusSignatureParamsG1 } from '../bbs-plus'; import { CredentialCommon } from './credential-common'; +import { BDDT16CredentialBuilder } from './credential-builder'; +import { BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; export abstract class Credential extends CredentialCommon { abstract verify(publicKey: PublicKey, signatureParams?: SignatureParams): VerifyResult; @@ -210,3 +212,57 @@ export class PSCredential extends Credential { + verify(publicKey: undefined, signatureParams?: BDDT16MacParams): VerifyResult { + throw new Error(`Not applicable`) + } + + /** + * This is just done for testing. In practice a credential holder will never have the secret key + * @param secretKey + * @param signatureParams + */ + verifyUsingSecretKey(secretKey: BDDT16MacSecretKey, signatureParams?: BDDT16MacParams): VerifyResult { + const cred = this.serializeForSigning(); + return this.signature.verifyMessageObject( + cred, + secretKey, + signatureParams ?? BDDT16_MAC_PARAMS_LABEL_BYTES, + this.schema.encoder + ); + } + + /** + * A credential will have at least some proof metadata like the type or purpose. This adds those defaults to the + * given object. + * @param s + */ + static applyDefaultProofMetadataIfNeeded(s: object) { + if (!s[PROOF_STR]) { + s[PROOF_STR] = { + type: BDDT16_CRED_PROOF_TYPE + }; + } + } + + static fromJSON(j: object, proofValue?: string): BDDT16Credential { + const [cryptoVersion, credentialSchema, credentialSubject, topLevelFields, sig, credentialStatus] = this.parseJSON( + j, + proofValue + ); + + return new this( + cryptoVersion, + credentialSchema, + credentialSubject, + topLevelFields, + new BDDT16Mac(sig), + credentialStatus + ); + } + + static getSigType(): SignatureType { + return SignatureType.Bddt16; + } +} \ No newline at end of file diff --git a/src/anonymous-credentials/delegated-proof.ts b/src/anonymous-credentials/delegated-proof.ts new file mode 100644 index 00000000..25a01899 --- /dev/null +++ b/src/anonymous-credentials/delegated-proof.ts @@ -0,0 +1,54 @@ +import { VerifyResult } from 'crypto-wasm-new'; +import { AccumulatorSecretKey } from '../accumulator'; +import { BDDT16MacSecretKey } from '../bddt16-mac'; +import { BDDT16DelegatedProof, VBAccumMembershipDelegatedProof } from '../delegated-proofs'; +import { ID_STR, REV_CHECK_STR, RevocationStatusProtocol, SignatureType, TYPE_STR } from './types-and-consts'; +import { Versioned } from './versioned'; + +export interface IDelegatedCredentialProof { + sigType: SignatureType, + proof: BDDT16DelegatedProof +} + +export interface IDelegatedCredentialStatusProof { + [ID_STR]: string; + [TYPE_STR]: RevocationStatusProtocol; + [REV_CHECK_STR]: string; + proof: VBAccumMembershipDelegatedProof +} + +export class DelegatedProof extends Versioned { + static VERSION = '0.1.0'; + + readonly credential?: IDelegatedCredentialProof; + readonly status?: IDelegatedCredentialStatusProof; + + constructor(credential?: IDelegatedCredentialProof, status?: IDelegatedCredentialStatusProof) { + super(DelegatedProof.VERSION); + this.credential = credential; + this.status = status; + } + + verify(credentialSecretKey?: BDDT16MacSecretKey, accumSecretKey?: AccumulatorSecretKey): VerifyResult { + const r = {verified: true, error: ""} + if (this.credential !== undefined) { + if (credentialSecretKey === undefined) { + throw new Error('Secret key not provided for credential') + } + const rc = this.credential.proof.verify(credentialSecretKey); + if (!rc.verified) { + return rc; + } + } + if (this.status !== undefined) { + if (accumSecretKey === undefined) { + throw new Error('Secret key not provided for accumulator') + } + const rc = this.status.proof.verify(accumSecretKey); + if (!rc.verified) { + return rc; + } + } + return r; + } +} \ No newline at end of file diff --git a/src/anonymous-credentials/presentation-builder.ts b/src/anonymous-credentials/presentation-builder.ts index 1b7c7c70..bf9daae1 100644 --- a/src/anonymous-credentials/presentation-builder.ts +++ b/src/anonymous-credentials/presentation-builder.ts @@ -1,9 +1,9 @@ import { Versioned } from './versioned'; -import { BBSCredential, BBSPlusCredential, PSCredential } from './credential'; +import { BBSCredential, BBSPlusCredential, BDDT16Credential, PSCredential } from './credential'; import { - CompositeProofG1, + CompositeProof, MetaStatements, - QuasiProofSpecG1, + QuasiProofSpec, SetupParam, Statement, Statements, @@ -13,7 +13,7 @@ import { } from '../composite-proof'; import { LegoProvingKey, LegoProvingKeyUncompressed } from '../legosnark'; import { CircomInputs } from '../r1cs'; -import { R1CS } from '@docknetwork/crypto-wasm'; +import { R1CS } from 'crypto-wasm-new'; import { CredentialSchema, getTransformedMinMax, ValueType } from './schema'; import { getRevealedAndUnrevealed } from '../sign-verify-js-objs'; import { @@ -26,7 +26,7 @@ import { CRYPTO_VERSION_STR, FlattenedSchema, ID_STR, - InequalityProtocol, + InequalityProtocol, MEM_CHECK_KV_STR, MEM_CHECK_STR, NON_MEM_CHECK_STR, PredicateParamType, @@ -51,10 +51,9 @@ import { PresentationSpecification } from './presentation-specification'; import { buildContextForProof, Presentation } from './presentation'; -import { AccumulatorPublicKey, AccumulatorWitness, MembershipWitness, NonMembershipWitness } from '../accumulator'; +import { AccumulatorPublicKey, AccumulatorWitness, VBMembershipWitness, VBNonMembershipWitness } from '../accumulator'; import { - accumulatorStatement, - buildSignatureStatementFromParamsRef, + accumulatorStatement, buildSignatureProverStatementFromParamsRef, buildWitness, createWitEq, createWitEqForBlindedCred, @@ -87,6 +86,7 @@ import { BoundCheckSmcWithKVProverParamsUncompressed } from '../bound-check'; import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { BDDT16MacParams } from '../bddt16-mac'; /** * Arguments required to generate the corresponding AttributeBoundPseudonym @@ -107,24 +107,24 @@ export interface UnboundedPseudonym { secretKey: Uint8Array; } -type Credential = BBSCredential | BBSPlusCredential | PSCredential; +type Credential = BBSCredential | BBSPlusCredential | PSCredential | BDDT16Credential; export class PresentationBuilder extends Versioned { // NOTE: Follows semver and must be updated accordingly when the logic of this class changes or the // underlying crypto changes. - static VERSION = '0.5.0'; + static VERSION = '0.6.0'; // This can specify the reason why the proof was created, or date of the proof, or self-attested attributes (as JSON string), etc _context?: string; // To prevent replay attack _nonce?: Uint8Array; - proof?: CompositeProofG1; + proof?: CompositeProof; // Just for debugging - private _proofSpec?: QuasiProofSpecG1; + private _proofSpec?: QuasiProofSpec; spec: PresentationSpecification; // Each credential is referenced by its index in this array - credentials: [Credential, PublicKey][]; + credentials: [Credential, PublicKey?][]; // Attributes revealed from each credential, key of the map is the credential index revealedAttributes: Map>; @@ -143,7 +143,7 @@ export class PresentationBuilder extends Versioned { attributeInequalities: Map>; // Each credential has only one accumulator for status - credStatuses: Map; + credStatuses: Map; // Bounds on attribute. The key of the map is the credential index and for the inner map is the attribute and value of map // denotes min, max, an identifier of the setup parameters for the protocol and the protocol name. @@ -202,7 +202,7 @@ export class PresentationBuilder extends Versioned { * @param credential * @param pk */ - addCredential(credential: Credential, pk: PublicKey): number { + addCredential(credential: Credential, pk?: PublicKey): number { // TODO: Accept reference to public keys in case of same key for many credentials this.credentials.push([credential, pk]); return this.credentials.length - 1; @@ -257,7 +257,7 @@ export class PresentationBuilder extends Versioned { credIdx: number, accumWitness: AccumulatorWitness, accumulated: Uint8Array, - accumPublicKey: AccumulatorPublicKey, + accumPublicKey?: AccumulatorPublicKey, extra: object = {} ) { this.validateCredIndex(credIdx); @@ -509,7 +509,7 @@ export class PresentationBuilder extends Versioned { } const paramsClass = paramsClassBySignature(cred.signature); if (paramsClass === null) { - throw new Error(`Invalid signature: ${cred.signature}`); + throw new Error(`Invalid signature: ${cred.signature.constructor.name} at credential index ${credIndex}`); } const sigParams = getSignatureParamsForMsgCount(sigParamsByScheme, paramsClass, numAttribs); @@ -521,7 +521,8 @@ export class PresentationBuilder extends Versioned { if ( cred.credentialStatus[ID_STR] === undefined || (cred.credentialStatus[REV_CHECK_STR] !== MEM_CHECK_STR && - cred.credentialStatus[REV_CHECK_STR] !== NON_MEM_CHECK_STR) + cred.credentialStatus[REV_CHECK_STR] !== NON_MEM_CHECK_STR && + cred.credentialStatus[REV_CHECK_STR] !== MEM_CHECK_KV_STR) ) { throw new Error(`Credential for ${credIndex} has invalid status ${cred.credentialStatus}`); } @@ -534,12 +535,12 @@ export class PresentationBuilder extends Versioned { revealedNames, schema.encoder ); - const statement = buildSignatureStatementFromParamsRef( + const statement = buildSignatureProverStatementFromParamsRef( setupParamsTrk, sigParams, - this.credentials[credIndex][1], numAttribs, - revealedAttrsEncoded + revealedAttrsEncoded, + this.credentials[credIndex][1], ); const witness = buildWitness(cred.signature, unrevealedAttrsEncoded); statements.add(statement); @@ -713,25 +714,25 @@ export class PresentationBuilder extends Versioned { } // Create statements and witnesses for accumulators used in credential status - credStatusAux.forEach(([i, t, value]) => { + credStatusAux.forEach(([i, checkType, value]) => { const s = this.credStatuses.get(i); if (s === undefined) { throw new Error(`No status details found for credential index ${i}`); } const [wit, acc, pk] = s; let witness; - if (t === MEM_CHECK_STR) { - if (!(wit instanceof MembershipWitness)) { + if (checkType === MEM_CHECK_STR || checkType === MEM_CHECK_KV_STR) { + if (!(wit instanceof VBMembershipWitness)) { throw new Error(`Expected membership witness but got non-membership witness for credential index ${i}`); } - witness = Witness.accumulatorMembership(value, wit); + witness = Witness.vbAccumulatorMembership(value, wit); } else { - if (!(wit instanceof NonMembershipWitness)) { + if (!(wit instanceof VBNonMembershipWitness)) { throw new Error(`Expected non-membership witness but got membership witness for credential index ${i}`); } - witness = Witness.accumulatorNonMembership(value, wit); + witness = Witness.vbAccumulatorNonMembership(value, wit); } - const statement = accumulatorStatement(t, pk, acc, setupParamsTrk); + const statement = accumulatorStatement(i, checkType, acc, setupParamsTrk, pk); const sIdx = statements.add(statement); witnesses.add(witness); @@ -1005,7 +1006,7 @@ export class PresentationBuilder extends Versioned { // Offset of attributes in the Pedersen Commitment, its 0 for BBS and 1 for BBS+ as the commitment in BBS+ is perfectly hiding. let pedCommWitnessOffset; - if (sigParams instanceof BBSSignatureParams || sigParams instanceof BBSPlusSignatureParamsG1) { + if (sigParams instanceof BBSSignatureParams || sigParams instanceof BBSPlusSignatureParamsG1 || sigParams instanceof BDDT16MacParams) { const commKey = sigParams.getParamsForIndices(blindedSubjectIndices); pedCommStId = statements.add(Statement.pedersenCommitmentG1(commKey, this.blindCredReq.req.commitment)); } else { @@ -1015,7 +1016,7 @@ export class PresentationBuilder extends Versioned { if (sigParams instanceof BBSSignatureParams) { witnesses.add(Witness.pedersenCommitment(blindedSubjectValues)); pedCommWitnessOffset = 0; - } else if (sigParams instanceof BBSPlusSignatureParamsG1) { + } else if (sigParams instanceof BBSPlusSignatureParamsG1 || sigParams instanceof BDDT16MacParams) { witnesses.add(Witness.pedersenCommitment([this.blindCredReq.blinding as Uint8Array, ...blindedSubjectValues])); pedCommWitnessOffset = 1; } else { @@ -1163,8 +1164,8 @@ export class PresentationBuilder extends Versioned { // The version and spec are also added to the proof thus binding these to the proof cryptographically. const ctx = buildContextForProof(this.version, this.spec, this._context); - this._proofSpec = new QuasiProofSpecG1(statements, metaStatements, setupParamsTrk.setupParams, ctx); - this.proof = CompositeProofG1.generateUsingQuasiProofSpec(this._proofSpec, witnesses, this._nonce); + this._proofSpec = new QuasiProofSpec(statements, metaStatements, setupParamsTrk.setupParams, ctx); + this.proof = CompositeProof.generateUsingQuasiProofSpec(this._proofSpec, witnesses, this._nonce); // Ciphertexts of credential attributes let attributeCiphertexts: Map | undefined; diff --git a/src/anonymous-credentials/presentation.ts b/src/anonymous-credentials/presentation.ts index dd75a34c..c6635a3a 100644 --- a/src/anonymous-credentials/presentation.ts +++ b/src/anonymous-credentials/presentation.ts @@ -1,52 +1,79 @@ -import { Versioned } from './versioned'; +import b58 from 'bs58'; +import { VerifyResult } from 'crypto-wasm-new'; +import { flatten } from 'flat'; +import stringify from 'json-stringify-deterministic'; +import semver from 'semver/preload'; +import { BBSSignatureParams } from '../bbs'; +import { BBSPlusSignatureParamsG1 } from '../bbs-plus'; +import { BDDT16MacParams } from '../bddt16-mac'; import { - IBoundedPseudonymCommitKey, - ICircomPredicate, ICircuitPrivateVar, ICircuitPrivateVarMultiCred, - IPresentedAttributeBound, - IPresentedAttributeInequality, - IPresentedAttributeVE, - IPresentedCredential, - PresentationSpecification -} from './presentation-specification'; + BoundCheckBppParams, + BoundCheckBppParamsUncompressed, + BoundCheckSmcParams, + BoundCheckSmcParamsUncompressed, + BoundCheckSmcWithKVVerifierParams, + BoundCheckSmcWithKVVerifierParamsUncompressed +} from '../bound-check'; import { - CompositeProofG1, + CompositeProof, MetaStatements, - QuasiProofSpecG1, + QuasiProofSpec, SetupParam, Statement, Statements, WitnessEqualityMetaStatement } from '../composite-proof'; +import { BDDT16DelegatedProof, VBAccumMembershipDelegatedProof } from '../delegated-proofs'; +import { LegoVerifyingKey, LegoVerifyingKeyUncompressed } from '../legosnark'; +import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { PSSignatureParams } from '../ps'; +import { Pseudonym, PseudonymBases } from '../Pseudonym'; +import { SaverCiphertext } from '../saver'; +import { flattenObjectToKeyValuesList } from '../util'; +import { DelegatedProof, IDelegatedCredentialProof, IDelegatedCredentialStatusProof } from './delegated-proof'; +import { + IBoundedPseudonymCommitKey, + ICircomPredicate, + ICircuitPrivateVar, + ICircuitPrivateVarMultiCred, + IPresentedAttributeBound, + IPresentedAttributeInequality, + IPresentedAttributeVE, + IPresentedCredential, + PresentationSpecification +} from './presentation-specification'; import { CredentialSchema, getTransformedMinMax, ValueType } from './schema'; -import { VerifyResult } from '@docknetwork/crypto-wasm'; -import { flatten } from 'flat'; +import { SetupParamsTracker } from './setup-params-tracker'; import { + AccumulatorVerificationParam, AttributeCiphertexts, BBS_BLINDED_CRED_PROOF_TYPE, BBS_PLUS_BLINDED_CRED_PROOF_TYPE, + BDDT16_BLINDED_CRED_PROOF_TYPE, + BlindSignatureType, + BoundCheckProtocol, + CircomProtocol, + CredentialVerificationParam, CRYPTO_VERSION_STR, FlattenedSchema, ID_STR, + InequalityProtocol, + MEM_CHECK_KV_STR, MEM_CHECK_STR, NON_MEM_CHECK_STR, - BlindSignatureType, - RevocationStatusProtocol, - SignatureType, PredicateParamType, PublicKey, REV_CHECK_STR, REV_ID_STR, + RevocationStatusProtocol, SCHEMA_STR, - STATUS_STR, - BoundCheckProtocol, - VerifiableEncryptionProtocol, - CircomProtocol, - InequalityProtocol + SignatureType, + STATUS_STR, TYPE_STR, + VerifiableEncryptionProtocol } from './types-and-consts'; -import { AccumulatorPublicKey } from '../accumulator'; import { accumulatorStatement, - buildSignatureStatementFromParamsRef, + buildSignatureVerifierStatementFromParamsRef, createWitEq, createWitEqForBlindedCred, deepClone, @@ -56,25 +83,7 @@ import { paramsClassByPublicKey, saverStatement } from './util'; -import { LegoVerifyingKey, LegoVerifyingKeyUncompressed } from '../legosnark'; -import { SaverCiphertext } from '../saver'; -import b58 from 'bs58'; -import { SetupParamsTracker } from './setup-params-tracker'; -import { flattenObjectToKeyValuesList } from '../util'; -import { Pseudonym, PseudonymBases } from '../Pseudonym'; -import { BBSSignatureParams } from '../bbs'; -import { BBSPlusSignatureParamsG1 } from '../bbs-plus'; -import { - BoundCheckBppParams, - BoundCheckBppParamsUncompressed, - BoundCheckSmcParams, - BoundCheckSmcParamsUncompressed, - BoundCheckSmcWithKVVerifierParams, - BoundCheckSmcWithKVVerifierParamsUncompressed -} from '../bound-check'; -import semver from 'semver/preload'; -import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; -import stringify from 'json-stringify-deterministic'; +import { Versioned } from './versioned'; /** * The context passed to the proof contains the version and the presentation spec as well. This is done to bind the @@ -105,7 +114,7 @@ export function buildContextForProof( export class Presentation extends Versioned { readonly spec: PresentationSpecification; - readonly proof: CompositeProofG1; + readonly proof: CompositeProof; // Ciphertexts for the verifiable encryption of required attributes. The key of the map is the credential index. // This is intentionally not part of presentation specification as this is created as part of the proof generation, // not before. @@ -119,7 +128,7 @@ export class Presentation extends Versioned { constructor( version: string, spec: PresentationSpecification, - proof: CompositeProofG1, + proof: CompositeProof, attributeCiphertexts?: Map, context?: string, nonce?: Uint8Array, @@ -136,7 +145,7 @@ export class Presentation extends Versioned { /** * - * @param publicKeys - Array of keys in the order of credentials in the presentation. + * @param credentialVerifParams - Array of keys in the order of credentials in the presentation. * @param accumulatorPublicKeys - Mapping credential index -> accumulator public key * @param predicateParams - Setup params for various predicates * @param circomOutputs - Values for the outputs variables of the Circom programs used for predicates. They key of the map @@ -146,22 +155,27 @@ export class Presentation extends Versioned { */ verify( // TODO: Accept reference to public keys in case of same key for many credentials - publicKeys: PublicKey[], - accumulatorPublicKeys?: Map, + credentialVerifParams: Map | CredentialVerificationParam[], + accumulatorPublicKeys?: Map, predicateParams?: Map, circomOutputs?: Map, blindedAttributesCircomOutputs?: Uint8Array[][], circomOutputsMultiCred?: Uint8Array[][], ): VerifyResult { - const numCreds = this.spec.credentials.length; - if (publicKeys.length !== numCreds) { - throw new Error(`Supply same no of public keys as creds. ${publicKeys.length} != ${numCreds}`); - } // NOTE: The order of processing predicates should match exactly to the order in presentation builder, eg. if circom predicates // are processed at the end in the builder than they should be processed at the end here as well, if verifiable encryption is - // processed at 2nd last in the builder than they should be processed at 2nd last here as well. + // processed at 2nd last in the builder than they should be processed at 2nd last here as well. By convention credentials are + // processed first, then their statuses (if present) and then any predicates. + let credVerifParams = new Map(); + if (credentialVerifParams instanceof Map) { + credVerifParams = credentialVerifParams; + } else { + credentialVerifParams.forEach((v, i) => { + credVerifParams.set(i, v) + }); + } const statements = new Statements(); const metaStatements = new MetaStatements(); @@ -187,6 +201,8 @@ export class Presentation extends Versioned { const setupParamsTrk = new SetupParamsTracker(); const sigParamsByScheme = new Map(); + const versionGt5 = semver.gt(this.version, '0.5.0'); + for (let credIndex = 0; credIndex < this.spec.credentials.length; credIndex++) { const presentedCred = this.spec.credentials[credIndex]; const presentedCredSchema = CredentialSchema.fromJSON(JSON.parse(presentedCred.schema)); @@ -195,18 +211,44 @@ export class Presentation extends Versioned { const revealedEncoded = Presentation.encodeRevealed(credIndex, presentedCred, presentedCredSchema, flattenedSchema[0]); - const paramsClass = paramsClassByPublicKey(publicKeys[credIndex]); - if (paramsClass === null) { - throw new Error(`Invalid public key: ${publicKeys[credIndex]}`); + let sigParamsClass; + switch (presentedCred.sigType) { + case SignatureType.Bbs: + sigParamsClass = BBSSignatureParams; + break; + case SignatureType.BbsPlus: + sigParamsClass = BBSPlusSignatureParamsG1; + break; + case SignatureType.Ps: + sigParamsClass = PSSignatureParams; + break; + case SignatureType.Bddt16: + sigParamsClass = BDDT16MacParams; + break; + default: + if (presentedCred.sigType !== undefined) { + throw new Error(`Invalid signature type ${presentedCred.sigType} for credential index ${credIndex}`); + } else { + const pk = credVerifParams.get(credIndex); + if (pk === undefined) { + throw new Error(`Public key not given for for credential index ${credIndex}`); + } + // KVAC were introduced later and by that time `sigType` is present in presented credentials + sigParamsClass = paramsClassByPublicKey(pk as PublicKey); + if (sigParamsClass === null) { + throw new Error(`Invalid public key: ${pk} for credential index ${credIndex}`); + } + } } - const sigParams = getSignatureParamsForMsgCount(sigParamsByScheme, paramsClass, numAttribs); + const sigParams = getSignatureParamsForMsgCount(sigParamsByScheme, sigParamsClass, numAttribs); - const statement = buildSignatureStatementFromParamsRef( + const statement = buildSignatureVerifierStatementFromParamsRef( setupParamsTrk, sigParams, - publicKeys[credIndex], numAttribs, - revealedEncoded + revealedEncoded, + credVerifParams.get(credIndex), + versionGt5 ); statements.add(statement); flattenedSchemas.push(flattenedSchema); @@ -240,13 +282,10 @@ export class Presentation extends Versioned { } } - credStatusAux.forEach(([i, t, accum]) => { + credStatusAux.forEach(([i, checkType, accum]) => { // let statement; const pk = accumulatorPublicKeys?.get(i); - if (pk === undefined) { - throw new Error(`Accumulator public key wasn't provided for credential index ${i}`); - } - const statement = accumulatorStatement(t, pk, accum, setupParamsTrk); + const statement = accumulatorStatement(i, checkType, accum, setupParamsTrk, pk); const sIdx = statements.add(statement); const witnessEq = new WitnessEqualityMetaStatement(); witnessEq.addWitnessRef(i, flattenedSchemas[i][0].indexOf(`${STATUS_STR}.${REV_ID_STR}`)); @@ -431,6 +470,9 @@ export class Presentation extends Versioned { } else if (sigType === BBS_PLUS_BLINDED_CRED_PROOF_TYPE) { sigParams = getSignatureParamsForMsgCount(sigParamsByScheme, BBSPlusSignatureParamsG1, numAttribs); pedCommWitnessOffset = 1; + } else if (sigType === BDDT16_BLINDED_CRED_PROOF_TYPE) { + sigParams = getSignatureParamsForMsgCount(sigParamsByScheme, BDDT16MacParams, numAttribs); + pedCommWitnessOffset = 1; } else { throw new Error('Blind signing not yet implemented for PS'); } @@ -551,8 +593,60 @@ export class Presentation extends Versioned { } const ctx = buildContextForProof(this.version, this.spec, this.context); - const proofSpec = new QuasiProofSpecG1(statements, metaStatements, setupParamsTrk.setupParams, ctx); - return this.proof.verifyUsingQuasiProofSpec(proofSpec, this.nonce); + const proofSpec = new QuasiProofSpec(statements, metaStatements, setupParamsTrk.setupParams, ctx); + return this.proof.verifyUsingQuasiProofSpec(proofSpec, this.nonce, versionGt5); + } + + /** + * Get delegated proof for + * @returns - The key in the returned map is the credential index + */ + getDelegatedProofs(): Map { + const r = new Map(); + const delegatedProofs = this.proof.getDelegatedProofs(); + let nextCredStatusStatementIdx = this.spec.credentials.length; + for (let i = 0; i < this.spec.credentials.length; i++) { + const presentedCred = this.spec.credentials[i]; + let credP: IDelegatedCredentialProof | undefined, statusP: IDelegatedCredentialStatusProof | undefined; + + if (presentedCred.sigType === SignatureType.Bddt16) { + const proof = delegatedProofs.get(i); + if (proof === undefined) { + throw new Error(`Could not find delegated credential proof for credential index ${i}`) + } + if (!(proof instanceof BDDT16DelegatedProof)) { + throw new Error(`Unexpected delegated credential proof type ${proof.constructor.name} for credential index ${i}`) + } + credP = { + sigType: presentedCred.sigType, + proof + } + } + + if (presentedCred.status !== undefined) { + if (presentedCred.status[TYPE_STR] === RevocationStatusProtocol.Vb22 && presentedCred.status[REV_CHECK_STR] === MEM_CHECK_KV_STR) { + const proof = delegatedProofs.get(nextCredStatusStatementIdx); + if (proof === undefined) { + throw new Error(`Could not find delegated credential status proof for credential index ${i}`) + } + if (!(proof instanceof VBAccumMembershipDelegatedProof)) { + throw new Error(`Unexpected delegated credential status proof type ${proof.constructor.name} for credential index ${i}`) + } + statusP = { + [ID_STR]: presentedCred.status[ID_STR], + [TYPE_STR]: presentedCred.status[TYPE_STR], + [REV_CHECK_STR]: presentedCred.status[REV_CHECK_STR], + proof + } + } + nextCredStatusStatementIdx++; + } + + if (credP !== undefined || statusP !== undefined) { + r.set(i, new DelegatedProof(credP, statusP)); + } + } + return r; } /** @@ -579,7 +673,8 @@ export class Presentation extends Versioned { if ( presentedCred.status[ID_STR] === undefined || (presentedCred.status[REV_CHECK_STR] !== MEM_CHECK_STR && - presentedCred.status[REV_CHECK_STR] !== NON_MEM_CHECK_STR) + presentedCred.status[REV_CHECK_STR] !== NON_MEM_CHECK_STR && + presentedCred.status[REV_CHECK_STR] !== MEM_CHECK_KV_STR) ) { throw new Error(`Presented credential for ${credIdx} has invalid status ${presentedCred.status}`); } @@ -1279,6 +1374,6 @@ export class Presentation extends Versioned { presSpec.blindCredentialRequest = req; } - return new Presentation(version, presSpec, new CompositeProofG1(b58.decode(proof)), atc, context, nnc, bac); + return new Presentation(version, presSpec, new CompositeProof(b58.decode(proof)), atc, context, nnc, bac); } } diff --git a/src/anonymous-credentials/types-and-consts.ts b/src/anonymous-credentials/types-and-consts.ts index bab722dd..029c9f81 100644 --- a/src/anonymous-credentials/types-and-consts.ts +++ b/src/anonymous-credentials/types-and-consts.ts @@ -1,4 +1,4 @@ -import { BBSPublicKey, BBSSignature, BBSSignatureParams } from '../bbs'; +import { BBSPublicKey, BBSSecretKey, BBSSignature, BBSSignatureParams } from '../bbs'; import { LegoProvingKey, LegoProvingKeyUncompressed } from '../legosnark'; import { SaverChunkedCommitmentKey, @@ -9,10 +9,16 @@ import { SaverProvingKey, SaverProvingKeyUncompressed } from '../saver'; -import { R1CS } from '@docknetwork/crypto-wasm'; -import { BBSPlusPublicKeyG2, BBSPlusSignatureG1, BBSPlusSignatureParamsG1 } from '../bbs-plus'; -import { PSPublicKey, PSSignature, PSSignatureParams } from '../ps'; -import { Accumulator, AccumulatorParams, MembershipProvingKey, NonMembershipProvingKey } from '../accumulator'; +import { R1CS } from 'crypto-wasm-new'; +import { BBSPlusPublicKeyG2, BBSPlusSecretKey, BBSPlusSignatureG1, BBSPlusSignatureParamsG1 } from '../bbs-plus'; +import { PSPublicKey, PSSecretKey, PSSignature, PSSignatureParams } from '../ps'; +import { + Accumulator, + AccumulatorParams, + AccumulatorPublicKey, AccumulatorSecretKey, + MembershipProvingKey, + NonMembershipProvingKey +} from '../accumulator'; import { BoundCheckBppParams, BoundCheckBppParamsUncompressed, @@ -24,6 +30,7 @@ import { BoundCheckSmcWithKVVerifierParamsUncompressed } from '../bound-check'; import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; export type StringOrObject = string | object; // Reference to an attribute of a credential. The first item of the pair is the credential index in the presentation. @@ -70,13 +77,19 @@ export type BoundType = number | DateType; export type FlattenedSchema = [string[], object[]]; export type AttributeCiphertexts = { [key: string]: object | SaverCiphertext | SaverCiphertext[] }; +export type SecretKey = BBSSecretKey | BBSPlusSecretKey | PSSecretKey | BDDT16MacSecretKey; export type PublicKey = BBSPublicKey | BBSPlusPublicKeyG2 | PSPublicKey; -export type Signature = BBSSignature | BBSPlusSignatureG1 | PSSignature; -export type SignatureParams = BBSSignatureParams | BBSPlusSignatureParamsG1 | PSSignatureParams; +export type Signature = BBSSignature | BBSPlusSignatureG1 | PSSignature | BDDT16Mac; +export type SignatureParams = BBSSignatureParams | BBSPlusSignatureParamsG1 | PSSignatureParams | BDDT16MacParams; export type SignatureParamsClass = | typeof BBSSignatureParams | typeof BBSPlusSignatureParamsG1 - | typeof PSSignatureParams; + | typeof PSSignatureParams + | typeof BDDT16MacParams; +// TODO: Find a better name +export type CredentialVerificationParam = PublicKey | BDDT16MacSecretKey; +// TODO: Find a better name +export type AccumulatorVerificationParam = AccumulatorPublicKey | AccumulatorSecretKey; export const VERSION_STR = 'version'; export const CRYPTO_VERSION_STR = 'cryptoVersion'; @@ -95,14 +108,16 @@ export const ID_STR = 'id'; export const REV_CHECK_STR = 'revocationCheck'; export const REV_ID_STR = 'revocationId'; export const MEM_CHECK_STR = 'membership'; -export const PROOF_STR = 'proof'; export const NON_MEM_CHECK_STR = 'non-membership'; +export const MEM_CHECK_KV_STR = 'membership-kv'; +export const PROOF_STR = 'proof'; export const BBS_CRED_PROOF_TYPE = 'Bls12381BBSSignatureDock2023'; export const BBS_BLINDED_CRED_PROOF_TYPE = 'Bls12381BlindedBBSSignatureDock2023'; export const BBS_PLUS_CRED_PROOF_TYPE = 'Bls12381BBS+SignatureDock2022'; export const BBS_PLUS_BLINDED_CRED_PROOF_TYPE = 'Bls12381BlindedBBS+SignatureDock2023'; export const PS_CRED_PROOF_TYPE = 'Bls12381PSSignatureDock2023'; - +export const BDDT16_CRED_PROOF_TYPE = 'Bls12381BDDT16Dock2024'; +export const BDDT16_BLINDED_CRED_PROOF_TYPE = 'Bls12381BlindedBDDT16Dock2024'; export const LEGOGROTH16 = 'LegoGroth16'; export const SAVER = 'SAVER'; @@ -121,6 +136,10 @@ export const BBS_SIGNATURE_PARAMS_LABEL_BYTES = te.encode(BBS_SIGNATURE_PARAMS_L export const BBS_PLUS_SIGNATURE_PARAMS_LABEL = 'DockBBS+Signature2022'; export const BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES = te.encode(BBS_PLUS_SIGNATURE_PARAMS_LABEL); +// Label used for generating BDDT16 MAC parameters +export const BDDT16_MAC_PARAMS_LABEL = 'DockBDDT16MAC'; +export const BDDT16_MAC_PARAMS_LABEL_BYTES = te.encode(BDDT16_MAC_PARAMS_LABEL); + // Label used for generating PS signature parameters export const PS_SIGNATURE_PARAMS_LABEL = 'DockPSSignature2023'; export const PS_SIGNATURE_PARAMS_LABEL_BYTES = te.encode(PS_SIGNATURE_PARAMS_LABEL); @@ -184,12 +203,14 @@ export function dockInequalityCommKeyUncompressed(): PederCommKeyUncompressed { export enum SignatureType { Bbs = BBS_CRED_PROOF_TYPE, BbsPlus = BBS_PLUS_CRED_PROOF_TYPE, - Ps = PS_CRED_PROOF_TYPE + Ps = PS_CRED_PROOF_TYPE, + Bddt16 = BDDT16_CRED_PROOF_TYPE } export enum BlindSignatureType { Bbs = BBS_BLINDED_CRED_PROOF_TYPE, - BbsPlus = BBS_PLUS_BLINDED_CRED_PROOF_TYPE + BbsPlus = BBS_PLUS_BLINDED_CRED_PROOF_TYPE, + Bddt16 = BDDT16_BLINDED_CRED_PROOF_TYPE } export enum RevocationStatusProtocol { diff --git a/src/anonymous-credentials/util.ts b/src/anonymous-credentials/util.ts index f1956994..fa5812db 100644 --- a/src/anonymous-credentials/util.ts +++ b/src/anonymous-credentials/util.ts @@ -1,10 +1,11 @@ -import { AccumulatorPublicKey } from '../accumulator'; +import { AccumulatorPublicKey, AccumulatorSecretKey } from '../accumulator'; import { + AccumulatorVerificationParam, AttributeEquality, AttributeRef, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, - BBS_SIGNATURE_PARAMS_LABEL_BYTES, - FlattenedSchema, + BBS_SIGNATURE_PARAMS_LABEL_BYTES, BDDT16_MAC_PARAMS_LABEL_BYTES, CredentialVerificationParam, + FlattenedSchema, MEM_CHECK_KV_STR, MEM_CHECK_STR, PredicateParamType, PS_SIGNATURE_PARAMS_LABEL_BYTES, @@ -29,6 +30,7 @@ import { SetupParam, Statement, Witness, WitnessEqualityMetaStatement } from '.. import { SetupParamsTracker } from './setup-params-tracker'; import { BBSPublicKey, BBSSignature, BBSSignatureParams } from '../bbs'; import { PSPublicKey, PSSignature, PSSignatureParams } from '../ps'; +import { BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; export function isValueDate(value: string): boolean { // YYYY-MM-DD @@ -165,6 +167,8 @@ export function paramsClassBySignature(signature: Signature): SignatureParamsCla return BBSPlusSignatureParamsG1; } else if (signature instanceof PSSignature) { return PSSignatureParams; + } else if (signature instanceof BDDT16Mac) { + return BDDT16MacParams; } else { return null; } @@ -182,39 +186,111 @@ export function paramsClassByPublicKey(pk: PublicKey): SignatureParamsClass | nu } } -export function buildSignatureStatementFromParamsRef( +export function buildSignatureVerifierStatementFromParamsRef( setupParamsTrk: SetupParamsTracker, sigParams: SignatureParams, - pk: PublicKey, messageCount: number, - revealedMessages: Map + revealedMessages: Map, + credVerParam?: CredentialVerificationParam, + useNewVersion = true ): Uint8Array { - if (paramsClassByPublicKey(pk) !== sigParams.constructor) { + let setupSigP: SetupParam, + setupPK: SetupParam | undefined, + buildStatement: (( + sigParamsRef: number, + publicKeyRef: number, + revealedMessages: Map, + encodeMessages: boolean + ) => Uint8Array) | (( + sigParamsRef: number, + revealedMessages: Map, + encodeMessages: boolean + ) => Uint8Array); + + function getPk(): PublicKey { + if (credVerParam === undefined) { + throw new Error('Public key needs to be provided for BBS signatures') + } + const pk = credVerParam as PublicKey; + if (paramsClassByPublicKey(pk) !== sigParams.constructor) { + throw new Error(`Public key and params have different schemes: ${credVerParam}, ${sigParams}`); + } + return pk; + } + + switch (sigParams.constructor) { + case BBSSignatureParams: + setupSigP = SetupParam.bbsSignatureParams(sigParams.adapt(messageCount) as BBSSignatureParams); + setupPK = SetupParam.bbsPlusSignaturePublicKeyG2(getPk()); + buildStatement = useNewVersion ? Statement.bbsSignatureVerifierFromSetupParamRefs : Statement.bbsSignatureFromSetupParamRefsOld; + return buildStatement(setupParamsTrk.add(setupSigP), setupParamsTrk.add(setupPK), revealedMessages, false); + case BBSPlusSignatureParamsG1: + setupPK = SetupParam.bbsPlusSignaturePublicKeyG2(getPk()); + setupSigP = SetupParam.bbsPlusSignatureParamsG1(sigParams.adapt(messageCount) as BBSPlusSignatureParamsG1); + buildStatement = useNewVersion ? Statement.bbsPlusSignatureVerifierFromSetupParamRefs : Statement.bbsPlusSignatureFromSetupParamRefsOld; + return buildStatement(setupParamsTrk.add(setupSigP), setupParamsTrk.add(setupPK), revealedMessages, false); + case PSSignatureParams: + let psPK = getPk() as PSPublicKey; + const supported = psPK.supportedMessageCount(); + if (messageCount !== supported) { + if (messageCount < supported) { + psPK = psPK.adaptForLess(messageCount); + } else { + throw new Error(`Unsupported message count - supported up to ${supported}, received = ${messageCount}`); + } + } + setupPK = SetupParam.psSignaturePublicKey(psPK); + setupSigP = SetupParam.psSignatureParams(sigParams.adapt(messageCount) as PSSignatureParams); + buildStatement = Statement.psSignatureFromSetupParamRefs; + return buildStatement(setupParamsTrk.add(setupSigP), setupParamsTrk.add(setupPK), revealedMessages, false); + case BDDT16MacParams: + setupSigP = SetupParam.bddt16MacParams(sigParams.adapt(messageCount) as BDDT16MacParams); + if (credVerParam instanceof BDDT16MacSecretKey) { + return Statement.bddt16MacFullVerifierFromSetupParamRefs(setupParamsTrk.add(setupSigP), credVerParam, revealedMessages, false); + } else { + return Statement.bddt16MacFromSetupParamRefs(setupParamsTrk.add(setupSigP), revealedMessages, false); + } + default: + throw new Error(`Signature params are invalid ${sigParams}`); + } +} + +export function buildSignatureProverStatementFromParamsRef( + setupParamsTrk: SetupParamsTracker, + sigParams: SignatureParams, + messageCount: number, + revealedMessages: Map, + pk?: PublicKey +): Uint8Array { + if (pk !== undefined && paramsClassByPublicKey(pk) !== sigParams.constructor) { throw new Error(`Public key and params have different schemes: ${pk}, ${sigParams}`); } let setupParams: SetupParam, - setupPK: SetupParam, - buildStatement: ( + setupPK: SetupParam | undefined, + buildStatement: (( sigParamsRef: number, publicKeyRef: number, revealedMessages: Map, encodeMessages: boolean - ) => Uint8Array; + ) => Uint8Array) | (( + sigParamsRef: number, + revealedMessages: Map, + encodeMessages: boolean + ) => Uint8Array); switch (sigParams.constructor) { case BBSSignatureParams: setupParams = SetupParam.bbsSignatureParams(sigParams.adapt(messageCount) as BBSSignatureParams); - setupPK = SetupParam.bbsPlusSignaturePublicKeyG2(pk); - buildStatement = Statement.bbsSignatureFromSetupParamRefs; - + buildStatement = Statement.bbsSignatureProverFromSetupParamRefs; break; case BBSPlusSignatureParamsG1: - setupPK = SetupParam.bbsPlusSignaturePublicKeyG2(pk); setupParams = SetupParam.bbsPlusSignatureParamsG1(sigParams.adapt(messageCount) as BBSPlusSignatureParamsG1); - buildStatement = Statement.bbsPlusSignatureFromSetupParamRefs; - + buildStatement = Statement.bbsPlusSignatureProverFromSetupParamRefs; break; case PSSignatureParams: + if (pk === undefined) { + throw new Error('Public key should be provided for PS signature') + } let psPK = pk as PSPublicKey; const supported = psPK.supportedMessageCount(); if (messageCount !== supported) { @@ -224,17 +300,20 @@ export function buildSignatureStatementFromParamsRef( throw new Error(`Unsupported message count - supported up to ${supported}, received = ${messageCount}`); } } - setupPK = SetupParam.psSignaturePublicKey(psPK); setupParams = SetupParam.psSignatureParams(sigParams.adapt(messageCount) as PSSignatureParams); buildStatement = Statement.psSignatureFromSetupParamRefs; - + break; + case BDDT16MacParams: + setupParams = SetupParam.bddt16MacParams(sigParams.adapt(messageCount) as BDDT16MacParams); + buildStatement = Statement.bddt16MacFromSetupParamRefs; break; default: - throw new Error(`Signature params are invalid ${sigParams}`); + throw new Error(`Signature params are invalid ${sigParams.constructor.name}`); } - return buildStatement(setupParamsTrk.add(setupParams), setupParamsTrk.add(setupPK), revealedMessages, false); + // @ts-ignore + return setupPK !== undefined ? buildStatement(setupParamsTrk.add(setupParams), setupParamsTrk.add(setupPK), revealedMessages, false) : buildStatement(setupParamsTrk.add(setupParams), revealedMessages, false); } /** @@ -250,6 +329,8 @@ export function getDefaultLabelBytesForSignatureParams(signatureParamsClass: Sig return BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES; case PSSignatureParams: return PS_SIGNATURE_PARAMS_LABEL_BYTES; + case BDDT16MacParams: + return BDDT16_MAC_PARAMS_LABEL_BYTES; default: return null; } @@ -262,8 +343,11 @@ export function buildWitness(signature: Signature, unrevealedMessages: Map { + const encodedMessages = encoder.encodeMessageObjectAsObject(messages); + const encodedMessageList = Object.values(encodedMessages); + + const sigParams = BDDT16MacParams.getMacParamsOfRequiredSize(encodedMessageList.length, labelOrParams); + const signature = BDDT16Mac.generate(encodedMessageList, secretKey, sigParams, false); + + return { + encodedMessages, + signature + }; + } + + /** + * Verifies the MAC on the given messages. Takes the messages as a JS object, flattens it, encodes the values similar + * to signing and then verifies the MAC. + * @param messages + * @param secretKey + * @param labelOrParams + * @param encoder + */ + verifyMessageObject( + messages: object, + secretKey: BDDT16MacSecretKey, + labelOrParams: Uint8Array | BDDT16MacParams, + encoder: Encoder + ): VerifyResult { + const [_, encodedValues] = encoder.encodeMessageObject(messages); + const msgCount = encodedValues.length; + + const sigParams = BDDT16MacParams.getMacParamsOfRequiredSize(msgCount, labelOrParams); + return this.verify(encodedValues, secretKey, sigParams, false); + } +} + +export class BDDT16BlindMac extends MessageEncoder { + /** + * Generates a blind MAC over the commitment of unrevealed messages and revealed messages + * @param commitment - Commitment over unrevealed messages sent by the requester of the blind MAC. Its assumed that + * the signers has verified the knowledge of committed messages + * @param revealedMessages + * @param secretKey + * @param params + * @param encodeMessages + */ + static generate( + commitment: Uint8Array, + revealedMessages: Map, + secretKey: BDDT16MacSecretKey, + params: BDDT16MacParams, + encodeMessages: boolean + ): BDDT16BlindMac { + if (revealedMessages.size >= params.supportedMessageCount()) { + throw new Error( + `Number of messages ${ + revealedMessages.size + } must be less than ${params.supportedMessageCount()} supported by the MAC params` + ); + } + const sig = bddt16BlindMacGenerate(commitment, revealedMessages, secretKey.value, params.value, encodeMessages); + return new BDDT16BlindMac(sig); + } + + /** + * Generate a blind MAC from request + * @param request + * @param secretKey + * @param params + * @returns {BDDT16BlindMac} + */ + static fromRequest( + { commitment, revealedMessages }: BDDT16BlindMacRequest, + secretKey: BDDT16MacSecretKey, + params: BDDT16MacParams + ): BDDT16BlindMac { + return this.generate(commitment, revealedMessages ?? new Map(), secretKey, params, false); + } + + /** + * Unblind the blind MAC to get a regular MAC that can be verified + * @param blinding + */ + unblind(blinding: Uint8Array): BDDT16Mac { + const sig = bddt16UnblindMac(this.value, blinding); + return new BDDT16Mac(sig); + } + + /** + * Generate a request for a blind MAC + * @param messagesToBlind - messages the requester wants to hide from the signer. The key of the map is the index of the + * message as per the params. + * @param params + * @param encodeMessages + * @param blinding - If not provided, a random blinding is generated + * @param revealedMessages - Any messages that the requester wishes to inform the signer about. This is for informational + * purpose only and has no cryptographic use. + */ + static generateRequest( + messagesToBlind: Map, + params: BDDT16MacParams, + encodeMessages: boolean, + blinding?: Uint8Array, + revealedMessages?: Map + ): [Uint8Array, BDDT16BlindMacRequest] { + const [commitment, b] = params.commitToMessages(messagesToBlind, encodeMessages, blinding); + const [blindedIndices, encodedRevealedMessages] = getBlindedIndicesAndRevealedMessages( + messagesToBlind, + encodeMessages, + revealedMessages + ); + return [b, { commitment, blindedIndices, revealedMessages: encodedRevealedMessages }]; + } + + /** + * Used by the signer to create a blind MAC + * @param blindSigRequest - The blind sig request sent by user. + * @param revealedMessages - The messages known to the signer + * @param secretKey + * @param msgStructure + * @param labelOrParams + * @param encoder + */ + static blindSignMessageObject( + blindSigRequest: BDDT16BlindMacRequest, + revealedMessages: object, + secretKey: BDDT16MacSecretKey, + msgStructure: MessageStructure, + labelOrParams: Uint8Array | BDDT16MacParams, + encoder: Encoder + ): SignedMessages { + const { + encodedByName: encodedMessages, + encodedByIndex: revealedMessagesEncoded, + total + } = encodeRevealedMessageObject(revealedMessages, blindSigRequest.blindedIndices.length, msgStructure, encoder); + + const macParams = BDDT16MacParams.getMacParamsOfRequiredSize(total, labelOrParams); + const signature = this.generate(blindSigRequest.commitment, revealedMessagesEncoded, secretKey, macParams, false); + + return { + encodedMessages, + signature + }; + } +} + +/** + * Structure to send to the signer to request a blind MAC for BDDT16 scheme. + */ +export interface BDDT16BlindMacRequest { + /** + * The commitment to the blinded messages + */ + commitment: Uint8Array; + /** + * The messages at these indices were committed to in the commitment and are not revealed to the signer. This is expected + * to be sorted in ascending order + */ + blindedIndices: number[]; + /** + * The messages which are known to the signer. Here the key is message index (as per the `MACParams`). This is not + * mandatory as the signer might already know the messages to sign. This is used when the requester wants to inform the + * signer of some or all of the message + */ + revealedMessages?: Map; +} diff --git a/src/bddt16-mac/params.ts b/src/bddt16-mac/params.ts new file mode 100644 index 00000000..5b9b72be --- /dev/null +++ b/src/bddt16-mac/params.ts @@ -0,0 +1,139 @@ +import { ISignatureParams, MessageStructure } from '../types'; +import { + bddt16GenerateMacParams, bddt16IsMacParamsValid, bddt16MacAdaptParamsForMsgCount, bddt16MacCommitMsgs, + Bddt16MacParams, bddt16MacParamsFromBytes, bddt16MacParamsToBytes, generateRandomFieldElement +} from 'crypto-wasm-new'; +import { flattenMessageStructure, getSigParamsOfRequiredSize } from '../sign-verify-js-objs'; + +/** + * BDDT16 MAC parameters. + */ +export class BDDT16MacParams implements ISignatureParams { + label?: Uint8Array; + value: Bddt16MacParams; + + constructor(params: Bddt16MacParams, label?: Uint8Array) { + this.value = params; + this.label = label; + } + + /** + * Number of messages that these params support and can be signed. If less or more messages are to be signed, use + * `adapt` + */ + supportedMessageCount(): number { + return this.value.g_vec.length; + } + + /** + * Is message index valid as per the params + * @param index + */ + isValidIndex(index: number): boolean { + return index >= 0 && index < this.supportedMessageCount(); + } + + getParamsForIndices(indices: number[]): Uint8Array[] { + const p: Uint8Array[] = []; + p.push(this.value.g); + for (const i of indices) { + if (!this.isValidIndex(i)) { + throw new Error(`Invalid index ${i} for params with supported message count ${this.supportedMessageCount()}`); + } + p.push(this.value.g_vec[i]); + } + return p; + } + + static generate(numMessages: number, label?: Uint8Array): BDDT16MacParams { + const params = bddt16GenerateMacParams(numMessages, label); + return new BDDT16MacParams(params, label); + } + + static generateAsBytes(numMessages: number, label?: Uint8Array): Uint8Array { + return BDDT16MacParams.generate(numMessages, label).toBytes(); + } + + toBytes(): Uint8Array { + return bddt16MacParamsToBytes(this.value); + } + + isValid(): boolean { + return bddt16IsMacParamsValid(this.value); + } + + static valueFromBytes(bytes: Uint8Array): Bddt16MacParams { + return bddt16MacParamsFromBytes(bytes); + } + + /** + * Transform current MAC params to sign a different number of messages. Needs the `label` field to be present + * @param newMsgCount + */ + adapt(newMsgCount: number): this { + if (this.label === undefined) { + throw new Error(`Label should be present`); + } + let newParams; + + if (newMsgCount <= this.supportedMessageCount()) { + newParams = { + g_0: this.value.g_0, + g: this.value.g, + h: this.value.h, + g_vec: this.value.g_vec.slice(0, newMsgCount) + }; + } else { + newParams = bddt16MacAdaptParamsForMsgCount(this.value, this.label, newMsgCount); + } + return new (this.constructor as typeof BDDT16MacParams)(newParams, this.label) as this; + } + + /** + * Commit to given messages and return the pair [blinding, commitment] + * @param messageToCommit + * @param encodeMessages + * @param blinding - If not provided, a random blinding is generated + */ + commitToMessages( + messageToCommit: Map, + encodeMessages: boolean, + blinding: Uint8Array = generateRandomFieldElement() + ): [Uint8Array, Uint8Array] { + const commitment = bddt16MacCommitMsgs(messageToCommit, blinding, this.value, encodeMessages); + return [commitment, blinding]; + } + + /** + * Gives `BDDT16MacParams` that can sign `msgCount` number of messages. + * @param msgCount + * @param labelOrParams + */ + static getMacParamsOfRequiredSize( + msgCount: number, + labelOrParams: Uint8Array | BDDT16MacParams + ): BDDT16MacParams { + return getSigParamsOfRequiredSize(BDDT16MacParams, msgCount, labelOrParams); + } + + static getMacParamsForMsgStructure( + msgStructure: MessageStructure, + labelOrParams: Uint8Array | BDDT16MacParams + ): BDDT16MacParams { + const msgCount = Object.keys(flattenMessageStructure(msgStructure)).length; + return this.getMacParamsOfRequiredSize(msgCount, labelOrParams); + } + + toJSON(): string { + return JSON.stringify({ + value: { + g_0: Array.from(this.value.g_0), + g: Array.from(this.value.g), + h: Array.from(this.value.h), + g_vec: this.value.g_vec.map((g: Uint8Array) => Array.from(g)) + }, + label: this.label + }); + } + +} \ No newline at end of file diff --git a/src/bound-check/index.ts b/src/bound-check/index.ts index 4e7400cb..34aec5e4 100644 --- a/src/bound-check/index.ts +++ b/src/bound-check/index.ts @@ -6,7 +6,7 @@ import { decompressSmcParams, boundCheckSmcWithKVSetup, decompressSmcParamsAndSk -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { LegoProvingKey } from '../legosnark'; import { BytearrayWrapper } from '../bytearray-wrapper'; import { ICompressed, IUncompressed } from '../ICompressed'; diff --git a/src/composite-proof/proof-spec.ts b/src/composite-proof/proof-spec.ts index 0123222e..aee2e008 100644 --- a/src/composite-proof/proof-spec.ts +++ b/src/composite-proof/proof-spec.ts @@ -1,12 +1,12 @@ import { MetaStatements, Statements } from './statement'; import { SetupParam } from './setup-param'; -import { generateProofSpecG1, isProofSpecG1Valid } from '@docknetwork/crypto-wasm'; +import { generateProofSpecG1, isProofSpecG1Valid } from 'crypto-wasm-new'; /** * The specification used to construct the proof. This contains all the statements and the meta statements. - * If you have a lot of `Statements` or `SetupParam`s or they have a large size like for SNARKs, use `QuasiProofSpecG1` + * If you have a lot of `Statements` or `SetupParam`s or they have a large size like for SNARKs, use `QuasiProofSpec` */ -export class ProofSpecG1 { +export class ProofSpec { value: Uint8Array; constructor( @@ -30,11 +30,11 @@ export class ProofSpecG1 { /** * The specification used to construct the proof. This contains all the statements and the meta statements. - * The difference between this and `ProofSpecG1` that this does not call WASM to generate a `ProofSpecG1` object that + * The difference between this and `ProofSpec` that this does not call WASM to generate a `ProofSpec` object that * corresponds to the `ProofSpec` struct in Rust. This WASM call be expensive due to the serialization overhead and thus * it's advised to use this when there are a lot of `Statements` or `SetupParam`s. */ -export class QuasiProofSpecG1 { +export class QuasiProofSpec { statements: Statements; metaStatements: MetaStatements; setupParams: SetupParam[]; @@ -69,7 +69,7 @@ export class QuasiProofSpecG1 { this.context = context; } - toProofSpec(): ProofSpecG1 { - return new ProofSpecG1(this.statements, this.metaStatements, this.setupParams, this.context); + toProofSpec(): ProofSpec { + return new ProofSpec(this.statements, this.metaStatements, this.setupParams, this.context); } } diff --git a/src/composite-proof/proof.ts b/src/composite-proof/proof.ts index 1ccedf78..b34b0d7b 100644 --- a/src/composite-proof/proof.ts +++ b/src/composite-proof/proof.ts @@ -1,32 +1,34 @@ -import { MetaStatements, Statements } from './statement'; import { generateCompositeProofG1, - generateCompositeProofG1WithDeconstructedProofSpec, + generateCompositeProofG1WithDeconstructedProofSpec, getAllDelegatedSubproofsFromProof, saverGetCiphertextFromProof, saverGetCiphertextsFromProof, verifyCompositeProofG1, verifyCompositeProofG1WithDeconstructedProofSpec, VerifyResult -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; +import {verifyCompositeProofG1 as verifyCompositeProofG1Old, verifyCompositeProofG1WithDeconstructedProofSpec as verifyCompositeProofG1WithDeconstructedProofSpecOld} from 'crypto-wasm-old'; +import { BDDT16DelegatedProof, VBAccumMembershipDelegatedProof } from '../delegated-proofs'; +import { MetaStatements, Statements } from './statement'; import { Witnesses } from './witness'; import { SetupParam } from './setup-param'; import { SaverCiphertext } from '../saver'; -import { ProofSpecG1, QuasiProofSpecG1 } from './proof-spec'; +import { ProofSpec, QuasiProofSpec } from './proof-spec'; import { BytearrayWrapper } from '../bytearray-wrapper'; /** * A proof of 1 or more statements and meta statements. */ -export class CompositeProofG1 extends BytearrayWrapper { +export class CompositeProof extends BytearrayWrapper { /** * Generate the composite proof using a `ProofSpec` * @param proofSpec * @param witnesses * @param nonce */ - static generate(proofSpec: ProofSpecG1, witnesses: Witnesses, nonce?: Uint8Array): CompositeProofG1 { + static generate(proofSpec: ProofSpec, witnesses: Witnesses, nonce?: Uint8Array): CompositeProof { const proof = generateCompositeProofG1(proofSpec.value, witnesses.values, nonce); - return new CompositeProofG1(proof); + return new CompositeProof(proof); } /** @@ -34,13 +36,14 @@ export class CompositeProofG1 extends BytearrayWrapper { * @param proofSpec * @param witnesses * @param nonce + * @param useNewVersion */ static generateUsingQuasiProofSpec( - proofSpec: QuasiProofSpecG1, + proofSpec: QuasiProofSpec, witnesses: Witnesses, nonce?: Uint8Array - ): CompositeProofG1 { - return CompositeProofG1.generateWithDeconstructedProofSpec( + ): CompositeProof { + return CompositeProof.generateWithDeconstructedProofSpec( proofSpec.statements, proofSpec.metaStatements, witnesses, @@ -54,23 +57,26 @@ export class CompositeProofG1 extends BytearrayWrapper { * Verify this composite proof using a `ProofSpec` * @param proofSpec * @param nonce + * @param useNewVersion - Whether to use the new version of the wasm library */ - verify(proofSpec: ProofSpecG1, nonce?: Uint8Array): VerifyResult { - return verifyCompositeProofG1(this.value, proofSpec.value, nonce); + verify(proofSpec: ProofSpec, nonce?: Uint8Array, useNewVersion = true): VerifyResult { + return useNewVersion ? verifyCompositeProofG1(this.value, proofSpec.value, nonce) : verifyCompositeProofG1Old(this.value, proofSpec.value, nonce); } /** * Verify this composite proof using a `QuasiProofSpecG1` * @param proofSpec * @param nonce + * @param useNewVersion - Whether to use the new version of the wasm library */ - verifyUsingQuasiProofSpec(proofSpec: QuasiProofSpecG1, nonce?: Uint8Array): VerifyResult { + verifyUsingQuasiProofSpec(proofSpec: QuasiProofSpec, nonce?: Uint8Array, useNewVersion = true): VerifyResult { return this.verifyWithDeconstructedProofSpec( proofSpec.statements, proofSpec.metaStatements, proofSpec.setupParams, proofSpec.context, - nonce + nonce, + useNewVersion ); } @@ -96,7 +102,7 @@ export class CompositeProofG1 extends BytearrayWrapper { setupParams?: SetupParam[], context?: Uint8Array, nonce?: Uint8Array - ): CompositeProofG1 { + ): CompositeProof { const params = (setupParams ?? new Array()).map((s) => s.value); const proof = generateCompositeProofG1WithDeconstructedProofSpec( statements.values, @@ -106,7 +112,7 @@ export class CompositeProofG1 extends BytearrayWrapper { context, nonce ); - return new CompositeProofG1(proof); + return new CompositeProof(proof); } verifyWithDeconstructedProofSpec( @@ -114,10 +120,18 @@ export class CompositeProofG1 extends BytearrayWrapper { metaStatements: MetaStatements, setupParams?: SetupParam[], context?: Uint8Array, - nonce?: Uint8Array + nonce?: Uint8Array, + useNewVersion = true ): VerifyResult { const params = (setupParams ?? new Array()).map((s) => s.value); - return verifyCompositeProofG1WithDeconstructedProofSpec( + return useNewVersion ? verifyCompositeProofG1WithDeconstructedProofSpec( + this.value, + statements.values, + metaStatements.values, + params, + context, + nonce + ): verifyCompositeProofG1WithDeconstructedProofSpecOld( this.value, statements.values, metaStatements.values, @@ -126,4 +140,25 @@ export class CompositeProofG1 extends BytearrayWrapper { nonce ); } + + /** + * Get delegated proofs from a composite proof. + * @returns - The key in the returned map is the statement index + */ + getDelegatedProofs(): Map { + const r = new Map(); + const delgProofs = getAllDelegatedSubproofsFromProof(this.value); + for (const [i, [t, v]] of delgProofs.entries()) { + let cls; + if (t === 0) { + cls = BDDT16DelegatedProof; + } else if (t === 1) { + cls = VBAccumMembershipDelegatedProof; + } else { + throw new Error(`Unknown type ${t} of delegated proof for credential index ${i}`); + } + r.set(i, new cls(v)) + } + return r; + } } diff --git a/src/composite-proof/setup-param.ts b/src/composite-proof/setup-param.ts index bc584627..8bab259a 100644 --- a/src/composite-proof/setup-param.ts +++ b/src/composite-proof/setup-param.ts @@ -20,8 +20,8 @@ import { generateSetupParamForFieldElemVec, generateSetupParamForBppParams, generateSetupParamForSmcParams, - generateSetupParamForSmcParamsAndSk -} from '@docknetwork/crypto-wasm'; + generateSetupParamForSmcParamsAndSk, generateSetupParamForBDDT16MacParameters +} from 'crypto-wasm-new'; import { BBSPlusPublicKeyG2, BBSPlusSignatureParamsG1 } from '../bbs-plus'; import { SaverChunkedCommitmentKey, @@ -44,9 +44,9 @@ import { import { AccumulatorParams, AccumulatorPublicKey, MembershipProvingKey, NonMembershipProvingKey } from '../accumulator'; import { BytearrayWrapper } from '../bytearray-wrapper'; import { BBSSignatureParams } from '../bbs'; -import { generateSetupParamForPSSignatureParameters } from '@docknetwork/crypto-wasm'; +import { generateSetupParamForPSSignatureParameters } from 'crypto-wasm-new'; import { PSPublicKey, PSSignatureParams } from '../ps'; -import { generateSetupParamForPSPublicKey, generateSetupParamForCommitmentKey } from '@docknetwork/crypto-wasm'; +import { generateSetupParamForPSPublicKey, generateSetupParamForCommitmentKey } from 'crypto-wasm-new'; import { getR1CS, ParsedR1CSFile } from '../r1cs/file'; import { BoundCheckBppParams, @@ -57,6 +57,7 @@ import { BoundCheckSmcWithKVVerifierParamsUncompressed } from '../bound-check'; import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { BDDT16MacParams } from '../bddt16-mac'; /** * Represents (public) setup parameters of different protocols. Different setup parameters can be wrapped in this and @@ -84,6 +85,10 @@ export class SetupParam extends BytearrayWrapper { return new SetupParam(generateSetupParamForPSPublicKey(publicKey.value)); } + static bddt16MacParams(params: BDDT16MacParams): SetupParam { + return new SetupParam(generateSetupParamForBDDT16MacParameters(params.value)); + } + static vbAccumulatorParams(params: AccumulatorParams): SetupParam { return new SetupParam(generateSetupParamForVbAccumulatorParams(params.value)); } diff --git a/src/composite-proof/statement.ts b/src/composite-proof/statement.ts index 967a458f..efa4ae4e 100644 --- a/src/composite-proof/statement.ts +++ b/src/composite-proof/statement.ts @@ -1,14 +1,18 @@ import { generateAccumulatorMembershipStatement, generatePedersenCommitmentG1Statement, - generatePoKBBSPlusSignatureStatement, - generatePoKBBSSignatureStatement, + generatePoKBBSSignatureProverStatement, + generatePoKBBSSignatureVerifierStatement, + generatePoKBBSPlusSignatureProverStatement, + generatePoKBBSPlusSignatureVerifierStatement, + generatePoKBBSSignatureProverStatementFromParamRefs, + generatePoKBBSSignatureVerifierStatementFromParamRefs, + generatePoKBBSPlusSignatureProverStatementFromParamRefs, + generatePoKBBSPlusSignatureVerifierStatementFromParamRefs, generatePoKPSSignatureStatement, generateAccumulatorNonMembershipStatement, generateWitnessEqualityMetaStatement, generatePedersenCommitmentG1StatementFromParamRefs, - generatePoKBBSPlusSignatureStatementFromParamRefs, - generatePoKBBSSignatureStatementFromParamRefs, generatePoKPSSignatureStatementFromParamRefs, generateAccumulatorMembershipStatementFromParamRefs, generateAccumulatorNonMembershipStatementFromParamRefs, @@ -34,8 +38,17 @@ import { generateBoundCheckSmcWithKVVerifierStatement, generateBoundCheckSmcWithKVVerifierStatementFromParamRefs, generatePublicInequalityG1Statement, - generatePublicInequalityG1StatementFromParamRefs -} from '@docknetwork/crypto-wasm'; + generatePublicInequalityG1StatementFromParamRefs, + generatePoKBDDT16MacStatementFromParamRefs, + generatePoKBDDT16MacStatement, + generatePoKBDDT16MacFullVerifierStatement, + generatePoKBDDT16MacFullVerifierStatementFromParamRefs, + generateAccumulatorKVFullVerifierMembershipStatement, + generateAccumulatorKVMembershipStatement +} from 'crypto-wasm-new'; +// import { generatePoKBBSSignatureStatement, generatePoKBBSPlusSignatureStatement, generatePoKBBSSignatureStatementFromParamRefs, generatePoKBBSPlusSignatureStatementFromParamRefs } from 'crypto-wasm-old/lib/composite_proof_system_wasm'; +// @ts-ignore +import { generatePoKBBSSignatureStatement, generatePoKBBSPlusSignatureStatement, generatePoKBBSSignatureStatementFromParamRefs, generatePoKBBSPlusSignatureStatementFromParamRefs } from 'crypto-wasm-old'; import { BBSPlusPublicKeyG2, BBSPlusSignatureParamsG1 } from '../bbs-plus'; import { getChunkBitSize, @@ -56,7 +69,13 @@ import { LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed } from '../legosnark'; -import { AccumulatorParams, AccumulatorPublicKey, MembershipProvingKey, NonMembershipProvingKey } from '../accumulator'; +import { + AccumulatorParams, + AccumulatorPublicKey, + AccumulatorSecretKey, + MembershipProvingKey, + NonMembershipProvingKey +} from '../accumulator'; import { AttributeBoundPseudonym, Pseudonym } from '../Pseudonym'; import { isPositiveInteger } from '../util'; import { BBSSignatureParams } from '../bbs'; @@ -73,6 +92,7 @@ import { BoundCheckSmcWithKVVerifierParamsUncompressed } from '../bound-check'; import { PederCommKey, PederCommKeyUncompressed } from '../ped-com'; +import { BDDT16MacParams, BDDT16MacSecretKey } from '../bddt16-mac'; /** * Relation which needs to be proven. Contains any public data that needs to be known to both prover and verifier @@ -96,6 +116,23 @@ export class Statement { return generatePedersenCommitmentG1StatementFromParamRefs(commitmentKeyRef, commitment); } + static bbsSignatureOld( + sigParams: BBSSignatureParams, + publicKey: BBSPlusPublicKeyG2, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSSignatureStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); + } + + static bbsSignatureProver( + sigParams: BBSSignatureParams, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSSignatureProverStatement(sigParams.value, revealedMessages, encodeMessages); + } + /** * Create statement for proving knowledge of BBS signature * @param sigParams @@ -103,13 +140,30 @@ export class Statement { * @param revealedMessages * @param encodeMessages */ - static bbsSignature( + static bbsSignatureVerifier( sigParams: BBSSignatureParams, publicKey: BBSPlusPublicKeyG2, revealedMessages: Map, encodeMessages: boolean ): Uint8Array { - return generatePoKBBSSignatureStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); + return generatePoKBBSSignatureVerifierStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); + } + + static bbsPlusSignatureOld( + sigParams: BBSPlusSignatureParamsG1, + publicKey: BBSPlusPublicKeyG2, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSPlusSignatureStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); + } + + static bbsPlusSignatureProver( + sigParams: BBSPlusSignatureParamsG1, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSPlusSignatureProverStatement(sigParams.value, revealedMessages, encodeMessages); } /** @@ -119,13 +173,13 @@ export class Statement { * @param revealedMessages * @param encodeMessages */ - static bbsPlusSignature( + static bbsPlusSignatureVerifier( sigParams: BBSPlusSignatureParamsG1, publicKey: BBSPlusPublicKeyG2, revealedMessages: Map, encodeMessages: boolean ): Uint8Array { - return generatePoKBBSPlusSignatureStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); + return generatePoKBBSPlusSignatureVerifierStatement(sigParams.value, publicKey.value, revealedMessages, encodeMessages); } /** @@ -147,38 +201,81 @@ export class Statement { return generatePoKPSSignatureStatement(sigParams.value, publicKey.value, revealedMessages); } + static bbsSignatureProverFromSetupParamRefs( + sigParamsRef: number, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSSignatureProverStatementFromParamRefs(sigParamsRef, revealedMessages, encodeMessages); + } + + static bbsSignatureFromSetupParamRefsOld( + sigParamsRef: number, + publicKeyRef: number, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSSignatureStatementFromParamRefs(sigParamsRef, publicKeyRef, revealedMessages, encodeMessages); + } + /** - * Same as `Statement.bbsSignature` but does not take the parameters directly but a reference to them as indices in the + * Same as `Statement.bbsSignatureVerifier` but does not take the parameters directly but a reference to them as indices in the * array of `SetupParam` * @param sigParamsRef * @param publicKeyRef * @param revealedMessages * @param encodeMessages */ - static bbsSignatureFromSetupParamRefs( + static bbsSignatureVerifierFromSetupParamRefs( sigParamsRef: number, publicKeyRef: number, revealedMessages: Map, encodeMessages: boolean ): Uint8Array { - return generatePoKBBSSignatureStatementFromParamRefs(sigParamsRef, publicKeyRef, revealedMessages, encodeMessages); + return generatePoKBBSSignatureVerifierStatementFromParamRefs(sigParamsRef, publicKeyRef, revealedMessages, encodeMessages); + } + + static bbsPlusSignatureFromSetupParamRefsOld( + sigParamsRef: number, + publicKeyRef: number, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSPlusSignatureStatementFromParamRefs( + sigParamsRef, + publicKeyRef, + revealedMessages, + encodeMessages + ); + } + + static bbsPlusSignatureProverFromSetupParamRefs( + sigParamsRef: number, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBBSPlusSignatureProverStatementFromParamRefs( + sigParamsRef, + revealedMessages, + encodeMessages + ); } /** - * Same as `Statement.bbsPlusSignature` but does not take the parameters directly but a reference to them as indices in the + * Same as `Statement.bbsPlusSignatureVerifier` but does not take the parameters directly but a reference to them as indices in the * array of `SetupParam` * @param sigParamsRef * @param publicKeyRef * @param revealedMessages * @param encodeMessages */ - static bbsPlusSignatureFromSetupParamRefs( + static bbsPlusSignatureVerifierFromSetupParamRefs( sigParamsRef: number, publicKeyRef: number, revealedMessages: Map, encodeMessages: boolean ): Uint8Array { - return generatePoKBBSPlusSignatureStatementFromParamRefs( + return generatePoKBBSPlusSignatureVerifierStatementFromParamRefs( sigParamsRef, publicKeyRef, revealedMessages, @@ -186,6 +283,49 @@ export class Statement { ); } + static bddt16Mac( + macParams: BDDT16MacParams, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBDDT16MacStatement(macParams.value, revealedMessages, encodeMessages); + } + + static bddt16MacFullVerifier( + macParams: BDDT16MacParams, + secretKey: BDDT16MacSecretKey, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBDDT16MacFullVerifierStatement(macParams.value, secretKey.value, revealedMessages, encodeMessages); + } + + static bddt16MacFromSetupParamRefs( + macParamsRef: number, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBDDT16MacStatementFromParamRefs( + macParamsRef, + revealedMessages, + encodeMessages + ); + } + + static bddt16MacFullVerifierFromSetupParamRefs( + macParamsRef: number, + secretKey: BDDT16MacSecretKey, + revealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBDDT16MacFullVerifierStatementFromParamRefs( + macParamsRef, + secretKey.value, + revealedMessages, + encodeMessages + ); + } + /** * Same as `Statement.psSignature` but does not take the parameters directly but a reference to them as indices in the * array of `SetupParam` @@ -208,7 +348,7 @@ export class Statement { * @param provingKey * @param accumulated */ - static accumulatorMembership( + static vbAccumulatorMembership( params: AccumulatorParams, publicKey: AccumulatorPublicKey, provingKey: MembershipProvingKey, @@ -218,14 +358,14 @@ export class Statement { } /** - * Same as `Statement.accumulatorMembership` but does not take the parameters directly but a reference to them as indices in the + * Same as `Statement.vbAccumulatorMembership` but does not take the parameters directly but a reference to them as indices in the * array of `SetupParam` * @param params * @param publicKey * @param provingKey * @param accumulated */ - static accumulatorMembershipFromSetupParamRefs( + static vbAccumulatorMembershipFromSetupParamRefs( params: number, publicKey: number, provingKey: number, @@ -241,7 +381,7 @@ export class Statement { * @param provingKey * @param accumulated */ - static accumulatorNonMembership( + static vccumulatorNonMembership( params: AccumulatorParams, publicKey: AccumulatorPublicKey, provingKey: NonMembershipProvingKey, @@ -251,14 +391,14 @@ export class Statement { } /** - * Same as `Statement.accumulatorNonMembership` but does not take the parameters directly but a reference to them as indices in the + * Same as `Statement.vbAccumulatorNonMembership` but does not take the parameters directly but a reference to them as indices in the * array of `SetupParam` * @param params * @param publicKey * @param provingKey * @param accumulated */ - static accumulatorNonMembershipFromSetupParamRefs( + static vbAccumulatorNonMembershipFromSetupParamRefs( params: number, publicKey: number, provingKey: number, @@ -267,6 +407,19 @@ export class Statement { return generateAccumulatorNonMembershipStatementFromParamRefs(params, publicKey, provingKey, accumulated); } + static vbAccumulatorMembershipKV( + accumulated: Uint8Array + ): Uint8Array { + return generateAccumulatorKVMembershipStatement(accumulated); + } + + static vbAccumulatorMembershipKVFullVerifier( + secretKey: AccumulatorSecretKey, + accumulated: Uint8Array, + ): Uint8Array { + return generateAccumulatorKVFullVerifierMembershipStatement(secretKey.value, accumulated); + } + /** * Create statement for verifiable encryption of a message using SAVER, for the prover. Accepts the parameters in uncompressed form. * @param encGens diff --git a/src/composite-proof/witness.ts b/src/composite-proof/witness.ts index 38395463..e50edee2 100644 --- a/src/composite-proof/witness.ts +++ b/src/composite-proof/witness.ts @@ -10,13 +10,14 @@ import { generateR1CSCircomWitness, generateBoundCheckBppWitness, generateBoundCheckSmcWitness, - generateBoundCheckSmcWithKVWitness, generatePublicInequalityWitness -} from '@docknetwork/crypto-wasm'; + generateBoundCheckSmcWithKVWitness, generatePublicInequalityWitness, generatePoKBDDT16MacWitness +} from 'crypto-wasm-new'; import { BBSPlusSignatureG1 } from '../bbs-plus'; -import { MembershipWitness, NonMembershipWitness } from '../accumulator'; +import { VBMembershipWitness, VBNonMembershipWitness } from '../accumulator'; import { CircomInputs } from '../r1cs'; import { PSSignature } from '../ps'; import { BBSSignature } from '../bbs'; +import { BDDT16Mac } from '../bddt16-mac'; /** * Private data known only to the prover whose knowledge is being proved in a proof. @@ -67,12 +68,20 @@ export class Witness { return generatePoKBBSPlusSignatureWitness(signature.value, unrevealedMessages, encodeMessages); } + static bddt16Mac( + mac: BDDT16Mac, + unrevealedMessages: Map, + encodeMessages: boolean + ): Uint8Array { + return generatePoKBDDT16MacWitness(mac.value, unrevealedMessages, encodeMessages); + } + /** * Accumulator member and its witness * @param member * @param accumulatorWitness */ - static accumulatorMembership(member: Uint8Array, accumulatorWitness: MembershipWitness): Uint8Array { + static vbAccumulatorMembership(member: Uint8Array, accumulatorWitness: VBMembershipWitness): Uint8Array { return generateAccumulatorMembershipWitness(member, accumulatorWitness.value); } @@ -81,7 +90,7 @@ export class Witness { * @param nonMember * @param accumulatorWitness */ - static accumulatorNonMembership(nonMember: Uint8Array, accumulatorWitness: NonMembershipWitness): Uint8Array { + static vbAccumulatorNonMembership(nonMember: Uint8Array, accumulatorWitness: VBNonMembershipWitness): Uint8Array { return generateAccumulatorNonMembershipWitness(nonMember, accumulatorWitness.value); } diff --git a/src/delegated-proofs.ts b/src/delegated-proofs.ts new file mode 100644 index 00000000..e67df939 --- /dev/null +++ b/src/delegated-proofs.ts @@ -0,0 +1,22 @@ +import { VerifyResult, verifyBDDT16DelegatedProof, verifyVBAccumMembershipDelegatedProof } from 'crypto-wasm-new'; +import { AccumulatorSecretKey } from './accumulator'; +import { BDDT16MacSecretKey } from './bddt16-mac'; +import { BytearrayWrapper } from './bytearray-wrapper'; + +/** + * Delegated proof of BDDT16 MAC. + */ +export class BDDT16DelegatedProof extends BytearrayWrapper { + verify(secretKey: BDDT16MacSecretKey): VerifyResult { + return verifyBDDT16DelegatedProof(this.value, secretKey.value) + } +} + +/** + * Delegated proof of membership in keyed-verification of VB accumulator. + */ +export class VBAccumMembershipDelegatedProof extends BytearrayWrapper { + verify(secretKey: AccumulatorSecretKey): VerifyResult { + return verifyVBAccumMembershipDelegatedProof(this.value, secretKey.value) + } +} \ No newline at end of file diff --git a/src/encoder.ts b/src/encoder.ts index a07f593e..ccf9a08e 100644 --- a/src/encoder.ts +++ b/src/encoder.ts @@ -1,4 +1,4 @@ -import { encodeMessageForSigning, fieldElementAsBytes, generateFieldElementFromNumber } from '@docknetwork/crypto-wasm'; +import { encodeMessageForSigning, fieldElementAsBytes, generateFieldElementFromNumber } from 'crypto-wasm-new'; import { convertDateToTimestamp, flattenObjectToKeyValuesList, isPositiveInteger } from './util'; import LZUTF8 from 'lzutf8'; import { BytearrayWrapper } from './bytearray-wrapper'; diff --git a/src/frost-dkg.ts b/src/frost-dkg.ts index c181f600..9910a109 100644 --- a/src/frost-dkg.ts +++ b/src/frost-dkg.ts @@ -13,7 +13,7 @@ import { frostKeygenG2StartRound1, frostKeygenG2ThresholdPubkeyFromPubkeys, generateKeyBaseFromGivenG2Point -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { PublicKeyBase } from './types'; import { BBSPlusSignatureParamsG1 } from './bbs-plus'; import { BBSSignatureParams } from './bbs'; diff --git a/src/index.ts b/src/index.ts index 4869d49a..222c1f6c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export { initializeWasm, isWasmInitialized, requireWasmInitialized } from '@docknetwork/crypto-wasm'; +export { initializeWasm, isWasmInitialized, requireWasmInitialized } from './init'; export * from './util'; export * from './bbs-plus'; export * from './bbs'; diff --git a/src/init.ts b/src/init.ts new file mode 100644 index 00000000..8f465ce1 --- /dev/null +++ b/src/init.ts @@ -0,0 +1,16 @@ +import { initializeWasm as newInit, isWasmInitialized as newCheck, requireWasmInitialized as newRequire} from 'crypto-wasm-new'; +import { initializeWasm as oldInit, isWasmInitialized as oldCheck, requireWasmInitialized as oldRequire} from 'crypto-wasm-old'; + +export async function initializeWasm() { + await oldInit(); + await newInit(); +} + +export function isWasmInitialized(): boolean { + return oldCheck() && newCheck(); +} + +export function requireWasmInitialized() { + oldRequire(); + newRequire(); +} \ No newline at end of file diff --git a/src/legosnark/index.ts b/src/legosnark/index.ts index 87895c4e..0014d127 100644 --- a/src/legosnark/index.ts +++ b/src/legosnark/index.ts @@ -1,6 +1,6 @@ import { BytearrayWrapper } from '../bytearray-wrapper'; import { ICompressed, IUncompressed } from '../ICompressed'; -import { legosnarkDecompressPk, legosnarkDecompressVk, legosnarkVkFromPk } from '@docknetwork/crypto-wasm'; +import { legosnarkDecompressPk, legosnarkDecompressVk, legosnarkVkFromPk } from 'crypto-wasm-new'; /** * Uncompressed proving key of LegoGroth16 diff --git a/src/ped-com.ts b/src/ped-com.ts index c7416d31..ca9ef1b3 100644 --- a/src/ped-com.ts +++ b/src/ped-com.ts @@ -1,6 +1,6 @@ import { BytearrayWrapper } from './bytearray-wrapper'; import { ICompressed, IUncompressed } from './ICompressed'; -import { generatePedersenCommKeyG1, decompressPedersenCommKeyG1 } from '@docknetwork/crypto-wasm'; +import { generatePedersenCommKeyG1, decompressPedersenCommKeyG1 } from 'crypto-wasm-new'; export class PederCommKeyUncompressed extends BytearrayWrapper implements IUncompressed {} diff --git a/src/ps/keys.ts b/src/ps/keys.ts index 87a56496..f24bbe56 100644 --- a/src/ps/keys.ts +++ b/src/ps/keys.ts @@ -9,8 +9,8 @@ import { psSigningKeyMaxSupportedMsgs, psPublicKeyMaxSupportedMsgs, psAdaptPublicKeyForLessMessages -} from '@docknetwork/crypto-wasm'; -import { psShamirDeal } from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; +import { psShamirDeal } from 'crypto-wasm-new'; /** * Public key for modified Pointcheval-Sanders signature scheme used in `Coconut`. diff --git a/src/ps/params.ts b/src/ps/params.ts index 505ee7b9..8752cf1b 100644 --- a/src/ps/params.ts +++ b/src/ps/params.ts @@ -6,9 +6,9 @@ import { psAdaptSignatureParamsForMsgCount, PSSigParams, psMessageCommitment -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { flattenMessageStructure, getSigParamsOfRequiredSize } from '../sign-verify-js-objs'; -import { psMultiMessageCommitment } from '@docknetwork/crypto-wasm'; +import { psMultiMessageCommitment } from 'crypto-wasm-new'; import { ISignatureParams, MessageStructure } from '../types'; /** diff --git a/src/ps/proof.ts b/src/ps/proof.ts index 2989e16d..2644511b 100644 --- a/src/ps/proof.ts +++ b/src/ps/proof.ts @@ -11,7 +11,7 @@ import { psVerifySignaturePoK, PSPoKSigProtocol, VerifyResult -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { PSPublicKey } from './keys'; import { BytearrayWrapper } from '../bytearray-wrapper'; diff --git a/src/ps/signature.ts b/src/ps/signature.ts index f10cc7cf..37daff7b 100644 --- a/src/ps/signature.ts +++ b/src/ps/signature.ts @@ -8,12 +8,12 @@ import { VerifyResult, psMessageCommitment, PSCommitmentOrMessage -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { PSPublicKey, PSSecretKey } from './keys'; import { BytearrayWrapper } from '../bytearray-wrapper'; import { encodeRevealedMessageObject } from '../sign-verify-js-objs'; import { Encoder, MessageEncoder } from '../encoder'; -import { psAggregateSignatures } from '@docknetwork/crypto-wasm'; +import { psAggregateSignatures } from 'crypto-wasm-new'; import { MessageStructure, SignedMessages } from '../types'; /** diff --git a/src/r1cs/circom-circuit.ts b/src/r1cs/circom-circuit.ts index 5ca85cf6..5d7cd391 100644 --- a/src/r1cs/circom-circuit.ts +++ b/src/r1cs/circom-circuit.ts @@ -1,5 +1,5 @@ import { CircomInputs } from './circom-inputs'; -import { R1CS, r1csCircuitSatisfied, r1csGenerateWires } from '@docknetwork/crypto-wasm'; +import { R1CS, r1csCircuitSatisfied, r1csGenerateWires } from 'crypto-wasm-new'; import { getR1CS, ParsedR1CSFile } from './file'; export class CircomCircuit { diff --git a/src/r1cs/file.ts b/src/r1cs/file.ts index f46de887..bd8ffe75 100644 --- a/src/r1cs/file.ts +++ b/src/r1cs/file.ts @@ -1,4 +1,4 @@ -import { Constraint, LC, LCTerm, R1CS } from '@docknetwork/crypto-wasm'; +import { Constraint, LC, LCTerm, R1CS } from 'crypto-wasm-new'; /** * The interface expected after parsing an R1CS file generated by Circom diff --git a/src/r1cs/setup.ts b/src/r1cs/setup.ts index 53ea1947..9b26d593 100644 --- a/src/r1cs/setup.ts +++ b/src/r1cs/setup.ts @@ -1,5 +1,5 @@ import { LegoProvingKey } from '../legosnark'; -import { R1CS, r1csSnarkSetup } from '@docknetwork/crypto-wasm'; +import { R1CS, r1csSnarkSetup } from 'crypto-wasm-new'; import { ParsedR1CSFile, processParsedR1CSFile } from './file'; /** diff --git a/src/saver/chunked-commitment.ts b/src/saver/chunked-commitment.ts index 1af7b274..f7b70bf8 100644 --- a/src/saver/chunked-commitment.ts +++ b/src/saver/chunked-commitment.ts @@ -3,7 +3,7 @@ import { ICompressed, IUncompressed } from '../ICompressed'; import { saverGenerateChunkedCommitmentGenerators, saverDecompressChunkedCommitmentGenerators -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; /** * Same as `SaverChunkedCommitmentKey` but in uncompressed form. diff --git a/src/saver/ciphertext.ts b/src/saver/ciphertext.ts index ded0c1cd..bac6fe6c 100644 --- a/src/saver/ciphertext.ts +++ b/src/saver/ciphertext.ts @@ -1,5 +1,5 @@ import { BytearrayWrapper } from '../bytearray-wrapper'; -import { saverVerifyDecryptionUsingSnarkVk, VerifyResult } from '@docknetwork/crypto-wasm'; +import { saverVerifyDecryptionUsingSnarkVk, VerifyResult } from 'crypto-wasm-new'; import { Decrypted, SaverDecryptionKey, diff --git a/src/saver/decryptor.ts b/src/saver/decryptor.ts index 0e163135..e9fb424c 100644 --- a/src/saver/decryptor.ts +++ b/src/saver/decryptor.ts @@ -8,7 +8,7 @@ import { saverGenerateEncryptionGenerators, saverGetSnarkVkFromPk, saverDecryptCiphertextUsingSnarkVk -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { getChunkBitSize } from './util'; import { ICompressed, IUncompressed } from '../ICompressed'; diff --git a/src/sign-verify-js-objs.ts b/src/sign-verify-js-objs.ts index 31e9e38c..8b5a2ec3 100644 --- a/src/sign-verify-js-objs.ts +++ b/src/sign-verify-js-objs.ts @@ -8,7 +8,8 @@ import { BBSBlindSignatureRequest, BBSSignatureParams } from './bbs'; import { PSBlindSignatureRequest, PSSignatureParams } from './ps'; import { Witness } from './composite-proof/witness'; import { ISignatureParams, MessageStructure } from './types'; -import { encodeMessageForSigning } from '@docknetwork/crypto-wasm'; +import { encodeMessageForSigning } from 'crypto-wasm-new'; +import { BDDT16BlindMacRequest, BDDT16MacParams } from './bddt16-mac'; export function flattenMessageStructure(msgStructure: MessageStructure): object { return flatten(msgStructure); @@ -309,6 +310,34 @@ export function getPSWitnessesForBlindSigRequest( ]; } +/** + * Get the `BBS+` statement to be used in composite proof for the blind signature request + * @param request + * @param macParams + */ +export function getBDDT16StatementForBlindMacRequest( + request: BDDT16BlindMacRequest, + macParams: BDDT16MacParams +): Uint8Array { + const commKey = macParams.getParamsForIndices(request.blindedIndices); + return Statement.pedersenCommitmentG1(commKey, request.commitment); +} + +/** + * Get the `BBS+` witness to be used in composite proof for the blind signature request + * @param messages + * @param blinding + */ +export function getBDDT16WitnessForBlindMacRequest( + messages: Map, + blinding: Uint8Array +): Uint8Array { + const sortedMessages = [...messages.entries()]; + sortedMessages.sort(([a], [b]) => a - b); + + return Witness.pedersenCommitment([blinding, ...sortedMessages.map(([_, m]) => m)]); +} + export function getBlindedIndicesAndRevealedMessages( messagesToBlind: Map, encodeMessages: boolean, diff --git a/src/threshold-sigs/base-ot.ts b/src/threshold-sigs/base-ot.ts index 4b42fee8..aa3c9b4e 100644 --- a/src/threshold-sigs/base-ot.ts +++ b/src/threshold-sigs/base-ot.ts @@ -5,7 +5,7 @@ import { baseOTPhaseProcessResponses, baseOTPhaseProcessSenderPubkey, startBaseOTPhase -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { BytearrayWrapper } from '../bytearray-wrapper'; import { PublicKeyBase } from '../types'; import { BaseOTOutput } from './common'; diff --git a/src/threshold-sigs/bbs-plus.ts b/src/threshold-sigs/bbs-plus.ts index b9072105..8f428b8a 100644 --- a/src/threshold-sigs/bbs-plus.ts +++ b/src/threshold-sigs/bbs-plus.ts @@ -12,7 +12,7 @@ import { thresholdBbsPlusPhase2Finish, thresholdBbsPlusCreateSignatureShare, thresholdBbsPlusAggregateSignatureShares -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { BBSPlusSecretKey, BBSPlusSignatureParamsG1, BBSPlusSignatureG1 } from '../bbs-plus'; export class ThresholdBbsPlusSigner extends ThresholdSigner { diff --git a/src/threshold-sigs/bbs.ts b/src/threshold-sigs/bbs.ts index 3cff1da3..faf84c89 100644 --- a/src/threshold-sigs/bbs.ts +++ b/src/threshold-sigs/bbs.ts @@ -12,7 +12,7 @@ import { thresholdBbsPhase2ReceiveMessage2, thresholdBbsPhase2Start, thresholdBbsStartPhase1 -} from '@docknetwork/crypto-wasm'; +} from 'crypto-wasm-new'; import { BBSSecretKey, BBSSignature, BBSSignatureParams } from '../bbs'; export class ThresholdBbsSigner extends ThresholdSigner { diff --git a/src/threshold-sigs/common.ts b/src/threshold-sigs/common.ts index 4889e7e9..6b0cb63d 100644 --- a/src/threshold-sigs/common.ts +++ b/src/threshold-sigs/common.ts @@ -1,5 +1,5 @@ import { BytearrayWrapper } from '../bytearray-wrapper'; -import { generateGadgetVectorForThresholdSig } from '@docknetwork/crypto-wasm'; +import { generateGadgetVectorForThresholdSig } from 'crypto-wasm-new'; export class GadgetVector extends BytearrayWrapper { static generate(label: Uint8Array): GadgetVector { diff --git a/src/util.ts b/src/util.ts index 4bdf3d05..111336cc 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ -import { generateFieldElementFromBytes, generateRandomFieldElement } from '@docknetwork/crypto-wasm'; +import { generateFieldElementFromBytes, generateRandomFieldElement } from 'crypto-wasm-new'; import { flatten } from 'flat'; import { LegoProvingKey } from './legosnark'; import b58 from 'bs58'; diff --git a/tests/accumulator.spec.ts b/tests/accumulator.spec.ts index fcde14af..945f56d6 100644 --- a/tests/accumulator.spec.ts +++ b/tests/accumulator.spec.ts @@ -1,11 +1,12 @@ -import { generateRandomFieldElement, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateRandomFieldElement } from 'crypto-wasm-new'; import { + initializeWasm, IInitialElementsStore, Accumulator, PositiveAccumulator, UniversalAccumulator, - MembershipWitness, - WitnessUpdatePublicInfo, + VBMembershipWitness, + VBWitnessUpdatePublicInfo, AccumulatorParams, AccumulatorKeypair } from '../src'; @@ -112,14 +113,14 @@ async function runCommonTests( await accumulator.addBatch([e7, e8], sk, state, store); // Witness updates by accumulator manager using secret key - const newWits = MembershipWitness.updateMultiplePostBatchUpdates(wits, [e5, e6], [e7, e8], [], accumulated, sk); + const newWits = VBMembershipWitness.updateMultiplePostBatchUpdates(wits, [e5, e6], [e7, e8], [], accumulated, sk); tempAccumulator = getAccum(accumulator); expect(tempAccumulator.verifyMembershipWitness(e5, newWits[0], pk, params)).toEqual(true); expect(tempAccumulator.verifyMembershipWitness(e6, newWits[1], pk, params)).toEqual(true); // Witness update info created by accumulator manager - const witnessUpdInfo = WitnessUpdatePublicInfo.new(accumulated, [e7, e8], [], sk); + const witnessUpdInfo = VBWitnessUpdatePublicInfo.new(accumulated, [e7, e8], [], sk); // Witness can be updated without secret key using public info wits[0].updateUsingPublicInfoPostBatchUpdate(e5, [e7, e8], [], witnessUpdInfo); @@ -131,8 +132,8 @@ async function runCommonTests( const e5Wit = await accumulator.membershipWitness(e5, sk, state); const e6Wit = await accumulator.membershipWitness(e6, sk, state); - let e5WitTemp = new MembershipWitness(e5Wit.value); - let e6WitTemp = new MembershipWitness(e6Wit.value); + let e5WitTemp = new VBMembershipWitness(e5Wit.value); + let e6WitTemp = new VBMembershipWitness(e6Wit.value); const e9 = Accumulator.encodePositiveNumberAsAccumulatorMember(109); const e10 = Accumulator.encodePositiveNumberAsAccumulatorMember(110); @@ -149,7 +150,7 @@ async function runCommonTests( ]; const removals = [[e7, e8], [e9], []]; - const witUpd1 = WitnessUpdatePublicInfo.new(accumulator.accumulated, additions[0], removals[0], sk); + const witUpd1 = VBWitnessUpdatePublicInfo.new(accumulator.accumulated, additions[0], removals[0], sk); await accumulator.addRemoveBatches(additions[0], removals[0], sk, state); tempAccumulator = getAccum(accumulator); @@ -158,7 +159,7 @@ async function runCommonTests( expect(tempAccumulator.verifyMembershipWitness(e5, e5WitTemp, pk, params)).toEqual(true); expect(tempAccumulator.verifyMembershipWitness(e6, e6WitTemp, pk, params)).toEqual(true); - const witUpd2 = WitnessUpdatePublicInfo.new(accumulator.accumulated, additions[1], removals[1], sk); + const witUpd2 = VBWitnessUpdatePublicInfo.new(accumulator.accumulated, additions[1], removals[1], sk); await accumulator.addRemoveBatches(additions[1], removals[1], sk, state); tempAccumulator = getAccum(accumulator); @@ -167,7 +168,7 @@ async function runCommonTests( expect(tempAccumulator.verifyMembershipWitness(e5, e5WitTemp, pk, params)).toEqual(true); expect(tempAccumulator.verifyMembershipWitness(e6, e6WitTemp, pk, params)).toEqual(true); - const witUpd3 = WitnessUpdatePublicInfo.new(accumulator.accumulated, additions[2], removals[2], sk); + const witUpd3 = VBWitnessUpdatePublicInfo.new(accumulator.accumulated, additions[2], removals[2], sk); await accumulator.addRemoveBatches(additions[2], removals[2], sk, state); tempAccumulator = getAccum(accumulator); diff --git a/tests/anonymous-credentials/blind-issuance.spec.ts b/tests/anonymous-credentials/blind-issuance.spec.ts index 6fdec380..57a028cf 100644 --- a/tests/anonymous-credentials/blind-issuance.spec.ts +++ b/tests/anonymous-credentials/blind-issuance.spec.ts @@ -1,4 +1,4 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateFieldElementFromNumber, initializeWasm } from 'crypto-wasm-new'; import { AccumulatorPublicKey, AccumulatorSecretKey, @@ -15,7 +15,7 @@ import { LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MEM_CHECK_STR, - MembershipWitness, + VBMembershipWitness, PositiveAccumulator, PredicateParamType, PresentationBuilder, @@ -44,21 +44,26 @@ import { BoundCheckSmcWithKVSetup, DefaultSchemaParsingOpts, META_SCHEMA_STR, - InequalityProtocol + InequalityProtocol, CredentialVerificationParam, BDDT16BlindedCredentialRequestBuilder, BDDT16BlindedCredential } from '../../src'; import { SignatureParams, - KeyPair, SecretKey, PublicKey, Credential, - SignatureLabelBytes, Scheme, isBBS, - isPS + isPS, isKvac } from '../scheme'; -import { checkCiphertext, getDecodedBoundedPseudonym, getExampleSchema, prefillAccumulator } from './utils'; +import { + checkCiphertext, + getDecodedBoundedPseudonym, + getExampleSchema, + getKeys, + prefillAccumulator, + verifyCred +} from './utils'; import { checkResult, getBoundCheckSnarkKeys, @@ -69,7 +74,7 @@ import { } from '../utils'; import { flatten, unflatten } from 'flat'; import { InMemoryState } from '../../src/accumulator/in-memory-persistence'; -import { BBSBlindedCredentialRequest, BBSPlusBlindedCredentialRequest, BlindedCredentialRequest } from '../../src'; +import { BDDT16BlindedCredentialRequest, BBSBlindedCredentialRequest, BBSPlusBlindedCredentialRequest, BlindedCredentialRequest } from '../../src'; const loadSnarkSetupFromFiles = true; @@ -89,7 +94,7 @@ function newReqBuilder( schema: CredentialSchema, subjectToBlind: object ): BlindedCredentialRequestBuilder { - const reqBuilder = isBBS() ? new BBSBlindedCredentialRequestBuilder() : new BBSPlusBlindedCredentialRequestBuilder(); + const reqBuilder = isKvac() ? new BDDT16BlindedCredentialRequestBuilder() : isBBS() ? new BBSBlindedCredentialRequestBuilder() : new BBSPlusBlindedCredentialRequestBuilder(); reqBuilder.schema = schema; reqBuilder.subjectToBlind = subjectToBlind; return reqBuilder; @@ -105,14 +110,14 @@ function checkBlindedSubject(req, blindedSubject) { function checkReqJson( req: BlindedCredentialRequest, - pks: PublicKey[], + pks: Map | CredentialVerificationParam[], accumulatorPublicKeys?: Map, predicateParams?: Map, circomOutputs?: Map, blindedAttributesCircomOutputs?: Uint8Array[][] ) { const reqJson = req.toJSON(); - const recreatedReq = isBBS() + const recreatedReq = isKvac() ? BDDT16BlindedCredentialRequest.fromJSON(reqJson) : isBBS() ? BBSBlindedCredentialRequest.fromJSON(reqJson) : BBSPlusBlindedCredentialRequest.fromJSON(reqJson); checkResult( @@ -121,15 +126,15 @@ function checkReqJson( expect(recreatedReq.toJSON()).toEqual(reqJson); } -function checkBlindedCredJson(blindedCred: BlindedCredential, pk: PublicKey, blindedSubject: object, blinding?) { +function checkBlindedCredJson(blindedCred: BlindedCredential, sk: SecretKey, pk: PublicKey, blindedSubject: object, blinding?) { const credJson = blindedCred.toJSON(); - const recreatedCred = isBBS() ? BBSBlindedCredential.fromJSON(credJson) : BBSPlusBlindedCredential.fromJSON(credJson); + const recreatedCred = isKvac() ? BDDT16BlindedCredential.fromJSON(credJson) : isBBS() ? BBSBlindedCredential.fromJSON(credJson) : BBSPlusBlindedCredential.fromJSON(credJson); // @ts-ignore const cred = isBBS() ? // @ts-ignore recreatedCred.toCredential(blindedSubject) : recreatedCred.toCredential(blindedSubject, blinding); - checkResult(cred.verify(pk)); + verifyCred(cred, pk, sk); expect(recreatedCred.toJSON()).toEqual(credJson); } @@ -154,7 +159,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS let accumulator1Sk: AccumulatorSecretKey; let accumulator1Members: Uint8Array[]; let accumulator1State: InMemoryState; - let accumulator1Witness: MembershipWitness; + let accumulator1Witness: VBMembershipWitness; let boundCheckProvingKey: LegoProvingKeyUncompressed; let boundCheckVerifyingKey: LegoVerifyingKeyUncompressed; @@ -237,11 +242,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS beforeAll(async () => { await initializeWasm(); - const params = SignatureParams.generate(100, SignatureLabelBytes); - - const keypair1 = KeyPair.generate(params, stringToBytes('seed1')); - sk1 = keypair1.sk; - pk1 = keypair1.pk; + [sk1, pk1] = getKeys('seed1'); if (withSchemaRef) { schema1 = new CredentialSchema( @@ -273,9 +274,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS 300 ); - const keypair2 = KeyPair.generate(params, stringToBytes('seed2')); - sk2 = keypair2.sk; - pk2 = keypair2.pk; + [sk2, pk2] = getKeys('seed2'); if (withSchemaRef) { schema2 = new CredentialSchema(nonEmbeddedSchema, DefaultSchemaParsingOpts, true, undefined, getExampleSchema(9)); @@ -283,9 +282,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS schema2 = new CredentialSchema(getExampleSchema(9)); } - const keypair3 = KeyPair.generate(params); - sk3 = keypair3.sk; - pk3 = keypair3.pk; + [sk3, pk3] = getKeys(); if (withSchemaRef) { schema3 = new CredentialSchema(nonEmbeddedSchema, DefaultSchemaParsingOpts, true, undefined, getExampleSchema(7)); @@ -368,7 +365,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS credential1 = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential1.verify(pk1)); + verifyCred(credential1, pk1, sk1); const verifAccumulator = PositiveAccumulator.fromAccumulated(accumulator1.accumulated); expect( verifAccumulator.verifyMembershipWitness( @@ -379,7 +376,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS ) ).toEqual(true); - checkBlindedCredJson(blindedCred, pk1, blindedSubject, blinding); + checkBlindedCredJson(blindedCred, sk1, pk1, blindedSubject, blinding); }); it('should be able to request a blinded-credential while presenting another credential and proving some attributes equal', () => { @@ -443,9 +440,9 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS credential2 = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential2.verify(pk2)); + verifyCred(credential2, pk2, sk2); - checkBlindedCredJson(blindedCred, pk2, blindedSubject, blinding); + checkBlindedCredJson(blindedCred, sk2, pk2, blindedSubject, blinding); }); it('should be able to request a blinded-credential while presenting 2 credentials and proving some attributes equal and predicates on some credential attributes', () => { @@ -754,9 +751,9 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS credential3 = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential3.verify(pk3)); + verifyCred(credential3, pk3, sk3); - checkBlindedCredJson(blindedCred, pk3, blindedSubject, blinding); + checkBlindedCredJson(blindedCred, sk3, pk3, blindedSubject, blinding); }); it('should be able to request a blinded-credential and prove bounds on and verifiably encrypt some of the blinded attributes', () => { @@ -925,9 +922,9 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS const credential = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential.verify(pk3)); + verifyCred(credential, pk3, sk3); - checkBlindedCredJson(blindedCred, pk3, blindedSubject, blinding); + checkBlindedCredJson(blindedCred, sk3, pk3, blindedSubject, blinding); }); it('should be able to request a blinded-credential and prove Circom predicates on some of the blinded attributes', async () => { @@ -1064,7 +1061,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS const credential = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential.verify(pk3)); + verifyCred(credential, pk3, sk3); }); it('should be able to present pseudonyms bounded to credential and blinded attributes', () => { @@ -1236,8 +1233,8 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS credential3 = isBBS() ? blindedCred.toCredential(blindedSubject) : blindedCred.toCredential(blindedSubject, blinding); - checkResult(credential3.verify(pk3)); + verifyCred(credential3, pk3, sk3); - checkBlindedCredJson(blindedCred, pk3, blindedSubject, blinding); + checkBlindedCredJson(blindedCred, sk3, pk3, blindedSubject, blinding); }); }); diff --git a/tests/anonymous-credentials/credential.spec.ts b/tests/anonymous-credentials/credential.spec.ts index 79898948..e00bee87 100644 --- a/tests/anonymous-credentials/credential.spec.ts +++ b/tests/anonymous-credentials/credential.spec.ts @@ -1,5 +1,5 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { + initializeWasm, CredentialSchema, MEM_CHECK_STR, ID_STR, @@ -11,7 +11,14 @@ import { TYPE_STR, IEmbeddedJsonSchema, META_SCHEMA_STR, DefaultSchemaParsingOpts, IJsonSchema } from '../../src'; import { checkResult } from '../utils'; -import { checkEmbeddedSchema, checkSchemaFromJson, getExampleBuilder, getExampleSchema } from './utils'; +import { + checkEmbeddedSchema, + checkSchemaFromJson, + getExampleBuilder, + getExampleSchema, + getKeys, + verifyCred +} from './utils'; import * as jsonld from 'jsonld'; import { validate } from 'jsonschema'; import { @@ -22,7 +29,7 @@ import { Credential, CredentialBuilder, SignatureLabelBytes, - Scheme + Scheme, isKvac } from '../scheme'; describe(`${Scheme} Credential signing and verification`, () => { @@ -30,21 +37,18 @@ describe(`${Scheme} Credential signing and verification`, () => { beforeAll(async () => { await initializeWasm(); - const params = SignatureParams.generate(100, SignatureLabelBytes); - const keypair = KeyPair.generate(params); - sk = keypair.sk; - pk = keypair.pk; + [sk, pk] = getKeys(); }); - function checkJsonConvForCred(cred: Credential, pk: PublicKey): Credential { + function checkJsonConvForCred(cred: Credential, sk: SecretKey, pk: PublicKey): Credential { const credJson = cred.toJSON(); // Check that the credential JSON contains the schema in JSON-schema format checkSchemaFromJson(credJson[SCHEMA_STR], cred.schema); // The recreated credential should verify const recreatedCred = Credential.fromJSON(credJson); - checkResult(recreatedCred.verify(pk)); - + verifyCred(recreatedCred, pk, sk); + // The JSON representation of original and recreated credential should be same expect(credJson).toEqual(recreatedCred.toJSON()); expect(recreatedCred.schema.version).toEqual(cred.schema.version); @@ -58,12 +62,11 @@ describe(`${Scheme} Credential signing and verification`, () => { expect(() => builder.sign(sk, undefined, { requireSameFieldsAsSchema: true })).toThrow(); const cred = builder.sign(sk, undefined, { requireSameFieldsAsSchema: false }); - - checkResult(cred.verify(pk)); - - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual(builder.subject); - checkResult(recreatedCred.verify(pk)); + verifyCred(recreatedCred, pk, sk); } function checkCredSerz(withSchemaRef: boolean, num: number, allNonEmbeddedSchemas: IJsonSchema[], fullJsonSchema: IEmbeddedJsonSchema) { @@ -102,9 +105,9 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.subject = { fname: 'John', lname: 'Smith' }; const cred = builder.sign(sk); - - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', lname: 'Smith' }); // The credential JSON should be valid as per the JSON schema @@ -188,8 +191,8 @@ describe(`${Scheme} Credential signing and verification`, () => { } }; const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', lname: 'Smith', @@ -237,8 +240,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.subject = { fname: 'John', isbool: true }; const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', isbool: true }); // The credential JSON should be valid as per the JSON schema @@ -294,8 +297,8 @@ describe(`${Scheme} Credential signing and verification`, () => { }; const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', lname: 'Smith', @@ -336,8 +339,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.subject = { fname: 'John', isDateTime: '2023-09-14T19:26:40.488Z' }; const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', isDateTime: '2023-09-14T19:26:40.488Z' }); // The credential JSON should be valid as per the JSON schema @@ -349,9 +352,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builderNegative.schema = credSchema; builderNegative.subject = { fname: 'John', isDateTime: '1800-09-14T19:26:40.488Z' }; const credNegative = builderNegative.sign(sk); - - checkResult(credNegative.verify(pk)); - const recreatedCredNegative = checkJsonConvForCred(credNegative, pk); + verifyCred(credNegative, pk, sk); + const recreatedCredNegative = checkJsonConvForCred(credNegative, sk, pk); expect(recreatedCredNegative.subject).toEqual({ fname: 'John', isDateTime: '1800-09-14T19:26:40.488Z' }); // The credential JSON fails to validate for an incorrect schema @@ -389,8 +391,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.subject = { fname: 'John', isDateTime: '2023-09-14' }; const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', isDateTime: '2023-09-14' }); // The credential JSON should be valid as per the JSON schema @@ -448,8 +450,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.setCredentialStatus('dock:accumulator:accumId123', MEM_CHECK_STR, 'user:A-123'); const cred = builder.sign(sk); - checkResult(cred.verify(pk)); - const recreatedCred = checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + const recreatedCred = checkJsonConvForCred(cred, sk, pk); expect(recreatedCred.subject).toEqual({ fname: 'John', lname: 'Smith', @@ -536,9 +538,8 @@ describe(`${Scheme} Credential signing and verification`, () => { builder.setTopLevelField('expirationDate', 1662011950934); const cred = builder.sign(sk); - - checkResult(cred.verify(pk)); - checkJsonConvForCred(cred, pk); + verifyCred(cred, pk, sk); + checkJsonConvForCred(cred, sk, pk); }); it('json-ld validation', async () => { diff --git a/tests/anonymous-credentials/delegated-proofs.spec.ts b/tests/anonymous-credentials/delegated-proofs.spec.ts new file mode 100644 index 00000000..383be5fa --- /dev/null +++ b/tests/anonymous-credentials/delegated-proofs.spec.ts @@ -0,0 +1,208 @@ +import { VerifyResult } from 'crypto-wasm-new'; +import { + AccumulatorPublicKey, + AccumulatorSecretKey, BDDT16Credential, BDDT16CredentialBuilder, CredentialSchema, ID_STR, + initializeWasm, MEM_CHECK_KV_STR, MEM_CHECK_STR, + PositiveAccumulator, PresentationBuilder, REV_CHECK_STR, RevocationStatusProtocol, SignatureType, TYPE_STR, + VBMembershipWitness +} from '../../src'; +import { BDDT16MacSecretKey } from '../../src/bddt16-mac'; +import { Credential, CredentialBuilder, isKvac, PublicKey, Scheme, SecretKey } from '../scheme'; +import { checkResult } from '../utils'; +import { getExampleSchema, getKeys, setupPrefilledAccum, verifyCred } from './utils'; + +describe(`Delegated proof verification with BDDT16 MAC and ${Scheme} signatures`, () => { + let sk: SecretKey, pk: PublicKey; + let skKvac: BDDT16MacSecretKey; + + let credential1: Credential; + let credential2: Credential; + let credential3: Credential; + let credential4: BDDT16Credential; + let credential5: BDDT16Credential; + + let accumulator1: PositiveAccumulator; + let accumulator1Pk: AccumulatorPublicKey; + let accumulator1Witness: VBMembershipWitness; + + let accumulator2: PositiveAccumulator; + let accumulator2Sk: AccumulatorSecretKey; + let accumulator2Witness: VBMembershipWitness; + + beforeAll(async () => { + await initializeWasm(); + + [sk, pk] = getKeys('seed1'); + skKvac = BDDT16MacSecretKey.generate(); + + const schema = new CredentialSchema(getExampleSchema(5)); + const subject = { + fname: 'John', + lname: 'Smith', + sensitive: { + very: { + secret: 'my-secret-that-wont-tell-anyone' + }, + email: 'john.smith@acme.com', + phone: '801009801', + SSN: '123-456789-0' + }, + lessSensitive: { + location: { + country: 'USA', + city: 'New York' + }, + department: { + name: 'Random', + location: { + name: 'Somewhere', + geo: { + lat: -23.658, + long: 2.556 + } + } + } + }, + rank: 6 + }; + + const builder1 = new CredentialBuilder(); + builder1.schema = schema; + builder1.subject = subject; + builder1.setCredentialStatus('dock:accumulator:accumId123', MEM_CHECK_STR, 'user:A-123'); + credential1 = builder1.sign(sk); + verifyCred(credential1, pk, sk); + + const builder2 = new CredentialBuilder(); + builder2.schema = schema; + builder2.subject = subject; + builder2.setCredentialStatus('dock:accumulator:accumId124', MEM_CHECK_KV_STR, 'user:A-124'); + credential2 = builder2.sign(sk); + verifyCred(credential2, pk, sk); + + const builder3 = new CredentialBuilder(); + builder3.schema = new CredentialSchema(getExampleSchema(9)); + builder3.subject = { + fname: 'John', + lname: 'Smith', + email: 'john.smith@example.com', + SSN: '123-456789-0', + userId: 'user:123-xyz-#', + country: 'USA', + city: 'New York', + timeOfBirth: 1662010849619, + height: 181.5, + weight: 210.4, + BMI: 23.25, + score: -13.5, + secret: 'my-secret-that-wont-tell-anyone' + }; + credential3 = builder3.sign(sk); + verifyCred(credential3, pk, sk); + + const builder4 = new BDDT16CredentialBuilder(); + builder4.schema = schema; + builder4.subject = subject; + builder4.setCredentialStatus('dock:accumulator:accumId123', MEM_CHECK_STR, 'user:A-123'); + // @ts-ignore + credential4 = builder4.sign(skKvac); + verifyCred(credential4, undefined, skKvac); + + const builder5 = new BDDT16CredentialBuilder(); + builder5.schema = schema; + builder5.subject = subject; + builder5.setCredentialStatus('dock:accumulator:accumId124', MEM_CHECK_KV_STR, 'user:A-124'); + // @ts-ignore + credential5 = builder5.sign(skKvac); + verifyCred(credential5, undefined, skKvac); + + // @ts-ignore + [, accumulator1Pk, accumulator1, accumulator1Witness] = await setupPrefilledAccum(200, 122, 'user:A-', schema); + + // @ts-ignore + [accumulator2Sk, , accumulator2, accumulator2Witness] = await setupPrefilledAccum(200, 123, 'user:A-', schema); + }); + + it('works', () => { + const builder = new PresentationBuilder(); + + expect(builder.addCredential(credential1, pk)).toEqual(0); + expect(builder.addCredential(credential2, pk)).toEqual(1); + expect(builder.addCredential(credential3, pk)).toEqual(2); + expect(builder.addCredential(credential4)).toEqual(3); + expect(builder.addCredential(credential5)).toEqual(4); + builder.addAccumInfoForCredStatus(0, accumulator1Witness, accumulator1.accumulated, accumulator1Pk, { + blockNo: 2010334 + }); + builder.addAccumInfoForCredStatus(1, accumulator2Witness, accumulator2.accumulated, undefined, { + blockNo: 2010335 + }); + builder.addAccumInfoForCredStatus(3, accumulator1Witness, accumulator1.accumulated, accumulator1Pk, { + blockNo: 2010336 + }); + builder.addAccumInfoForCredStatus(4, accumulator2Witness, accumulator2.accumulated, undefined, { + blockNo: 2010337 + }); + + const pres = builder.finalize(); + + const pks = new Map(); + pks.set(0, pk); + pks.set(1, pk); + pks.set(2, pk); + const accumPks = new Map(); + accumPks.set(0, accumulator1Pk); + accumPks.set(3, accumulator1Pk); + + checkResult(pres.verify(pks, accumPks)); + + pks.set(3, skKvac); + pks.set(4, skKvac); + accumPks.set(1, accumulator2Sk); + accumPks.set(4, accumulator2Sk); + checkResult(pres.verify(pks, accumPks)); + + const delegatedProofs = pres.getDelegatedProofs(); + + expect(delegatedProofs.size).toEqual(isKvac() ? 5 : 3); + if (isKvac()) { + for (let j = 0; j < 3; j++) { + const delgCredProof = delegatedProofs.get(j); + expect(delgCredProof?.credential).toMatchObject({ + sigType: SignatureType.Bddt16 + }); + checkResult(delgCredProof?.credential?.proof.verify(sk) as VerifyResult); + } + } + + const delgCredProof2 = delegatedProofs.get(1); + if (!isKvac()) { + expect(delgCredProof2?.credential).not.toBeDefined(); + } + expect(delgCredProof2?.status).toMatchObject({ + [ID_STR]: 'dock:accumulator:accumId124', + [TYPE_STR]: RevocationStatusProtocol.Vb22, + [REV_CHECK_STR]: MEM_CHECK_KV_STR + }); + checkResult(delgCredProof2?.status?.proof.verify(accumulator2Sk) as VerifyResult); + + const delgCredProof4 = delegatedProofs.get(3); + expect(delgCredProof4?.credential).toMatchObject({ + sigType: SignatureType.Bddt16 + }); + checkResult(delgCredProof4?.credential?.proof.verify(skKvac) as VerifyResult); + expect(delgCredProof4?.status).not.toBeDefined(); + + const delgCredProof5 = delegatedProofs.get(4); + expect(delgCredProof5?.credential).toMatchObject({ + sigType: SignatureType.Bddt16 + }); + checkResult(delgCredProof5?.credential?.proof.verify(skKvac) as VerifyResult); + expect(delgCredProof5?.status).toMatchObject({ + [ID_STR]: 'dock:accumulator:accumId124', + [TYPE_STR]: RevocationStatusProtocol.Vb22, + [REV_CHECK_STR]: MEM_CHECK_KV_STR + }); + checkResult(delgCredProof5?.status?.proof.verify(accumulator2Sk) as VerifyResult); + }) +}) \ No newline at end of file diff --git a/tests/anonymous-credentials/presentation-circom.spec.ts b/tests/anonymous-credentials/presentation-circom.spec.ts index da288762..43bad9f6 100644 --- a/tests/anonymous-credentials/presentation-circom.spec.ts +++ b/tests/anonymous-credentials/presentation-circom.spec.ts @@ -1,27 +1,18 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CredentialSchema, - ParsedR1CSFile, - R1CSSnarkSetup, + DefaultSchemaParsingOpts, getR1CS, + initializeWasm, META_SCHEMA_STR, - DefaultSchemaParsingOpts, + ParsedR1CSFile, + R1CSSnarkSetup, SUBJECT_STR } from '../../src'; -import { - SignatureParams, - KeyPair, - SecretKey, - PublicKey, - CredentialBuilder, - Credential, - PresentationBuilder, - SignatureLabelBytes, - Scheme -} from '../scheme'; - -import { checkPresentationJson, getExampleSchema } from './utils'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../utils'; +import { Credential, CredentialBuilder, PresentationBuilder, PublicKey, Scheme, SecretKey } from '../scheme'; + +import { checkPresentationJson, getExampleSchema, getKeys, verifyCred } from './utils'; +import { checkResult, getWasmBytes, parseR1CSFile } from '../utils'; describe.each([true, false])( `${Scheme} Presentation creation and verification with Circom predicates with withSchemaRef=%s`, @@ -53,10 +44,7 @@ describe.each([true, false])( beforeAll(async () => { await initializeWasm(); - const params = SignatureParams.generate(100, SignatureLabelBytes); - const keypair = KeyPair.generate(params, stringToBytes('seed1')); - sk = keypair.sk; - pk = keypair.pk; + [sk, pk] = getKeys('seed1'); let credSchema1: CredentialSchema, credSchema2: CredentialSchema; const schema1 = getExampleSchema(12); @@ -377,7 +365,7 @@ describe.each([true, false])( }; expect(builder.subject.amount).toBeLessThan(maxAmount); credentials.push(builder.sign(sk)); - checkResult(credentials[i].verify(pk)); + verifyCred(credentials[i], pk, sk); } const builder = new PresentationBuilder(); @@ -499,7 +487,7 @@ describe.each([true, false])( }; expect(builder.subject.salary.amount).toBeLessThan(maxSalary); credentials.push(builder.sign(sk)); - checkResult(credentials[i].verify(pk)); + verifyCred(credentials[i], pk, sk); } const builder = new PresentationBuilder(); @@ -612,7 +600,7 @@ describe.each([true, false])( } }; assetCreds.push(builder.sign(sk)); - checkResult(assetCreds[i].verify(pk)); + verifyCred(assetCreds[i], pk, sk); } const liabCreds: Credential[] = []; @@ -631,7 +619,7 @@ describe.each([true, false])( } }; liabCreds.push(builder.sign(sk)); - checkResult(liabCreds[i].verify(pk)); + verifyCred(liabCreds[i], pk, sk); } const builder = new PresentationBuilder(); diff --git a/tests/anonymous-credentials/presentation-multiple-bounds-and-ve.spec.ts b/tests/anonymous-credentials/presentation-multiple-bounds-and-ve.spec.ts index 6fae8826..d305739d 100644 --- a/tests/anonymous-credentials/presentation-multiple-bounds-and-ve.spec.ts +++ b/tests/anonymous-credentials/presentation-multiple-bounds-and-ve.spec.ts @@ -1,6 +1,6 @@ import { Credential, - CredentialBuilder, + CredentialBuilder, isKvac, KeyPair, PresentationBuilder, PublicKey, @@ -10,6 +10,7 @@ import { SignatureParams } from '../scheme'; import { + initializeWasm, BoundCheckProtocol, CredentialSchema, dockSaverEncryptionGens, @@ -26,8 +27,8 @@ import { VerifiableEncryptionProtocol } from '../../src'; import { checkResult, getBoundCheckSnarkKeys, readByteArrayFromFile, stringToBytes } from '../utils'; -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkCiphertext, checkPresentationJson } from './utils'; +import { checkCiphertext, checkPresentationJson, getKeys, verifyCred } from './utils'; +import { BDDT16MacSecretKey } from '../../src/bddt16-mac'; // Setting it to false will make the test run the SNARK setups making tests quite slow const loadSnarkSetupFromFiles = true; @@ -83,10 +84,7 @@ describe(`${Scheme} Presentation creation and verification`, () => { beforeAll(async () => { await initializeWasm(); - const params = SignatureParams.generate(100, SignatureLabelBytes); - const keypair = KeyPair.generate(params, stringToBytes('seed1')); - sk = keypair.sk; - pk = keypair.pk; + [sk, pk] = getKeys('seed1'); const schema = CredentialSchema.essential(); const subjectItem = { @@ -148,7 +146,7 @@ describe(`${Scheme} Presentation creation and verification`, () => { } ]; credential = builder.sign(sk); - checkResult(credential.verify(pk)); + verifyCred(credential, pk, sk); }); it('with proving multiple bounds on a single attribute', () => { diff --git a/tests/anonymous-credentials/presentation-multiple-sig-types.spec.ts b/tests/anonymous-credentials/presentation-multiple-sig-types.spec.ts index 11b54eda..b789d642 100644 --- a/tests/anonymous-credentials/presentation-multiple-sig-types.spec.ts +++ b/tests/anonymous-credentials/presentation-multiple-sig-types.spec.ts @@ -1,5 +1,5 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { + initializeWasm, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, BBS_SIGNATURE_PARAMS_LABEL_BYTES, BBSCredential, @@ -25,11 +25,13 @@ import { PSKeypair, PSPublicKey, PSSecretKey, - PSSignatureParams, SignatureType + PSSignatureParams, SignatureType, BDDT16Credential, BDDT16_MAC_PARAMS_LABEL_BYTES, BDDT16CredentialBuilder } from '../../src'; import { checkResult, stringToBytes } from '../utils'; import { checkPresentationJson, getExampleSchema } from './utils'; import { PederCommKey } from '../../src/ped-com'; +import { BDDT16MacParams, BDDT16MacSecretKey } from '../../src/bddt16-mac'; +import { isKvac } from '../scheme'; describe.each([true, false])( `Presentation creation and verification with withSchemaRef=%s involving credentials with different signature schemes`, @@ -37,10 +39,12 @@ describe.each([true, false])( let skBbs: BBSSecretKey, pkBbs: BBSPublicKey; let skBbsPlus: BBSPlusSecretKey, pkBbsPlus: BBSPlusPublicKeyG2; let skPs: PSSecretKey, pkPs: PSPublicKey; + let skBddt16: BDDT16MacSecretKey; let credentialBbs: BBSCredential; let credentialBbsPlus: BBSPlusCredential; let credentialPs: PSCredential; + let credentialBddt16: BDDT16Credential; const nonEmbeddedSchema = { $id: 'https://example.com?hash=abc123ff', @@ -56,6 +60,7 @@ describe.each([true, false])( const keypairBbs = BBSKeypair.generate(paramsBbs, stringToBytes('seed1')); const keypairBbsPlus = BBSPlusKeypairG2.generate(paramsBbsPlus, stringToBytes('seed2')); const keypairPs = PSKeypair.generate(paramsPs, stringToBytes('seed3')); + skBddt16 = BDDT16MacSecretKey.generate(stringToBytes('seed4')); skBbs = keypairBbs.sk; pkBbs = keypairBbs.pk; skBbsPlus = keypairBbsPlus.sk; @@ -66,7 +71,8 @@ describe.each([true, false])( for (const [credBuilder, sk, pk] of [ [BBSCredentialBuilder, skBbs, pkBbs], [BBSPlusCredentialBuilder, skBbsPlus, pkBbsPlus], - [PSCredentialBuilder, skPs, pkPs] + [PSCredentialBuilder, skPs, pkPs], + [BDDT16CredentialBuilder, skBddt16, undefined] ]) { const schema = getExampleSchema(11); // @ts-ignore @@ -99,7 +105,11 @@ describe.each([true, false])( score: -13.5 }; const credential = builder.sign(sk); - checkResult(credential.verify(pk)); + if (!(sk instanceof BDDT16MacSecretKey)) { + checkResult(credential.verify(pk)); + } else { + checkResult(credential.verifyUsingSecretKey(sk)); + } if (sk instanceof BBSSecretKey) { credentialBbs = credential; } @@ -109,6 +119,9 @@ describe.each([true, false])( if (sk instanceof PSSecretKey) { credentialPs = credential; } + if (sk instanceof BDDT16MacSecretKey) { + credentialBddt16 = credential; + } } }); @@ -120,34 +133,40 @@ describe.each([true, false])( expect(builder.addCredential(credentialBbs, pkBbs)).toEqual(0); expect(builder.addCredential(credentialBbsPlus, pkBbsPlus)).toEqual(1); expect(builder.addCredential(credentialPs, pkPs)).toEqual(2); + expect(builder.addCredential(credentialBddt16)).toEqual(3); builder.markAttributesRevealed(0, new Set(['credentialSubject.fname', 'credentialSubject.lname'])); builder.markAttributesRevealed(1, new Set(['credentialSubject.isbool'])); builder.markAttributesRevealed(2, new Set(['credentialSubject.location.city'])); + builder.markAttributesRevealed(3, new Set(['credentialSubject.location.country'])); builder.markAttributesEqual( [0, 'credentialSubject.sensitive.SSN'], [1, 'credentialSubject.sensitive.SSN'], - [2, 'credentialSubject.sensitive.SSN'] + [2, 'credentialSubject.sensitive.SSN'], + [3, 'credentialSubject.sensitive.SSN'] ); builder.markAttributesEqual( [0, 'credentialSubject.sensitive.email'], [1, 'credentialSubject.sensitive.email'], - [2, 'credentialSubject.sensitive.email'] + [2, 'credentialSubject.sensitive.email'], + [3, 'credentialSubject.sensitive.email'] ); const inEqualEmail = 'alice@example.com'; builder.enforceAttributeInequality(0, 'credentialSubject.sensitive.email', inEqualEmail, commKeyId, commKey); builder.enforceAttributeInequality(1, 'credentialSubject.sensitive.email', inEqualEmail, commKeyId); builder.enforceAttributeInequality(2, 'credentialSubject.sensitive.email', inEqualEmail, commKeyId); + builder.enforceAttributeInequality(3, 'credentialSubject.sensitive.email', inEqualEmail, commKeyId); const pres = builder.finalize(); - expect(pres.spec.credentials.length).toEqual(3); + expect(pres.spec.credentials.length).toEqual(4); expect(pres.spec.credentials[0].sigType).toEqual(SignatureType.Bbs); expect(pres.spec.credentials[1].sigType).toEqual(SignatureType.BbsPlus); expect(pres.spec.credentials[2].sigType).toEqual(SignatureType.Ps); + expect(pres.spec.credentials[3].sigType).toEqual(SignatureType.Bddt16); expect(pres.spec.credentials[0].revealedAttributes).toEqual({ credentialSubject: { @@ -165,8 +184,13 @@ describe.each([true, false])( location: { city: 'New York' } } }); + expect(pres.spec.credentials[3].revealedAttributes).toEqual({ + credentialSubject: { + location: { country: 'USA' } + } + }); - for (let i = 0; i < 3; i++) { + for (let i = 0; i < 4; i++) { expect(pres.spec.credentials[i].attributeInequalities).toEqual({ credentialSubject: { sensitive: { @@ -178,8 +202,17 @@ describe.each([true, false])( const pp = new Map(); pp.set(commKeyId, commKey); - checkResult(pres.verify([pkBbs, pkBbsPlus, pkPs], undefined, pp)); - checkPresentationJson(pres, [pkBbs, pkBbsPlus, pkPs], undefined, pp); + + const pks = new Map(); + pks.set(0, pkBbs); + pks.set(1, pkBbsPlus); + pks.set(2, pkPs); + checkResult(pres.verify(pks, undefined, pp)); + checkPresentationJson(pres, pks, undefined, pp); + + pks.set(3, skBddt16); + checkResult(pres.verify(pks, undefined, pp)); + checkPresentationJson(pres, pks, undefined, pp); }); } ); diff --git a/tests/anonymous-credentials/presentation.spec.ts b/tests/anonymous-credentials/presentation.spec.ts index 54b0414a..f6c68512 100644 --- a/tests/anonymous-credentials/presentation.spec.ts +++ b/tests/anonymous-credentials/presentation.spec.ts @@ -1,4 +1,5 @@ import { + initializeWasm, AccumulatorPublicKey, CredentialSchema, dockAccumulatorParams, @@ -6,7 +7,7 @@ import { LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MEM_CHECK_STR, - MembershipWitness, + VBMembershipWitness, PositiveAccumulator, Pseudonym, PseudonymBases, @@ -34,9 +35,9 @@ import { BoundCheckSmcWithKVSetup, META_SCHEMA_STR, DefaultSchemaParsingOpts, - InequalityProtocol, BoundCheckParamType + InequalityProtocol, BoundCheckParamType, AccumulatorSecretKey, MEM_CHECK_KV_STR } from '../../src'; -import { generateRandomFieldElement, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateRandomFieldElement } from 'crypto-wasm-new'; import { areUint8ArraysEqual, checkResult, @@ -51,19 +52,16 @@ import { checkSchemaFromJson, getDecodedBoundedPseudonym, getExampleBuilder, - getExampleSchema, - prefillAccumulator + getExampleSchema, getKeys, + prefillAccumulator, setupPrefilledAccum, verifyCred } from './utils'; import { Credential, CredentialBuilder, - KeyPair, PresentationBuilder, Scheme, PublicKey, - SecretKey, - SignatureLabelBytes, - SignatureParams + SecretKey, isKvac } from '../scheme'; // Setting it to false will make the test run the SNARK setups making tests quite slow @@ -89,12 +87,14 @@ describe.each([true, false])( const scope1 = stringToBytes('Service provider 1'); let accumulator3: PositiveAccumulator; + let accumulator3Sk: AccumulatorSecretKey; let accumulator3Pk: AccumulatorPublicKey; - let accumulator3Witness: MembershipWitness; + let accumulator3Witness: VBMembershipWitness; let accumulator4: PositiveAccumulator; + let accumulator4Sk: AccumulatorSecretKey; let accumulator4Pk: AccumulatorPublicKey; - let accumulator4Witness: MembershipWitness; + let accumulator4Witness: VBMembershipWitness; let boundCheckProvingKey: LegoProvingKeyUncompressed; let boundCheckVerifyingKey: LegoVerifyingKeyUncompressed; @@ -177,19 +177,10 @@ describe.each([true, false])( beforeAll(async () => { await initializeWasm(); - const params = SignatureParams.generate(100, SignatureLabelBytes); - const keypair1 = KeyPair.generate(params, stringToBytes('seed1')); - const keypair2 = KeyPair.generate(params, stringToBytes('seed2')); - const keypair3 = KeyPair.generate(params, stringToBytes('seed3')); - const keypair4 = KeyPair.generate(params); - sk1 = keypair1.sk; - pk1 = keypair1.pk; - sk2 = keypair2.sk; - pk2 = keypair2.pk; - sk3 = keypair3.sk; - pk3 = keypair3.pk; - sk4 = keypair4.sk; - pk4 = keypair4.pk; + [sk1, pk1] = getKeys('seed1'); + [sk2, pk2] = getKeys('seed2'); + [sk3, pk3] = getKeys('seed3'); + [sk4, pk4] = getKeys(); const schema1 = getExampleSchema(9); const builder1 = new CredentialBuilder(); @@ -214,7 +205,7 @@ describe.each([true, false])( secret: 'my-secret-that-wont-tell-anyone' }; credential1 = builder1.sign(sk1); - checkResult(credential1.verify(pk1)); + verifyCred(credential1, pk1, sk1); const schema2 = getExampleSchema(11); const builder2 = new CredentialBuilder(); @@ -246,7 +237,7 @@ describe.each([true, false])( score: -13.5 }; credential2 = builder2.sign(sk2); - checkResult(credential2.verify(pk2)); + verifyCred(credential2, pk2, sk2); const schema3 = getExampleSchema(5); let credSchema3: CredentialSchema; @@ -288,36 +279,11 @@ describe.each([true, false])( }; builder3.setCredentialStatus('dock:accumulator:accumId123', MEM_CHECK_STR, 'user:A-123'); credential3 = builder3.sign(sk3); - checkResult(credential3.verify(pk3)); + verifyCred(credential3, pk3, sk3); const seed = stringToBytes('secret-seed-for-accum'); - const accumKeypair3 = PositiveAccumulator.generateKeypair(dockAccumulatorParams(), seed); - accumulator3Pk = accumKeypair3.publicKey; - accumulator3 = PositiveAccumulator.initialize(dockAccumulatorParams()); - const accumState3 = new InMemoryState(); - const allMembers3 = await prefillAccumulator( - accumulator3, - accumKeypair3.secretKey, - accumState3, - credSchema3, - 'user:A-', - `${STATUS_STR}.${REV_ID_STR}`, - 200 - ); - accumulator3Witness = await accumulator3.membershipWitness( - allMembers3[122], - accumKeypair3.secretKey, - accumState3 - ); - let verifAccumulator3 = PositiveAccumulator.fromAccumulated(accumulator3.accumulated); - expect( - verifAccumulator3.verifyMembershipWitness( - allMembers3[122], - accumulator3Witness, - accumulator3Pk, - dockAccumulatorParams() - ) - ).toEqual(true); + // @ts-ignore + [accumulator3Sk, accumulator3Pk, accumulator3, accumulator3Witness] = await setupPrefilledAccum(200, 122, 'user:A-', credSchema3, seed); const schema4 = getExampleSchema(10); @@ -357,35 +323,10 @@ describe.each([true, false])( }; builder4.setCredentialStatus('dock:accumulator:accumId124', MEM_CHECK_STR, 'tran:2022-YZ4-250'); credential4 = builder4.sign(sk4); - checkResult(credential4.verify(pk4)); - - const accumKeypair4 = PositiveAccumulator.generateKeypair(dockAccumulatorParams()); - accumulator4Pk = accumKeypair4.publicKey; - accumulator4 = PositiveAccumulator.initialize(dockAccumulatorParams()); - const accumState4 = new InMemoryState(); - const allMembers4 = await prefillAccumulator( - accumulator4, - accumKeypair4.secretKey, - accumState4, - credSchema4, - 'tran:2022-YZ4-', - `${STATUS_STR}.${REV_ID_STR}`, - 300 - ); - accumulator4Witness = await accumulator4.membershipWitness( - allMembers4[249], - accumKeypair4.secretKey, - accumState4 - ); - const verifAccumulator4 = PositiveAccumulator.fromAccumulated(accumulator4.accumulated); - expect( - verifAccumulator4.verifyMembershipWitness( - allMembers4[249], - accumulator4Witness, - accumulator4Pk, - dockAccumulatorParams() - ) - ).toEqual(true); + verifyCred(credential4, pk4, sk4); + + // @ts-ignore + [accumulator4Sk, accumulator4Pk, accumulator4, accumulator4Witness] = await setupPrefilledAccum(300, 249, 'tran:2022-YZ4-', credSchema4); const schema5 = CredentialSchema.essential(); const subjectItem = { @@ -451,7 +392,7 @@ describe.each([true, false])( } ]; credential5 = builder5.sign(sk1); - checkResult(credential5.verify(pk1)); + verifyCred(credential5, pk1, sk1); const schema6 = CredentialSchema.essential(); const subjectItem2 = { @@ -534,7 +475,7 @@ describe.each([true, false])( builder6.setTopLevelField('issuanceDate', 1662010849700); builder6.setTopLevelField('expirationDate', 1662011950934); credential6 = builder6.sign(sk1); - checkResult(credential6.verify(pk1)); + verifyCred(credential6, pk1, sk1); // Schema with date type const schema7 = CredentialSchema.essential(); @@ -563,7 +504,7 @@ describe.each([true, false])( builder7.setTopLevelField('issuanceDate', 1694719600488); builder7.setTopLevelField('expirationDate', 1994719600488); credential7 = builder7.sign(sk1); - checkResult(credential7.verify(pk1)); + verifyCred(credential7, pk1, sk1); }); it('from a flat credential - `credential1`', () => { @@ -665,15 +606,15 @@ describe.each([true, false])( function check(credBuilder: CredentialBuilder, sk: SecretKey, pk: PublicKey) { const credential = credBuilder.sign(sk, undefined, { requireSameFieldsAsSchema: false }); - checkResult(credential.verify(pk1)); + verifyCred(credential, pk, sk); const builder7 = new PresentationBuilder(); expect(builder7.addCredential(credential, pk)).toEqual(0); const pres7 = builder7.finalize(); expect(pres7.spec.credentials.length).toEqual(1); - checkResult(pres7.verify([pk1])); + checkResult(pres7.verify([pk])); - checkPresentationJson(pres7, [pk1]); + checkPresentationJson(pres7, [pk]); } }); @@ -796,7 +737,7 @@ describe.each([true, false])( expect(pres3.spec.getStatus(0)).toEqual({ id: 'dock:accumulator:accumId123', [TYPE_STR]: VB_ACCUMULATOR_22, - revocationCheck: 'membership', + revocationCheck: MEM_CHECK_STR, accumulated: accumulator3.accumulated, extra: { blockNo: 2010334 } }); @@ -851,8 +792,10 @@ describe.each([true, false])( } }); - // Public keys in wrong order - expect(pres4.verify([pk2, pk1]).verified).toEqual(false); + if (!isKvac()) { + // Public keys in wrong order + expect(pres4.verify([pk2, pk1]).verified).toEqual(false); + } checkResult(pres4.verify([pk1, pk2])); @@ -918,14 +861,14 @@ describe.each([true, false])( expect(pres5.spec.getStatus(0)).toEqual({ id: 'dock:accumulator:accumId123', [TYPE_STR]: VB_ACCUMULATOR_22, - revocationCheck: 'membership', + revocationCheck: MEM_CHECK_STR, accumulated: accumulator3.accumulated, extra: { blockNo: 2010334 } }); expect(pres5.spec.getStatus(1)).toEqual({ id: 'dock:accumulator:accumId124', [TYPE_STR]: VB_ACCUMULATOR_22, - revocationCheck: 'membership', + revocationCheck: MEM_CHECK_STR, accumulated: accumulator4.accumulated, extra: { blockNo: 2010340 } }); @@ -1022,14 +965,14 @@ describe.each([true, false])( expect(pres6.spec.getStatus(2)).toEqual({ id: 'dock:accumulator:accumId123', [TYPE_STR]: VB_ACCUMULATOR_22, - revocationCheck: 'membership', + revocationCheck: MEM_CHECK_STR, accumulated: accumulator3.accumulated, extra: { blockNo: 2010334 } }); expect(pres6.spec.getStatus(3)).toEqual({ id: 'dock:accumulator:accumId124', [TYPE_STR]: VB_ACCUMULATOR_22, - revocationCheck: 'membership', + revocationCheck: MEM_CHECK_STR, accumulated: accumulator4.accumulated, extra: { blockNo: 2010340 } }); @@ -2120,5 +2063,96 @@ describe.each([true, false])( checkPresentationJson(pres2, [pk1], undefined, pp); }); + + it('from credential with status with keyed verification', () => { + const schema = getExampleSchema(5); + let credSchema: CredentialSchema; + if (withSchemaRef) { + credSchema = new CredentialSchema(nonEmbeddedSchema, DefaultSchemaParsingOpts, true, undefined, schema); + } else { + credSchema = new CredentialSchema(schema); + } + const credBuilder = new CredentialBuilder(); + credBuilder.schema = credSchema; + credBuilder.subject = { + fname: 'John', + lname: 'Smith', + sensitive: { + very: { + secret: 'my-secret-that-wont-tell-anyone' + }, + email: 'john.smith@acme.com', + phone: '801009801', + SSN: '123-456789-0' + }, + lessSensitive: { + location: { + country: 'USA', + city: 'New York' + }, + department: { + name: 'Random', + location: { + name: 'Somewhere', + geo: { + lat: -23.658, + long: 2.556 + } + } + } + }, + rank: 6 + }; + credBuilder.setCredentialStatus('dock:accumulator:accumId123', MEM_CHECK_KV_STR, 'user:A-123'); + const credential = credBuilder.sign(sk3); + verifyCred(credential, pk3, sk3); + + const presBuilder = new PresentationBuilder(); + expect(presBuilder.addCredential(credential, pk3)).toEqual(0); + presBuilder.markAttributesRevealed( + 0, + new Set([ + 'credentialSubject.fname', + 'credentialSubject.lessSensitive.location.country', + 'credentialSubject.lessSensitive.department.location.name' + ]) + ); + presBuilder.addAccumInfoForCredStatus(0, accumulator3Witness, accumulator3.accumulated, undefined, { + blockNo: 2010334 + }); + const pres = presBuilder.finalize(); + + expect(pres.spec.credentials[0].revealedAttributes).toEqual({ + credentialSubject: { + fname: 'John', + lessSensitive: { location: { country: 'USA' }, department: { location: { name: 'Somewhere' } } } + } + }); + // This check is made by the verifier, i.e. verifier checks that the accumulator id, type, value and timestamp (`blockNo`) + // are as expected + expect(pres.spec.getStatus(0)).toEqual({ + id: 'dock:accumulator:accumId123', + [TYPE_STR]: VB_ACCUMULATOR_22, + revocationCheck: MEM_CHECK_KV_STR, + accumulated: accumulator3.accumulated, + extra: { blockNo: 2010334 } + }); + + checkResult(pres.verify([pk3])); + + const presJson = pres.toJSON(); + + // The schema of the credential in the presentation matches the JSON-schema + // @ts-ignore + checkSchemaFromJson(presJson.spec.credentials[0].schema, credential.schema); + + checkPresentationJson(pres, [pk3]); + + // Verifier passes the accumulator public key for verification + const acc = new Map(); + acc.set(0, accumulator3Sk); + checkResult(pres.verify([pk3], acc)); + checkPresentationJson(pres, [pk3], acc); + }) } ); diff --git a/tests/anonymous-credentials/schema.spec.ts b/tests/anonymous-credentials/schema.spec.ts index 941ec94e..13e1febe 100644 --- a/tests/anonymous-credentials/schema.spec.ts +++ b/tests/anonymous-credentials/schema.spec.ts @@ -1,5 +1,5 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { + initializeWasm, CRYPTO_VERSION_STR, CredentialSchema, DefaultSchemaParsingOpts, diff --git a/tests/anonymous-credentials/serialized-credential.spec.ts b/tests/anonymous-credentials/serialized-credential.spec.ts index 9de531d7..dfa7e4a8 100644 --- a/tests/anonymous-credentials/serialized-credential.spec.ts +++ b/tests/anonymous-credentials/serialized-credential.spec.ts @@ -1,8 +1,8 @@ import * as fs from 'fs'; -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { Credential, PublicKey, Scheme } from '../scheme'; +import { Credential, isKvac, isPS, PublicKey, Scheme } from '../scheme'; import { checkResult } from '../utils'; +import {initializeWasm} from '../../src'; describe(`${Scheme} Credential creation and verification from JSON`, () => { const fileNamePrefix = Scheme.toLowerCase(); @@ -25,11 +25,13 @@ describe(`${Scheme} Credential creation and verification from JSON`, () => { } } - it('check version 0.0.2', () => { + const skipIfKvac = isKvac() ? it.skip : it; + + skipIfKvac('check version 0.0.2', () => { check('0.0.2', '0.0.1'); }) - it('check version 0.4.0', () => { + skipIfKvac('check version 0.4.0', () => { check('0.4.0', '0.2.0'); }) }) \ No newline at end of file diff --git a/tests/anonymous-credentials/serialized-presentation.spec.ts b/tests/anonymous-credentials/serialized-presentation.spec.ts index 0493f96a..36c5a204 100644 --- a/tests/anonymous-credentials/serialized-presentation.spec.ts +++ b/tests/anonymous-credentials/serialized-presentation.spec.ts @@ -1,11 +1,12 @@ import * as fs from 'fs'; -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { Credential, Presentation, PresentationBuilder, PublicKey, Scheme } from '../scheme'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; +import { Credential, isKvac, Presentation, PresentationBuilder, PublicKey, Scheme } from '../scheme'; import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../utils'; import { checkCiphertext } from './utils'; import { AccumulatorPublicKey, getR1CS, + initializeWasm, LegoVerifyingKeyUncompressed, SaverChunkedCommitmentKey, SaverDecryptionKeyUncompressed, @@ -18,6 +19,8 @@ describe(`${Scheme} Presentation creation and verification from JSON`, () => { const fileNamePrefix = Scheme.toLowerCase(); const chunkBitSize = 16; + const skipIfKvac = isKvac() ? it.skip : it; + beforeAll(async () => { await initializeWasm(); }); @@ -153,20 +156,20 @@ describe(`${Scheme} Presentation creation and verification from JSON`, () => { expect(pres2Json).toEqual(pres2.toJSON()); } - it('check version 0.1.0', () => { + skipIfKvac('check version 0.1.0', () => { check('0.0.2', '0.1.0', 'bound-check-legogroth16-vk'); }); - it('check version 0.1.0 with circom predicates', async () => { + skipIfKvac('check version 0.1.0 with circom predicates', async () => { await checkCircom('0.1.0', 'circom-set_membership_5_public-vk'); }); - it('check version 0.4.0', () => { + skipIfKvac('check version 0.4.0', () => { // Legosnark keys changed due type of certain values changed from `u64` to `u32` check('0.4.0', '0.4.0', 'bound-check-legogroth16-vk2'); }); - it('check version 0.4.0 with circom predicates', async () => { + skipIfKvac('check version 0.4.0 with circom predicates', async () => { await checkCircom('0.4.0', 'circom-set_membership_5_public-2-vk'); }); }); diff --git a/tests/anonymous-credentials/serialized-schema.spec.ts b/tests/anonymous-credentials/serialized-schema.spec.ts index 48f11c11..272027e9 100644 --- a/tests/anonymous-credentials/serialized-schema.spec.ts +++ b/tests/anonymous-credentials/serialized-schema.spec.ts @@ -1,7 +1,6 @@ import * as fs from 'fs'; -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { CredentialSchema } from '../../src'; +import { initializeWasm, CredentialSchema } from '../../src'; describe('Credential Schema creation from JSON', () => { beforeAll(async () => { diff --git a/tests/anonymous-credentials/utils.ts b/tests/anonymous-credentials/utils.ts index 6a7a5e43..65099ff4 100644 --- a/tests/anonymous-credentials/utils.ts +++ b/tests/anonymous-credentials/utils.ts @@ -1,26 +1,39 @@ import { Accumulator, - AccumulatorSecretKey, - CredentialSchema, + AccumulatorPublicKey, + AccumulatorSecretKey, AccumulatorVerificationParam, + AttributeBoundPseudonym, + AttributeCiphertexts, BDDT16Credential, + CredentialSchema, CredentialVerificationParam, dockAccumulatorParams, dockSaverEncryptionGensUncompressed, IAccumulatorState, IEmbeddedJsonSchema, + IJsonSchema, PositiveAccumulator, + PredicateParamType, + PseudonymBases, REV_ID_STR, + SaverCiphertext, SaverDecryptor, SCHEMA_TYPE_STR, STATUS_STR, - SUBJECT_STR, - SaverCiphertext, - AttributeCiphertexts, - PseudonymBases, - AttributeBoundPseudonym, - AccumulatorPublicKey, - PredicateParamType, IJsonSchema + SUBJECT_STR } from '../../src'; -import { Credential, CredentialBuilder, Presentation, PublicKey } from '../scheme'; +import { + Credential, + CredentialBuilder, + isKvac, + KeyPair, + Presentation, + PublicKey, + SecretKey, + SignatureLabelBytes, + SignatureParams +} from '../scheme'; import * as _ from 'lodash'; -import { checkResult } from '../utils'; +import { checkResult, stringToBytes } from '../utils'; import fs from 'fs'; import { BytearrayWrapper } from '../../src/bytearray-wrapper'; +import { BDDT16MacParams, BDDT16MacSecretKey } from '../../src/bddt16-mac'; +import { InMemoryState } from '../../src/accumulator/in-memory-persistence'; export function getExampleSchema(num): IEmbeddedJsonSchema { const schema = CredentialSchema.essential(); @@ -655,8 +668,8 @@ export function getDecodedBoundedPseudonym( */ export function checkPresentationJson( pres: Presentation, - pks: PublicKey[], - accumulatorPublicKeys?: Map, + pks: Map | CredentialVerificationParam[], + accumulatorPublicKeys?: Map, predicateParams?: Map, circomOutputs?: Map, // TODO: Rename @@ -714,4 +727,51 @@ export function checkEmbeddedSchema(withSchemaRef: boolean, schema: CredentialSc expect(schema.jsonSchema).toEqual(fullJsonSchema); expect(schema.fullJsonSchema).not.toBeDefined(); } +} + +export function getKeys(seed?: string): [SecretKey, PublicKey] { + const params = SignatureParams.generate(100, SignatureLabelBytes); + const s = seed ? stringToBytes(seed) : undefined; + const isKvac = params instanceof BDDT16MacParams; + const keypair = !isKvac ? KeyPair.generate(params, s) : undefined; + const sk = !isKvac ? keypair.sk : BDDT16MacSecretKey.generate(s); + const pk = !isKvac ? keypair.pk : undefined; + return [sk, pk]; +} + +export function verifyCred(cred: Credential, pk: PublicKey, sk: SecretKey) { + const isKvac = cred instanceof BDDT16Credential; + checkResult(!isKvac ? cred.verify(pk) : cred.verifyUsingSecretKey(sk)); +} + +export async function setupPrefilledAccum(totalMembers: number, memberIdx: number, memberValPrefix: string, schema: CredentialSchema, seed?: Uint8Array) { + const kp = PositiveAccumulator.generateKeypair(dockAccumulatorParams(), seed); + const sk = kp.secretKey; + const pk = kp.publicKey; + const accumulator = PositiveAccumulator.initialize(dockAccumulatorParams()); + const state = new InMemoryState(); + const allMembers = await prefillAccumulator( + accumulator, + sk, + state, + schema, + memberValPrefix, + `${STATUS_STR}.${REV_ID_STR}`, + totalMembers + ); + const witness = await accumulator.membershipWitness( + allMembers[memberIdx], + kp.secretKey, + state + ); + const verifAccumulator = PositiveAccumulator.fromAccumulated(accumulator.accumulated); + expect( + verifAccumulator.verifyMembershipWitness( + allMembers[memberIdx], + witness, + pk, + dockAccumulatorParams() + ) + ).toEqual(true); + return [sk, pk, accumulator, witness] } \ No newline at end of file diff --git a/tests/bound-check.spec.ts b/tests/bound-check.spec.ts index e2001307..2c8fefd6 100644 --- a/tests/bound-check.spec.ts +++ b/tests/bound-check.spec.ts @@ -1,4 +1,5 @@ import { + initializeWasm, BoundCheckSnarkSetup, BoundCheckBppParams, BoundCheckBppParamsUncompressed, @@ -10,7 +11,6 @@ import { BoundCheckSmcWithKVVerifierParamsUncompressed, BoundCheckSmcWithKVVerifierParams } from '../src'; -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { areUint8ArraysEqual, checkLegoProvingKey, stringToBytes } from './utils'; describe('Bound check snark setup', () => { diff --git a/tests/composite-proofs/blind-signature.spec.ts b/tests/composite-proofs/blind-signature.spec.ts index beb83a57..3fa63f00 100644 --- a/tests/composite-proofs/blind-signature.spec.ts +++ b/tests/composite-proofs/blind-signature.spec.ts @@ -1,6 +1,5 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; -import { CompositeProofG1, MetaStatements, ProofSpecG1, Statements, Witness, Witnesses } from '../../src'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../utils'; +import { initializeWasm, CompositeProof, MetaStatements, ProofSpec, Statements, Witnesses } from '../../src'; import { BlindSignature, KeyPair, @@ -11,9 +10,9 @@ import { encodeMessageForSigningIfPS, isPS, encodeMessageForSigningIfNotPS, - Scheme + Scheme, isBBS, isKvac } from '../scheme'; -import { generateRandomG1Element } from '@docknetwork/crypto-wasm'; +import { generateRandomG1Element } from 'crypto-wasm-new'; describe(`${Scheme} Getting a blind signature, i.e. signature where signer is not aware of certain attributes of the user`, () => { it('works', async () => { @@ -24,12 +23,9 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no const messageCount = 5; const label = stringToBytes('My sig params in g1'); - const params = SignatureParams.generate(messageCount, label); // Signers keys - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - const pk = keypair.publicKey; + const [params, sk, pk] = getParamsAndKeys(messageCount, label); const h = generateRandomG1Element(); // Prepare messages that will be blinded (hidden) and known to signer @@ -61,10 +57,10 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no void 0, revealedMessages ); - } else if (isBBSPlus()) { - [blinding, request] = BlindSignature.generateRequest(blindedMessages, params, true, void 0, revealedMessages); - } else { + } else if (isBBS()) { request = BlindSignature.generateRequest(blindedMessages, params, true, revealedMessages); + } else { + [blinding, request] = BlindSignature.generateRequest(blindedMessages, params, true, void 0, revealedMessages); } if (isPS()) expect([...request.commitments.keys()].sort((a, b) => a - b)).toEqual(blindedIndices); @@ -72,7 +68,7 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no const statements = new Statements(getStatementForBlindSigRequest(request, params, h)); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proofSpec = new ProofSpec(statements, new MetaStatements()); expect(proofSpec.isValid()).toEqual(true); // The witness to the Pedersen commitment contains the blinding at index 0 by convention and then the hidden messages @@ -84,7 +80,7 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no ) ); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proofSpec, witnesses); checkResult(proof.verify(proofSpec)); @@ -94,7 +90,7 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no : BlindSignature.fromRequest(request, sk, params); // User unblind the signature - const sig = isPS() ? blindSig.unblind(blindings, pk) : isBBSPlus() ? blindSig.unblind(blinding) : blindSig; + const sig = isPS() ? blindSig.unblind(blindings, pk) : isBBS() ? blindSig : blindSig.unblind(blinding); // Combine blinded and revealed messages in an array const messages = Array(blindedMessages.size + revealedMessages.size); @@ -105,7 +101,7 @@ describe(`${Scheme} Getting a blind signature, i.e. signature where signer is no messages[i] = m; } - const result = sig.verify(messages, pk, params, true); + const result = sig.verify(messages, isKvac() ? sk : pk, params, true); expect(result.verified).toEqual(true); }); }); diff --git a/tests/composite-proofs/bound-check.spec.ts b/tests/composite-proofs/bound-check.spec.ts index ef7766b1..08dabcbd 100644 --- a/tests/composite-proofs/bound-check.spec.ts +++ b/tests/composite-proofs/bound-check.spec.ts @@ -1,4 +1,4 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateFieldElementFromNumber, initializeWasm } from 'crypto-wasm-new'; import { BoundCheckBppParams, BoundCheckBppParamsUncompressed, @@ -7,12 +7,12 @@ import { BoundCheckSmcWithKVProverParamsUncompressed, BoundCheckSmcWithKVSetup, BoundCheckSmcWithKVVerifierParamsUncompressed, - CompositeProofG1, + CompositeProof, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatement, MetaStatements, - QuasiProofSpecG1, + QuasiProofSpec, SetupParam, Statement, Statements, @@ -20,7 +20,14 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../src'; -import { checkResult, getRevealedUnrevealed, stringToBytes, getBoundCheckSnarkKeys } from '../utils'; +import { + checkResult, + getRevealedUnrevealed, + stringToBytes, + getBoundCheckSnarkKeys, + getParamsAndKeys, + signAndVerify, proverStmt, verifierStmt +} from '../utils'; import { KeyPair, SecretKey, @@ -28,8 +35,8 @@ import { Signature, SignatureParams, buildWitness, - buildStatement, - Scheme + buildVerifierStatement, + Scheme, isPS, buildProverStatement } from '../scheme'; describe(`Bound check of ${Scheme} signed messages`, () => { @@ -81,15 +88,8 @@ describe(`Bound check of ${Scheme} signed messages`, () => { }); it('do signers setup', () => { - sigParams1 = SignatureParams.generate(messageCount); - const sigKeypair1 = KeyPair.generate(sigParams1); - sigSk1 = sigKeypair1.secretKey; - sigPk1 = sigKeypair1.publicKey; - - sigParams2 = SignatureParams.generate(messageCount); - const sigKeypair2 = KeyPair.generate(sigParams2); - sigSk2 = sigKeypair2.secretKey; - sigPk2 = sigKeypair2.publicKey; + [sigParams1, sigSk1, sigPk1] = getParamsAndKeys(messageCount); + [sigParams2, sigSk2, sigPk2] = getParamsAndKeys(messageCount); messages1 = []; messages2 = []; @@ -103,10 +103,12 @@ describe(`Bound check of ${Scheme} signed messages`, () => { } } - sig1 = Signature.generate(messages1, sigSk1, sigParams1, false); - sig2 = Signature.generate(messages2, sigSk2, sigParams2, false); - expect(sig1.verify(messages1, sigPk1, sigParams1, false).verified).toEqual(true); - expect(sig2.verify(messages2, sigPk2, sigParams2, false).verified).toEqual(true); + let result1, result2; + [sig1, result1] = signAndVerify(messages1, sigParams1, sigSk1, sigPk1); + checkResult(result1); + [sig2, result2] = signAndVerify(messages2, sigParams2, sigSk2, sigPk2); + checkResult(result2); + }); function validateBounds(boundCheckProver, boundCheckProverFromRefs, boundCheckVerifier, boundCheckVerifierFromRefs) { @@ -172,17 +174,17 @@ describe(`Bound check of ${Scheme} signed messages`, () => { sigPk: PublicKey, messages: Uint8Array[], sig: Signature, - proverStmt, + pStmt, witnessGen, - verifierStmt, + vStmt, proverParams, verifierParams ) { const revealedIndices = new Set(); revealedIndices.add(0); const [revealedMsgs, unrevealedMsgs] = getRevealedUnrevealed(messages, revealedIndices); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); - const statement2 = proverStmt(min1, max1, proverParams); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); + const statement2 = pStmt(min1, max1, proverParams); const proverStatements = new Statements(statement1); proverStatements.add(statement2); @@ -197,26 +199,27 @@ describe(`Bound check of ${Scheme} signed messages`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements); const nonce = stringToBytes('a nonce'); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); - const statement3 = verifierStmt(min1, max1, verifierParams); - const verifierStatements = new Statements(statement1); + const statement3 = vStmt(min1, max1, verifierParams); + const statement4 = verifierStmt(sigParams, revealedMsgs, sigPk); + const verifierStatements = new Statements(statement4); verifierStatements.add(statement3); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec, nonce)); } function proveAndVerifyMultiple( proverSetupParamGen, verifierSetupParamGen, - proverStmt, + pStmt, witnessGen, - verifierStmt, + vStmt, proverParams, verifierParams ) { @@ -226,12 +229,12 @@ describe(`Bound check of ${Scheme} signed messages`, () => { const [revealedMsgs1, unrevealedMsgs1] = getRevealedUnrevealed(messages1, new Set()); const [revealedMsgs2, unrevealedMsgs2] = getRevealedUnrevealed(messages2, new Set()); - const statement1 = buildStatement(sigParams1, sigPk1, revealedMsgs1, false); - const statement2 = buildStatement(sigParams2, sigPk2, revealedMsgs2, false); - const statement3 = proverStmt(min1, max1, 0); - const statement4 = proverStmt(min2, max2, 0); - const statement5 = proverStmt(min3, max3, 0); - const statement6 = proverStmt(min4, max4, 0); + const statement1 = proverStmt(sigParams1, revealedMsgs1, sigPk1); + const statement2 = proverStmt(sigParams2, revealedMsgs2, sigPk2); + const statement3 = pStmt(min1, max1, 0); + const statement4 = pStmt(min2, max2, 0); + const statement5 = pStmt(min3, max3, 0); + const statement6 = pStmt(min4, max4, 0); const proverStatements = new Statements(); proverStatements.add(statement1); @@ -271,27 +274,29 @@ describe(`Bound check of ${Scheme} signed messages`, () => { witnesses.add(witnessGen(messages2[msgIdx])); witnesses.add(witnessGen(messages2[msgIdx + 1])); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements, proverSetupParams); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements, proverSetupParams); const nonce = stringToBytes('a nonce'); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(verifierSetupParamGen(verifierParams)); - const statement7 = verifierStmt(min1, max1, 0); - const statement8 = verifierStmt(min2, max2, 0); - const statement9 = verifierStmt(min3, max3, 0); - const statement10 = verifierStmt(min4, max4, 0); + const statement7 = vStmt(min1, max1, 0); + const statement8 = vStmt(min2, max2, 0); + const statement9 = vStmt(min3, max3, 0); + const statement10 = vStmt(min4, max4, 0); + const statement11 = verifierStmt(sigParams1, revealedMsgs1, sigPk1); + const statement12 = verifierStmt(sigParams2, revealedMsgs2, sigPk2); - const verifierStatements = new Statements([].concat(statement1, statement2)); + const verifierStatements = new Statements([].concat(statement11, statement12)); verifierStatements.add(statement7); verifierStatements.add(statement8); verifierStatements.add(statement9); verifierStatements.add(statement10); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements, verifierSetupParams); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements, verifierSetupParams); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec, nonce)); } @@ -299,9 +304,9 @@ describe(`Bound check of ${Scheme} signed messages`, () => { function boundsOnTimestamps( proverSetupParamGen, verifierSetupParamGen, - proverStmt, + pStmt, witnessGen, - verifierStmt, + vStmt, proverParams, verifierParams ) { @@ -322,7 +327,8 @@ describe(`Bound check of ${Scheme} signed messages`, () => { attributes.push(Signature.encodePositiveNumberForSigning(now + 2000000)); // Expiration date as no. of milliseconds since epoch // Signer creates the signature and shares with prover - const sig = Signature.generate(attributes, sigSk1, sigParams1, false); + const [sig, result] = signAndVerify(attributes, sigParams1, sigSk1, sigPk1); + checkResult(result); const proverSetupParams: SetupParam[] = []; proverSetupParams.push(proverSetupParamGen(proverParams)); @@ -330,13 +336,13 @@ describe(`Bound check of ${Scheme} signed messages`, () => { const revealedIndices = new Set(); revealedIndices.add(0); const [revealedAttrs, unrevealedAttrs] = getRevealedUnrevealed(attributes, revealedIndices); - const statement1 = buildStatement(sigParams1, sigPk1, revealedAttrs, false); + const statement1 = proverStmt(sigParams1, revealedAttrs, sigPk1); // For proving birth date was after `bornAfter` - const statement2 = proverStmt(bornAfter, now, 0); + const statement2 = pStmt(bornAfter, now, 0); // For proving issuance date was between `earliestIssuance` and `latestIssuance` - const statement3 = proverStmt(earliestIssuance, latestIssuance, 0); + const statement3 = pStmt(earliestIssuance, latestIssuance, 0); // For proving expiration date was between `now` and `someDistantFuture`, i.e. its not expired as of now. - const statement4 = proverStmt(now, someDistantFuture, 0); + const statement4 = pStmt(now, someDistantFuture, 0); const proverStatements = new Statements(statement1); proverStatements.add(statement2); @@ -369,29 +375,30 @@ describe(`Bound check of ${Scheme} signed messages`, () => { witnesses.add(witnessGen(attributes[3])); witnesses.add(witnessGen(attributes[4])); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements, proverSetupParams); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements, proverSetupParams); const nonce = stringToBytes('a nonce'); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(verifierSetupParamGen(verifierParams)); // For verifying birth date was after `bornAfter` - const statement5 = verifierStmt(bornAfter, now, 0); + const statement5 = vStmt(bornAfter, now, 0); // For verifying issuance date was between `earliestIssuance` and `latestIssuance` - const statement6 = verifierStmt(earliestIssuance, latestIssuance, 0); + const statement6 = vStmt(earliestIssuance, latestIssuance, 0); // For verifying expiration date was between `now` and `someDistantFuture`, i.e. its not expired as of now. - const statement7 = verifierStmt(now, someDistantFuture, 0); + const statement7 = vStmt(now, someDistantFuture, 0); + const statement8 = verifierStmt(sigParams1, revealedAttrs, sigPk1); const verifierStatements = new Statements(); - verifierStatements.add(statement1); + verifierStatements.add(statement8); verifierStatements.add(statement5); verifierStatements.add(statement6); verifierStatements.add(statement7); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements, verifierSetupParams); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements, verifierSetupParams); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec, nonce)); } @@ -399,9 +406,9 @@ describe(`Bound check of ${Scheme} signed messages`, () => { function boundsOnNegativeAndDecimal( proverSetupParamGen, verifierSetupParamGen, - proverStmt, + pStmt, witnessGen, - verifierStmt, + vStmt, proverParams, verifierParams ) { @@ -505,19 +512,20 @@ describe(`Bound check of ${Scheme} signed messages`, () => { } // Signer creates the signature and shares with prover - const sig = Signature.generate(encodedAttributes, sigSk1, sigParams1, false); + const [sig, result] = signAndVerify(encodedAttributes, sigParams1, sigSk1, sigPk1); + checkResult(result); const proverSetupParams: SetupParam[] = []; proverSetupParams.push(proverSetupParamGen(proverParams)); const [revealedAttrs, unrevealedAttrs] = getRevealedUnrevealed(encodedAttributes, new Set()); - const statement1 = buildStatement(sigParams1, sigPk1, revealedAttrs, false); + const statement1 = proverStmt(sigParams1, revealedAttrs, sigPk1); - const statement2 = proverStmt(transMin1, transMax1, 0); - const statement3 = proverStmt(transMin2, transMax2, 0); - const statement4 = proverStmt(transMin3, transMax3, 0); - const statement5 = proverStmt(transMin3, transMax3, 0); - const statement6 = proverStmt(transMin4, transMax4, 0); + const statement2 = pStmt(transMin1, transMax1, 0); + const statement3 = pStmt(transMin2, transMax2, 0); + const statement4 = pStmt(transMin3, transMax3, 0); + const statement5 = pStmt(transMin3, transMax3, 0); + const statement6 = pStmt(transMin4, transMax4, 0); const proverStatements = new Statements(statement1); proverStatements.add(statement2); @@ -540,29 +548,30 @@ describe(`Bound check of ${Scheme} signed messages`, () => { witnesses.add(witnessGen(encodedAttributes[i])); } - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements, proverSetupParams); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements, proverSetupParams); const nonce = stringToBytes('a nonce'); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses, nonce); const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(verifierSetupParamGen(verifierParams)); - const statement7 = verifierStmt(transMin1, transMax1, 0); - const statement8 = verifierStmt(transMin2, transMax2, 0); - const statement9 = verifierStmt(transMin3, transMax3, 0); - const statement10 = verifierStmt(transMin3, transMax3, 0); - const statement11 = verifierStmt(transMin4, transMax4, 0); + const statement7 = vStmt(transMin1, transMax1, 0); + const statement8 = vStmt(transMin2, transMax2, 0); + const statement9 = vStmt(transMin3, transMax3, 0); + const statement10 = vStmt(transMin3, transMax3, 0); + const statement11 = vStmt(transMin4, transMax4, 0); + const statement12 = verifierStmt(sigParams1, revealedAttrs, sigPk1); - const verifierStatements = new Statements(statement1); + const verifierStatements = new Statements(statement12); verifierStatements.add(statement7); verifierStatements.add(statement8); verifierStatements.add(statement9); verifierStatements.add(statement10); verifierStatements.add(statement11); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements, verifierSetupParams); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements, verifierSetupParams); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec, nonce)); } diff --git a/tests/composite-proofs/many-signatures.spec.ts b/tests/composite-proofs/many-signatures.spec.ts index 35df6bec..e8b6b118 100644 --- a/tests/composite-proofs/many-signatures.spec.ts +++ b/tests/composite-proofs/many-signatures.spec.ts @@ -1,25 +1,25 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; +import { checkResult, getParamsAndKeys, proverStmt, signAndVerify, stringToBytes, verifierStmt } from '../utils'; import { - CompositeProofG1, + initializeWasm, + CompositeProof, MetaStatement, MetaStatements, - ProofSpecG1, + ProofSpec, Statements, WitnessEqualityMetaStatement, - Witnesses + Witnesses, Statement } from '../../src'; import { KeyPair, Scheme, Signature, SignatureParams, - buildStatement, + buildVerifierStatement, buildWitness, - encodeMessageForSigningIfPS, -} from '../scheme' + encodeMessageForSigningIfPS, isPS, buildProverStatement, isKvac +} from '../scheme'; -describe(`${Scheme} Proving knowledge of 2 BBS+ signatures over attributes and equality of a specific attribute`, () => { +describe(`Proving knowledge of 2 ${Scheme} signatures over attributes and equality of a specific attribute`, () => { it('works', async () => { // Load the WASM module await initializeWasm(); @@ -61,40 +61,26 @@ describe(`${Scheme} Proving knowledge of 2 BBS+ signatures over attributes and e const messageCount2 = messages2.length; - // 1st Signer's params + // 1st Signer's params and keys const label1 = stringToBytes('Label-1'); - const params1 = SignatureParams.generate(messageCount1, label1); + const [params1, sk1, pk1] = getParamsAndKeys(messageCount1, label1); - // 2nd Signer's params + // 2nd Signer's params and keys const label2 = stringToBytes('Label-2'); - const params2 = SignatureParams.generate(messageCount2, label2); - - // Signer 1 keys - const keypair1 = KeyPair.generate(params1); - const sk1 = keypair1.secretKey; - const pk1 = keypair1.publicKey; - - // Signer 2 keys - const keypair2 = KeyPair.generate(params2); - const sk2 = keypair2.secretKey; - const pk2 = keypair2.publicKey; + const [params2, sk2, pk2] = getParamsAndKeys(messageCount2, label2); // 1st Signer signs - const sig1 = Signature.generate(messages1, sk1, params1, true); - // User verifies signature from 1st signer - const result1 = sig1.verify(messages1, pk1, params1, true); - expect(result1.verified).toEqual(true); + const [sig1, result1] = signAndVerify(messages1, params1, sk1, pk1, true); + checkResult(result1); // 2nd Signer signs - const sig2 = Signature.generate(messages2, sk2, params2, true); - // User verifies signature from 2nd signer - const result2 = sig2.verify(messages2, pk2, params2, true); - expect(result2.verified).toEqual(true); + const [sig2, result2] = signAndVerify(messages2, params2, sk2, pk2, true); + checkResult(result2); // User wants to prove knowledge of 2 signatures and hence 2 statements // Statement for signature of 1st signer, not revealing any messages to the verifier - const statement1 = buildStatement(params1, pk1, new Map(), true); + const statement1 = proverStmt(params1, new Map(), pk1, true); // Statement for signature of 2nd signer, revealing 1 message to the verifier const revealedMsgIndices: Set = new Set(); @@ -108,11 +94,11 @@ describe(`${Scheme} Proving knowledge of 2 BBS+ signatures over attributes and e unrevealedMsgs2.set(i, messages2[i]); } } - const statement2 = buildStatement(params2, pk2, revealedMsgs, true); + const statement2 = proverStmt(params2, revealedMsgs, pk2, true); - const statements = new Statements(); - const sId1 = statements.add(statement1); - const sId2 = statements.add(statement2); + const proverStatements = new Statements(); + const sId1 = proverStatements.add(statement1); + const sId2 = proverStatements.add(statement2); const metaStatements = new MetaStatements(); // For proving equality of SSN, messages1[0] == messages2[5], specify using MetaStatement @@ -133,8 +119,8 @@ describe(`${Scheme} Proving knowledge of 2 BBS+ signatures over attributes and e const context = stringToBytes('test-context'); - const proofSpec = new ProofSpecG1(statements, metaStatements, [], context); - expect(proofSpec.isValid()).toEqual(true); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements, [], context); + expect(proverProofSpec.isValid()).toEqual(true); // Using the messages and signature from 1st signer const unrevealedMsgs1 = new Map(messages1.map((m, i) => [i, m])); @@ -147,8 +133,27 @@ describe(`${Scheme} Proving knowledge of 2 BBS+ signatures over attributes and e const nonce = stringToBytes('some unique nonce'); - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); + const proof = CompositeProof.generate(proverProofSpec, witnesses, nonce); - checkResult(proof.verify(proofSpec, nonce)); + // Statement for signature of 1st signer, not revealing any messages to the verifier + const statement3 = verifierStmt(params1, new Map(), pk1, true); + const statement4 = verifierStmt(params2, revealedMsgs, pk2, true); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement4); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements, [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); + + if (isKvac()) { + const statement5 = Statement.bddt16MacFullVerifier(params1, sk1, new Map(), true); + const statement6 = Statement.bddt16MacFullVerifier(params2, sk2, revealedMsgs, true); + const verifierStatements = new Statements(); + verifierStatements.add(statement5); + verifierStatements.add(statement6); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements, [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); + } }); }); diff --git a/tests/composite-proofs/msg-js-obj/accumulator.spec.ts b/tests/composite-proofs/msg-js-obj/accumulator.spec.ts index 6df95369..1508e7d5 100644 --- a/tests/composite-proofs/msg-js-obj/accumulator.spec.ts +++ b/tests/composite-proofs/msg-js-obj/accumulator.spec.ts @@ -1,8 +1,7 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { Accumulator, AccumulatorSecretKey, - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, EncodeFunc, Encoder, @@ -11,21 +10,23 @@ import { getIndicesForMsgNames, getRevealedAndUnrevealed, IAccumulatorState, + initializeWasm, MetaStatements, PositiveAccumulator, - ProofSpecG1, + ProofSpec, Statement, Statements, + VBWitnessUpdatePublicInfo, Witness, WitnessEqualityMetaStatement, - Witnesses, - WitnessUpdatePublicInfo + Witnesses } from '../../../src'; -import { checkResult, stringToBytes } from '../../utils'; import { InMemoryState } from '../../../src/accumulator/in-memory-persistence'; +import { buildWitness, Scheme } from '../../scheme'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; import { attributes1, attributes1Struct, attributes2, attributes2Struct, defaultEncoder } from './data-and-encoder'; import { checkMapsEqual } from './index'; -import { adaptKeyForParams, buildStatement, buildWitness, KeyPair, Scheme, SignatureParams, Signature } from '../../scheme'; +import { proverStmt, signAndVerify, verifierStmt } from './util'; describe(`${Scheme} Accumulator`, () => { beforeAll(async () => { @@ -62,18 +63,12 @@ describe(`${Scheme} Accumulator`, () => { // 1st signer's setup const label1 = stringToBytes('Sig params label 1'); // Message count shouldn't matter as `label1` is known - let params1 = SignatureParams.generate(100, label1); - const keypair1 = KeyPair.generate(params1); - const sk1 = keypair1.secretKey; - const pk1 = keypair1.publicKey; + const [params1, sk1, pk1] = getParamsAndKeys(100, label1); // 2nd signer's setup const label2 = stringToBytes('Sig params label 2'); // Message count shouldn't matter as `label2` is known - let params2 = SignatureParams.generate(100, label2); - const keypair2 = KeyPair.generate(params2); - const sk2 = keypair2.secretKey; - const pk2 = keypair2.publicKey; + const [params2, sk2, pk2] = getParamsAndKeys(100, label2); // Accumulator manager 1's setup const accumParams1 = PositiveAccumulator.generateParams(stringToBytes('Accumulator params 1')); @@ -107,7 +102,7 @@ describe(`${Scheme} Accumulator`, () => { // Sign and verify all signatures // Signer 1 signs the attributes - const signed1 = Signature.signMessageObject(attributes1, sk1, label1, encoder); + const signed1 = signAndVerify(attributes1, encoder, label1, sk1, pk1); // Accumulator manager 1 generates the witness for the accumulator member, i.e. attribute signed1.encodedMessages['user-id'] // and gives the witness to the user. @@ -117,8 +112,6 @@ describe(`${Scheme} Accumulator`, () => { accumState1 ); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label1, encoder)); - // The user verifies the accumulator membership by using the witness let verifAccumulator1 = PositiveAccumulator.fromAccumulated(accumulator1.accumulated); expect( @@ -131,7 +124,7 @@ describe(`${Scheme} Accumulator`, () => { ).toEqual(true); // Signer 2 signs the attributes - const signed2 = Signature.signMessageObject(attributes2, sk2, label2, encoder); + const signed2 = signAndVerify(attributes2, encoder, label2, sk2, pk2); // Accumulator manager 2 generates the witness and gives it to the user const accumWitness2 = await accumulator2.membershipWitness( @@ -140,8 +133,6 @@ describe(`${Scheme} Accumulator`, () => { accumState2 ); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk2, label2, encoder)); - // The user verifies the accumulator membership by using the witness let verifAccumulator2 = PositiveAccumulator.fromAccumulated(accumulator2.accumulated); expect( @@ -173,31 +164,36 @@ describe(`${Scheme} Accumulator`, () => { const sigParams1 = getAdaptedSignatureParamsForMessages(params1, attributes1Struct); const sigParams2 = getAdaptedSignatureParamsForMessages(params2, attributes2Struct); - const sigPk1 = adaptKeyForParams(pk1, sigParams1); - const sigPk2 = adaptKeyForParams(pk2, sigParams2); - const [revealedMsgs1, unrevealedMsgs1, revealedMsgsRaw1] = getRevealedAndUnrevealed( attributes1, revealedNames1, encoder ); - const statement1 = buildStatement(sigParams1, sigPk1, revealedMsgs1, false); + const statement1 = proverStmt( + sigParams1, + revealedMsgs1, + pk1, + ); const [revealedMsgs2, unrevealedMsgs2, revealedMsgsRaw2] = getRevealedAndUnrevealed( attributes2, revealedNames2, encoder ); - const statement2 = buildStatement(sigParams2, sigPk2, revealedMsgs2, false); + const statement2 = proverStmt( + sigParams2, + revealedMsgs2, + pk2, + ); - const statement3 = Statement.accumulatorMembership( + const statement3 = Statement.vbAccumulatorMembership( accumParams1, accumKeypair1.publicKey, provingKey1, accumulator1.accumulated ); - const statement4 = Statement.accumulatorMembership( + const statement4 = Statement.vbAccumulatorMembership( accumParams2, accumKeypair2.publicKey, provingKey2, @@ -233,19 +229,19 @@ describe(`${Scheme} Accumulator`, () => { metaStmtsProver.addWitnessEquality(witnessEq3); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs1, false); const witness2 = buildWitness(signed2.signature, unrevealedMsgs2, false); - const witness3 = Witness.accumulatorMembership(signed1.encodedMessages['user-id'], accumWitness1); - const witness4 = Witness.accumulatorMembership(signed2.encodedMessages['sensitive.user-id'], accumWitness2); + const witness3 = Witness.vbAccumulatorMembership(signed1.encodedMessages['user-id'], accumWitness1); + const witness4 = Witness.vbAccumulatorMembership(signed2.encodedMessages['sensitive.user-id'], accumWitness2); const witnesses = new Witnesses([].concat(witness1, witness2)); witnesses.add(witness3); witnesses.add(witness4); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgs1FromVerifier = encodeRevealedMsgs(revealedMsgsRaw1, attributes1Struct, encoder); @@ -253,15 +249,23 @@ describe(`${Scheme} Accumulator`, () => { const revealedMsgs2FromVerifier = encodeRevealedMsgs(revealedMsgsRaw2, attributes2Struct, encoder); checkMapsEqual(revealedMsgs2, revealedMsgs2FromVerifier); - const statement5 = buildStatement(sigParams1, sigPk1, revealedMsgs1FromVerifier, false); - const statement6 = buildStatement(sigParams2, sigPk2, revealedMsgs2FromVerifier, false); - const statement7 = Statement.accumulatorMembership( + const statement5 = verifierStmt( + sigParams1, + revealedMsgs1FromVerifier, + pk1 + ); + const statement6 = verifierStmt( + sigParams2, + revealedMsgs2FromVerifier, + pk2 + ); + const statement7 = Statement.vbAccumulatorMembership( accumParams1, accumKeypair1.publicKey, provingKey1, accumulator1.accumulated ); - const statement8 = Statement.accumulatorMembership( + const statement8 = Statement.vbAccumulatorMembership( accumParams2, accumKeypair2.publicKey, provingKey2, @@ -295,7 +299,7 @@ describe(`${Scheme} Accumulator`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq6); // The verifier should independently construct this `ProofSpec` - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -303,13 +307,13 @@ describe(`${Scheme} Accumulator`, () => { // Remove members from accumulator // Prepare witness update info that needs to be shared with the members - const witnessUpdInfo1 = WitnessUpdatePublicInfo.new( + const witnessUpdInfo1 = VBWitnessUpdatePublicInfo.new( accumulator1.accumulated, [], [allMembers1[5]], accumKeypair1.secretKey ); - const witnessUpdInfo2 = WitnessUpdatePublicInfo.new( + const witnessUpdInfo2 = VBWitnessUpdatePublicInfo.new( accumulator2.accumulated, [], [allMembers1[20]], diff --git a/tests/composite-proofs/msg-js-obj/blind-sig-with-attribute-equality-and-pseudonym.spec.ts b/tests/composite-proofs/msg-js-obj/blind-sig-with-attribute-equality-and-pseudonym.spec.ts index 642a1d94..b351b0fa 100644 --- a/tests/composite-proofs/msg-js-obj/blind-sig-with-attribute-equality-and-pseudonym.spec.ts +++ b/tests/composite-proofs/msg-js-obj/blind-sig-with-attribute-equality-and-pseudonym.spec.ts @@ -1,14 +1,14 @@ -import { generateRandomG1Element, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../../utils'; +import { generateRandomG1Element } from 'crypto-wasm-new'; import { AttributeBoundPseudonym, BBSSignature, - CompositeProofG1, + CompositeProof, getAdaptedSignatureParamsForMessages, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, MetaStatements, - ProofSpecG1, + ProofSpec, PseudonymBases, Statement, Statements, @@ -16,23 +16,23 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; -import { attributes1, attributes1Struct, attributes4, attributes4Struct, GlobalEncoder } from './data-and-encoder'; import { - KeyPair, - Signature, + adaptKeyForParams, BlindSignature, - SignatureParams, - isPS, - isBBSPlus, - getWitnessForBlindSigRequest, - getStatementForBlindSigRequest, - Scheme, - buildStatement, buildWitness, + getStatementForBlindSigRequest, + getWitnessForBlindSigRequest, isBBS, - adaptKeyForParams + isBBSPlus, + isKvac, + isPS, + Scheme } from '../../scheme'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; +import { attributes1, attributes1Struct, attributes4, attributes4Struct, GlobalEncoder } from './data-and-encoder'; +import { proverStmt, signAndVerify, verifierStmt } from './util'; +// TODO: Fix me - This test should work with PS sig as well. const skipIfPS = isPS() ? describe.skip : describe; skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid proof and pseudonym`, () => { @@ -53,18 +53,12 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr beforeAll(async () => { // Load the WASM module await initializeWasm(); - params = SignatureParams.generate(100, label); + [params, sk1, pk1] = getParamsAndKeys(100, label); + [params, sk2, pk2] = getParamsAndKeys(100, label); h = generateRandomG1Element(); - const keypair1 = KeyPair.generate(params); - sk1 = keypair1.secretKey; - pk1 = keypair1.publicKey; - const keypair2 = KeyPair.generate(params); - sk2 = keypair2.secretKey; - pk2 = keypair2.publicKey; // User requests `signature1` and verifies it - signed1 = Signature.signMessageObject(attributes1, sk1, label, GlobalEncoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label, GlobalEncoder)); + signed1 = signAndVerify(attributes1, GlobalEncoder, label, sk1, pk1); // pseudonym1 is for attribute `user-id` only basesForPseudonym1 = PseudonymBases.generateBasesForAttributes(1, scope1); @@ -95,7 +89,6 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr }; const sigParams1 = getAdaptedSignatureParamsForMessages(params, attributes1Struct); - const sigPk1 = adaptKeyForParams(pk1, sigParams1); const sigParams2 = getAdaptedSignatureParamsForMessages(params, attributes4Struct); const sigPk2 = adaptKeyForParams(pk2, sigParams2); @@ -125,7 +118,11 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr const [revealed, unrevealed] = getRevealedAndUnrevealed(attributes1, new Set(), GlobalEncoder); - const stId1 = proverStatements.add(buildStatement(sigParams1, sigPk1, revealed, false)); + const stId1 = proverStatements.add(proverStmt( + sigParams1, + revealed, + pk1 + )); const stId2 = proverStatements.add(Statement.attributeBoundPseudonym(pseudonymId, basesForPseudonym1)); witnesses.add(buildWitness(signed1.signature, unrevealed, false)); witnesses.add(Witness.attributeBoundPseudonym([signed1.encodedMessages['user-id']])); @@ -135,14 +132,15 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr if (isPS()) { // @ts-ignore [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams2, h, blindings); - } else if (isBBSPlus()) { + } else if (isBBS()) { // @ts-ignore - [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams2, false); + request = BlindSignature.generateRequest(hiddenMsgs, sigParams2, false); } else { // @ts-ignore - request = BlindSignature.generateRequest(hiddenMsgs, sigParams2, false); + [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams2, false); } + // Fix me: This isn't correct for PS sigs as there will be multiple statements const stId3 = proverStatements.add(getStatementForBlindSigRequest(request, sigParams2, h)); witnesses.add(getWitnessForBlindSigRequest(hiddenMsgs, blinding, blindings)); @@ -150,25 +148,25 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr const witnessEq = new WitnessEqualityMetaStatement(); witnessEq.addWitnessRef(stId1, getIndicesForMsgNames(['user-id'], attributes1Struct)[0]); witnessEq.addWitnessRef(stId2, 0); - if (isBBSPlus()) { - witnessEq.addWitnessRef(stId3, 1); - } else if (isBBS()) { + if (isBBS()) { witnessEq.addWitnessRef(stId3, 0); + } else { + witnessEq.addWitnessRef(stId3, 1); } proverMetaStatements.addWitnessEquality(witnessEq); - const proofSpecProver = new ProofSpecG1(proverStatements, proverMetaStatements); + const proofSpecProver = new ProofSpec(proverStatements, proverMetaStatements); expect(proofSpecProver.isValid()).toEqual(true); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // The signer is the verifier of the user's proof here. Uses the blind signature request to create the statement // and proof spec independently. const verifierStatements = new Statements(); const verifierMetaStatements = new MetaStatements(); - const stId4 = verifierStatements.add(buildStatement(sigParams1, sigPk1, revealed, false)); + const stId4 = verifierStatements.add(verifierStmt(sigParams1, revealed, pk1, false)); const stId5 = verifierStatements.add(Statement.attributeBoundPseudonym(pseudonymId, basesForPseudonym1)); const stId6 = verifierStatements.add(getStatementForBlindSigRequest(request, sigParams2, h)); @@ -185,7 +183,7 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr verifierMetaStatements.addWitnessEquality(witnessEq1); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, verifierMetaStatements); + const proofSpecVerifier = new ProofSpec(verifierStatements, verifierMetaStatements); expect(proofSpecVerifier.isValid()).toEqual(true); // Signer/verifier verifies the proof @@ -206,12 +204,12 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr const unblindedSig = isPS() ? // @ts-ignore blingSignature.signature.unblind(blindings, sigPk2) - : isBBSPlus() - ? // @ts-ignore - blingSignature.signature.unblind(blinding) - : new BBSSignature(blingSignature.signature.value); + : isBBS() + ? new BBSSignature(blingSignature.signature.value) + : // @ts-ignore + blingSignature.signature.unblind(blinding); - checkResult(unblindedSig.verifyMessageObject(attributes4, sigPk2, sigParams2, GlobalEncoder)); + checkResult(isKvac() ? unblindedSig.verifyMessageObject(attributes4, sigSk2, sigParams2, GlobalEncoder) : unblindedSig.verifyMessageObject(attributes4, sigPk2, sigParams2, GlobalEncoder)); signed2 = { encodedMessages: GlobalEncoder.encodeMessageObjectAsObject(attributes4), @@ -223,10 +221,8 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr // Prove knowledge of both signatures and share a pseudonym from 2 attributes of 2nd signature const sigParams1 = getAdaptedSignatureParamsForMessages(params, attributes1Struct); - const sigPk1 = adaptKeyForParams(pk1, sigParams1); const sigParams2 = getAdaptedSignatureParamsForMessages(params, attributes4Struct); - const sigPk2 = adaptKeyForParams(pk2, sigParams2); const revealedNames = new Set(); revealedNames.add('poll-id'); @@ -244,8 +240,16 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr const [revealed1, unrevealed1] = getRevealedAndUnrevealed(attributes1, new Set(), GlobalEncoder); const [revealed2, unrevealed2] = getRevealedAndUnrevealed(attributes4, revealedNames, GlobalEncoder); - const stId1 = proverStatements.add(buildStatement(sigParams1, sigPk1, revealed1, false)); - const stId2 = proverStatements.add(buildStatement(sigParams2, sigPk2, revealed2, false)); + const stId1 = proverStatements.add(proverStmt( + sigParams1, + revealed1, + pk1 + )); + const stId2 = proverStatements.add(proverStmt( + sigParams2, + revealed2, + pk2 + )); const stId3 = proverStatements.add(Statement.attributeBoundPseudonym(pseudonymIdSk, basesForPseudonym2)); witnesses.add(buildWitness(signed1.signature, unrevealed1, false)); witnesses.add(buildWitness(signed2.signature, unrevealed2, false)); @@ -276,16 +280,16 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr witnessEq3.addWitnessRef(stId3, 1); proverMetaStatements.addWitnessEquality(witnessEq3); - const proofSpecProver = new ProofSpecG1(proverStatements, proverMetaStatements); + const proofSpecProver = new ProofSpec(proverStatements, proverMetaStatements); expect(proofSpecProver.isValid()).toEqual(true); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); const verifierStatements = new Statements(); const verifierMetaStatements = new MetaStatements(); - const stId4 = verifierStatements.add(buildStatement(sigParams1, sigPk1, revealed1, false)); - const stId5 = verifierStatements.add(buildStatement(sigParams2, sigPk2, revealed2, false)); + const stId4 = verifierStatements.add(verifierStmt(sigParams1, revealed1, pk1, false)); + const stId5 = verifierStatements.add(verifierStmt(sigParams2, revealed2, pk2, false)); const stId6 = verifierStatements.add(Statement.attributeBoundPseudonym(pseudonymIdSk, basesForPseudonym2)); const witnessEq4 = new WitnessEqualityMetaStatement(); @@ -303,7 +307,7 @@ skipIfPS(`With ${Scheme}, requesting blind signatures after providing a valid pr witnessEq6.addWitnessRef(stId6, 1); verifierMetaStatements.addWitnessEquality(witnessEq6); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, verifierMetaStatements); + const proofSpecVerifier = new ProofSpec(verifierStatements, verifierMetaStatements); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/blind-sig.spec.ts b/tests/composite-proofs/msg-js-obj/blind-sig.spec.ts index fddeff9f..aeb7404d 100644 --- a/tests/composite-proofs/msg-js-obj/blind-sig.spec.ts +++ b/tests/composite-proofs/msg-js-obj/blind-sig.spec.ts @@ -1,14 +1,25 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../../utils'; +import { generateRandomG1Element } from 'crypto-wasm-new'; import { BBSSignature, - CompositeProofG1, + CompositeProof, getAdaptedSignatureParamsForMessages, + initializeWasm, MetaStatements, - ProofSpecG1, + ProofSpec, Statements, Witnesses } from '../../../src'; +import { + adaptKeyForParams, + BlindSignature, + getStatementForBlindSigRequest, + getWitnessForBlindSigRequest, + isBBS, + isKvac, + isPS, + Scheme +} from '../../scheme'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; import { attributes1, attributes1Struct, @@ -18,18 +29,6 @@ import { attributes3Struct, GlobalEncoder } from './data-and-encoder'; -import { - KeyPair, - BlindSignature, - SignatureParams, - isPS, - isBBSPlus, - getWitnessForBlindSigRequest, - getStatementForBlindSigRequest, - Scheme, - adaptKeyForParams -} from '../../scheme'; -import { generateRandomG1Element } from '@docknetwork/crypto-wasm'; describe(`${Scheme} Requesting blind signatures`, () => { beforeAll(async () => { @@ -44,11 +43,8 @@ describe(`${Scheme} Requesting blind signatures`, () => { const label = stringToBytes('Sig params label - this is public'); // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); + const [params, sk, pk] = getParamsAndKeys(100, label); const h = generateRandomG1Element(); - const sk = keypair.secretKey; - const pk = keypair.publicKey; // The user will hide the "user-id" and "secret" attributes from the signer for the 1st signature const hiddenAttrNames1 = new Set(); @@ -161,10 +157,10 @@ describe(`${Scheme} Requesting blind signatures`, () => { let blinding, request; if (isPS()) { [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams, h, blindings); - } else if (isBBSPlus()) { - [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams, false); - } else { + } else if (isBBS()) { request = BlindSignature.generateRequest(hiddenMsgs, sigParams, false); + } else { + [blinding, request] = BlindSignature.generateRequest(hiddenMsgs, sigParams, false); } const witnesses = new Witnesses(getWitnessForBlindSigRequest(hiddenMsgs, blinding, blindings)); @@ -172,16 +168,16 @@ describe(`${Scheme} Requesting blind signatures`, () => { // The user creates a proof of knowledge of the blinded attributes. const proverStatements = new Statements(getStatementForBlindSigRequest(request, sigParams, h)); - const proofSpecProver = new ProofSpecG1(proverStatements, new MetaStatements()); + const proofSpecProver = new ProofSpec(proverStatements, new MetaStatements()); expect(proofSpecProver.isValid()).toEqual(true); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // The signer is the verifier of the user's proof here. Uses the blind signature request to create the statement // and proof spec independently. const verifierStatements = new Statements(getStatementForBlindSigRequest(request, sigParams, h)); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, new MetaStatements()); + const proofSpecVerifier = new ProofSpec(verifierStatements, new MetaStatements()); expect(proofSpecVerifier.isValid()).toEqual(true); // Signer/verifier verifies the proof @@ -201,12 +197,12 @@ describe(`${Scheme} Requesting blind signatures`, () => { // User unblinds the blind signature const revealedSig = isPS() ? blindSignature.signature.unblind(blindings, sigPk) - : isBBSPlus() - ? blindSignature.signature.unblind(blinding) - : new BBSSignature(blindSignature.signature.value); + : isBBS() + ? new BBSSignature(blindSignature.signature.value) + : blindSignature.signature.unblind(blinding); // The revealed signature can now be used in the usual verification process - checkResult(revealedSig.verifyMessageObject(attributes, sigPk, sigParams, GlobalEncoder)); + checkResult(isKvac() ? revealedSig.verifyMessageObject(attributes, sigSk, sigParams, GlobalEncoder) : revealedSig.verifyMessageObject(attributes, sigPk, sigParams, GlobalEncoder)); // Proof of knowledge of signature can be created and verified as usual. } diff --git a/tests/composite-proofs/msg-js-obj/blood-group.spec.ts b/tests/composite-proofs/msg-js-obj/blood-group.spec.ts index 118b34a6..9e1a73b9 100644 --- a/tests/composite-proofs/msg-js-obj/blood-group.spec.ts +++ b/tests/composite-proofs/msg-js-obj/blood-group.spec.ts @@ -1,13 +1,12 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { areUint8ArraysEqual, checkResult, stringToBytes } from '../../utils'; import { - CompositeProofG1, + CompositeProof, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, MetaStatements, - ProofSpecG1, + ProofSpec, SignedMessages, Statement, Statements, @@ -15,20 +14,12 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; -import { checkMapsEqual } from './index'; -import { defaultEncoder } from './data-and-encoder'; -import { - PublicKey, - KeyPair, - SignatureParams, - Signature, - buildStatement, - buildWitness, - isPS, - Scheme, - adaptKeyForParams -} from '../../scheme'; import { PederCommKey } from '../../../src/ped-com'; +import { buildWitness, PublicKey, Scheme, SecretKey, Signature, SignatureParams } from '../../scheme'; +import { areUint8ArraysEqual, checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; +import { defaultEncoder } from './data-and-encoder'; +import { checkMapsEqual } from './index'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from './util'; // Test for a scenario where a user wants to prove that his blood group is AB- without revealing the blood group. // Similar test can be written for other "not-equals" relations like user is not resident of certain city @@ -37,6 +28,8 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { let encodedABNeg: Uint8Array; const label = stringToBytes('Sig params label'); + let params: SignatureParams; + let sk: SecretKey; let pk: PublicKey; let commKey: PederCommKey; @@ -103,16 +96,10 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { it('signers signs attributes', () => { // Message count shouldn't matter as `label` is known - const params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - pk = keypair.publicKey; - - signed1 = Signature.signMessageObject(attributes1, sk, label, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk, label, encoder)); + [params, sk, pk] = getParamsAndKeys(100, label); - signed2 = Signature.signMessageObject(attributes2, sk, label, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk, label, encoder)); + signed1 = signAndVerify(attributes1, encoder, label, sk, pk); + signed2 = signAndVerify(attributes2, encoder, label, sk, pk); }); it('proof verifies when blood groups is not AB-', () => { @@ -121,8 +108,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - const sigPK = adaptKeyForParams(pk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes1, revealedNames, @@ -130,7 +116,11 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'John' }); - const statement1 = buildStatement(sigParams, sigPK, revealedMsgs, false); + const statement1 = proverStmt( + sigParams, + revealedMsgs, + pk + ); const statement2 = Statement.publicInequalityG1FromCompressedParams(encodedABNeg, commKey); const statementsProver = new Statements(); @@ -145,7 +135,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs, false); @@ -154,13 +144,17 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const witnesses = new Witnesses([witness1, witness2]); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement(sigParams, sigPK, revealedMsgsFromVerifier, false); + const statement3 = verifierStmt( + sigParams, + revealedMsgsFromVerifier, + pk + ); const statement4 = Statement.publicInequalityG1FromCompressedParams(encodedABNeg, commKey); const statementsVerifier = new Statements(); @@ -174,7 +168,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/bound-check.spec.ts b/tests/composite-proofs/msg-js-obj/bound-check.spec.ts index 1d55263a..47cc25ca 100644 --- a/tests/composite-proofs/msg-js-obj/bound-check.spec.ts +++ b/tests/composite-proofs/msg-js-obj/bound-check.spec.ts @@ -1,5 +1,3 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getBoundCheckSnarkKeys, stringToBytes } from '../../utils'; import { BoundCheckBppParams, BoundCheckBppParamsUncompressed, @@ -8,17 +6,18 @@ import { BoundCheckSmcWithKVProverParamsUncompressed, BoundCheckSmcWithKVSetup, BoundCheckSmcWithKVVerifierParamsUncompressed, - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, Encoder, encodeRevealedMsgs, getAdaptedSignatureParamsForMessages, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, - ProofSpecG1, + ProofSpec, SetupParam, Statement, Statements, @@ -26,6 +25,8 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; +import { buildWitness, PublicKey, Scheme, SecretKey, SignatureParams } from '../../scheme'; +import { checkResult, getBoundCheckSnarkKeys, getParamsAndKeys, stringToBytes } from '../../utils'; import { attributes1, attributes1Struct, @@ -36,17 +37,7 @@ import { GlobalEncoder } from './data-and-encoder'; import { checkMapsEqual } from './index'; -import { - adaptKeyForParams, - buildStatement, - buildWitness, - KeyPair, - Scheme, - SignatureParams, - Signature, - SecretKey, - PublicKey -} from '../../scheme'; +import { proverStmt, signAndVerify, verifierStmt } from './util'; const loadSnarkSetupFromFiles = true; @@ -76,26 +67,17 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { // 1st signer's setup const label1 = stringToBytes('Sig params label 1'); // Message count shouldn't matter as `label1` is known - params1 = SignatureParams.generate(100, label1); - const keypair1 = KeyPair.generate(params1); - sk1 = keypair1.secretKey; - pk1 = keypair1.publicKey; + [params1, sk1, pk1] = getParamsAndKeys(100, label1); // 2nd signer's setup const label2 = stringToBytes('Sig params label 2'); // Message count shouldn't matter as `label2` is known - params2 = SignatureParams.generate(100, label2); - const keypair2 = KeyPair.generate(params2); - sk2 = keypair2.secretKey; - pk2 = keypair2.publicKey; + [params2, sk2, pk2] = getParamsAndKeys(100, label2); // 3rd signer's setup const label3 = stringToBytes('Sig params label 3'); // Message count shouldn't matter as `label3` is known - params3 = SignatureParams.generate(100, label3); - const keypair3 = KeyPair.generate(params3); - sk3 = keypair3.secretKey; - pk3 = keypair3.publicKey; + [params3, sk3, pk3] = getParamsAndKeys(100, label3); [snarkProvingKey, snarkVerifyingKey] = getBoundCheckSnarkKeys(loadSnarkSetupFromFiles); @@ -110,22 +92,17 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { boundCheckSmcKVVerifierParams = p2[1].decompress(); // Sign and verify all signatures - signed1 = Signature.signMessageObject(attributes1, sk1, label1, GlobalEncoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label1, GlobalEncoder)); - - signed2 = Signature.signMessageObject(attributes2, sk2, label2, GlobalEncoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk2, label2, GlobalEncoder)); - - signed3 = Signature.signMessageObject(attributes3, sk3, label3, GlobalEncoder); - checkResult(signed3.signature.verifyMessageObject(attributes3, pk3, label3, GlobalEncoder)); + signed1 = signAndVerify(attributes1, GlobalEncoder, label1, sk1, pk1); + signed2 = signAndVerify(attributes2, GlobalEncoder, label2, sk2, pk2); + signed3 = signAndVerify(attributes3, GlobalEncoder, label3, sk3, pk3); }); function check( proverSetupParamGen, verifierSetupParamGen, - proverStmt, + pStmt, witnessGen, - verifierStmt, + vStmt, proverParams, verifierParams ) { @@ -183,10 +160,6 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { const sigParams2 = getAdaptedSignatureParamsForMessages(params2, attributes2Struct); const sigParams3 = getAdaptedSignatureParamsForMessages(params3, attributes3Struct); - const sigPk1 = adaptKeyForParams(pk1, sigParams1); - const sigPk2 = adaptKeyForParams(pk2, sigParams2); - const sigPk3 = adaptKeyForParams(pk3, sigParams3); - // Prover needs to do many bound checks with the same verification key const proverSetupParams: SetupParam[] = []; proverSetupParams.push(proverSetupParamGen(proverParams)); @@ -198,7 +171,11 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { ); expect(revealedMsgsRaw1).toEqual({ fname: 'John', country: 'USA' }); - const statement1 = buildStatement(sigParams1, sigPk1, revealedMsgs1, false); + const statement1 = proverStmt( + sigParams1, + revealedMsgs1, + pk1, + ); const [revealedMsgs2, unrevealedMsgs2, revealedMsgsRaw2] = getRevealedAndUnrevealed( attributes2, @@ -207,7 +184,11 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { ); expect(revealedMsgsRaw2).toEqual({ fname: 'John', location: { country: 'USA' } }); - const statement2 = buildStatement(sigParams2, sigPk2, revealedMsgs2, false); + const statement2 = proverStmt( + sigParams2, + revealedMsgs2, + pk2, + ); const [revealedMsgs3, unrevealedMsgs3, revealedMsgsRaw3] = getRevealedAndUnrevealed( attributes3, @@ -226,16 +207,20 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { } }); - const statement3 = buildStatement(sigParams3, sigPk3, revealedMsgs3, false); + const statement3 = proverStmt( + sigParams3, + revealedMsgs3, + pk3, + ); // Construct statements for bound check - const statement4 = proverStmt(timeMin, timeMax, 0); - const statement5 = proverStmt(weightMin, weightMax, 0); - const statement6 = proverStmt(heightMin, heightMax, 0); - const statement7 = proverStmt(bmiMin, bmiMax, 0); - const statement8 = proverStmt(scoreMin, scoreMax, 0); - const statement9 = proverStmt(latMin, latMax, 0); - const statement10 = proverStmt(longMin, longMax, 0); + const statement4 = pStmt(timeMin, timeMax, 0); + const statement5 = pStmt(weightMin, weightMax, 0); + const statement6 = pStmt(heightMin, heightMax, 0); + const statement7 = pStmt(bmiMin, bmiMax, 0); + const statement8 = pStmt(scoreMin, scoreMax, 0); + const statement9 = pStmt(latMin, latMax, 0); + const statement10 = pStmt(longMin, longMax, 0); const statementsProver = new Statements(); const sIdx1 = statementsProver.add(statement1); @@ -337,7 +322,7 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { metaStmtsProver.addWitnessEquality(witnessEq11); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver, proverSetupParams); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver, proverSetupParams); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs1, false); @@ -354,7 +339,7 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { witnesses.add(witnessGen(signed3.encodedMessages['lessSensitive.department.location.geo.lat'])); witnesses.add(witnessGen(signed3.encodedMessages['lessSensitive.department.location.geo.long'])); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(verifierSetupParamGen(verifierParams)); @@ -367,18 +352,18 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { const revealedMsgs3FromVerifier = encodeRevealedMsgs(revealedMsgsRaw3, attributes3Struct, GlobalEncoder); checkMapsEqual(revealedMsgs3, revealedMsgs3FromVerifier); - const statement11 = buildStatement(sigParams1, sigPk1, revealedMsgs1FromVerifier, false); - const statement12 = buildStatement(sigParams2, sigPk2, revealedMsgs2FromVerifier, false); - const statement13 = buildStatement(sigParams3, sigPk3, revealedMsgs3FromVerifier, false); + const statement11 = verifierStmt(sigParams1, revealedMsgs1FromVerifier, pk1); + const statement12 = verifierStmt(sigParams2, revealedMsgs2FromVerifier, pk2); + const statement13 = verifierStmt(sigParams3, revealedMsgs3FromVerifier, pk3); // Construct statements for bound check - const statement14 = verifierStmt(timeMin, timeMax, 0); - const statement15 = verifierStmt(weightMin, weightMax, 0); - const statement16 = verifierStmt(heightMin, heightMax, 0); - const statement17 = verifierStmt(bmiMin, bmiMax, 0); - const statement18 = verifierStmt(scoreMin, scoreMax, 0); - const statement19 = verifierStmt(latMin, latMax, 0); - const statement20 = verifierStmt(longMin, longMax, 0); + const statement14 = vStmt(timeMin, timeMax, 0); + const statement15 = vStmt(weightMin, weightMax, 0); + const statement16 = vStmt(heightMin, heightMax, 0); + const statement17 = vStmt(bmiMin, bmiMax, 0); + const statement18 = vStmt(scoreMin, scoreMax, 0); + const statement19 = vStmt(latMin, latMax, 0); + const statement20 = vStmt(longMin, longMax, 0); const statementsVerifier = new Statements(); const sIdx11 = statementsVerifier.add(statement11); @@ -479,7 +464,7 @@ describe(`${Scheme} Range proof using LegoGroth16`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq22); // The verifier should independently construct this `ProofSpec` - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier, verifierSetupParams); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier, verifierSetupParams); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/cities.spec.ts b/tests/composite-proofs/msg-js-obj/cities.spec.ts index d351e88b..dba5e0df 100644 --- a/tests/composite-proofs/msg-js-obj/cities.spec.ts +++ b/tests/composite-proofs/msg-js-obj/cities.spec.ts @@ -1,14 +1,12 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { areUint8ArraysEqual, checkResult, stringToBytes } from '../../utils'; import { - CircomInputs, - CompositeProofG1, + CompositeProof, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, MetaStatements, - ProofSpecG1, + ProofSpec, SetupParam, SignedMessages, Statement, @@ -17,19 +15,12 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; -import { checkMapsEqual } from './index'; -import { defaultEncoder } from './data-and-encoder'; -import { - SignatureParams, - KeyPair, - PublicKey, - Signature, - buildStatement, - buildWitness, - Scheme, - adaptKeyForParams -} from '../../scheme'; import { PederCommKey } from '../../../src/ped-com'; +import { buildWitness, PublicKey, Scheme, SecretKey, Signature, SignatureParams } from '../../scheme'; +import { areUint8ArraysEqual, checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; +import { defaultEncoder } from './data-and-encoder'; +import { checkMapsEqual } from './index'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from './util'; // Test for scenario where the user wants to prove that he is not resident of certain cities. // Similar test can be written for other "set-membership" relations @@ -37,7 +28,9 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { let encoder: Encoder; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; + let params: SignatureParams; + let sk: SecretKey; + let pk: PublicKey; let commKey: PederCommKey; let signed: SignedMessages; @@ -74,13 +67,9 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { it('signers signs attributes', () => { // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(20, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - sigPk = keypair.publicKey; + [params, sk, pk] = getParamsAndKeys(100, label); - signed = Signature.signMessageObject(attributes, sk, label, encoder); - checkResult(signed.signature.verifyMessageObject(attributes, sigPk, label, encoder)); + signed = signAndVerify(attributes, encoder, label, sk, pk); }); it('proof verifies when city is neither NYC, SF, LA, Chicago, Seattle', () => { @@ -89,8 +78,7 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - sigPk = adaptKeyForParams(sigPk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes, revealedNames, @@ -104,7 +92,11 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { const metaStmtsProver = new MetaStatements(); const witnesses = new Witnesses(); - const sIdx1 = statementsProver.add(buildStatement(sigParams, sigPk, revealedMsgs, false)); + const sIdx1 = statementsProver.add(proverStmt( + sigParams, + revealedMsgs, + pk + )); witnesses.add(buildWitness(signed.signature, unrevealedMsgs, false)); for (const c of encodedCities) { @@ -117,10 +109,10 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { } // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver, setupParams); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver, setupParams); expect(proofSpecProver.isValid()).toEqual(true); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); @@ -129,7 +121,11 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { const statementsVerifier = new Statements(); const metaStmtsVerifier = new MetaStatements(); - const sIdx2 = statementsVerifier.add(buildStatement(sigParams, sigPk, revealedMsgs, false)); + const sIdx2 = statementsVerifier.add(verifierStmt( + sigParams, + revealedMsgsFromVerifier, + pk + )); for (const c of encodedCities) { const sIdx = statementsVerifier.add(Statement.publicInequalityG1FromSetupParamRefs(c, 0)); @@ -139,7 +135,7 @@ describe(`${Scheme} Proving that not resident of certain cities`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq); } - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier, setupParams); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier, setupParams); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/all_receipts_different.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/all_receipts_different.spec.ts index 232d9d5e..21ce5e94 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/all_receipts_different.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/all_receipts_different.spec.ts @@ -1,18 +1,18 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, EncodeFunc, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SetupParam, SignedMessages, @@ -22,19 +22,19 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; -import { defaultEncoder } from '../data-and-encoder'; import { - PublicKey, - Signature, - KeyPair, - SignatureParams, - buildSignatureParamsSetupParam, buildPublicKeySetupParam, - buildStatementFromSetupParamsRef, + buildSignatureParamsSetupParam, buildWitness, - Scheme + isKvac, + PublicKey, + Scheme, + Signature } from '../../../scheme'; +import { checkResult, getParamsAndKeys, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { defaultEncoder } from '../data-and-encoder'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmtFromSetupParamsRef, signAndVerify, verifierStmtFromSetupParamsRef } from '../util'; // Test for a scenario where a user wants to prove that he has 10 receipts where: // 1. all are unique because they have different ids @@ -53,7 +53,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece let minDateEncoded: Uint8Array; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; + let sigPk: PublicKey, sk, params; let r1csForUnique: ParsedR1CSFile, wasmForUnique: Uint8Array; let r1csForGreaterThan: ParsedR1CSFile, wasmForGreaterThan: Uint8Array; @@ -110,10 +110,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece it('signers signs attributes', () => { const numAttrs = Object.keys(receiptAttributesStruct).length; // Issuing multiple credentials with the same number of attributes so create sig. params only once for faster execution - let params = SignatureParams.generate(numAttrs, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - sigPk = keypair.publicKey; + [params, sk, sigPk] = getParamsAndKeys(numAttrs, label); for (let i = 0; i < numReceipts; i++) { receiptsAttributes.push({ @@ -123,10 +120,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece amount: minAmount + Math.ceil(Math.random() * 100), otherDetails: Math.random().toString(36).slice(2, 20) // https://stackoverflow.com/a/38622545 }); - signed.push(Signature.signMessageObject(receiptsAttributes[i], sk, params, encoder)); - checkResult( - signed[i].signature.verifyMessageObject(receiptsAttributes[i], sigPk, params, encoder) - ); + signed.push(signAndVerify(receiptsAttributes[i], encoder, label, sk, sigPk)) } }); @@ -148,7 +142,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece const revealedNames = new Set(); revealedNames.add('posId'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(receiptAttributesStruct, label); + const sigParams = adaptedSigParams(receiptAttributesStruct, label); const revealedMsgs: Map[] = []; const unrevealedMsgs: Map[] = []; @@ -165,7 +159,9 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece const proverSetupParams: SetupParam[] = []; // Setup params for the signature proverSetupParams.push(buildSignatureParamsSetupParam(sigParams)); - proverSetupParams.push(buildPublicKeySetupParam(sigPk)); + if (!isKvac()) { + proverSetupParams.push(buildPublicKeySetupParam(sigPk)); + } // Setup params for the uniqueness check SNARK proverSetupParams.push(SetupParam.r1cs(r1csForUnique)); proverSetupParams.push(SetupParam.bytes(wasmForUnique)); @@ -175,23 +171,25 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece proverSetupParams.push(SetupParam.bytes(wasmForGreaterThan)); proverSetupParams.push(SetupParam.legosnarkProvingKeyUncompressed(provingKeyForGreaterThan)); + const r1csSetupParamOffset = isKvac() ? 1: 0; + const statementsProver = new Statements(); // 1 statement for proving knowledge of 1 signature (receipt) const sIdxs: number[] = []; for (let i = 0; i < numReceipts; i++) { - sIdxs.push(statementsProver.add(buildStatementFromSetupParamsRef(0, 1, revealedMsgs[i], false))); + sIdxs.push(statementsProver.add(proverStmtFromSetupParamsRef(0, revealedMsgs[i],1))); } // Statement to prove uniqueness of all receipt-ids - sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(2, 3, 4))); + sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(2 - r1csSetupParamOffset, 3 - r1csSetupParamOffset, 4 - r1csSetupParamOffset))); // Creating 2 statements for greater than check, one for amount and other for date of each receipt for (let i = 0; i < numReceipts; i++) { // For greater than check on amount - sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(5, 6, 7))); + sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(5 - r1csSetupParamOffset, 6 - r1csSetupParamOffset, 7 - r1csSetupParamOffset))); // For greater than check on date - sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(5, 6, 7))); + sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(5 - r1csSetupParamOffset, 6 - r1csSetupParamOffset, 7 - r1csSetupParamOffset))); } const metaStmtsProver = new MetaStatements(); @@ -216,7 +214,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece metaStmtsProver.addWitnessEquality(witnessEq3); } - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver, proverSetupParams); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver, proverSetupParams); expect(proofSpecProver.isValid()).toEqual(true); const witnesses = new Witnesses(); @@ -246,7 +244,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece witnesses.add(Witness.r1csCircomWitness(inputs3)); } - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); console.timeEnd('Proof generate'); console.time('Proof verify'); @@ -259,7 +257,9 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(buildSignatureParamsSetupParam(sigParams)); - verifierSetupParams.push(buildPublicKeySetupParam(sigPk)); + if (!isKvac()) { + verifierSetupParams.push(buildPublicKeySetupParam(sigPk)); + } // generateFieldElementFromNumber(1) as uniqueness check passes, i.e. all ids are different verifierSetupParams.push(SetupParam.fieldElementVec([generateFieldElementFromNumber(1)])); verifierSetupParams.push(SetupParam.legosnarkVerifyingKeyUncompressed(verifyingKeyForUniqueness)); @@ -273,14 +273,14 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece const sIdxVs: number[] = []; for (let i = 0; i < numReceipts; i++) { - sIdxVs.push(statementsVerifier.add(buildStatementFromSetupParamsRef(0, 1, revealedMsgsFromVerifier[i], false))); + sIdxVs.push(statementsVerifier.add(verifierStmtFromSetupParamsRef(0, revealedMsgsFromVerifier[i], 1, false))); } - sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(2, 3))); + sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(2 - r1csSetupParamOffset, 3 - r1csSetupParamOffset))); for (let i = 0; i < numReceipts; i++) { - sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(4, 6))); - sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(5, 6))); + sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(4 - r1csSetupParamOffset, 6 - r1csSetupParamOffset))); + sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(5 - r1csSetupParamOffset, 6 - r1csSetupParamOffset))); } const metaStmtsVerifier = new MetaStatements(); @@ -302,7 +302,7 @@ describe(`${Scheme} Proving the possession of 10 unique receipts, with each rece metaStmtsVerifier.addWitnessEquality(witnessEq3); } - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier, verifierSetupParams); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier, verifierSetupParams); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/assets-liabilities.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/assets-liabilities.spec.ts index efb9a14d..0fe7c06d 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/assets-liabilities.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/assets-liabilities.spec.ts @@ -1,8 +1,7 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, EncodeFunc, Encoder, @@ -10,11 +9,12 @@ import { flattenObjectToKeyValuesList, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - QuasiProofSpecG1, + QuasiProofSpec, R1CSSnarkSetup, SetupParam, SignedMessages, @@ -24,21 +24,20 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; -import { defaultEncoder } from '../data-and-encoder'; import { - SignatureParams, - KeyPair, - Signature, - PublicKey, - buildSignatureParamsSetupParam, + adaptKeyForParams, buildPublicKeySetupParam, - buildStatementFromSetupParamsRef, - buildWitness, - isPS, + buildSignatureParamsSetupParam, + buildWitness, isKvac, + PublicKey, Scheme, - adaptKeyForParams + Signature, + SignatureParams } from '../../../scheme'; +import { checkResult, getParamsAndKeys, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { defaultEncoder } from '../data-and-encoder'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmtFromSetupParamsRef, signAndVerify, verifierStmtFromSetupParamsRef } from '../util'; // Test for a scenario where a user have 20 assets and liabilities, in different credentials (signed documents). The user // proves that the sum of his assets is greater than sum of liabilities by 10000 without revealing actual values of either. @@ -46,7 +45,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie let encoder: Encoder; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; + let pk: PublicKey, sk, params; let r1cs: ParsedR1CSFile; let wasm: Uint8Array; @@ -140,11 +139,10 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie const numAssetAttrs = flattenObjectToKeyValuesList(assetAttributesStruct)[0].length; const numLiablAttrs = flattenObjectToKeyValuesList(liabilitiesAttributesStruct)[0].length; // Issuing multiple credentials with the same number of attributes so create sig. params only once for faster execution + [params, sk, pk] = getParamsAndKeys(Math.max(numAssetAttrs, numLiablAttrs), label); + let assetSigParams = SignatureParams.generate(numAssetAttrs, label); let liablSigParams = SignatureParams.generate(numLiablAttrs, label); - const keypair = KeyPair.generate(assetSigParams); - const sk = keypair.secretKey; - sigPk = keypair.publicKey; // Generate assets and liabilities for (let i = 0; i < numAssetCredentials; i++) { @@ -163,15 +161,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie id5: (i + 5) * 10000 } }); - signedAssets.push(Signature.signMessageObject(assetAttributes[i], sk, assetSigParams, encoder)); - checkResult( - signedAssets[i].signature.verifyMessageObject( - assetAttributes[i], - sigPk, - assetSigParams, - encoder - ) - ); + signedAssets.push(signAndVerify(assetAttributes[i], encoder, label, sk, pk)); } for (let i = 0; i < numLiabilityCredentials; i++) { @@ -189,15 +179,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie id4: (i + 4) * 100 } }); - signedLiabilities.push(Signature.signMessageObject(liabilityAttributes[i], sk, liablSigParams, encoder)); - checkResult( - signedLiabilities[i].signature.verifyMessageObject( - liabilityAttributes[i], - sigPk, - liablSigParams, - encoder - ) - ); + signedLiabilities.push(signAndVerify(liabilityAttributes[i], encoder, label, sk, pk)); } }); @@ -227,8 +209,8 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie const revealedNames = new Set(); revealedNames.add('fname'); - const sigParamsAssets = SignatureParams.getSigParamsForMsgStructure(assetAttributesStruct, label); - const sigParamsLiabilities = SignatureParams.getSigParamsForMsgStructure(liabilitiesAttributesStruct, label); + const sigParamsAssets = adaptedSigParams(assetAttributesStruct, label); + const sigParamsLiabilities = adaptedSigParams(liabilitiesAttributesStruct, label); console.time('Proof generate'); // Prepare revealed and unrevealed attributes @@ -256,29 +238,31 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie const proverSetupParams: SetupParam[] = []; proverSetupParams.push(buildSignatureParamsSetupParam(sigParamsAssets)); proverSetupParams.push(buildSignatureParamsSetupParam(sigParamsLiabilities)); - proverSetupParams.push( - buildPublicKeySetupParam(adaptKeyForParams(sigPk, sigParamsAssets)) - ); proverSetupParams.push(SetupParam.r1cs(r1cs)); proverSetupParams.push(SetupParam.bytes(wasm)); proverSetupParams.push(SetupParam.legosnarkProvingKeyUncompressed(provingKey)); - proverSetupParams.push( - buildPublicKeySetupParam(adaptKeyForParams(sigPk, sigParamsLiabilities)) - ); + if (!isKvac()) { + proverSetupParams.push( + buildPublicKeySetupParam(adaptKeyForParams(pk, sigParamsAssets)) + ); + proverSetupParams.push( + buildPublicKeySetupParam(adaptKeyForParams(pk, sigParamsLiabilities)) + ); + } const statementsProver = new Statements(); // Statements to prove possesion of credentials const sIdxs: number[] = []; for (let i = 0; i < numAssetCredentials; i++) { - sIdxs.push(statementsProver.add(buildStatementFromSetupParamsRef(0, 2, revealedMsgs[i], false))); + sIdxs.push(statementsProver.add(proverStmtFromSetupParamsRef(0, revealedMsgs[i], 5, false))); } for (let i = numAssetCredentials; i < numAssetCredentials + numLiabilityCredentials; i++) { - sIdxs.push(statementsProver.add(buildStatementFromSetupParamsRef(1, 6, revealedMsgs[i], false))); + sIdxs.push(statementsProver.add(proverStmtFromSetupParamsRef(1, revealedMsgs[i], 6, false))); } // For proving the relation between assets and liabilities. - sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(3, 4, 5))); + sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(2, 3, 4))); const metaStmtsProver = new MetaStatements(); @@ -337,7 +321,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie } } - const proofSpecProver = new QuasiProofSpecG1(statementsProver, metaStmtsProver, proverSetupParams); + const proofSpecProver = new QuasiProofSpec(statementsProver, metaStmtsProver, proverSetupParams); const witnesses = new Witnesses(); for (let i = 0; i < numAssetCredentials; i++) { @@ -373,7 +357,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie inputs.setPublicInput('min', minDiffEncoded); witnesses.add(Witness.r1csCircomWitness(inputs)); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proofSpecProver, witnesses); + const proof = CompositeProof.generateUsingQuasiProofSpec(proofSpecProver, witnesses); console.timeEnd('Proof generate'); console.time('Proof verify'); @@ -391,31 +375,33 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(buildSignatureParamsSetupParam(sigParamsAssets)); verifierSetupParams.push(buildSignatureParamsSetupParam(sigParamsLiabilities)); - verifierSetupParams.push( - buildPublicKeySetupParam(adaptKeyForParams(sigPk, sigParamsAssets)) - ); // generateFieldElementFromNumber(1) as the condition "sum of assets - sum of liabilities > minDiff" should be true, // if "sum of assets - sum of liabilities <= minDiff" was being checked, then use generateFieldElementFromNumber(0) verifierSetupParams.push(SetupParam.fieldElementVec([generateFieldElementFromNumber(1), minDiffEncoded])); verifierSetupParams.push(SetupParam.legosnarkVerifyingKeyUncompressed(verifyingKey)); - verifierSetupParams.push( - buildPublicKeySetupParam(adaptKeyForParams(sigPk, sigParamsLiabilities)) - ); + if (!isKvac()) { + verifierSetupParams.push( + buildPublicKeySetupParam(adaptKeyForParams(pk, sigParamsAssets)) + ); + verifierSetupParams.push( + buildPublicKeySetupParam(adaptKeyForParams(pk, sigParamsLiabilities)) + ); + } const statementsVerifier = new Statements(); const sIdxVs: number[] = []; for (let i = 0; i < numAssetCredentials; i++) { - for (const stmt of [].concat(buildStatementFromSetupParamsRef(0, 2, revealedMsgsFromVerifier[i], false))) + for (const stmt of [].concat(verifierStmtFromSetupParamsRef(0, revealedMsgsFromVerifier[i], 4, false))) sIdxVs.push(statementsVerifier.add(stmt)); } for (let i = numAssetCredentials; i < numAssetCredentials + numLiabilityCredentials; i++) { - for (const stmt of [].concat(buildStatementFromSetupParamsRef(1, 5, revealedMsgsFromVerifier[i], false))) + for (const stmt of [].concat(verifierStmtFromSetupParamsRef(1, revealedMsgsFromVerifier[i], 5, false))) sIdxVs.push(statementsVerifier.add(stmt)); } - sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(3, 4))); + sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(2, 3))); const metaStmtsVerifier = new MetaStatements(); @@ -472,7 +458,7 @@ describe(`${Scheme} Proving that sum of assets is greater than sum of liabilitie } } - const proofSpecVerifier = new QuasiProofSpecG1(statementsVerifier, metaStmtsVerifier, verifierSetupParams); + const proofSpecVerifier = new QuasiProofSpec(statementsVerifier, metaStmtsVerifier, verifierSetupParams); checkResult(proof.verifyUsingQuasiProofSpec(proofSpecVerifier)); console.timeEnd('Proof verify'); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/blood-group.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/blood-group.spec.ts index 1f80dcbf..75315604 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/blood-group.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/blood-group.spec.ts @@ -1,17 +1,17 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { areUint8ArraysEqual, checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SignedMessages, Statement, @@ -20,19 +20,18 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; -import { defaultEncoder } from '../data-and-encoder'; +import { buildWitness, PublicKey, Scheme, Signature } from '../../../scheme'; import { - PublicKey, - KeyPair, - SignatureParams, - Signature, - buildStatement, - buildWitness, - isPS, - Scheme, - adaptKeyForParams -} from '../../../scheme'; + areUint8ArraysEqual, + checkResult, + getParamsAndKeys, + getWasmBytes, + parseR1CSFile, + stringToBytes +} from '../../../utils'; +import { defaultEncoder } from '../data-and-encoder'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from '../util'; // Test for a scenario where a user wants to prove that his blood group is AB- without revealing the blood group. // Similar test can be written for other "not-equals" relations like user is not resident of certain city @@ -41,7 +40,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { let encodedABNeg: Uint8Array; const label = stringToBytes('Sig params label'); - let pk: PublicKey; + let pk: PublicKey, sk, params; // CredentialBuilder for the user with blood group AB+ let signed1: SignedMessages; @@ -120,16 +119,10 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { it('signers signs attributes', () => { // Message count shouldn't matter as `label` is known - const params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - pk = keypair.publicKey; - - signed1 = Signature.signMessageObject(attributes1, sk, label, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk, label, encoder)); + [params, sk, pk] = getParamsAndKeys(100, label); - signed2 = Signature.signMessageObject(attributes2, sk, label, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk, label, encoder)); + signed1 = signAndVerify(attributes1, encoder, label, sk, pk); + signed2 = signAndVerify(attributes2, encoder, label, sk, pk); }); it('proof verifies when blood groups is not AB-', () => { @@ -138,8 +131,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - const sigPK = adaptKeyForParams(pk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes1, revealedNames, @@ -147,7 +139,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'John' }); - const statement1 = buildStatement(sigParams, sigPK, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, pk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(); @@ -163,7 +155,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs, false); @@ -176,13 +168,13 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement(sigParams, sigPK, revealedMsgsFromVerifier, false); + const statement3 = verifierStmt(sigParams, revealedMsgsFromVerifier, pk); const pub = [generateFieldElementFromNumber(1), encodedABNeg]; const statement4 = Statement.r1csCircomVerifier(pub, verifyingKey); @@ -197,7 +189,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -209,8 +201,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - const sigPK = adaptKeyForParams(pk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes2, revealedNames, @@ -218,12 +209,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'Carol' }); - const statement1 = buildStatement( - sigParams, - adaptKeyForParams(pk, sigParams), - revealedMsgs, - false - ); + const statement1 = proverStmt(sigParams, revealedMsgs, pk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(); @@ -238,7 +224,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed2.signature, unrevealedMsgs, false); @@ -251,13 +237,13 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement(sigParams, sigPK, revealedMsgsFromVerifier, false); + const statement3 = verifierStmt(sigParams, revealedMsgsFromVerifier, pk); const pub = [generateFieldElementFromNumber(1), encodedABNeg]; const statement4 = Statement.r1csCircomVerifier(pub, verifyingKey); @@ -272,7 +258,7 @@ describe(`${Scheme} Proving that blood group is not AB-`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); expect(proof.verify(proofSpecVerifier).verified).toEqual(false); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/grade.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/grade.spec.ts index 93612ca8..2be3bc6a 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/grade.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/grade.spec.ts @@ -1,8 +1,16 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { areUint8ArraysEqual, checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { + areUint8ArraysEqual, + checkResult, + getParamsAndKeys, + getWasmBytes, + parseR1CSFile, + stringToBytes +} from '../../../utils'; +import { + initializeWasm, CircomInputs, - CompositeProofG1, + CompositeProof, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, @@ -11,7 +19,7 @@ import { LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SignedMessages, Statement, @@ -27,11 +35,12 @@ import { KeyPair, PublicKey, Signature, - buildStatement, + buildVerifierStatement, buildWitness, Scheme, adaptKeyForParams } from '../../../scheme'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from '../util'; // Test for scenario where the user wants to prove that his grade belongs/does not belong to the given set. // Similar test can be written for other "set-membership" relations like user is not resident of certain cities @@ -39,7 +48,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { let encoder: Encoder; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; + let sigPk: PublicKey, sk, params; let signed1: SignedMessages; let signed2: SignedMessages; @@ -101,16 +110,10 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { it('signers signs attributes', () => { // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(20, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - sigPk = keypair.publicKey; - - signed1 = Signature.signMessageObject(attributes1, sk, label, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, sigPk, label, encoder)); + [params, sk, sigPk] = getParamsAndKeys(20, label); - signed2 = Signature.signMessageObject(attributes2, sk, label, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, sigPk, label, encoder)); + signed1 = signAndVerify(attributes1, encoder, label, sk, sigPk); + signed2 = signAndVerify(attributes2, encoder, label, sk, sigPk); }); it('proof verifies when grade is either A+, A, B+, B or C', () => { @@ -119,8 +122,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - sigPk = adaptKeyForParams(sigPk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes1, revealedNames, @@ -128,7 +130,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'John' }); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(statement1); @@ -142,7 +144,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs, false); @@ -155,13 +157,13 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement3 = verifierStmt(sigParams, revealedMsgs, sigPk); // generateFieldElementFromNumber(1) because membership is being check, use generateFieldElementFromNumber(0) for checking non-membership const pub = [generateFieldElementFromNumber(1), ...encodedGrades]; const statement4 = Statement.r1csCircomVerifier(pub, verifyingKey); @@ -181,7 +183,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { const metaStmtsVerifier = new MetaStatements(); metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(verifierStatements, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -193,7 +195,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes2, revealedNames, @@ -201,7 +203,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'Carol' }); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(); @@ -216,7 +218,7 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed2.signature, unrevealedMsgs, false); @@ -229,14 +231,14 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement(sigParams, sigPk, revealedMsgs, false); - const pub = [generateFieldElementFromNumber(1), ...encodedGrades]; + const statement3 = verifierStmt(sigParams, revealedMsgs, sigPk); + const pub = [generateFieldElementFromNumber(0), ...encodedGrades]; const statement4 = Statement.r1csCircomVerifier(pub, verifyingKey); const verifierStatements = new Statements(statement3); @@ -253,9 +255,9 @@ describe(`${Scheme} Proving that grade is either A+, A, B+, B or C`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(verifierStatements, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); - expect(proof.verify(proofSpecVerifier).verified).toEqual(false); + checkResult(proof.verify(proofSpecVerifier)); }); }); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/mimc-hash.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/mimc-hash.spec.ts index 29f5fee0..e1cf73f0 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/mimc-hash.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/mimc-hash.spec.ts @@ -1,18 +1,18 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, EncodeFunc, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SignedMessages, Statement, @@ -21,19 +21,11 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; +import { buildWitness, PublicKey, Scheme, Signature } from '../../../scheme'; +import { getParamsAndKeys, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; import { defaultEncoder } from '../data-and-encoder'; -import { - PublicKey, - KeyPair, - SignatureParams, - Signature, - buildStatement, - buildWitness, - isPS, - Scheme, - adaptKeyForParams -} from '../../../scheme'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from '../util'; // Test for a scenario where user wants to prove that certain attribute of his credential is the preimage of a public MiMC hash. describe(`${Scheme} Proving that certain attribute of a credential is the preimage of a public MiMC hash`, () => { @@ -43,7 +35,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima const pubKeyHash = '30898ada1347d8fc53ffe37656edd4f8c42d4b791730ce05a1f41b72bc30f039'; // This is a big-endian hex string const label = stringToBytes('Sig params label'); - let pk: PublicKey; + let pk: PublicKey, sk, params; let signed1: SignedMessages; let signed2: SignedMessages; @@ -126,16 +118,10 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima it('signers signs attributes', () => { // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - pk = keypair.publicKey; + [params, sk, pk] = getParamsAndKeys(100, label); - signed1 = Signature.signMessageObject(attributes1, sk, label, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk, label, encoder)); - - signed2 = Signature.signMessageObject(attributes2, sk, label, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk, label, encoder)); + signed1 = signAndVerify(attributes1, encoder, label, sk, pk); + signed2 = signAndVerify(attributes2, encoder, label, sk, pk); }); it('proof verifies when public key hash matches the expected hash', () => { @@ -150,8 +136,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima const revealedNames = new Set(); revealedNames.add('fname'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); - const sigPk = adaptKeyForParams(pk, sigParams); + const sigParams = adaptedSigParams(attributesStruct, label); const [revealedMsgs, unrevealedMsgs, revealedMsgsRaw] = getRevealedAndUnrevealed( attributes1, revealedNames, @@ -160,7 +145,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima expect(revealedMsgsRaw).toEqual({ fname: 'John' }); console.time('Proof generate'); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, pk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(); @@ -175,7 +160,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima metaStmtsProver.addWitnessEquality(witnessEq1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed.signature, unrevealedMsgs, false); @@ -188,7 +173,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); console.timeEnd('Proof generate'); console.time('Proof verify'); @@ -196,12 +181,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement3 = buildStatement( - sigParams, - adaptKeyForParams(pk, sigParams), - revealedMsgsFromVerifier, - false - ); + const statement3 = verifierStmt(sigParams, revealedMsgsFromVerifier, pk); const pub = [encodedPubKeyHash]; const statement4 = Statement.r1csCircomVerifier(pub, verifyingKey); @@ -216,7 +196,7 @@ describe(`${Scheme} Proving that certain attribute of a credential is the preima metaStmtsVerifier.addWitnessEquality(witnessEq2); - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); expect(proof.verify(proofSpecVerifier).verified).toEqual(doesCheckPass); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/vaccination.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/vaccination.spec.ts index 16ca01a7..2ccf2e4a 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/vaccination.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/vaccination.spec.ts @@ -1,19 +1,19 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, EncodeFunc, Encoder, encodeRevealedMsgs, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SignedMessages, Statement, @@ -22,20 +22,11 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; +import { buildWitness, PublicKey, Scheme, SecretKey, Signature } from '../../../scheme'; +import { checkResult, getParamsAndKeys, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; import { defaultEncoder } from '../data-and-encoder'; -import { - buildStatement, - buildWitness, - Signature, - KeyPair, - PublicKey, - SecretKey, - SignatureParams, - isPS, - Scheme, - adaptKeyForParams -} from '../../../scheme'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmt, signAndVerify, verifierStmt } from '../util'; // Test for a scenario where a user wants to prove that he either got the vaccination less than 30 days ago or got // tested negative less than 2 days ago but does not reveal when these events happened or which of these conditions is true. @@ -43,8 +34,8 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last let encoder: Encoder; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; - let sigSk: SecretKey; + let pk: PublicKey, params; + let sk: SecretKey; const secondsInADay = 24 * 60 * 60; // Time in seconds as of now @@ -118,10 +109,8 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last function sign(vDays: number, tDays: number): [SignedMessages, SignedMessages] { vaccinationAttributes.vaccination.date = now - vDays * secondsInADay; diseaseTestAttributes.test.date = now - tDays * secondsInADay; - const signedV = Signature.signMessageObject(vaccinationAttributes, sigSk, label, encoder); - checkResult(signedV.signature.verifyMessageObject(vaccinationAttributes, sigPk, label, encoder)); - const signedT = Signature.signMessageObject(diseaseTestAttributes, sigSk, label, encoder); - checkResult(signedT.signature.verifyMessageObject(diseaseTestAttributes, sigPk, label, encoder)); + const signedV = signAndVerify(vaccinationAttributes, encoder, label, sk, pk); + const signedT = signAndVerify(diseaseTestAttributes, encoder, label, sk, pk); return [signedV, signedT]; } @@ -145,10 +134,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last wasm = getWasmBytes('greater_than_or_public_64.wasm'); // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - sigSk = keypair.secretKey; - sigPk = keypair.publicKey; + [params, sk, pk] = getParamsAndKeys(100, label); }); it('verifier generates SNARk proving and verifying key', async () => { @@ -166,8 +152,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last revealedNamesV.add('fname'); revealedNamesV.add('vaccination.name'); - const sigParamsV = SignatureParams.getSigParamsForMsgStructure(vaccinationAttributesStruct, label); - const pkV = adaptKeyForParams(sigPk, sigParamsV); + const sigParamsV = adaptedSigParams(vaccinationAttributesStruct, label); const [revealedMsgsV, unrevealedMsgsV, revealedMsgsRawV] = getRevealedAndUnrevealed( vaccinationAttributes, revealedNamesV, @@ -180,8 +165,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last revealedNamesT.add('test.type'); revealedNamesT.add('test.result'); - const sigParamsT = SignatureParams.getSigParamsForMsgStructure(diseaseTestAttributesStruct, label); - const pkT = adaptKeyForParams(sigPk, sigParamsT); + const sigParamsT = adaptedSigParams(diseaseTestAttributesStruct, label); const [revealedMsgsT, unrevealedMsgsT, revealedMsgsRawT] = getRevealedAndUnrevealed( diseaseTestAttributes, revealedNamesT, @@ -189,8 +173,8 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last ); expect(revealedMsgsRawT).toEqual({ fname: 'John', test: { type: 'Antigen', result: 'Negative' } }); - const statement1 = buildStatement(sigParamsV, pkV, revealedMsgsV, false); - const statement2 = buildStatement(sigParamsT, pkT, revealedMsgsT, false); + const statement1 = proverStmt(sigParamsV, revealedMsgsV, pk); + const statement2 = proverStmt(sigParamsT, revealedMsgsT, pk); const statement3 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const statementsProver = new Statements(); @@ -221,7 +205,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last metaStmtsProver.addWitnessEquality(witnessEq2); metaStmtsProver.addWitnessEquality(witnessEq3); - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witnesses = new Witnesses(); @@ -235,7 +219,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last inputs.setPublicInput('in4', encodedTime2DaysAgo); witnesses.add(Witness.r1csCircomWitness(inputs)); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); const revealedMsgsFromVerifierV = encodeRevealedMsgs(revealedMsgsRawV, vaccinationAttributesStruct, encoder); checkMapsEqual(revealedMsgsV, revealedMsgsFromVerifierV); @@ -243,8 +227,8 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last const revealedMsgsFromVerifierT = encodeRevealedMsgs(revealedMsgsRawT, diseaseTestAttributesStruct, encoder); checkMapsEqual(revealedMsgsT, revealedMsgsFromVerifierT); - const statement4 = buildStatement(sigParamsV, pkV, revealedMsgsFromVerifierV, false); - const statement5 = buildStatement(sigParamsT, pkT, revealedMsgsFromVerifierT, false); + const statement4 = verifierStmt(sigParamsV, revealedMsgsFromVerifierV, pk, false); + const statement5 = verifierStmt(sigParamsT, revealedMsgsFromVerifierT, pk, false); const pub = [generateFieldElementFromNumber(checkShouldPass ? 1 : 0), encodedTime30DaysAgo, encodedTime2DaysAgo]; const statement6 = Statement.r1csCircomVerifier(pub, verifyingKey); @@ -276,7 +260,7 @@ describe(`${Scheme} Proving that either vaccinated less than 30 days ago OR last metaStmtsVerifier.addWitnessEquality(witnessEq5); metaStmtsVerifier.addWitnessEquality(witnessEq6); - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/r1cs/yearly-income.spec.ts b/tests/composite-proofs/msg-js-obj/r1cs/yearly-income.spec.ts index d791674b..c1c9f121 100644 --- a/tests/composite-proofs/msg-js-obj/r1cs/yearly-income.spec.ts +++ b/tests/composite-proofs/msg-js-obj/r1cs/yearly-income.spec.ts @@ -1,8 +1,7 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { CircomInputs, - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, EncodeFunc, Encoder, @@ -10,11 +9,12 @@ import { flattenObjectToKeyValuesList, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, SetupParam, SignedMessages, @@ -24,19 +24,18 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../../src'; -import { checkMapsEqual } from '../index'; -import { defaultEncoder } from '../data-and-encoder'; import { - PublicKey, - KeyPair, - SignatureParams, - Signature, buildPublicKeySetupParam, - buildStatementFromSetupParamsRef, buildSignatureParamsSetupParam, - buildWitness, - Scheme + buildWitness, isKvac, + PublicKey, + Scheme, + Signature } from '../../../scheme'; +import { checkResult, getParamsAndKeys, getWasmBytes, parseR1CSFile, stringToBytes } from '../../../utils'; +import { defaultEncoder } from '../data-and-encoder'; +import { checkMapsEqual } from '../index'; +import { adaptedSigParams, proverStmtFromSetupParamsRef, signAndVerify, verifierStmtFromSetupParamsRef } from '../util'; // Test for a scenario where a user wants to prove that his yearly income is less than 25000 where his income comprises // of 12 payslip credentials, 1 for each month's. @@ -44,7 +43,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips let encoder: Encoder; const label = stringToBytes('Sig params label'); - let sigPk: PublicKey; + let pk: PublicKey, sk, params; let r1cs: ParsedR1CSFile; let wasm: Uint8Array; @@ -107,10 +106,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips it('signers signs attributes', () => { const numAttrs = flattenObjectToKeyValuesList(payslipAttributesStruct)[0].length; // Issuing multiple credentials with the same number of attributes so create sig. params only once for faster execution - let params = SignatureParams.generate(numAttrs, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - sigPk = keypair.publicKey; + [params, sk, pk] = getParamsAndKeys(numAttrs, label); for (let i = 0; i < numPayslips; i++) { payslipAttributes.push({ @@ -129,10 +125,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips amount: Math.floor(Math.random() * 2000) // salary will be under 2000 } }); - signed.push(Signature.signMessageObject(payslipAttributes[i], sk, params, encoder)); - checkResult( - signed[i].signature.verifyMessageObject(payslipAttributes[i], sigPk, params, encoder) - ); + signed.push(signAndVerify(payslipAttributes[i], encoder, label, sk, pk)); } }); @@ -155,7 +148,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips revealedNames.add('salary.year'); revealedNames.add('salary.month'); - const sigParams = SignatureParams.getSigParamsForMsgStructure(payslipAttributesStruct, label); + const sigParams = adaptedSigParams(payslipAttributesStruct, label); const revealedMsgs: Map[] = []; const unrevealedMsgs: Map[] = []; @@ -171,19 +164,21 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips const proverSetupParams: SetupParam[] = []; proverSetupParams.push(buildSignatureParamsSetupParam(sigParams)); - proverSetupParams.push(buildPublicKeySetupParam(sigPk)); proverSetupParams.push(SetupParam.r1cs(r1cs)); proverSetupParams.push(SetupParam.bytes(wasm)); proverSetupParams.push(SetupParam.legosnarkProvingKeyUncompressed(provingKey)); + if (!isKvac()) { + proverSetupParams.push(buildPublicKeySetupParam(pk)); + } const statementsProver = new Statements(); const sIdxs: number[] = []; for (let i = 0; i < numPayslips; i++) { - sIdxs.push(statementsProver.add(buildStatementFromSetupParamsRef(0, 1, revealedMsgs[i], false))); + sIdxs.push(statementsProver.add(proverStmtFromSetupParamsRef(0, revealedMsgs[i], 4, false))); } - sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(2, 3, 4))); + sIdxs.push(statementsProver.add(Statement.r1csCircomProverFromSetupParamRefs(1, 2, 3))); const metaStmtsProver = new MetaStatements(); @@ -217,7 +212,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips metaStmtsProver.addWitnessEquality(witnessEq); } - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver, proverSetupParams); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver, proverSetupParams); expect(proofSpecProver.isValid()).toEqual(true); const witnesses = new Witnesses(); @@ -234,7 +229,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips inputs.setPublicInput('max', salaryLimitEncoded); witnesses.add(Witness.r1csCircomWitness(inputs)); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); console.timeEnd('Proof generate'); console.time('Proof verify'); @@ -247,7 +242,6 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(buildSignatureParamsSetupParam(sigParams)); - verifierSetupParams.push(buildPublicKeySetupParam(sigPk)); // To prove not less than, i.e. <= or >, replace `generateFieldElementFromNumber(1)` with `generateFieldElementFromNumber(0)` // as 1 indicates success of the check, 0 indicates failure of the check @@ -255,14 +249,18 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips verifierSetupParams.push(SetupParam.legosnarkVerifyingKeyUncompressed(verifyingKey)); + if (!isKvac()) { + verifierSetupParams.push(buildPublicKeySetupParam(pk)); + } + const statementsVerifier = new Statements(); const sIdxVs: number[] = []; for (let i = 0; i < numPayslips; i++) { - sIdxVs.push(statementsVerifier.add(buildStatementFromSetupParamsRef(0, 1, revealedMsgsFromVerifier[i], false))); + sIdxVs.push(statementsVerifier.add(verifierStmtFromSetupParamsRef(0, revealedMsgsFromVerifier[i], 3, false))); } - sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(2, 3))); + sIdxVs.push(statementsVerifier.add(Statement.r1csCircomVerifierFromSetupParamRefs(1, 2))); const metaStmtsVerifier = new MetaStatements(); @@ -295,7 +293,7 @@ describe(`${Scheme} Proving that yearly income calculated from monthly payslips metaStmtsVerifier.addWitnessEquality(witnessEq); } - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier, verifierSetupParams); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier, verifierSetupParams); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/msg-js-obj/saver.spec.ts b/tests/composite-proofs/msg-js-obj/saver.spec.ts index 7011c0cd..6184d2f6 100644 --- a/tests/composite-proofs/msg-js-obj/saver.spec.ts +++ b/tests/composite-proofs/msg-js-obj/saver.spec.ts @@ -1,14 +1,13 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getBoundCheckSnarkKeys, readByteArrayFromFile, stringToBytes } from '../../utils'; import { - CompositeProofG1, + CompositeProof, dockSaverEncryptionGensUncompressed, encodeRevealedMsgs, getAdaptedSignatureParamsForMessages, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, MetaStatements, - QuasiProofSpecG1, + QuasiProofSpec, SaverChunkedCommitmentKey, SaverDecryptionKeyUncompressed, SaverDecryptor, @@ -23,9 +22,17 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; +import { adaptKeyForParams, buildWitness, Scheme, Signature } from '../../scheme'; +import { + checkResult, + getBoundCheckSnarkKeys, + getParamsAndKeys, + readByteArrayFromFile, + stringToBytes +} from '../../utils'; import { attributes1, attributes1Struct, GlobalEncoder } from './data-and-encoder'; import { checkMapsEqual } from './index'; -import { adaptKeyForParams, buildStatement, buildWitness, isPS, KeyPair, Scheme, Signature, SignatureParams } from '../../scheme'; +import { proverStmt, signAndVerify, verifierStmt } from './util'; describe(`${Scheme} Verifiable encryption using SAVER`, () => { beforeAll(async () => { @@ -42,13 +49,9 @@ describe(`${Scheme} Verifiable encryption using SAVER`, () => { const label = stringToBytes('Sig params label - this is public'); // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - const pk = keypair.publicKey; + const [params, sk, pk] = getParamsAndKeys(100, label); - const signed = Signature.signMessageObject(attributes1, sk, label, GlobalEncoder); - checkResult(signed.signature.verifyMessageObject(attributes1, pk, label, GlobalEncoder)); + const signed = signAndVerify(attributes1, GlobalEncoder, label, sk, pk); // Setup for decryptor let saverEncGens, saverSk, saverProvingKey, saverVerifyingKey, saverEk, saverDk; @@ -113,7 +116,11 @@ describe(`${Scheme} Verifiable encryption using SAVER`, () => { ); expect(revealedMsgsRaw).toEqual({ fname: 'John', lname: 'Smith', country: 'USA' }); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt( + sigParams, + revealedMsgs, + sigPk + ); const statement2 = Statement.saverProver(saverEncGens, commKey, saverEk, saverProvingKey, chunkBitSize); const statement3 = Statement.boundCheckLegoProver(timeMin, timeMax, boundCheckProvingKey); @@ -135,7 +142,7 @@ describe(`${Scheme} Verifiable encryption using SAVER`, () => { metaStmtsProver.addWitnessEquality(witnessEq2); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new QuasiProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new QuasiProofSpec(statementsProver, metaStmtsProver); const witness1 = buildWitness(signed.signature, unrevealedMsgs, false); const witness2 = Witness.saver(signed.encodedMessages['SSN']); @@ -144,13 +151,17 @@ describe(`${Scheme} Verifiable encryption using SAVER`, () => { witnesses.add(witness2); witnesses.add(witness3); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proofSpecProver, witnesses); + const proof = CompositeProof.generateUsingQuasiProofSpec(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributes1Struct, GlobalEncoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement4 = buildStatement(sigParams, sigPk, revealedMsgsFromVerifier, false); + const statement4 = verifierStmt( + sigParams, + revealedMsgsFromVerifier, + sigPk + ); const statement5 = Statement.saverVerifier(saverEncGens, commKey, saverEk, saverVerifyingKey, chunkBitSize); const statement6 = Statement.boundCheckLegoVerifier(timeMin, timeMax, boundCheckVerifyingKey); @@ -171,7 +182,7 @@ describe(`${Scheme} Verifiable encryption using SAVER`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq3); metaStmtsVerifier.addWitnessEquality(witnessEq4); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStmtsVerifier); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStmtsVerifier); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec)); // Verifier extracts the ciphertext diff --git a/tests/composite-proofs/msg-js-obj/scheme.spec.ts b/tests/composite-proofs/msg-js-obj/scheme.spec.ts index 544f1095..f964863c 100644 --- a/tests/composite-proofs/msg-js-obj/scheme.spec.ts +++ b/tests/composite-proofs/msg-js-obj/scheme.spec.ts @@ -1,20 +1,24 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../../utils'; import { - CompositeProofG1, + CompositeProof, createWitnessEqualityMetaStatement, Encoder, encodeRevealedMsgs, getAdaptedSignatureParamsForMessages, getIndicesForMsgNames, getRevealedAndUnrevealed, + initializeWasm, isValidMsgStructure, MetaStatements, - ProofSpecG1, Statement, - Statements, Witness, + ProofSpec, + Statement, + Statements, + Witness, WitnessEqualityMetaStatement, Witnesses } from '../../../src'; +import { PederCommKey } from '../../../src/ped-com'; +import { buildWitness, Scheme } from '../../scheme'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../../utils'; import { attributes1, attributes1Struct, @@ -24,11 +28,10 @@ import { attributes3Struct, defaultEncoder } from './data-and-encoder'; -import { SignatureParams, KeyPair, isPS, buildStatement, buildWitness, Scheme, adaptKeyForParams, Signature } from '../../scheme'; import { checkMapsEqual, signedToHex } from './index'; -import { PederCommKey } from '../../../src/ped-com'; +import { proverStmt, signAndVerify, verifierStmt } from './util'; -describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { +describe(`Signing and proof of knowledge of ${Scheme} signatures`, () => { // NOTE: The following tests contain a lot of duplicated code but that is intentional as this code is for illustration purpose. beforeAll(async () => { @@ -42,10 +45,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const label = stringToBytes('Sig params label - this is public'); // Message count shouldn't matter as `label` is known - let params = SignatureParams.generate(100, label); - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - const pk = keypair.publicKey; + const [params, sk, pk] = getParamsAndKeys(100, label); // The encoder has to be known and agreed upon by all system participants, i.e. signer, prover and verifier. const encoder = new Encoder(undefined, defaultEncoder); @@ -62,8 +62,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { ]) { expect(isValidMsgStructure(attributes, attributesStruct)).toEqual(true); - const signed = Signature.signMessageObject(attributes, sk, label, encoder); - checkResult(signed.signature.verifyMessageObject(attributes, pk, label, encoder)); + const signed = signAndVerify(attributes, encoder, label, sk, pk); // For debugging console.log(signedToHex(signed)); @@ -117,24 +116,23 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { }); } - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, - false + pk ); const statementsProver = new Statements(); statementsProver.add(statement1); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, new MetaStatements()); + const proofSpecProver = new ProofSpec(statementsProver, new MetaStatements()); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed.signature, unrevealedMsgs, false); const witnesses = new Witnesses(); witnesses.add(witness1); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // For debugging console.log(proof.hex); @@ -142,17 +140,16 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const revealedMsgsFromVerifier = encodeRevealedMsgs(revealedMsgsRaw, attributesStruct, encoder); checkMapsEqual(revealedMsgs, revealedMsgsFromVerifier); - const statement2 = buildStatement( + const statement2 = verifierStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgsFromVerifier, - false + pk ); const statementsVerifier = new Statements(); statementsVerifier.add(statement2); // The verifier should independently construct this `ProofSpec` - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, new MetaStatements()); + const proofSpecVerifier = new ProofSpec(statementsVerifier, new MetaStatements()); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -169,27 +166,18 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { // 1st signer's setup const label1 = stringToBytes('Sig params label 1'); // Message count shouldn't matter as `label1` is known - let params1 = SignatureParams.generate(100, label1); - const keypair1 = KeyPair.generate(params1); - const sk1 = keypair1.secretKey; - const pk1 = keypair1.publicKey; + const [params1, sk1, pk1] = getParamsAndKeys(100, label1); // 2nd signer's setup const label2 = stringToBytes('Sig params label 2'); // Message count shouldn't matter as `label2` is known - let params2 = SignatureParams.generate(100, label2); - const keypair2 = KeyPair.generate(params2); - const sk2 = keypair2.secretKey; - const pk2 = keypair2.publicKey; + const [params2, sk2, pk2] = getParamsAndKeys(100, label2); const encoder = new Encoder(undefined, defaultEncoder); // Sign and verify all signatures - const signed1 = Signature.signMessageObject(attributes1, sk1, label1, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label1, encoder)); - - const signed2 = Signature.signMessageObject(attributes2, sk2, label2, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk2, label2, encoder)); + const signed1 = signAndVerify(attributes1, encoder, label1, sk1, pk1); + const signed2 = signAndVerify(attributes2, encoder, label2, sk2, pk2); // Reveal // - first name ("fname" attribute) from both sets of signed attributes @@ -218,11 +206,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { ); expect(revealedMsgsRaw1).toEqual({ fname: 'John', BMI: 23.25, country: 'USA' }); - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams1, - adaptKeyForParams(pk1, sigParams1), revealedMsgs1, - false + pk1, ); const [revealedMsgs2, unrevealedMsgs2, revealedMsgsRaw2] = getRevealedAndUnrevealed( @@ -241,11 +228,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { score: -13.5 }); - const statement2 = buildStatement( + const statement2 = proverStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2, - false + pk2, ); const statementsProver = new Statements(); @@ -253,7 +239,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { statementsProver.add(statement2); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, new MetaStatements()); + const proofSpecProver = new ProofSpec(statementsProver, new MetaStatements()); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs1, false); @@ -262,7 +248,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { witnesses.add(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgs1FromVerifier = encodeRevealedMsgs(revealedMsgsRaw1, attributes1Struct, encoder); @@ -270,24 +256,22 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const revealedMsgs2FromVerifier = encodeRevealedMsgs(revealedMsgsRaw2, attributes2Struct, encoder); checkMapsEqual(revealedMsgs2, revealedMsgs2FromVerifier); - const statement3 = buildStatement( + const statement3 = verifierStmt( sigParams1, - adaptKeyForParams(pk1, sigParams1), revealedMsgs1FromVerifier, - false + pk1 ); - const statement4 = buildStatement( + const statement4 = verifierStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2FromVerifier, - false + pk2 ); const statementsVerifier = new Statements(); statementsVerifier.add(statement3); statementsVerifier.add(statement4); // The verifier should independently construct this `ProofSpec` - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, new MetaStatements()); + const proofSpecVerifier = new ProofSpec(statementsVerifier, new MetaStatements()); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -300,38 +284,24 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { // 1st signer's setup const label1 = stringToBytes('Sig params label 1'); // Message count shouldn't matter as `label1` is known - let params1 = SignatureParams.generate(100, label1); - const keypair1 = KeyPair.generate(params1); - const sk1 = keypair1.secretKey; - const pk1 = keypair1.publicKey; + const [params1, sk1, pk1] = getParamsAndKeys(100, label1); // 2nd signer's setup const label2 = stringToBytes('Sig params label 2'); // Message count shouldn't matter as `label2` is known - let params2 = SignatureParams.generate(100, label2); - const keypair2 = KeyPair.generate(params2); - const sk2 = keypair2.secretKey; - const pk2 = keypair2.publicKey; + const [params2, sk2, pk2] = getParamsAndKeys(100, label2); // 3rd signer's setup const label3 = stringToBytes('Sig params label 3'); // Message count shouldn't matter as `label3` is known - let params3 = SignatureParams.generate(100, label3); - const keypair3 = KeyPair.generate(params3); - const sk3 = keypair3.secretKey; - const pk3 = keypair3.publicKey; + const [params3, sk3, pk3] = getParamsAndKeys(100, label3); const encoder = new Encoder(undefined, defaultEncoder); // Sign and verify all signatures - const signed1 = Signature.signMessageObject(attributes1, sk1, label1, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label1, encoder)); - - const signed2 = Signature.signMessageObject(attributes2, sk2, label2, encoder); - checkResult(signed2.signature.verifyMessageObject(attributes2, pk2, label2, encoder)); - - const signed3 = Signature.signMessageObject(attributes3, sk3, label3, encoder); - checkResult(signed3.signature.verifyMessageObject(attributes3, pk3, label3, encoder)); + const signed1 = signAndVerify(attributes1, encoder, label1, sk1, pk1); + const signed2 = signAndVerify(attributes2, encoder, label2, sk2, pk2); + const signed3 = signAndVerify(attributes3, encoder, label3, sk3, pk3); // Reveal // - first name ("fname" attribute) from all 3 sets of signed attributes @@ -373,11 +343,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { ); expect(revealedMsgsRaw1).toEqual({ fname: 'John', BMI: 23.25, country: 'USA' }); - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams1, - adaptKeyForParams(pk1, sigParams1), revealedMsgs1, - false + pk1, ); const [revealedMsgs2, unrevealedMsgs2, revealedMsgsRaw2] = getRevealedAndUnrevealed( @@ -395,11 +364,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { } }); - const statement2 = buildStatement( + const statement2 = proverStmt( sigParams2, - adaptKeyForParams(pk2, sigParams1), revealedMsgs2, - false + pk2, ); const [revealedMsgs3, unrevealedMsgs3, revealedMsgsRaw3] = getRevealedAndUnrevealed( @@ -423,11 +391,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { rank: 6 }); - const statement3 = buildStatement( + const statement3 = proverStmt( sigParams3, - adaptKeyForParams(pk3, sigParams3), revealedMsgs3, - false + pk3, ); const statementsProver = new Statements(); @@ -518,7 +485,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { metaStmtsProver.addWitnessEquality(witnessEq9); // The prover should independently construct this `ProofSpec` - const proofSpecProver = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpecProver = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs1, false); @@ -529,7 +496,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { witnesses.add(witness2); witnesses.add(witness3); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); // Verifier independently encodes revealed messages const revealedMsgs1FromVerifier = encodeRevealedMsgs(revealedMsgsRaw1, attributes1Struct, encoder); @@ -539,23 +506,20 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const revealedMsgs3FromVerifier = encodeRevealedMsgs(revealedMsgsRaw3, attributes3Struct, encoder); checkMapsEqual(revealedMsgs3, revealedMsgs3FromVerifier); - const statement4 = buildStatement( + const statement4 = verifierStmt( sigParams1, - adaptKeyForParams(pk1, sigParams1), revealedMsgs1FromVerifier, - false + pk1 ); - const statement5 = buildStatement( + const statement5 = verifierStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2FromVerifier, - false + pk2 ); - const statement6 = buildStatement( + const statement6 = verifierStmt( sigParams3, - adaptKeyForParams(pk3, sigParams3), revealedMsgs3FromVerifier, - false + pk3 ); const statementsVerifier = new Statements(); const sIdx4 = statementsVerifier.add(statement4); @@ -639,7 +603,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { metaStmtsVerifier.addWitnessEquality(witnessEq18); // The verifier should independently construct this `ProofSpec` - const proofSpecVerifier = new ProofSpecG1(statementsVerifier, metaStmtsVerifier); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsVerifier); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); @@ -649,16 +613,12 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const commKey = new PederCommKey(stringToBytes('test')); const label1 = stringToBytes('Sig params label 1'); // Message count shouldn't matter as `label1` is known - let params1 = SignatureParams.generate(100, label1); - const keypair1 = KeyPair.generate(params1); - const sk1 = keypair1.secretKey; - const pk1 = keypair1.publicKey; + const [params1, sk1, pk1] = getParamsAndKeys(100, label1); const encoder = new Encoder(undefined, defaultEncoder); // Sign and verify all signatures - const signed1 = Signature.signMessageObject(attributes1, sk1, label1, encoder); - checkResult(signed1.signature.verifyMessageObject(attributes1, pk1, label1, encoder)); + const signed1 = signAndVerify(attributes1, encoder, label1, sk1, pk1); const revealedNames1 = new Set(); revealedNames1.add('fname'); @@ -679,11 +639,10 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const wrongEmail1Encoded = encoder.encodeMessage('email', wrongEmail1); const wrongEmail2Encoded = encoder.encodeMessage('email', wrongEmail2); - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams1, - adaptKeyForParams(pk1, sigParams1), revealedMsgs1, - false + pk1, ); const statement2 = Statement.publicInequalityG1FromCompressedParams(wrongEmail1Encoded, commKey); @@ -701,7 +660,7 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { const metaStmtsProver = new MetaStatements(); metaStmtsProver.addWitnessEquality(witnessEq1); - const proofSpec = new ProofSpecG1(statementsProver, metaStmtsProver); + const proofSpec = new ProofSpec(statementsProver, metaStmtsProver); expect(proofSpec.isValid()).toEqual(true); const witness1 = buildWitness(signed1.signature, unrevealedMsgs1, false); @@ -713,7 +672,18 @@ describe(`${Scheme} Signing and proof of knowledge of signatures`, () => { witnesses.add(witness2); witnesses.add(witness3); - const proof = CompositeProofG1.generate(proofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const proof = CompositeProof.generate(proofSpec, witnesses); + + const statement4 = verifierStmt( + sigParams1, + revealedMsgs1, + pk1 + ); + const statementsVerifier = new Statements(statement4); + statementsVerifier.add(statement2); + statementsVerifier.add(statement3); + const proofSpecVerifier = new ProofSpec(statementsVerifier, metaStmtsProver); + expect(proofSpecVerifier.isValid()).toEqual(true); + checkResult(proof.verify(proofSpecVerifier)); }); }); diff --git a/tests/composite-proofs/msg-js-obj/util.spec.ts b/tests/composite-proofs/msg-js-obj/util.spec.ts index 4ce06380..963994f9 100644 --- a/tests/composite-proofs/msg-js-obj/util.spec.ts +++ b/tests/composite-proofs/msg-js-obj/util.spec.ts @@ -1,7 +1,6 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { EncodeFunc, Encoder, flattenObjectToKeyValuesList } from '../../../src'; +import { initializeWasm, EncodeFunc, Encoder, flattenObjectToKeyValuesList } from '../../../src'; import { stringToBytes } from '../../utils'; -import { Signature, SignatureParams, Scheme } from '../../scheme'; +import { Signature, SignatureParams, Scheme, isKvac } from '../../scheme'; describe(`${Scheme} Utils`, () => { beforeAll(async () => { @@ -32,17 +31,18 @@ describe(`${Scheme} Utils`, () => { it('Signature params getter', () => { const params1 = SignatureParams.generate(2); - expect(() => SignatureParams.getSigParamsOfRequiredSize(1, params1)).toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(3, params1)).toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(2, params1)).not.toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(1, stringToBytes('some label'))).not.toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(2, stringToBytes('some label'))).not.toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(3, stringToBytes('some label'))).not.toThrow(); + const f = isKvac() ? SignatureParams.getMacParamsOfRequiredSize : SignatureParams.getSigParamsOfRequiredSize; + expect(() => f(1, params1)).toThrow(); + expect(() => f(3, params1)).toThrow(); + expect(() => f(2, params1)).not.toThrow(); + expect(() => f(1, stringToBytes('some label'))).not.toThrow(); + expect(() => f(2, stringToBytes('some label'))).not.toThrow(); + expect(() => f(3, stringToBytes('some label'))).not.toThrow(); const params2 = SignatureParams.generate(2, stringToBytes('label2')); - expect(() => SignatureParams.getSigParamsOfRequiredSize(1, params2)).not.toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(2, params2)).not.toThrow(); - expect(() => SignatureParams.getSigParamsOfRequiredSize(3, params2)).not.toThrow(); + expect(() => f(1, params2)).not.toThrow(); + expect(() => f(2, params2)).not.toThrow(); + expect(() => f(3, params2)).not.toThrow(); }); it('encoder works', () => { diff --git a/tests/composite-proofs/msg-js-obj/util.ts b/tests/composite-proofs/msg-js-obj/util.ts new file mode 100644 index 00000000..7d59f3e2 --- /dev/null +++ b/tests/composite-proofs/msg-js-obj/util.ts @@ -0,0 +1,71 @@ +import { + adaptKeyForParams, + buildProverStatement, buildProverStatementFromSetupParamsRef, + buildVerifierStatement, buildVerifierStatementFromSetupParamsRef, + isKvac, isPS, PublicKey, + Signature, + SignatureParams +} from '../../scheme'; +import { checkResult } from '../../utils'; + +export function signAndVerify(messages, encoder, label, sk, pk) { + const signed = Signature.signMessageObject(messages, sk, label, encoder); + checkResult(isKvac() ? signed.signature.verifyMessageObject(messages, sk, label, encoder) : signed.signature.verifyMessageObject(messages, pk, label, encoder)); + return signed; +} + +export function proverStmt(params: SignatureParams, revealedMsgs: Map, pk?: PublicKey, encode = false) { + return !isPS() ? buildProverStatement( + params, + revealedMsgs, + encode + ) : buildProverStatement( + params, + adaptKeyForParams(pk, params), + revealedMsgs, + encode + ) +} + +export function verifierStmt(params: SignatureParams, revealedMsgs: Map, pk?: PublicKey, encode = false) { + return isKvac() ? buildVerifierStatement( + params, + revealedMsgs, + encode + ): buildVerifierStatement( + params, + adaptKeyForParams(pk, params), + revealedMsgs, + encode + ) +} + +export function proverStmtFromSetupParamsRef(paramsRef: number, revealedMsgs: Map, pkRef?: number, encode = false) { + return !isPS() ? buildProverStatementFromSetupParamsRef( + paramsRef, + revealedMsgs, + encode + ) : buildProverStatementFromSetupParamsRef( + paramsRef, + pkRef, + revealedMsgs, + encode + ) +} + +export function verifierStmtFromSetupParamsRef(paramsRef: number, revealedMsgs: Map, pkRef?: PublicKey, encode = false) { + return isKvac() ? buildVerifierStatementFromSetupParamsRef( + paramsRef, + revealedMsgs, + encode + ): buildVerifierStatementFromSetupParamsRef( + paramsRef, + pkRef, + revealedMsgs, + encode + ) +} + +export function adaptedSigParams(attributesStruct, label) { + return isKvac() ? SignatureParams.getMacParamsForMsgStructure(attributesStruct, label) : SignatureParams.getSigParamsForMsgStructure(attributesStruct, label); +} \ No newline at end of file diff --git a/tests/composite-proofs/pseudonyms.spec.ts b/tests/composite-proofs/pseudonyms.spec.ts index cc641f1c..e89d1222 100644 --- a/tests/composite-proofs/pseudonyms.spec.ts +++ b/tests/composite-proofs/pseudonyms.spec.ts @@ -1,9 +1,11 @@ +import { generateRandomFieldElement } from 'crypto-wasm-new'; import { AttributeBoundPseudonym, - CompositeProofG1, + CompositeProof, + initializeWasm, MetaStatement, MetaStatements, - ProofSpecG1, + ProofSpec, Pseudonym, PseudonymBases, Statement, @@ -12,9 +14,16 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../src'; -import { generateRandomFieldElement, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getRevealedUnrevealed, stringToBytes } from '../utils'; -import { KeyPair, Scheme, Signature, SignatureParams, buildStatement, buildWitness } from '../scheme'; +import { buildWitness, Scheme, Signature } from '../scheme'; +import { + checkResult, + getParamsAndKeys, + getRevealedUnrevealed, + proverStmt, + signAndVerify, + stringToBytes, + verifierStmt +} from '../utils'; // Get some attributes for testing function getAttributes(): Uint8Array[] { @@ -44,13 +53,13 @@ function registerUsingPseudonym(pseudonym: Pseudonym, base: Uint8Array, secretKe const statements = new Statements(); statements.add(statement); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proofSpec = new ProofSpec(statements, new MetaStatements()); const witness = Witness.pseudonym(secretKey); const witnesses = new Witnesses(); witnesses.add(witness); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proofSpec, witnesses); checkResult(proof.verify(proofSpec)); } @@ -67,13 +76,13 @@ function registerUsingAttributeBoundPseudonym( const statements = new Statements(); statements.add(statement); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proofSpec = new ProofSpec(statements, new MetaStatements()); const witness = Witness.attributeBoundPseudonym(attributes, secretKey); const witnesses = new Witnesses(); witnesses.add(witness); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proofSpec, witnesses); checkResult(proof.verify(proofSpec)); } @@ -133,55 +142,63 @@ describe(`${Scheme} Register using pseudonym not bound to any attributes`, () => // User gets a credential (attributes + signature) const encodedAttributes = getAttributes(); const label = stringToBytes('My sig params in g1'); - const sigParams = SignatureParams.generate(encodedAttributes.length, label); // Signers keys - const sigKeypair = KeyPair.generate(sigParams); - const sigSk = sigKeypair.secretKey; - const sigPk = sigKeypair.publicKey; + const [sigParams, sigSk, sigPk] = getParamsAndKeys(encodedAttributes.length, label); - const sig = Signature.generate(encodedAttributes, sigSk, sigParams, false); + const [sig, result] = signAndVerify(encodedAttributes, sigParams, sigSk, sigPk); + checkResult(result); // Prover is not revealing any attribute const [_, unrevealed] = getRevealedUnrevealed(encodedAttributes, new Set()); // User using its pseudonym at service provider 1 { - const statement1 = buildStatement(sigParams, sigPk, new Map(), false); + const statement1 = proverStmt(sigParams, new Map(), sigPk); const statement2 = Statement.pseudonym(pseudonym1, base1); - const statements = new Statements(); - statements.add(statement1); - statements.add(statement2); + const proverStatements = new Statements(); + proverStatements.add(statement1); + proverStatements.add(statement2); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proverProofSpec = new ProofSpec(proverStatements, new MetaStatements()); const witness1 = buildWitness(sig, unrevealed, false); const witness2 = Witness.pseudonym(secretKey); const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement3 = verifierStmt(sigParams, new Map(), sigPk); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, new MetaStatements()); + checkResult(proof.verify(verifierProofSpec)); } // User using its pseudonym at service provider 2 { - const statement1 = buildStatement(sigParams, sigPk, new Map(), false); + const statement1 = proverStmt(sigParams, new Map(), sigPk); const statement2 = Statement.pseudonym(pseudonym2, base2); - const statements = new Statements(statement1); - statements.add(statement2); + const proverStatements = new Statements(statement1); + proverStatements.add(statement2); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proverProofSpec = new ProofSpec(proverStatements, new MetaStatements()); const witness1 = buildWitness(sig, unrevealed, false); const witness2 = Witness.pseudonym(secretKey); const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement3 = verifierStmt(sigParams, new Map(), sigPk); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, new MetaStatements()); + checkResult(proof.verify(verifierProofSpec)); } }); }); @@ -282,14 +299,9 @@ describe(`${Scheme} Using pseudonym bound to some attributes`, () => { it('Usage along with credential', () => { const label = stringToBytes('My sig params in g1'); - const sigParams = SignatureParams.generate(encodedAttributes.length, label); - - // Signers keys - const sigKeypair = KeyPair.generate(sigParams); - const sigSk = sigKeypair.secretKey; - const sigPk = sigKeypair.publicKey; - - const sig = Signature.generate(encodedAttributes, sigSk, sigParams, false); + const [sigParams, sigSk, sigPk] = getParamsAndKeys(encodedAttributes.length, label); + const [sig, result] = signAndVerify(encodedAttributes, sigParams, sigSk, sigPk, false); + checkResult(result); // Prover is not revealing 1 attribute const revealedIndices = new Set(); @@ -298,11 +310,11 @@ describe(`${Scheme} Using pseudonym bound to some attributes`, () => { // User using its pseudonym at service provider 1 { - const statement1 = buildStatement(sigParams, sigPk, revealed, false); + const statement1 = proverStmt(sigParams, revealed, sigPk); const statement2 = Statement.attributeBoundPseudonym(pseudonym1, bases1ForAttributes, base1ForSecretKey); - const statements = new Statements(); - statements.add(statement1); - statements.add(statement2); + const proverStatements = new Statements(); + proverStatements.add(statement1); + proverStatements.add(statement2); // The 0th attribute in the credential is bound to the pseudonym const witnessEq = new WitnessEqualityMetaStatement(); @@ -314,25 +326,30 @@ describe(`${Scheme} Using pseudonym bound to some attributes`, () => { const metaStatements = new MetaStatements(); metaStatements.add(MetaStatement.witnessEquality(witnessEq)); - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements); const witness1 = buildWitness(sig, unrevealed, false); const witness2 = Witness.attributeBoundPseudonym(attributesPseudonym1, secretKey); const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement3 = verifierStmt(sigParams, revealed, sigPk); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements); + checkResult(proof.verify(verifierProofSpec)); } // User using its pseudonym at service provider 2 { - const statement1 = buildStatement(sigParams, sigPk, revealed, false); + const statement1 = proverStmt(sigParams, revealed, sigPk); const statement2 = Statement.attributeBoundPseudonym(pseudonym2, bases2ForAttributes, base2ForSecretKey); - const statements = new Statements(); - statements.add(statement1); - statements.add(statement2); + const proverStatements = new Statements(); + proverStatements.add(statement1); + proverStatements.add(statement2); // The 0th attribute in the credential is bound to the pseudonym at index 0 const witnessEq1 = new WitnessEqualityMetaStatement(); @@ -352,25 +369,30 @@ describe(`${Scheme} Using pseudonym bound to some attributes`, () => { metaStatements.add(MetaStatement.witnessEquality(witnessEq1)); metaStatements.add(MetaStatement.witnessEquality(witnessEq2)); - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements); const witness1 = buildWitness(sig, unrevealed, false); const witness2 = Witness.attributeBoundPseudonym(attributesPseudonym2, secretKey); const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement3 = verifierStmt(sigParams, revealed, sigPk); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements); + checkResult(proof.verify(verifierProofSpec)); } // User using its pseudonym at service provider 3 { - const statement1 = buildStatement(sigParams, sigPk, revealed, false); + const statement1 = proverStmt(sigParams, revealed, sigPk); const statement2 = Statement.attributeBoundPseudonym(pseudonym3, bases3ForAttributes); - const statements = new Statements(); - statements.add(statement1); - statements.add(statement2); + const proverStatements = new Statements(); + proverStatements.add(statement1); + proverStatements.add(statement2); // The 0th attribute in the credential is bound to the pseudonym at index 0 const witnessEq1 = new WitnessEqualityMetaStatement(); @@ -390,16 +412,21 @@ describe(`${Scheme} Using pseudonym bound to some attributes`, () => { metaStatements.add(MetaStatement.witnessEquality(witnessEq1)); metaStatements.add(MetaStatement.witnessEquality(witnessEq2)); - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements); const witness1 = buildWitness(sig, unrevealed, false); const witness2 = Witness.attributeBoundPseudonym(attributesPseudonym3); const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement3 = verifierStmt(sigParams, revealed, sigPk); + const verifierStatements = new Statements(); + verifierStatements.add(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements); + checkResult(proof.verify(verifierProofSpec)); } }); }); diff --git a/tests/composite-proofs/r1cs/less_than_greater_than.spec.ts b/tests/composite-proofs/r1cs/less_than_greater_than.spec.ts index ebab7f1b..e8d33915 100644 --- a/tests/composite-proofs/r1cs/less_than_greater_than.spec.ts +++ b/tests/composite-proofs/r1cs/less_than_greater_than.spec.ts @@ -1,14 +1,22 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, getRevealedUnrevealed, getWasmBytes, parseR1CSFile, stringToBytes } from '../../utils'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { + checkResult, + getParamsAndKeys, + getRevealedUnrevealed, + getWasmBytes, + parseR1CSFile, proverStmt, signAndVerify, + stringToBytes, verifierStmt +} from '../../utils'; +import { + initializeWasm, CircomInputs, - CompositeProofG1, + CompositeProof, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatement, MetaStatements, ParsedR1CSFile, - QuasiProofSpecG1, + QuasiProofSpec, R1CSSnarkSetup, Statement, Statements, @@ -23,7 +31,7 @@ import { Signature, SignatureParams, buildWitness, - buildStatement, + buildVerifierStatement, Scheme } from '../../scheme'; @@ -67,15 +75,8 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = }); it('do signers setup', () => { - sigParams1 = SignatureParams.generate(messageCount); - const sigKeypair1 = KeyPair.generate(sigParams1); - sigSk1 = sigKeypair1.secretKey; - sigPk1 = sigKeypair1.publicKey; - - sigParams2 = SignatureParams.generate(messageCount); - const sigKeypair2 = KeyPair.generate(sigParams2); - sigSk2 = sigKeypair2.secretKey; - sigPk2 = sigKeypair2.publicKey; + [sigParams1, sigSk1, sigPk1] = getParamsAndKeys(messageCount); + [sigParams2, sigSk2, sigPk2] = getParamsAndKeys(messageCount); messages1 = []; messages2 = []; @@ -84,10 +85,11 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = messages2.push(generateFieldElementFromNumber(2000 + i)); } - sig1 = Signature.generate(messages1, sigSk1, sigParams1, false); - sig2 = Signature.generate(messages2, sigSk2, sigParams2, false); - expect(sig1.verify(messages1, sigPk1, sigParams1, false).verified).toEqual(true); - expect(sig2.verify(messages2, sigPk2, sigParams2, false).verified).toEqual(true); + let result1, result2; + [sig1, result1] = signAndVerify(messages1, sigParams1, sigSk1, sigPk1); + checkResult(result1); + [sig2, result2] = signAndVerify(messages2, sigParams2, sigSk2, sigPk2); + checkResult(result2); }); function proveAndVerifyLessThan( @@ -99,7 +101,7 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = const publicMax = generateFieldElementFromNumber(5000); const [revealedMsgs, unrevealedMsgs] = getRevealedUnrevealed(messages, new Set()); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); const statement2 = Statement.r1csCircomProver(ltR1cs, ltWasm, ltProvingKey); const statement3 = Statement.r1csCircomProver(ltPubR1cs, ltPubWasm, ltPubProvingKey); @@ -140,19 +142,20 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = witnesses.add(witness2); witnesses.add(witness3); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses); const statement4 = Statement.r1csCircomVerifier([generateFieldElementFromNumber(1)], ltVerifyingKey); const statement5 = Statement.r1csCircomVerifier([generateFieldElementFromNumber(1), publicMax], ltPubVerifyingKey); + const statement6 = verifierStmt(sigParams, revealedMsgs, sigPk); const verifierStatements = new Statements(); - verifierStatements.add(statement1); + verifierStatements.add(statement6); verifierStatements.add(statement4); verifierStatements.add(statement5); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec)); } @@ -168,8 +171,8 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = const [revealedMsgs1, unrevealedMsgs1] = getRevealedUnrevealed(messages1, new Set()); const [revealedMsgs2, unrevealedMsgs2] = getRevealedUnrevealed(messages2, new Set()); - const statement1 = buildStatement(sigParams1, sigPk1, revealedMsgs1, false); - const statement2 = buildStatement(sigParams2, sigPk2, revealedMsgs2, false); + const statement1 = proverStmt(sigParams1, revealedMsgs1, sigPk1); + const statement2 = proverStmt(sigParams2, revealedMsgs2, sigPk2); const statement3 = Statement.r1csCircomProver(ltR1cs, ltWasm, ltProvingKey); @@ -199,18 +202,20 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: less than checks`, () = const witnesses = new Witnesses([].concat(witness1).concat(witness2)); witnesses.add(witness3); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses); const statement4 = Statement.r1csCircomVerifier([generateFieldElementFromNumber(1)], ltVerifyingKey); + const statement5 = verifierStmt(sigParams1, revealedMsgs1, sigPk1); + const statement6 = verifierStmt(sigParams2, revealedMsgs2, sigPk2); const verifierStatements = new Statements(); - verifierStatements.add(statement1); - verifierStatements.add(statement2); + verifierStatements.add(statement5); + verifierStatements.add(statement6); verifierStatements.add(statement4); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements); checkResult(proof.verifyUsingQuasiProofSpec(verifierProofSpec)); }); }); diff --git a/tests/composite-proofs/r1cs/set-membership.spec.ts b/tests/composite-proofs/r1cs/set-membership.spec.ts index 3a9be8da..8cec8c2b 100644 --- a/tests/composite-proofs/r1cs/set-membership.spec.ts +++ b/tests/composite-proofs/r1cs/set-membership.spec.ts @@ -1,12 +1,13 @@ import { + initializeWasm, CircomInputs, - CompositeProofG1, + CompositeProof, LegoProvingKeyUncompressed, LegoVerifyingKeyUncompressed, MetaStatement, MetaStatements, ParsedR1CSFile, - ProofSpecG1, + ProofSpec, R1CSSnarkSetup, Statement, Statements, @@ -14,8 +15,15 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../../src'; -import { generateFieldElementFromNumber, initializeWasm, generateRandomFieldElement } from '@docknetwork/crypto-wasm'; -import { checkResult, getRevealedUnrevealed, getWasmBytes, parseR1CSFile } from '../../utils'; +import { generateFieldElementFromNumber, generateRandomFieldElement } from 'crypto-wasm-new'; +import { + checkResult, + getParamsAndKeys, + getRevealedUnrevealed, + getWasmBytes, + parseR1CSFile, proverStmt, + signAndVerify, verifierStmt +} from '../../utils'; import { PublicKey, SecretKey, @@ -23,7 +31,7 @@ import { Signature, SignatureParams, buildWitness, - buildStatement, + buildVerifierStatement, Scheme } from '../../scheme'; @@ -53,18 +61,16 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: set membership check`, }); it('do signers setup', () => { - sigParams = SignatureParams.generate(messageCount); - const sigKeypair1 = KeyPair.generate(sigParams); - sigSk = sigKeypair1.secretKey; - sigPk = sigKeypair1.publicKey; + [sigParams, sigSk, sigPk] = getParamsAndKeys(messageCount); messages = []; for (let i = 0; i < messageCount; i++) { messages.push(generateFieldElementFromNumber(1000 + i)); } - sig = Signature.generate(messages, sigSk, sigParams, false); - expect(sig.verify(messages, sigPk, sigParams, false).verified).toEqual(true); + let result; + [sig, result] = signAndVerify(messages, sigParams, sigSk, sigPk); + checkResult(result); }); it('check for message present in the set', () => { @@ -77,7 +83,7 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: set membership check`, ]; const [revealedMsgs, unrevealedMsgs] = getRevealedUnrevealed(messages, new Set()); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); const statement2 = Statement.r1csCircomProver(r1cs, wasm, provingKey); const proverStatements = new Statements(); @@ -91,7 +97,7 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: set membership check`, const metaStatements = new MetaStatements(); metaStatements.add(MetaStatement.witnessEquality(witnessEq1)); - const proofSpecProver = new ProofSpecG1(proverStatements, metaStatements); + const proofSpecProver = new ProofSpec(proverStatements, metaStatements); expect(proofSpecProver.isValid()).toEqual(true); const witness1 = buildWitness(sig, unrevealedMsgs, false); @@ -104,15 +110,16 @@ describe(`${Scheme} Proof with R1CS and Circom circuits: set membership check`, const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proof = CompositeProofG1.generate(proofSpecProver, witnesses); + const proof = CompositeProof.generate(proofSpecProver, witnesses); const statement3 = Statement.r1csCircomVerifier([generateFieldElementFromNumber(1), ...publicSet], verifyingKey); + const statement4 = verifierStmt(sigParams, revealedMsgs, sigPk); const verifierStatements = new Statements(); - verifierStatements.add(statement1); + verifierStatements.add(statement4); verifierStatements.add(statement3); - const proofSpecVerifier = new ProofSpecG1(verifierStatements, metaStatements); + const proofSpecVerifier = new ProofSpec(verifierStatements, metaStatements); expect(proofSpecVerifier.isValid()).toEqual(true); checkResult(proof.verify(proofSpecVerifier)); diff --git a/tests/composite-proofs/saver.spec.ts b/tests/composite-proofs/saver.spec.ts index 4953a51e..6546f5e4 100644 --- a/tests/composite-proofs/saver.spec.ts +++ b/tests/composite-proofs/saver.spec.ts @@ -1,10 +1,10 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { - CompositeProofG1, + CompositeProof, dockSaverEncryptionGensUncompressed, + initializeWasm, MetaStatement, MetaStatements, - QuasiProofSpecG1, + QuasiProofSpec, SaverChunkedCommitmentKey, SaverDecryptionKeyUncompressed, SaverDecryptor, @@ -21,17 +21,18 @@ import { WitnessEqualityMetaStatement, Witnesses } from '../../src'; -import { areUint8ArraysEqual, getRevealedUnrevealed, readByteArrayFromFile, stringToBytes } from '../utils'; +import { buildWitness, PublicKey, Scheme, SecretKey, Signature, SignatureParams } from '../scheme'; import { - PublicKey, - KeyPair, - Signature, - SecretKey, - SignatureParams, - buildStatement, - buildWitness, - Scheme -} from '../scheme'; + areUint8ArraysEqual, + checkResult, + getParamsAndKeys, + getRevealedUnrevealed, + proverStmt, + readByteArrayFromFile, + signAndVerify, + stringToBytes, + verifierStmt +} from '../utils'; describe(`${Scheme} Verifiable encryption of signed messages`, () => { const chunkBitSize = 16; @@ -133,23 +134,17 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { messages2.push(Signature.reversibleEncodeStringForSigning(messages2AsStrings[i])); } - sigParams1 = SignatureParams.generate(messageCount); - const sigKeypair1 = KeyPair.generate(sigParams1); - sigSk1 = sigKeypair1.secretKey; - sigPk1 = sigKeypair1.publicKey; + [sigParams1, sigSk1, sigPk1] = getParamsAndKeys(messageCount); + [sigParams2, sigSk2, sigPk2] = getParamsAndKeys(messageCount); - sigParams2 = SignatureParams.generate(messageCount); - const sigKeypair2 = KeyPair.generate(sigParams2); - sigSk2 = sigKeypair2.secretKey; - sigPk2 = sigKeypair2.publicKey; - - sig1 = Signature.generate(messages1, sigSk1, sigParams1, false); - sig2 = Signature.generate(messages2, sigSk2, sigParams2, false); - expect(sig1.verify(messages1, sigPk1, sigParams1, false).verified).toEqual(true); - expect(sig2.verify(messages2, sigPk2, sigParams2, false).verified).toEqual(true); + let result1, result2; + [sig1, result1] = signAndVerify(messages1, sigParams1, sigSk1, sigPk1); + checkResult(result1); + [sig2, result2] = signAndVerify(messages2, sigParams2, sigSk2, sigPk2); + checkResult(result2); }); - function decryptAndVerify(proof: CompositeProofG1, statementIndex: number, message: Uint8Array) { + function decryptAndVerify(proof: CompositeProof, statementIndex: number, message: Uint8Array) { // Verifier extracts the ciphertext const ciphertext = proof.getSaverCiphertext(statementIndex); const ciphertext1 = proof.getSaverCiphertexts([statementIndex]); @@ -179,11 +174,10 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { const revealedIndices = new Set(); revealedIndices.add(0); const [revealedMsgs, unrevealedMsgs] = getRevealedUnrevealed(messages, revealedIndices); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); const statement2 = Statement.saverProver(saverEncGens, commKey, saverEk, snarkProvingKey, chunkBitSize); const proverStatements = new Statements(statement1); - //proverStatements.add(statement1); proverStatements.add(statement2); const witnessEq = new WitnessEqualityMetaStatement(); @@ -197,15 +191,15 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { const witnesses = new Witnesses(witness1); witnesses.add(witness2); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses); const statement3 = Statement.saverVerifier(saverEncGens, commKey, saverEk, snarkVerifyingKey, chunkBitSize); - const verifierStatements = new Statements(statement1); - // verifierStatements.add(statement1); + const statement4 = verifierStmt(sigParams, revealedMsgs, sigPk); + const verifierStatements = new Statements(statement4); verifierStatements.add(statement3); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements); expect(proof.verifyUsingQuasiProofSpec(verifierProofSpec).verified).toEqual(true); // The ciphertext present in the proof is decrypted and checked to match the original message @@ -235,8 +229,8 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { proverSetupParams.push(SetupParam.saverEncryptionKeyUncompressed(saverEk)); proverSetupParams.push(SetupParam.saverProvingKeyUncompressed(snarkProvingKey)); - const statement1 = buildStatement(sigParams1, sigPk1, revealedMsgs1, false); - const statement2 = buildStatement(sigParams2, sigPk2, revealedMsgs2, false); + const statement1 = proverStmt(sigParams1, revealedMsgs1, sigPk1); + const statement2 = proverStmt(sigParams2, revealedMsgs2, sigPk2); const statement3 = Statement.saverProverFromSetupParamRefs(0, 1, 2, 3, chunkBitSize); const statement4 = Statement.saverProverFromSetupParamRefs(0, 1, 2, 3, chunkBitSize); @@ -262,8 +256,8 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { witnesses.add(Witness.saver(messages1[encMsgIdx])); witnesses.add(Witness.saver(messages2[encMsgIdx])); - const proverProofSpec = new QuasiProofSpecG1(proverStatements, metaStatements, proverSetupParams); - const proof = CompositeProofG1.generateUsingQuasiProofSpec(proverProofSpec, witnesses); + const proverProofSpec = new QuasiProofSpec(proverStatements, metaStatements, proverSetupParams); + const proof = CompositeProof.generateUsingQuasiProofSpec(proverProofSpec, witnesses); const verifierSetupParams: SetupParam[] = []; verifierSetupParams.push(SetupParam.saverEncryptionGensUncompressed(saverEncGens)); @@ -273,13 +267,15 @@ describe(`${Scheme} Verifiable encryption of signed messages`, () => { const statement5 = Statement.saverVerifierFromSetupParamRefs(0, 1, 2, 3, chunkBitSize); const statement6 = Statement.saverVerifierFromSetupParamRefs(0, 1, 2, 3, chunkBitSize); + const statement7 = verifierStmt(sigParams1, revealedMsgs1, sigPk1); + const statement8 = verifierStmt(sigParams2, revealedMsgs2, sigPk2); const verifierStatements = new Statements(); - verifierStatements.add(statement1); - verifierStatements.add(statement2); + verifierStatements.add(statement7); + verifierStatements.add(statement8); verifierStatements.add(statement5); verifierStatements.add(statement6); - const verifierProofSpec = new QuasiProofSpecG1(verifierStatements, metaStatements, verifierSetupParams); + const verifierProofSpec = new QuasiProofSpec(verifierStatements, metaStatements, verifierSetupParams); expect(proof.verifyUsingQuasiProofSpec(verifierProofSpec).verified).toEqual(true); decryptAndVerify(proof, 2, messages1[encMsgIdx]); diff --git a/tests/composite-proofs/signature-and-accumulator.spec.ts b/tests/composite-proofs/signature-and-accumulator.spec.ts index 83852e0b..1c080fd4 100644 --- a/tests/composite-proofs/signature-and-accumulator.spec.ts +++ b/tests/composite-proofs/signature-and-accumulator.spec.ts @@ -1,26 +1,27 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; import { Accumulator, - CompositeProofG1, + CompositeProof, + initializeWasm, MetaStatement, MetaStatements, PositiveAccumulator, - ProofSpecG1, + ProofSpec, Statement, Statements, Witness, WitnessEqualityMetaStatement, Witnesses } from '../../src'; -import { KeyPair, Scheme, Signature, SignatureParams, buildStatement, buildWitness } from '../scheme'; import { InMemoryState } from '../../src/accumulator/in-memory-persistence'; +import { buildWitness, isKvac, Scheme, Signature } from '../scheme'; +import { checkResult, getParamsAndKeys, proverStmt, signAndVerify, stringToBytes, verifierStmt } from '../utils'; describe(`Proving knowledge of 1 ${Scheme} signature and a certain message in the accumulator`, () => { - it('works', async () => { - // Load the WASM module + beforeAll(async () => { await initializeWasm(); + }); + async function check(isKvAccum: boolean) { // Messages to sign const messages: Uint8Array[] = []; // SSN @@ -48,21 +49,17 @@ describe(`Proving knowledge of 1 ${Scheme} signature and a certain message in th } const label = stringToBytes('My sig params in g1'); - const sigParams = SignatureParams.generate(messageCount, label); // Signers keys - const sigKeypair = KeyPair.generate(sigParams); - const sigSk = sigKeypair.secretKey; - const sigPk = sigKeypair.publicKey; + const [sigParams, sigSk, sigPk] = getParamsAndKeys(messageCount, label); const accumParams = PositiveAccumulator.generateParams(stringToBytes('Accumulator params')); const accumKeypair = PositiveAccumulator.generateKeypair(accumParams); const accumulator = PositiveAccumulator.initialize(accumParams); const state = new InMemoryState(); - const sig = Signature.generate(encodedMessages, sigSk, sigParams, false); - const result = sig.verify(encodedMessages, sigPk, sigParams, false); - expect(result.verified).toEqual(true); + const [sig, result] = signAndVerify(encodedMessages, sigParams, sigSk, sigPk, false); + checkResult(result); const userIdIdx = messageCount - 1; await accumulator.add(encodedMessages[userIdIdx], accumKeypair.secretKey, state); @@ -83,15 +80,15 @@ describe(`Proving knowledge of 1 ${Scheme} signature and a certain message in th const provingKey = Accumulator.generateMembershipProvingKey(stringToBytes('Our proving key')); - const statement1 = buildStatement(sigParams, sigPk, revealedMsgs, false); - const statement2 = Statement.accumulatorMembership( + const statement1 = proverStmt(sigParams, revealedMsgs, sigPk); + const statement2 = isKvAccum ? Statement.vbAccumulatorMembershipKV(accumulator.accumulated) : Statement.vbAccumulatorMembership( accumParams, accumKeypair.publicKey, provingKey, accumulator.accumulated ); - const statements = new Statements(statement1); - statements.add(statement2); + const proverStatements = new Statements(statement1); + proverStatements.add(statement2); // The last message in the signature is same as the accumulator member const witnessEq = new WitnessEqualityMetaStatement(); @@ -106,17 +103,44 @@ describe(`Proving knowledge of 1 ${Scheme} signature and a certain message in th const context = stringToBytes('some context'); - const proofSpec = new ProofSpecG1(statements, metaStatements, [], context); - expect(proofSpec.isValid()).toEqual(true); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements, [], context); + expect(proverProofSpec.isValid()).toEqual(true); const witness1 = buildWitness(sig, unrevealedMsgs, false); - const witness2 = Witness.accumulatorMembership(encodedMessages[userIdIdx], accumWitness); + const witness2 = Witness.vbAccumulatorMembership(encodedMessages[userIdIdx], accumWitness); const witnesses = new Witnesses(witness1); witnesses.add(witness2); const nonce = stringToBytes('some unique nonce'); - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); - checkResult(proof.verify(proofSpec, nonce)); + const proof = CompositeProof.generate(proverProofSpec, witnesses, nonce); + + const statement3 = verifierStmt(sigParams, revealedMsgs, sigPk); + const verifierStatements = new Statements(statement3); + verifierStatements.add(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements, [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); + + if (isKvac()) { + const statement4 = Statement.bddt16MacFullVerifier(sigParams, sigSk, revealedMsgs, false); + const verifierStatements = new Statements(statement4); + if (isKvAccum) { + verifierStatements.add(Statement.vbAccumulatorMembershipKVFullVerifier(accumKeypair.secretKey, accumulator.accumulated)) + } else { + verifierStatements.add(statement2); + } + const verifierProofSpec = new ProofSpec(verifierStatements, metaStatements, [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); + } + } + + it('works with non-kv accumulator', async () => { + await check(false) + }); + + it('works with kv accumulator', async () => { + await check(true) }); }); diff --git a/tests/composite-proofs/single-signature.spec.ts b/tests/composite-proofs/single-signature.spec.ts index 8ab10a38..986f0109 100644 --- a/tests/composite-proofs/single-signature.spec.ts +++ b/tests/composite-proofs/single-signature.spec.ts @@ -1,21 +1,6 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; -import { - CompositeProofG1, - MetaStatements, - ProofSpecG1, - Statements, - Witnesses -} from '../../src'; -import { - KeyPair, - Scheme, - Signature, - SignatureParams, - buildStatement, - buildWitness, - encodeMessageForSigningIfPS -} from '../scheme' +import { CompositeProof, initializeWasm, MetaStatements, ProofSpec, Statement, Statements, Witnesses } from '../../src'; +import { buildWitness, encodeMessageForSigningIfPS, isKvac, Scheme } from '../scheme'; +import { checkResult, getParamsAndKeys, proverStmt, signAndVerify, stringToBytes, verifierStmt } from '../utils'; describe(`${Scheme} Proving knowledge of 1 signature over the attributes`, () => { it('works', async () => { @@ -35,20 +20,15 @@ describe(`${Scheme} Proving knowledge of 1 signature over the attributes`, () => // City messages.push(encodeMessageForSigningIfPS(stringToBytes('New York'))); - const messageCount = messages.length; + const messageCount= messages.length; const label = stringToBytes('My sig params in g1'); - const params = SignatureParams.generate(messageCount, label); - // Signers keys - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - const pk = keypair.publicKey; + const [params, sk, pk] = getParamsAndKeys(messageCount, label); // Signer knows all the messages and signs - const sig = Signature.generate(messages, sk, params, true); - const result = sig.verify(messages, pk, params, true); - expect(result.verified).toEqual(true); + const [sig, result] = signAndVerify(messages, params, sk, pk, true); + checkResult(result); // User reveals 2 messages at index 2 and 4 to verifier, last name and city const revealedMsgIndices: Set = new Set(); @@ -64,23 +44,37 @@ describe(`${Scheme} Proving knowledge of 1 signature over the attributes`, () => } } - const statement1 = buildStatement(params, pk, revealedMsgs, true); - const statements = new Statements(statement1); + const statement1 = proverStmt(params, revealedMsgs, pk, true); + const proverStatements = new Statements(statement1); // Optional context of the proof const context = stringToBytes('some context'); // Both the prover (user) and verifier should independently construct this `ProofSpec` but only for testing, i am reusing it. - const proofSpec = new ProofSpecG1(statements, new MetaStatements(), [], context); - expect(proofSpec.isValid()).toEqual(true); + const proverProofSpec = new ProofSpec(proverStatements, new MetaStatements(), [], context); + expect(proverProofSpec.isValid()).toEqual(true); const witness1 = buildWitness(sig, unrevealedMsgs, true); const witnesses = new Witnesses(witness1); const nonce = stringToBytes('some unique nonce'); - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); + const proof = CompositeProof.generate(proverProofSpec, witnesses, nonce); + + const statement2 = verifierStmt(params, revealedMsgs, pk, true); + const verifierStatements = new Statements(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, new MetaStatements(), [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); + + if (isKvac()) { + const statement3 = Statement.bddt16MacFullVerifier(params, sk, revealedMsgs, true); + const verifierStatements = new Statements(statement3); + const verifierProofSpec = new ProofSpec(verifierStatements, new MetaStatements(), [], context); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec, nonce)); - checkResult(proof.verify(proofSpec, nonce)); + + } }); }); diff --git a/tests/composite-proofs/social-kyc.spec.ts b/tests/composite-proofs/social-kyc.spec.ts index a4b7a33c..79831784 100644 --- a/tests/composite-proofs/social-kyc.spec.ts +++ b/tests/composite-proofs/social-kyc.spec.ts @@ -1,29 +1,32 @@ -import { CompositeProofG1, MetaStatements, ProofSpecG1, Statement, Statements, Witness, Witnesses } from '../../src'; - +import { generateRandomFieldElement, generateRandomG1Element, pedersenCommitmentG1 } from 'crypto-wasm-new'; import { - generateRandomFieldElement, - generateRandomG1Element, + CompositeProof, initializeWasm, - pedersenCommitmentG1 -} from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; + MetaStatements, + ProofSpec, + Statement, + Statements, + Witness, + Witnesses +} from '../../src'; import { - Signature, BlindSignature, - SignatureParams, - KeyPair, + encodeMessageForSigningIfNotPS, + encodeMessageForSigningIfPS, + getStatementForBlindSigRequest, + getWitnessForBlindSigRequest, + isBBS, + isKvac, + isPS, PublicKey, + Scheme, SecretKey, - isPS, - isBBSPlus, - getWitnessForBlindSigRequest, - getStatementForBlindSigRequest, - encodeMessageForSigningIfPS, - encodeMessageForSigningIfNotPS, - Scheme + Signature, + SignatureParams } from '../scheme'; +import { checkResult, getParamsAndKeys, stringToBytes } from '../utils'; -describe(`${Scheme} Social KYC (Know Your Customer)`, () => { +describe(`Social KYC (Know Your Customer) with ${Scheme} credentials`, () => { // A social KYC (Know Your Customer) credential claims that the subject owns certain social media profile like a twitter // profile credential claims that a user owns the twitter profile with certain handle. User posts a commitment to some // random value on his profile and then requests a credential from the issuer by supplying a proof of knowledge of the @@ -46,12 +49,8 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { // Load the WASM module await initializeWasm(); - sigParams = SignatureParams.generate(attributeCount); - // Generate keys - const sigKeypair = KeyPair.generate(sigParams); - sk = sigKeypair.secretKey; - pk = sigKeypair.publicKey; + [sigParams, sk, pk] = getParamsAndKeys(attributeCount); h = generateRandomG1Element(); g = generateRandomG1Element(); @@ -88,10 +87,10 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { void 0, knownAttributes ); - } else if (isBBSPlus()) { - [blinding, request] = BlindSignature.generateRequest(blindedAttributes, sigParams, true, void 0, knownAttributes); - } else { + } else if (isBBS()) { request = BlindSignature.generateRequest(blindedAttributes, sigParams, true, knownAttributes); + } else { + [blinding, request] = BlindSignature.generateRequest(blindedAttributes, sigParams, true, void 0, knownAttributes); } // The proof is created for 2 statements. @@ -105,7 +104,7 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { const context = stringToBytes('Verifying twitter profile with issuer 1'); const meta = new MetaStatements(); - const proofSpec = new ProofSpecG1(statements, meta, [], context); + const proofSpec = new ProofSpec(statements, meta, [], context); // This is the opening of the commitment posted in tweet const witness1 = Witness.pedersenCommitment([randomValueTweet]); @@ -120,7 +119,7 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { witnesses.add(witness1); // User creates this proof and sends to the issuer. - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proofSpec, witnesses); // Issuer checks that the commitment `commitmentTweet` is present in the tweet and then verifies the following // proof to check user's knowledge of its opening. @@ -132,11 +131,11 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { : BlindSignature.fromRequest(request, sk, sigParams); // // User unblinds the signature and now has valid credential - const sig: Signature = isBBSPlus() - ? blindSig.unblind(blinding!) + const sig: Signature = isBBS() + ? blindSig : isPS() ? blindSig.unblind(blindings!, pk) - : blindSig; + : blindSig.unblind(blinding!); // Combine blinded and known attributes in an array const attributes = Array(blindedAttributes.size + knownAttributes.size); @@ -147,7 +146,7 @@ describe(`${Scheme} Social KYC (Know Your Customer)`, () => { attributes[i] = m; } - const result = sig.verify(attributes, pk, sigParams, true); + const result = isKvac() ? sig.verify(attributes, sk, sigParams, true) : sig.verify(attributes, pk, sigParams, true); checkResult(result); }); }); diff --git a/tests/composite-proofs/variable-number-of-messages.spec.ts b/tests/composite-proofs/variable-number-of-messages.spec.ts index 664870d0..3590d50c 100644 --- a/tests/composite-proofs/variable-number-of-messages.spec.ts +++ b/tests/composite-proofs/variable-number-of-messages.spec.ts @@ -1,17 +1,8 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; -import { checkResult, stringToBytes } from '../utils'; -import { CompositeProofG1, MetaStatements, ProofSpecG1, Statements, Witnesses } from '../../src'; -import { - Signature, - KeyPair, - SignatureParams, - buildStatement, - buildWitness, - encodeMessageForSigningIfPS, - Scheme -} from '../scheme'; +import { CompositeProof, initializeWasm, MetaStatements, ProofSpec, Statements, Witnesses } from '../../src'; +import { buildWitness, encodeMessageForSigningIfPS, Scheme } from '../scheme'; +import { checkResult, getParamsAndKeys, proverStmt, signAndVerify, stringToBytes, verifierStmt } from '../utils'; -describe(`${Scheme} Proving knowledge of 1 signature where some of the attributes are null, i.e.not applicable`, () => { +describe(`Proving knowledge of 1 ${Scheme} signature where some of the attributes are null, i.e. not applicable`, () => { it('works', async () => { // Load the WASM module await initializeWasm(); @@ -43,17 +34,13 @@ describe(`${Scheme} Proving knowledge of 1 signature where some of the attribute const messageCount = messages.length; const label = stringToBytes('My sig params in g1'); - const params = SignatureParams.generate(messageCount, label); // Signers keys - const keypair = KeyPair.generate(params); - const sk = keypair.secretKey; - const pk = keypair.publicKey; + const [params, sk, pk] = getParamsAndKeys(messageCount, label); // Signer knows all the messages and signs - const sig = Signature.generate(messages, sk, params, true); - const result = sig.verify(messages, pk, params, true); - expect(result.verified).toEqual(true); + const [sig, result] = signAndVerify(messages, params, sk, pk, true); + checkResult(result); // User reveals his name, high school year and city to verifier, i.e. indices 2, 4 and 8. He also needs to reveal first // attribute (index 0) which indicates which attributes don't apply to him. @@ -72,18 +59,22 @@ describe(`${Scheme} Proving knowledge of 1 signature where some of the attribute } } - const statement1 = buildStatement(params, pk, revealedMsgs, true); + const statement1 = proverStmt(params, revealedMsgs, pk, true); const statements = new Statements(statement1); // Both the prover (user) and verifier should independently construct this `ProofSpec` but only for testing, i am reusing it. - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); - expect(proofSpec.isValid()).toEqual(true); + const proverProofSpec = new ProofSpec(statements, new MetaStatements()); + expect(proverProofSpec.isValid()).toEqual(true); const witness1 = buildWitness(sig, unrevealedMsgs, true); const witnesses = new Witnesses(witness1); - const proof = CompositeProofG1.generate(proofSpec, witnesses); + const proof = CompositeProof.generate(proverProofSpec, witnesses); - checkResult(proof.verify(proofSpec)); + const statement2 = verifierStmt(params, revealedMsgs, pk, true); + const verifierStatements = new Statements(statement2); + const verifierProofSpec = new ProofSpec(verifierStatements, new MetaStatements(), []); + expect(verifierProofSpec.isValid()).toEqual(true); + checkResult(proof.verify(verifierProofSpec)); }); }); diff --git a/tests/demo.spec.ts b/tests/demo.spec.ts index 6e572a62..d37bc561 100644 --- a/tests/demo.spec.ts +++ b/tests/demo.spec.ts @@ -1,18 +1,18 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { + initializeWasm, Accumulator, AccumulatorParams, AccumulatorPublicKey, AccumulatorSecretKey, - CompositeProofG1, + CompositeProof, MembershipProvingKey, - MembershipWitness, + VBMembershipWitness, MetaStatement, MetaStatements, NonMembershipProvingKey, - NonMembershipWitness, + VBNonMembershipWitness, PositiveAccumulator, - ProofSpecG1, + ProofSpec, Statement, Statements, UniversalAccumulator, @@ -21,25 +21,25 @@ import { Witnesses, randomFieldElement } from '../src'; +import { proverStmt, verifierStmt } from './composite-proofs/msg-js-obj/util'; import { areUint8ArraysEqual, stringToBytes } from './utils'; import { PublicKey, Signature, SecretKey, BlindSignature, - buildStatement, + buildVerifierStatement, KeyPair, buildWitness, SignatureParams, isPS, getStatementForBlindSigRequest, - isBBSPlus, getWitnessForBlindSigRequest, isBBS, Scheme, - adaptKeyForParams + adaptKeyForParams, isKvac } from './scheme'; -import { generateRandomG1Element } from '@docknetwork/crypto-wasm'; +import { generateRandomG1Element } from 'crypto-wasm-new'; // Test demonstrating the flow where holder (user) gets credentials (message lists and signatures) from multiple issuers (signers) // one by one and it proves the knowledge of previously received credentials before getting the next credential (message list and signature). @@ -107,7 +107,7 @@ let Accum2: PositiveAccumulator; let Accum3: UniversalAccumulator; export interface BlindSigRequest { - proof: CompositeProofG1; + proof: CompositeProof; request: any; } @@ -135,23 +135,25 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u } function checkPublicKey(sk: SecretKey, pk: PublicKey, params: any) { - if (!pk.isValid()) { - throw new Error('Public key is invalid'); - } - let gpk = isPS() || isBBS() ? sk.generatePublicKey(params) : sk.generatePublicKeyG2(params); - - if (!areUint8ArraysEqual(gpk.value, pk.value)) { - throw new Error(`Generated public key ${gpk.value} different from expected public key ${pk.value}`); - } - if (!gpk.isValid()) { - throw new Error('Generated public key is invalid'); + if (!isKvac()) { + if (!pk.isValid()) { + throw new Error('Public key is invalid'); + } + let gpk = isPS() || isBBS() ? sk.generatePublicKey(params) : sk.generatePublicKeyG2(params); + + if (!areUint8ArraysEqual(gpk.value, pk.value)) { + throw new Error(`Generated public key ${gpk.value} different from expected public key ${pk.value}`); + } + if (!gpk.isValid()) { + throw new Error('Generated public key is invalid'); + } } } function setupIssuer1Keys() { - const kp = KeyPair.generate(Issuer12SigParams); - Issuer1Sk = kp.secretKey; - Issuer1Pk = kp.publicKey; + const kp = !isKvac() ? KeyPair.generate(Issuer12SigParams) : undefined; + Issuer1Sk = !isKvac() ? kp.secretKey : SecretKey.generate(); + Issuer1Pk = !isKvac() ? kp.publicKey : undefined; checkPublicKey(Issuer1Sk, Issuer1Pk, Issuer12SigParams); log("Issuer 1's secret and public keys are:"); log(Issuer1Sk); @@ -159,9 +161,10 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u } function setupIssuer2Keys() { - const kp = KeyPair.generate(Issuer12SigParams, stringToBytes('my secret passphrase')); - Issuer2Sk = kp.secretKey; - Issuer2Pk = kp.publicKey; + const seed = stringToBytes('my secret passphrase'); + const kp = !isKvac() ? KeyPair.generate(Issuer12SigParams, seed) : undefined; + Issuer2Sk = !isKvac() ? kp.secretKey : SecretKey.generate(seed); + Issuer2Pk = !isKvac() ? kp.publicKey : undefined; checkPublicKey(Issuer2Sk, Issuer2Pk, Issuer12SigParams); log("Issuer 2's secret and public keys are:"); log(Issuer2Sk); @@ -170,9 +173,9 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u function setupIssuer3Keys() { const seed = stringToBytes('my-secret-seed'); - const kp = KeyPair.generate(Issuer3SigParams, seed); - Issuer3Sk = kp.secretKey; - Issuer3Pk = kp.publicKey; + const kp = !isKvac() ? KeyPair.generate(Issuer3SigParams, seed) : undefined; + Issuer3Sk = !isKvac() ? kp.secretKey : SecretKey.generate(seed); + Issuer3Pk = !isKvac() ? kp.publicKey : undefined; checkPublicKey(Issuer3Sk, Issuer3Pk, Issuer3SigParams); log("Issuer 3's secret and public keys are:"); log(Issuer3Sk); @@ -276,10 +279,10 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u let blinding, request; if (isPS()) { [blinding, request] = BlindSignature.generateRequest(msgsToCommit, sigParams, h, blindings); - } else if (isBBSPlus()) { - [blinding, request] = BlindSignature.generateRequest(msgsToCommit, sigParams, false, void 0); - } else { + } else if (isBBS()) { request = BlindSignature.generateRequest(msgsToCommit, sigParams, false); + } else { + [blinding, request] = BlindSignature.generateRequest(msgsToCommit, sigParams, false, void 0); } const statements = new Statements(getStatementForBlindSigRequest(request, sigParams, h)); const witnesses = new Witnesses(getWitnessForBlindSigRequest(msgsToCommit, blinding, blindings)); @@ -300,11 +303,11 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u ); // Proof spec with statement and meta-statement - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proofSpec = new ProofSpec(statements, new MetaStatements()); expect(proofSpec.isValid()).toEqual(true); // Composite proof for proving knowledge of opening of Pedersen commitment - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); + const proof = CompositeProof.generate(proofSpec, witnesses, nonce); return [{ proof, request }, blinding, blindings]; } @@ -320,7 +323,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk: AccumulatorPublicKey, prk: MembershipProvingKey, accumulated: Uint8Array, - membershipWitness: MembershipWitness, + membershipWitness: VBMembershipWitness, h: Uint8Array, nonce?: Uint8Array ): [BlindSigRequest, Uint8Array, Map] { @@ -330,11 +333,11 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // 3) opening of commitment in the blind signature request. const statements = new Statements(); - const statement1 = buildStatement(sigParams, pk, revealedMsgs, false); + const statement1 = proverStmt(sigParams, revealedMsgs, pk, false); const witness1 = buildWitness(credential, unrevealedMsgs, false); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); - const witness2 = Witness.accumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); + const witness2 = Witness.vbAccumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); const [blindStatements, blindWitnesses, request, blinding, blindings] = blindSigRequestWithSecretStatementAndWitness(secret, sigParamsForRequestedCredential, h); @@ -362,14 +365,14 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(ms2); // Create proof spec with statements and meta statements - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proofSpec = new ProofSpec(statements, metaStatements); expect(proofSpec.isValid()).toEqual(true); const witnesses = new Witnesses(); witnesses.add(witness1); witnesses.add(witness2); witnesses.append(blindWitnesses); - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); + const proof = CompositeProof.generate(proofSpec, witnesses, nonce); return [{ proof, request }, blinding, blindings]; } @@ -385,7 +388,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk: AccumulatorPublicKey, prk: MembershipProvingKey, accumulated: Uint8Array, - membershipWitness: MembershipWitness, + membershipWitness: VBMembershipWitness, credential2: Signature, sigParams2: SignatureParams, pk2: PublicKey, @@ -395,7 +398,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk2: AccumulatorPublicKey, prk2: MembershipProvingKey, accumulated2: Uint8Array, - membershipWitness2: MembershipWitness, + membershipWitness2: VBMembershipWitness, h: Uint8Array, nonce?: Uint8Array ): [BlindSigRequest, Uint8Array, Map] { @@ -406,37 +409,35 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // 4) accumulator membership for credential1, // 5) opening of commitment in the blind signature request. - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, - false + pk, ); const witness1 = buildWitness(credential, unrevealedMsgs, false); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); - const witness2 = Witness.accumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); + const witness2 = Witness.vbAccumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); - const statement3 = buildStatement( + const statement3 = proverStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2, - false + pk2, ); const witness3 = buildWitness(credential2, unrevealedMsgs2, false); - const statement4 = Statement.accumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); - const witness4 = Witness.accumulatorMembership(unrevealedMsgs2.get(1) as Uint8Array, membershipWitness2); + const statement4 = Statement.vbAccumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); + const witness4 = Witness.vbAccumulatorMembership(unrevealedMsgs2.get(1) as Uint8Array, membershipWitness2); const [blindStatemenents, blindWitnesses, request, blinding, blindings] = blindSigRequestWithSecretStatementAndWitness(secret, sigParamsForRequestedCredential, h); - const statements = new Statements(); + const proverStatements = new Statements(); - statements.add(statement1); - statements.add(statement2); - statements.add(statement3); - statements.add(statement4); - statements.append(blindStatemenents); + proverStatements.add(statement1); + proverStatements.add(statement2); + proverStatements.add(statement3); + proverStatements.add(statement4); + proverStatements.append(blindStatemenents); // Prove equality of holder's secret in `credential`, `credential1` and blind signature request. const witnessEq1 = new WitnessEqualityMetaStatement(); @@ -459,8 +460,8 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(MetaStatement.witnessEquality(witnessEq2)); metaStatements.add(MetaStatement.witnessEquality(witnessEq3)); - const proofSpec = new ProofSpecG1(statements, metaStatements); - expect(proofSpec.isValid()).toEqual(true); + const proverProofSpec = new ProofSpec(proverStatements, metaStatements); + expect(proverProofSpec.isValid()).toEqual(true); const witnesses = new Witnesses(); @@ -470,7 +471,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u witnesses.add(witness4); witnesses.append(blindWitnesses); - const proof = CompositeProofG1.generate(proofSpec, witnesses, nonce); + const proof = CompositeProof.generate(proverProofSpec, witnesses, nonce); return [{ proof, request }, blinding, blindings]; } @@ -487,7 +488,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // Verify knowledge of opening of commitment and issue blind signature with that commitment const statements = new Statements(getStatementForBlindSigRequest(blindSigReq.request, sigParams, h)); - const proofSpec = new ProofSpecG1(statements, new MetaStatements()); + const proofSpec = new ProofSpec(statements, new MetaStatements()); expect(proofSpec.isValid()).toEqual(true); const res = blindSigReq.proof.verify(proofSpec, nonce); @@ -523,13 +524,13 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u const indicesToCommit: number[] = []; indicesToCommit.push(0); const bases = sigParamsForRequestedCredential.getParamsForIndices(indicesToCommit); - const statement1 = buildStatement( + const statement1 = verifierStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, + pk, false ); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); const restStatements = getStatementForBlindSigRequest(blindSigReq.request, sigParams, h); const statements = new Statements(); @@ -553,7 +554,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(ms2); } - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proofSpec = new ProofSpec(statements, metaStatements); expect(proofSpec.isValid()).toEqual(true); const res = blindSigReq.proof.verify(proofSpec, nonce); @@ -599,20 +600,20 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // 4) accumulator membership for credential1, // 5) opening of commitment in the blind signature request. - const statement1 = buildStatement( + const statement1 = verifierStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, + pk, false ); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); - const statement3 = buildStatement( + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); + const statement3 = verifierStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2, + pk2, false ); - const statement4 = Statement.accumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); + const statement4 = Statement.vbAccumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); const statement5 = getStatementForBlindSigRequest(blindSigReq.request, sigParamsForRequestedCredential, h); const statements = new Statements( @@ -639,7 +640,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(MetaStatement.witnessEquality(witnessEq3)); } - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proofSpec = new ProofSpec(statements, metaStatements); expect(proofSpec.isValid()).toEqual(true); const res = blindSigReq.proof.verify(proofSpec, nonce); @@ -665,7 +666,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk: AccumulatorPublicKey, prk: MembershipProvingKey, accumulated: Uint8Array, - membershipWitness: MembershipWitness, + membershipWitness: VBMembershipWitness, credential2: Signature, sigParams2: SignatureParams, pk2: PublicKey, @@ -675,7 +676,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk2: AccumulatorPublicKey, prk2: MembershipProvingKey, accumulated2: Uint8Array, - membershipWitness2: MembershipWitness, + membershipWitness2: VBMembershipWitness, credential3: Signature, sigParams3: SignatureParams, pk3: PublicKey, @@ -685,7 +686,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u accumPk3: AccumulatorPublicKey, prk3: MembershipProvingKey, accumulated3: Uint8Array, - membershipWitness3: MembershipWitness, + membershipWitness3: VBMembershipWitness, nonce?: Uint8Array ) { // Create composite proof of 6 statements, @@ -696,38 +697,38 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // 5) knowledge of a signature in credential2, // 6) accumulator membership for credential2, - const statement1 = buildStatement( + const statement1 = proverStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, + pk, false ); const witness1 = buildWitness(credential, unrevealedMsgs, false); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); - const witness2 = Witness.accumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); + const witness2 = Witness.vbAccumulatorMembership(unrevealedMsgs.get(1) as Uint8Array, membershipWitness); - const statement3 = buildStatement( + const statement3 = proverStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2, + pk2, false ); const witness3 = buildWitness(credential2, unrevealedMsgs2, false); - const statement4 = Statement.accumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); - const witness4 = Witness.accumulatorMembership(unrevealedMsgs2.get(1) as Uint8Array, membershipWitness2); + const statement4 = Statement.vbAccumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); + const witness4 = Witness.vbAccumulatorMembership(unrevealedMsgs2.get(1) as Uint8Array, membershipWitness2); - const statement5 = buildStatement( + const statement5 = proverStmt( sigParams3, - adaptKeyForParams(pk3, sigParams3), revealedMsgs3, + pk3, false ); const witness5 = buildWitness(credential3, unrevealedMsgs3, false); - const statement6 = Statement.accumulatorMembership(accumParams3, accumPk3, prk3, accumulated3); - const witness6 = Witness.accumulatorMembership(unrevealedMsgs3.get(1) as Uint8Array, membershipWitness3); + const statement6 = Statement.vbAccumulatorMembership(accumParams3, accumPk3, prk3, accumulated3); + const witness6 = Witness.vbAccumulatorMembership(unrevealedMsgs3.get(1) as Uint8Array, membershipWitness3); const statements = new Statements(); statements.add(statement1); @@ -760,7 +761,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(MetaStatement.witnessEquality(witnessEq3)); metaStatements.add(MetaStatement.witnessEquality(witnessEq4)); - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proofSpec = new ProofSpec(statements, metaStatements); expect(proofSpec.isValid()).toEqual(true); const witnesses = new Witnesses(); @@ -771,11 +772,11 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u witnesses.add(witness5); witnesses.add(witness6); - return CompositeProofG1.generate(proofSpec, witnesses, nonce); + return CompositeProof.generate(proofSpec, witnesses, nonce); } function verifyProofOf3Creds( - proof: CompositeProofG1, + proof: CompositeProof, sigParams: SignatureParams, pk: PublicKey, revealedMsgs: Map, @@ -807,27 +808,27 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u // 5) knowledge of a signature in credential2, // 6) accumulator membership for credential2, - const statement1 = buildStatement( + const statement1 = verifierStmt( sigParams, - adaptKeyForParams(pk, sigParams), revealedMsgs, + pk, false ); - const statement2 = Statement.accumulatorMembership(accumParams, accumPk, prk, accumulated); - const statement3 = buildStatement( + const statement2 = Statement.vbAccumulatorMembership(accumParams, accumPk, prk, accumulated); + const statement3 = verifierStmt( sigParams2, - adaptKeyForParams(pk2, sigParams2), revealedMsgs2, + pk2, false ); - const statement4 = Statement.accumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); - const statement5 = buildStatement( + const statement4 = Statement.vbAccumulatorMembership(accumParams2, accumPk2, prk2, accumulated2); + const statement5 = verifierStmt( sigParams3, - adaptKeyForParams(pk3, sigParams3), revealedMsgs3, + pk3, false ); - const statement6 = Statement.accumulatorMembership(accumParams3, accumPk3, prk3, accumulated3); + const statement6 = Statement.vbAccumulatorMembership(accumParams3, accumPk3, prk3, accumulated3); const statements = new Statements(); statements.add(statement1); @@ -860,7 +861,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u metaStatements.add(MetaStatement.witnessEquality(witnessEq3)); metaStatements.add(MetaStatement.witnessEquality(witnessEq4)); - const proofSpec = new ProofSpecG1(statements, metaStatements); + const proofSpec = new ProofSpec(statements, metaStatements); expect(proofSpec.isValid()).toEqual(true); const res = proof.verify(proofSpec, nonce); @@ -885,17 +886,18 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u holderSecret: Uint8Array, msgs: Uint8Array[], pk: PublicKey, + sk: SecretKey, sigParams: SignatureParams ): [Signature, Uint8Array[]] { const revealed = isPS() ? blindedSig.unblind(blindings, pk) - : isBBSPlus() - ? blindedSig.unblind(blinding) - : blindedSig; + : isBBS() + ? blindedSig + : blindedSig.unblind(blinding); let final: Uint8Array[] = []; final.push(Signature.encodeMessageForSigning(holderSecret)); final = final.concat(msgs); - const res1 = revealed.verify(final, pk, sigParams, false); + const res1 = revealed.verify(final, isKvac() ? sk : pk, sigParams, false); if (!res1.verified) { throw new Error(`Failed to verify revealed sig1 due to ${res1.error}`); } @@ -952,6 +954,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u holderSecret, holderAttrs1, Issuer1Pk, + Issuer1Sk, Issuer12SigParams ); // Holder checks that attribute at index 1 is in the accumulator @@ -1029,6 +1032,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u holderSecret, holderMessages2, Issuer2Pk, + Issuer2Sk, Issuer12SigParams ); const memCheck2 = Accum2.verifyMembershipWitness(revocationId2, membershipWitness2, Accum2Pk, Accum2Params); @@ -1116,6 +1120,7 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u holderSecret, holderMessages3, Issuer3Pk, + Issuer3Sk, Issuer3SigParams ); const memCheck3 = Accum3.verifyMembershipWitness(revocationId3, membershipWitness3, Accum3Pk); @@ -1223,22 +1228,22 @@ describe(`A demo showing combined use of ${Scheme} signatures and accumulators u } const j4 = membershipWitness1.toJSON(); - if (!areUint8ArraysEqual(membershipWitness1.value, MembershipWitness.fromJSON(j4).value)) { + if (!areUint8ArraysEqual(membershipWitness1.value, VBMembershipWitness.fromJSON(j4).value)) { throw new Error('From JSON failed for witness 1'); } const j5 = membershipWitness2.toJSON(); - if (!areUint8ArraysEqual(membershipWitness2.value, MembershipWitness.fromJSON(j5).value)) { + if (!areUint8ArraysEqual(membershipWitness2.value, VBMembershipWitness.fromJSON(j5).value)) { throw new Error('From JSON failed for witness 2'); } const j6 = membershipWitness3.toJSON(); - if (!areUint8ArraysEqual(membershipWitness3.value, MembershipWitness.fromJSON(j6).value)) { + if (!areUint8ArraysEqual(membershipWitness3.value, VBMembershipWitness.fromJSON(j6).value)) { throw new Error('From JSON failed for witness 1'); } const j7 = nonMemWitness.toJSON(); - const l = NonMembershipWitness.fromJSON(j7).value; + const l = VBNonMembershipWitness.fromJSON(j7).value; if (!areUint8ArraysEqual(nonMemWitness.value.d, l.d)) { throw new Error('From JSON failed for non-member witness'); } diff --git a/tests/frost-dkg.spec.ts b/tests/frost-dkg.spec.ts index 0c78692d..0a4caf92 100644 --- a/tests/frost-dkg.spec.ts +++ b/tests/frost-dkg.spec.ts @@ -1,7 +1,8 @@ -import { generateRandomG1Element, generateRandomG2Element, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateRandomG1Element, generateRandomG2Element } from 'crypto-wasm-new'; import { runFrostKeygen, stringToBytes } from './utils'; import { ParticipantG1, ParticipantG2 } from '../src/frost-dkg'; import { PublicKeyBase } from '../src/types'; +import { initializeWasm } from '../src'; describe('Frost DKG', () => { let pkBaseG1: PublicKeyBase; diff --git a/tests/prefilled-positive-accumulator.spec.ts b/tests/prefilled-positive-accumulator.spec.ts index 06352bb1..95addd96 100644 --- a/tests/prefilled-positive-accumulator.spec.ts +++ b/tests/prefilled-positive-accumulator.spec.ts @@ -1,11 +1,11 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { Accumulator, AccumulatorKeypair, AccumulatorParams, - MembershipWitness, + initializeWasm, PositiveAccumulator, - WitnessUpdatePublicInfo + VBMembershipWitness, + VBWitnessUpdatePublicInfo } from '../src'; import { InMemoryState } from '../src/accumulator/in-memory-persistence'; import { stringToBytes } from './utils'; @@ -69,7 +69,7 @@ describe('Prefilled positive accumulator', () => { expect(verifAccumulator.verifyMembershipWitness(member2, witness2, keypair.publicKey, params)).toEqual(true); // Manager decides to remove a member, the new accumulated value will be published along with witness update info - const witnessUpdInfo = WitnessUpdatePublicInfo.new(accumulator.accumulated, [], [member2], keypair.secretKey); + const witnessUpdInfo = VBWitnessUpdatePublicInfo.new(accumulator.accumulated, [], [member2], keypair.secretKey); await accumulator.remove(member2, keypair.secretKey, state); verifAccumulator = PositiveAccumulator.fromAccumulated(accumulator.accumulated); @@ -90,11 +90,11 @@ describe('Prefilled positive accumulator', () => { expect(verifAccumulator.verifyMembershipWitness(member3, witness3, keypair.publicKey, params)).toEqual(true); // Update using knowledge of witness info - const witness1Old = MembershipWitness.fromJSON(witness1OldJson); + const witness1Old = VBMembershipWitness.fromJSON(witness1OldJson); witness1Old.updateUsingPublicInfoPostBatchUpdate(member1, [], [member2], witnessUpdInfo); expect(verifAccumulator.verifyMembershipWitness(member1, witness1Old, keypair.publicKey, params)).toEqual(true); - const witness3Old = MembershipWitness.fromJSON(witness3OldJson); + const witness3Old = VBMembershipWitness.fromJSON(witness3OldJson); witness3Old.updateUsingPublicInfoPostBatchUpdate(member3, [], [member2], witnessUpdInfo); expect(verifAccumulator.verifyMembershipWitness(member3, witness3Old, keypair.publicKey, params)).toEqual(true); }); diff --git a/tests/r1cs.spec.ts b/tests/r1cs.spec.ts index c7c1e7eb..b1fe94b6 100644 --- a/tests/r1cs.spec.ts +++ b/tests/r1cs.spec.ts @@ -1,6 +1,6 @@ -import { generateFieldElementFromNumber, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateFieldElementFromNumber } from 'crypto-wasm-new'; import { checkLegoProvingKey, fromLeToBigInt, getWasmBytes, parseR1CSFile } from './utils'; -import { CircomCircuit, CircomInputs, processParsedR1CSFile, R1CSSnarkSetup } from '../src'; +import { initializeWasm, CircomCircuit, CircomInputs, processParsedR1CSFile, R1CSSnarkSetup } from '../src'; describe('For R1CS from Circom', () => { beforeAll(async () => { diff --git a/tests/saver.spec.ts b/tests/saver.spec.ts index 42162287..a93cff40 100644 --- a/tests/saver.spec.ts +++ b/tests/saver.spec.ts @@ -1,5 +1,5 @@ -import { initializeWasm } from '@docknetwork/crypto-wasm'; import { + initializeWasm, getChunkBitSize, SaverChunkedCommitmentKey, SaverChunkedCommitmentKeyUncompressed, diff --git a/tests/scheme.spec.ts b/tests/scheme.spec.ts index 82659ea2..11163549 100644 --- a/tests/scheme.spec.ts +++ b/tests/scheme.spec.ts @@ -1,21 +1,19 @@ -import { generateRandomG1Element, encodeMessageForSigning } from '@docknetwork/crypto-wasm'; -import { - initializeWasm, - randomFieldElement, - bytesToChallenge, - PSBlindSignature, -} from '../src'; -import { checkResult, getRevealedUnrevealed, stringToBytes } from './utils'; +import { encodeMessageForSigning, generateRandomG1Element } from 'crypto-wasm-new'; +import { bytesToChallenge, initializeWasm, PSBlindSignature, randomFieldElement } from '../src'; +import { checkResult, getParamsAndKeys, getRevealedUnrevealed, signAndVerify, stringToBytes } from './utils'; import { BlindSignature, - PoKSignatureProtocol, - isPS, - Signature, - SignatureParams, - SecretKey, encodeMessageForSigningIfPS, + isBBS, isBBSPlus, - Scheme, PublicKey + isKvac, + isPS, + PoKSignatureProtocol, + PublicKey, + Scheme, + SecretKey, + Signature, + SignatureParams } from './scheme'; function getMessages(count: number): Uint8Array[] { @@ -38,48 +36,46 @@ describe(`${Scheme} signature sunny day scenario`, () => { } const label = stringToBytes('My sig params in g1'); - const params = SignatureParams.generate(messageCount, label); - - const sk = SecretKey.generate(isPS() ? messageCount : void 0); - const pk = isBBSPlus() ? sk.generatePublicKeyG2(params) : sk.generatePublicKey(params); + const [params, sk, pk] = getParamsAndKeys(messageCount, label); - const sig = isPS() ? Signature.generate(messages, sk, params) : Signature.generate(messages, sk, params, false); - const result = isPS() ? sig.verify(messages, pk, params) : sig.verify(messages, pk, params, false); + const [sig, result] = signAndVerify(messages, params, sk, pk, false); console.log(`Signature verified ? ${JSON.stringify(result)}`); checkResult(result); // Check serialization - const pkHex = pk.hex; - const skHex = sk.hex; - const sig_ = isPS() ? Signature.generate(messages, SecretKey.fromHex(skHex), params) : Signature.generate(messages, SecretKey.fromHex(skHex), params, false); - const result_ = isPS() ? sig_.verify(messages, PublicKey.fromHex(pkHex), params) : sig_.verify(messages, PublicKey.fromHex(pkHex), params, false); + const pkH = isKvac() ? undefined : PublicKey.fromHex(pk.hex); + const skH = SecretKey.fromHex(sk.hex); + const [, result_] = signAndVerify(messages, params, skH, pkH, false); checkResult(result_); - // 2 revealed messages and 1 user supplied blinding - let revealed: Set = new Set(); - let revealedMsgs: Map = new Map(); - revealed.add(0); - revealed.add(2); - revealedMsgs.set(0, messages[0]); - revealedMsgs.set(2, messages[2]); - const blindings: Map = new Map(); - blindings.set(1, randomFieldElement()); - - const protocol = isPS() - ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) - : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); - const challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); - const challengeProver = bytesToChallenge(challengeContributionP); - const proof = protocol.generateProof(challengeProver); - - let challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); - let challengeVerifier = bytesToChallenge(challengeContributionV); - - const result1 = isPS() - ? proof.verify(challengeVerifier, pk, params, revealedMsgs) - : proof.verify(challengeVerifier, pk, params, false, revealedMsgs); - console.log(`Proof verified ? ${JSON.stringify(result1)}`); - checkResult(result1); + // For KVAC, proof of knowledge is integrated in the composite proof system only + if (!isKvac()) { + // 2 revealed messages and 1 user supplied blinding + let revealed: Set = new Set(); + let revealedMsgs: Map = new Map(); + revealed.add(0); + revealed.add(2); + revealedMsgs.set(0, messages[0]); + revealedMsgs.set(2, messages[2]); + const blindings: Map = new Map(); + blindings.set(1, randomFieldElement()); + + const protocol = isPS() + ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) + : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); + const challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); + const challengeProver = bytesToChallenge(challengeContributionP); + const proof = protocol.generateProof(challengeProver); + + let challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); + let challengeVerifier = bytesToChallenge(challengeContributionV); + + const result1 = isPS() + ? proof.verify(challengeVerifier, pk, params, revealedMsgs) + : proof.verify(challengeVerifier, pk, params, false, revealedMsgs); + console.log(`Proof verified ? ${JSON.stringify(result1)}`); + checkResult(result1); + } }); }); @@ -94,7 +90,8 @@ describe(`${Scheme} signature`, () => { let blindings = new Map(); const label = stringToBytes('My sig params in g1'); - const params = SignatureParams.generate(messageCount, label); + // const params = SignatureParams.generate(messageCount, label); + const [params, sk, pk] = getParamsAndKeys(messageCount, label); expect(params.isValid()).toEqual(true); expect(params.supportedMessageCount()).toEqual(messageCount); @@ -103,96 +100,93 @@ describe(`${Scheme} signature`, () => { const deserializedParams = SignatureParams.valueFromBytes(paramBytes); expect(params.value).toEqual(deserializedParams); - const sk = SecretKey.generate(isPS() ? messageCount : void 0); - const pk = isBBSPlus() ? sk.generatePublicKeyG2(params) : sk.generatePublicKey(params); + if (!isKvac()) { + expect(pk.isValid()).toEqual(true); + } - expect(pk.isValid()).toEqual(true); + const [sig, result] = signAndVerify(messages, params, sk, pk, false); + checkResult(result); - const sig = isPS() ? Signature.generate(messages, sk, params) : Signature.generate(messages, sk, params, false); - let result = isPS() ? sig.verify(messages, pk, params) : sig.verify(messages, pk, params, false); - expect(result.verified).toEqual(true); // Passing different `encodeMessages` to verify and sign results in error - expect(() => isPS() ? sig.verify(getMessages(messageCount), pk, params) : sig.verify(getMessages(messageCount), pk, params, false)).toThrow(); + expect(() => isKvac() ? sig.verify(getMessages(messageCount), sk, params, false) : isPS() ? sig.verify(getMessages(messageCount), pk, params) : sig.verify(getMessages(messageCount), pk, params, false)).toThrow(); // Pre encoded message - const sig1 = isPS() ? Signature.generate(messages, sk, params) : Signature.generate(messages, sk, params, false); - result = isPS() ? sig1.verify(messages, pk, params) : sig.verify(messages, pk, params, false); - expect(result.verified).toEqual(true); - - // No revealed messages and no user supplied blindings - let protocol = isPS() - ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings) - : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings); - let challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, new Map()); - let challengeProver = bytesToChallenge(challengeContributionP); - let proof = protocol.generateProof(challengeProver); - - let challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, new Map()); - let challengeVerifier = bytesToChallenge(challengeContributionV); - - expect(challengeProver).toEqual(challengeVerifier); - - result = isPS() - ? proof.verify(challengeVerifier, pk, params, new Map()) - : proof.verify(challengeVerifier, pk, params, false, new Map()); - expect(result.verified).toEqual(true); - - // 2 revealed messages but no user supplied blindings - let revealed: Set = new Set(); - let revealedMsgs: Map = new Map(); - revealed.add(0); - revealed.add(2); - revealedMsgs.set(0, messages[0]); - revealedMsgs.set(2, messages[2]); - - protocol = isPS() - ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) - : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); - challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); - challengeProver = bytesToChallenge(challengeContributionP); - proof = protocol.generateProof(challengeProver); - - challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); - challengeVerifier = bytesToChallenge(challengeContributionV); - - expect(challengeProver).toEqual(challengeVerifier); - - checkResult( - isPS() - ? proof.verify(challengeVerifier, pk, params, revealedMsgs) - : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) - ); - - // 2 revealed messages and 1 user supplied blinding - blindings = new Map(); - blindings.set(1, randomFieldElement()); - protocol = isPS() - ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) - : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); - challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); - challengeProver = bytesToChallenge(challengeContributionP); - proof = protocol.generateProof(challengeProver); - - challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); - challengeVerifier = bytesToChallenge(challengeContributionV); - - expect(challengeProver).toEqual(challengeVerifier); - - checkResult( - isPS() - ? proof.verify(challengeVerifier, pk, params, revealedMsgs) - : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) - ); + const [, result1] = signAndVerify(messages, params, sk, pk, false); + checkResult(result1); + + if (!isKvac()) { + // No revealed messages and no user supplied blindings + let protocol = isPS() + ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings) + : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings); + let challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, new Map()); + let challengeProver = bytesToChallenge(challengeContributionP); + let proof = protocol.generateProof(challengeProver); + + let challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, new Map()); + let challengeVerifier = bytesToChallenge(challengeContributionV); + + expect(challengeProver).toEqual(challengeVerifier); + + const result2 = isPS() + ? proof.verify(challengeVerifier, pk, params, new Map()) + : proof.verify(challengeVerifier, pk, params, false, new Map()); + expect(result2.verified).toEqual(true); + + // 2 revealed messages but no user supplied blindings + let revealed: Set = new Set(); + let revealedMsgs: Map = new Map(); + revealed.add(0); + revealed.add(2); + revealedMsgs.set(0, messages[0]); + revealedMsgs.set(2, messages[2]); + + protocol = isPS() + ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) + : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); + challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); + challengeProver = bytesToChallenge(challengeContributionP); + proof = protocol.generateProof(challengeProver); + + challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); + challengeVerifier = bytesToChallenge(challengeContributionV); + + expect(challengeProver).toEqual(challengeVerifier); + + checkResult( + isPS() + ? proof.verify(challengeVerifier, pk, params, revealedMsgs) + : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) + ); + + // 2 revealed messages and 1 user supplied blinding + blindings = new Map(); + blindings.set(1, randomFieldElement()); + protocol = isPS() + ? PoKSignatureProtocol.initialize(messages, sig, pk, params, blindings, revealed) + : PoKSignatureProtocol.initialize(messages, sig, params, false, blindings, revealed); + challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); + challengeProver = bytesToChallenge(challengeContributionP); + proof = protocol.generateProof(challengeProver); + + challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); + challengeVerifier = bytesToChallenge(challengeContributionV); + + expect(challengeProver).toEqual(challengeVerifier); + + checkResult( + isPS() + ? proof.verify(challengeVerifier, pk, params, revealedMsgs) + : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) + ); + } }); it('should sign and verify blind signature', () => { const messageCount = 10; const messages = getMessages(messageCount).map(encodeMessageForSigningIfPS); const label = stringToBytes('My new sig params'); - const params = SignatureParams.generate(messageCount, label); - - const sk = SecretKey.generate(isPS() ? messageCount : void 0); - const pk = isBBSPlus() ? sk.generatePublicKeyG2(params) : sk.generatePublicKey(params); + const [params, sk, pk] = getParamsAndKeys(messageCount, label); const messagesToHide = new Map(); messagesToHide.set(1, messages[1]); @@ -218,10 +212,10 @@ describe(`${Scheme} signature`, () => { void 0, revealedMessages ); - } else if (isBBSPlus()) { - [blinding, request] = BlindSignature.generateRequest(messagesToHide, params, true, void 0, revealedMessages); - } else { + } else if (isBBS()) { request = BlindSignature.generateRequest(messagesToHide, params, true, revealedMessages); + } else { + [blinding, request] = BlindSignature.generateRequest(messagesToHide, params, true, void 0, revealedMessages); } let blindSig = isPS() @@ -238,35 +232,30 @@ describe(`${Scheme} signature`, () => { ) : BlindSignature.fromRequest(request, sk, params); - const sig = isPS() ? blindSig.unblind(blindings, pk) : isBBSPlus() ? blindSig.unblind(blinding) : blindSig; - expect(sig.verify(messages, pk, params, true).verified).toEqual(true); + const sig = isPS() ? blindSig.unblind(blindings, pk) : isBBS() ? blindSig : blindSig.unblind(blinding); + expect((isKvac() ? sig.verify(messages, sk, params, true) : sig.verify(messages, pk, params, true)).verified).toEqual(true); }); it('params should be adaptable', () => { const ten = 10; const messages10 = getMessages(ten).map(encodeMessageForSigningIfPS); const label = stringToBytes('Some label for params'); - const params10 = SignatureParams.generate(ten, label); - - const sk10 = SecretKey.generate(isPS() ? ten : void 0); - const pk10 = isBBSPlus() ? sk10.generatePublicKeyG2(params10) : sk10.generatePublicKey(params10); + const [params10, sk10, pk10] = getParamsAndKeys(ten, label); - const sig = Signature.generate(messages10, sk10, params10, true); - expect(sig.verify(messages10, pk10, params10, true).verified).toEqual(true); + const [, result] = signAndVerify(messages10, params10, sk10, pk10, true); + checkResult(result); const twelve = 12; const messages12 = getMessages(twelve).map(encodeMessageForSigningIfPS); expect(() => Signature.generate(messages12, sk10, params10, true)).toThrow(); - const params12 = params10.adapt(twelve); - const sk12 = SecretKey.generate(isPS() ? twelve : void 0); - const pk12 = isBBSPlus() ? sk12.generatePublicKeyG2(params12) : sk12.generatePublicKey(params12); + const [params12, sk12, pk12] = getParamsAndKeys(twelve, label); expect(params12.isValid()).toEqual(true); expect(params12.supportedMessageCount()).toEqual(twelve); - const sig1 = Signature.generate(messages12, sk12, params12, true); - expect(sig1.verify(messages12, pk12, params12, true).verified).toEqual(true); + const [, result1] = signAndVerify(messages12, params12, sk12, pk12, true); + checkResult(result1); const five = 5; const messages5 = getMessages(five).map(encodeMessageForSigningIfPS); @@ -274,21 +263,19 @@ describe(`${Scheme} signature`, () => { expect(() => Signature.generate(messages5, sk12, params10, true)).toThrow(); expect(() => Signature.generate(messages5, sk12, params12, true)).toThrow(); - const params5 = params12.adapt(five); - const sk5 = SecretKey.generate(isPS() ? five : void 0); - const pk5 = isBBSPlus() ? sk5.generatePublicKeyG2(params5) : sk5.generatePublicKey(params5); + const [params5, sk5, pk5] = getParamsAndKeys(five, label); expect(params5.isValid()).toEqual(true); expect(params5.supportedMessageCount()).toEqual(five); - const sig2 = Signature.generate(messages5, sk5, params5, true); - expect(sig2.verify(messages5, pk5, params5, true).verified).toEqual(true); + const [, result2] = signAndVerify(messages5, params5, sk5, pk5, true); + checkResult(result2); const params10Again = params10.adapt(ten); expect(params10Again.isValid()).toEqual(true); expect(params10Again.supportedMessageCount()).toEqual(ten); - const sig3 = Signature.generate(messages10, sk10, params10Again, true); - expect(sig3.verify(messages10, pk10, params10Again, true).verified).toEqual(true); + const [, result3] = signAndVerify(messages10, params10Again, sk10, pk10, true); + checkResult(result3); }); it('should support reversible encoding', () => { @@ -308,42 +295,41 @@ describe(`${Scheme} signature`, () => { const decoded = Signature.reversibleDecodeStringForSigning(encodedMessages[i], compress); expect(decoded).toEqual(messages[i]); } - const params = SignatureParams.generate(count); - const sk = SecretKey.generate(isPS() ? messages.length : void 0); - const pk = isBBSPlus() ? sk.generatePublicKeyG2(params) : sk.generatePublicKey(params); + const [params, sk, pk] = getParamsAndKeys(count); - const sig = isPS() ? Signature.generate(encodedMessages, sk, params) : Signature.generate(encodedMessages, sk, params, false); - const result = isPS() ? sig.verify(encodedMessages, pk, params) : sig.verify(encodedMessages, pk, params, false); - expect(result.verified).toEqual(true); + const [sig, result] = signAndVerify(encodedMessages, params, sk, pk, false); + checkResult(result); - // Reveal all messages! This is done for testing purposes only. - let revealed: Set = new Set(); - for (let i = 0; i < count - 1; i++) { - revealed.add(i); - } + if (!isKvac()) { + // Reveal all messages! This is done for testing purposes only. + let revealed: Set = new Set(); + for (let i = 0; i < count - 1; i++) { + revealed.add(i); + } - const [revealedMsgs] = getRevealedUnrevealed(encodedMessages, revealed); - const protocol = isPS() - ? PoKSignatureProtocol.initialize(encodedMessages, sig, pk, params, blindings, revealed) - : PoKSignatureProtocol.initialize(encodedMessages, sig, params, false, blindings, revealed); + const [revealedMsgs] = getRevealedUnrevealed(encodedMessages, revealed); + const protocol = isPS() + ? PoKSignatureProtocol.initialize(encodedMessages, sig, pk, params, blindings, revealed) + : PoKSignatureProtocol.initialize(encodedMessages, sig, params, false, blindings, revealed); - const challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); - const challengeProver = bytesToChallenge(challengeContributionP); - const proof = protocol.generateProof(challengeProver); + const challengeContributionP = isPS() ? protocol.challengeContribution(params, pk) : protocol.challengeContribution(params, false, revealedMsgs); + const challengeProver = bytesToChallenge(challengeContributionP); + const proof = protocol.generateProof(challengeProver); - const challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); - const challengeVerifier = bytesToChallenge(challengeContributionV); + const challengeContributionV = isPS() ? proof.challengeContribution(params, pk) : proof.challengeContribution(params, false, revealedMsgs); + const challengeVerifier = bytesToChallenge(challengeContributionV); - expect(challengeProver).toEqual(challengeVerifier); + expect(challengeProver).toEqual(challengeVerifier); - checkResult( - isPS() - ? proof.verify(challengeVerifier, pk, params, revealedMsgs) - : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) - ); - for (let i = 0; i < count - 1; i++) { - const decoded = Signature.reversibleDecodeStringForSigning(revealedMsgs.get(i) as Uint8Array); - expect(decoded).toEqual(messages[i]); + checkResult( + isPS() + ? proof.verify(challengeVerifier, pk, params, revealedMsgs) + : proof.verify(challengeVerifier, pk, params, false, revealedMsgs) + ); + for (let i = 0; i < count - 1; i++) { + const decoded = Signature.reversibleDecodeStringForSigning(revealedMsgs.get(i) as Uint8Array); + expect(decoded).toEqual(messages[i]); + } } } diff --git a/tests/scheme.ts b/tests/scheme.ts index 905ff3cb..7afb1eae 100644 --- a/tests/scheme.ts +++ b/tests/scheme.ts @@ -1,4 +1,4 @@ -import { encodeMessageForSigning } from '@docknetwork/crypto-wasm'; +import { encodeMessageForSigning } from 'crypto-wasm-new'; import { BBSBlindSignature, BBSCredential, @@ -38,8 +38,12 @@ import { getPSWitnessesForBlindSigRequest, BBS_SIGNATURE_PARAMS_LABEL_BYTES, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES, - PS_SIGNATURE_PARAMS_LABEL_BYTES + PS_SIGNATURE_PARAMS_LABEL_BYTES, + BDDT16_MAC_PARAMS_LABEL_BYTES, + getBDDT16StatementForBlindMacRequest, + getBDDT16WitnessForBlindMacRequest, BDDT16CredentialBuilder, BDDT16Credential } from '../src'; +import { BDDT16BlindMac, BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../src/bddt16-mac'; export { Presentation } from '../src/anonymous-credentials/presentation'; export { PresentationBuilder } from '../src/anonymous-credentials/presentation-builder'; @@ -56,10 +60,12 @@ export let Scheme: string = process.env.TEST_SIGNATURE_SCHEME || 'BBS', getStatementForBlindSigRequest, getWitnessForBlindSigRequest, buildWitness, - buildStatement, + buildProverStatement, + buildVerifierStatement, buildPublicKeySetupParam, buildSignatureParamsSetupParam, - buildStatementFromSetupParamsRef, + buildProverStatementFromSetupParamsRef, + buildVerifierStatementFromSetupParamsRef, CredentialBuilder, Credential, encodeMessageForSigningIfPS: (msg: Uint8Array) => Uint8Array, @@ -67,6 +73,7 @@ export let Scheme: string = process.env.TEST_SIGNATURE_SCHEME || 'BBS', isBBS = () => false, isBBSPlus = () => false, isPS = () => false, + isKvac = () => false, adaptKeyForParams = (key, _params) => key; switch (Scheme) { @@ -79,10 +86,12 @@ switch (Scheme) { SignatureParams = BBSSignatureParams; PoKSignatureProtocol = BBSPoKSignatureProtocol; buildWitness = Witness.bbsSignature; - buildStatement = Statement.bbsSignature; + buildProverStatement = Statement.bbsSignatureProver; + buildVerifierStatement = Statement.bbsSignatureVerifier; buildPublicKeySetupParam = SetupParam.bbsPlusSignaturePublicKeyG2; buildSignatureParamsSetupParam = SetupParam.bbsSignatureParams; - buildStatementFromSetupParamsRef = Statement.bbsSignatureFromSetupParamRefs; + buildProverStatementFromSetupParamsRef = Statement.bbsSignatureProverFromSetupParamRefs; + buildVerifierStatementFromSetupParamsRef = Statement.bbsSignatureVerifierFromSetupParamRefs; getStatementForBlindSigRequest = getBBSStatementForBlindSigRequest; getWitnessForBlindSigRequest = getBBSWitnessForBlindSigRequest; CredentialBuilder = BBSCredentialBuilder; @@ -101,10 +110,12 @@ switch (Scheme) { SignatureParams = BBSPlusSignatureParamsG1; PoKSignatureProtocol = BBSPlusPoKSignatureProtocol; buildWitness = Witness.bbsPlusSignature; - buildStatement = Statement.bbsPlusSignature; + buildProverStatement = Statement.bbsPlusSignatureProver; + buildVerifierStatement = Statement.bbsPlusSignatureVerifier; buildPublicKeySetupParam = SetupParam.bbsPlusSignaturePublicKeyG2; buildSignatureParamsSetupParam = SetupParam.bbsPlusSignatureParamsG1; - buildStatementFromSetupParamsRef = Statement.bbsPlusSignatureFromSetupParamRefs; + buildProverStatementFromSetupParamsRef = Statement.bbsPlusSignatureProverFromSetupParamRefs; + buildVerifierStatementFromSetupParamsRef = Statement.bbsPlusSignatureVerifierFromSetupParamRefs; getStatementForBlindSigRequest = getBBSPlusStatementForBlindSigRequest; getWitnessForBlindSigRequest = getBBSPlusWitnessForBlindSigRequest; CredentialBuilder = BBSPlusCredentialBuilder; @@ -123,10 +134,12 @@ switch (Scheme) { SignatureParams = PSSignatureParams; PoKSignatureProtocol = PSPoKSignatureProtocol; buildWitness = Witness.psSignature; - buildStatement = Statement.psSignature; + buildProverStatement = Statement.psSignature; + buildVerifierStatement = Statement.psSignature; buildPublicKeySetupParam = SetupParam.psSignaturePublicKey; buildSignatureParamsSetupParam = SetupParam.psSignatureParams; - buildStatementFromSetupParamsRef = Statement.psSignatureFromSetupParamRefs; + buildProverStatementFromSetupParamsRef = Statement.psSignatureFromSetupParamRefs; + buildVerifierStatementFromSetupParamsRef = Statement.psSignatureFromSetupParamRefs; getStatementForBlindSigRequest = getPSStatementsForBlindSigRequest; getWitnessForBlindSigRequest = getPSWitnessesForBlindSigRequest; CredentialBuilder = PSCredentialBuilder; @@ -137,9 +150,33 @@ switch (Scheme) { isPS = () => true; adaptKeyForParams = (key, params) => key.adaptForLess(params.supportedMessageCount()); break; + case 'BDDT16': + PublicKey = undefined; + SecretKey = BDDT16MacSecretKey; + Signature = BDDT16Mac; + BlindSignature = BDDT16BlindMac; + KeyPair = undefined; + SignatureParams = BDDT16MacParams; + PoKSignatureProtocol = undefined; + buildWitness = Witness.bddt16Mac; + buildProverStatement = Statement.bddt16Mac; + buildVerifierStatement = Statement.bddt16Mac; + buildPublicKeySetupParam = undefined; + buildSignatureParamsSetupParam = SetupParam.bddt16MacParams; + buildProverStatementFromSetupParamsRef = Statement.bddt16MacFromSetupParamRefs; + buildVerifierStatementFromSetupParamsRef = Statement.bddt16MacFromSetupParamRefs; + getStatementForBlindSigRequest = getBDDT16StatementForBlindMacRequest; + getWitnessForBlindSigRequest = getBDDT16WitnessForBlindMacRequest; + CredentialBuilder = BDDT16CredentialBuilder; + Credential = BDDT16Credential; + SignatureLabelBytes = BDDT16_MAC_PARAMS_LABEL_BYTES; + encodeMessageForSigningIfPS = (msg) => msg; + encodeMessageForSigningIfNotPS = encodeMessageForSigning; + isKvac = () => true; + break; default: throw new Error( - `Unknown signature scheme provided in \`TEST_SIGNATURE_SCHEME\`: ${Scheme}, expected either \`BBS\`, \`BBS+\` or \`PS\`` + `Unknown signature scheme provided in \`TEST_SIGNATURE_SCHEME\`: ${Scheme}, expected either \`BBS\`, \`BBS+\`, \`PS\` or BDDT16` ); } @@ -151,10 +188,12 @@ export type BlindSignature = typeof BlindSignature; export type SignatureParams = typeof SignatureParams; export type PoKSignatureProtocol = typeof PoKSignatureProtocol; export type buildWitness = typeof buildWitness; -export type buildStatement = typeof buildStatement; +export type buildProverStatement = typeof buildProverStatement; +export type buildVerifierStatement = typeof buildVerifierStatement; export type buildPublicKeySetupParam = typeof buildPublicKeySetupParam; export type buildSignatureParamsSetupParam = typeof buildSignatureParamsSetupParam; -export type buildStatementFromSetupParamsRef = typeof buildStatementFromSetupParamsRef; +export type buildProverStatementFromSetupParamsRef = typeof buildProverStatementFromSetupParamsRef; +export type buildVerifierStatementFromSetupParamsRef = typeof buildVerifierStatementFromSetupParamsRef; export type getStatementForBlindSigRequest = typeof getStatementForBlindSigRequest; export type getWitnessForBlindSigRequest = typeof getWitnessForBlindSigRequest; export type CredentialBuilder = typeof CredentialBuilder; diff --git a/tests/threshold-sigs.spec.ts b/tests/threshold-sigs.spec.ts index 940f08df..6fc7881e 100644 --- a/tests/threshold-sigs.spec.ts +++ b/tests/threshold-sigs.spec.ts @@ -1,33 +1,34 @@ -import { generateRandomG1Element, initializeWasm } from '@docknetwork/crypto-wasm'; +import { generateRandomG1Element } from 'crypto-wasm-new'; import { - ThresholdBbsPlusSigner, + BBSPlusPublicKeyG2, + BBSPlusSecretKey, + BBSPlusSignatureParamsG1, + BBSPublicKey, + BBSSecretKey, + BBSSignatureParams, + initializeWasm +} from '../src'; +import { ParticipantG2 } from '../src/frost-dkg'; +import { + BaseOTOutput, Challenges, + Commitments, + CommitmentsForZeroSharing, GadgetVector, HashedKeys, + Message1, + Message2, Participant as BaseOTParticipant, ReceiverPublicKey, Responses, SenderPublicKey, - Commitments, - CommitmentsForZeroSharing, - BaseOTOutput, - Message1, - Message2, - ThresholdBbsSignatureShare, - ThresholdBbsPlusSignatureShare + ThresholdBbsPlusSignatureShare, + ThresholdBbsPlusSigner, + ThresholdBbsSignatureShare } from '../src/threshold-sigs'; +import { ThresholdBbsSigner } from '../src/threshold-sigs/bbs'; import { PublicKeyBase } from '../src/types'; import { checkResult, runFrostKeygen, stringToBytes } from './utils'; -import { - BBSPlusPublicKeyG2, - BBSPlusSecretKey, - BBSPlusSignatureParamsG1, - BBSPublicKey, - BBSSecretKey, - BBSSignatureParams -} from '../src'; -import { ParticipantG2 } from '../src/frost-dkg'; -import { ThresholdBbsSigner } from '../src/threshold-sigs/bbs'; describe('Threshold BBS+ and BBS', () => { const threshold = 3; diff --git a/tests/utils.ts b/tests/utils.ts index 002fc11d..6bb41844 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -11,8 +11,19 @@ import { ParsedR1CSFile, PublicKeyBase } from '../src'; -import { VerifyResult } from '@docknetwork/crypto-wasm'; +import { VerifyResult } from 'crypto-wasm-new'; import { Participant, Round1Msg, Share } from '../src/frost-dkg'; +import { + buildProverStatement, + buildVerifierStatement, + isBBSPlus, + isKvac, + isPS, + PublicKey, + SecretKey, + Signature, + SignatureParams +} from './scheme'; /** * Converts a UTF-8 Encoded string to a byte array @@ -217,4 +228,26 @@ export function runFrostKeygen(participants: Participant[], pkBase: PublicKeyBas expect(expectedTpk as Uint8Array).toEqual(participants[0].generateThresholdPublicKeyFromPublicKeys(pkWithIds).value); // @ts-ignore return [sks, pks, expectedTpk]; +} + +export function getParamsAndKeys(messageCount: number, label?: Uint8Array): [SignatureParams, SecretKey, PublicKey] { + const params = SignatureParams.generate(messageCount, label); + + const sk = SecretKey.generate(isPS() ? messageCount : void 0); + const pk = isKvac() ? undefined : isBBSPlus() ? sk.generatePublicKeyG2(params) : sk.generatePublicKey(params); + return [params, sk, pk]; +} + +export function signAndVerify(messages, params, sk, pk, encode = false): [Signature, VerifyResult] { + const sig = isPS() ? Signature.generate(messages, sk, params) : Signature.generate(messages, sk, params, encode); + const result = isKvac() ? sig.verify(messages, sk, params, encode) : isPS() ? sig.verify(messages, pk, params) : sig.verify(messages, pk, params, encode); + return [sig, result]; +} + +export function proverStmt(params: SignatureParams, revealedMsgs: Map, pk?: PublicKey, encode = false) { + return isPS() ? buildProverStatement(params, pk, revealedMsgs, encode) : buildProverStatement(params, revealedMsgs, encode) +} + +export function verifierStmt(params: SignatureParams, revealedMsgs: Map, pk?: PublicKey, encode = false) { + return isKvac() ? buildVerifierStatement(params, revealedMsgs, encode) : buildVerifierStatement(params, pk, revealedMsgs, encode); } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a7bcafd3..78af37a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -479,13 +479,6 @@ ky-universal "^0.10.1" undici "^5.2.0" -"@docknetwork/crypto-wasm@0.23.0": - version "0.23.0" - resolved "https://registry.yarnpkg.com/@docknetwork/crypto-wasm/-/crypto-wasm-0.23.0.tgz#5ae04db0f7990fb6fc9c7ad3f0a1cb7255518169" - integrity sha512-/bDSy05HkIZIZL9HDHowjCKxTDf9Cf04e1ElIY0o/q9ewbxHQ4/r8Ppv5V5bOnVkxcFG9lWQQstKXQDV86UWRw== - dependencies: - buffer "^6.0.3" - "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1516,6 +1509,20 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +"crypto-wasm-new@npm:@docknetwork/crypto-wasm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@docknetwork/crypto-wasm/-/crypto-wasm-0.24.0.tgz#ecd8c69181b19f2134f109750bdfcc454768b860" + integrity sha512-OERhW1IfGK70Zgu615IUSHO+Vif8e5jd3CmF+5L6fBujYrNoRLIPgN/GguKbAagv4+qQIUkT9rIslOlOHmjikw== + dependencies: + buffer "^6.0.3" + +"crypto-wasm-old@npm:@docknetwork/crypto-wasm@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@docknetwork/crypto-wasm/-/crypto-wasm-0.23.0.tgz#5ae04db0f7990fb6fc9c7ad3f0a1cb7255518169" + integrity sha512-/bDSy05HkIZIZL9HDHowjCKxTDf9Cf04e1ElIY0o/q9ewbxHQ4/r8Ppv5V5bOnVkxcFG9lWQQstKXQDV86UWRw== + dependencies: + buffer "^6.0.3" + data-uri-to-buffer@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" @@ -1773,6 +1780,18 @@ eslint-plugin-import@^2.27.5: semver "^6.3.0" tsconfig-paths "^3.14.1" +eslint-plugin-unused-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz#db015b569d3774e17a482388c95c17bd303bc602" + integrity sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3822,10 +3841,10 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== +typescript@5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== unbox-primitive@^1.0.2: version "1.0.2"