Skip to content

Commit

Permalink
Add more checks and some docs
Browse files Browse the repository at this point in the history
Signed-off-by: lovesh <[email protected]>
  • Loading branch information
lovesh committed Mar 12, 2024
1 parent 268136f commit 0b407ed
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 91 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@docknetwork/crypto-wasm-ts",
"version": "0.54.0",
"version": "0.55.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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export abstract class BlindedCredentialRequestBuilder<SigParams> extends Version
throw new Error('This method should be implemented by extending class');
}

addCredentialToPresentation(credential: Credential, pk: PublicKey): number {
addCredentialToPresentation(credential: Credential, pk?: PublicKey): number {
return this.presentationBuilder.addCredential(credential, pk);
}

Expand Down
2 changes: 1 addition & 1 deletion src/anonymous-credentials/blinded-credential-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export abstract class BlindedCredentialRequest extends Versioned {
}

verify(
publicKeys: Map<number, CredentialVerificationParam | undefined> | CredentialVerificationParam[],
publicKeys: Map<number, CredentialVerificationParam> | CredentialVerificationParam[],
accumulatorPublicKeys?: Map<number, AccumulatorPublicKey>,
predicateParams?: Map<string, PredicateParamType>,
circomOutputs?: Map<number, Uint8Array[][]>,
Expand Down
69 changes: 68 additions & 1 deletion src/anonymous-credentials/delegated-proof.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import b58 from 'bs58';
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 {
ID_STR,
MEM_CHECK_KV_STR,
REV_CHECK_STR,
RevocationStatusProtocol,
SignatureType,
TYPE_STR
} from './types-and-consts';
import { Versioned } from './versioned';

export interface IDelegatedCredentialProof {
Expand All @@ -17,20 +25,27 @@ export interface IDelegatedCredentialStatusProof {
proof: VBAccumMembershipDelegatedProof;
}

/**
* Delegated proof for a KVAC. It can contain proof for either the credential or the status or both
*/
export class DelegatedProof extends Versioned {
static VERSION = '0.1.0';

readonly credential?: IDelegatedCredentialProof;
readonly status?: IDelegatedCredentialStatusProof;

constructor(credential?: IDelegatedCredentialProof, status?: IDelegatedCredentialStatusProof) {
if (credential === undefined && status === undefined) {
throw new Error(`At least one of credential or status must be defined`)
}
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');
Expand All @@ -40,15 +55,67 @@ export class DelegatedProof extends Versioned {
return rc;
}
}

if (this.status !== undefined) {
if (accumSecretKey === undefined) {
throw new Error('Secret key not provided for accumulator');
}
if (this.status[ID_STR] === undefined) {
throw new Error(`${ID_STR} field is required in the delegated proof`);
}
if (this.status[TYPE_STR] !== RevocationStatusProtocol.Vb22 || this.status[REV_CHECK_STR] !== MEM_CHECK_KV_STR) {
throw new Error(`Unexpected values for ${TYPE_STR} and ${REV_CHECK_STR}: ${this.status[TYPE_STR]}, ${this.status[REV_CHECK_STR]}`);
}
const rc = this.status.proof.verify(accumSecretKey);
if (!rc.verified) {
return rc;
}
}

return r;
}

toJSON(): object {
let d = {};
if (this.credential !== undefined) {
d['credential'] = {
sigType: this.credential.sigType,
proof: b58.encode(this.credential.proof.bytes)
};
}
if (this.status !== undefined) {
d['status'] = {
[ID_STR]: this.status[ID_STR],
[TYPE_STR]: this.status[TYPE_STR],
[REV_CHECK_STR]: this.status[REV_CHECK_STR],
proof: b58.encode(this.status.proof.bytes)
};
}
return d;
}

static fromJSON(j: object): DelegatedProof {
let credential, status;
if (j['credential'] !== undefined) {
if (j['credential'].sigType === undefined || j['credential'].proof === undefined) {
throw new Error(`Expected fields sigType and proof but found the credential object to be ${j['credential']}`);
}
credential = {
sigType: j['credential'].sigType,
proof: new BDDT16DelegatedProof(b58.decode(j['credential'].proof))
};
}
if (j['status'] !== undefined) {
if (j['status'][ID_STR] === undefined || j['status'][TYPE_STR] === undefined || j['status'][REV_CHECK_STR] === undefined || j['status'].proof === undefined) {
throw new Error(`Expected fields ${ID_STR}, ${TYPE_STR}, ${REV_CHECK_STR} and proof but found the status object to be ${j['status']}`);
}
status = {
[ID_STR]: j['status'][ID_STR],
[TYPE_STR]: j['status'][TYPE_STR],
[REV_CHECK_STR]: j['status'][REV_CHECK_STR],
proof: new VBAccumMembershipDelegatedProof(b58.decode(j['status'].proof))
};
}
return new DelegatedProof(credential, status)
}
}
2 changes: 1 addition & 1 deletion src/anonymous-credentials/presentation-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class PresentationBuilder extends Versioned {
/**
* Add a credential to this presentation. This will result in a proof of possession of this credential being created
* @param credential
* @param pk
* @param pk - Only certain kinds of credentials need a public key for creating presentation
*/
addCredential(credential: Credential, pk?: PublicKey): number {
// TODO: Accept reference to public keys in case of same key for many credentials
Expand Down
13 changes: 9 additions & 4 deletions src/anonymous-credentials/presentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,11 @@ export class Presentation extends Versioned {

/**
*
* @param credentialVerifParams - Array of keys in the order of credentials in the presentation.
* @param accumulatorPublicKeys - Mapping credential index -> accumulator public key
* @param credentialVerifParams - Map of verification parameters for credentials in the presentation. The key of the map
* is the credential index. Can also take array of keys in the order of credentials in the presentation for supporting old API but this will
* be removed in future. The verification param could be a public key or secret key. Certain kinds of credentials don't require
* either for (partial) verification but will require for full verification
* @param accumulatorPublicKeys - Mapping credential index -> accumulator verification parameters.
* @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
* is the credential index
Expand All @@ -156,7 +159,7 @@ export class Presentation extends Versioned {
*/
verify(
// TODO: Accept reference to public keys in case of same key for many credentials
credentialVerifParams: Map<number, CredentialVerificationParam | undefined> | CredentialVerificationParam[],
credentialVerifParams: Map<number, CredentialVerificationParam> | CredentialVerificationParam[],
accumulatorPublicKeys?: Map<number, AccumulatorVerificationParam>,
predicateParams?: Map<string, PredicateParamType>,
circomOutputs?: Map<number, Uint8Array[][]>,
Expand All @@ -168,6 +171,7 @@ export class Presentation extends Versioned {
// 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.

// Dealing with old API - convert array to map
let credVerifParams = new Map<number, CredentialVerificationParam | undefined>();
if (credentialVerifParams instanceof Map) {
credVerifParams = credentialVerifParams;
Expand All @@ -176,6 +180,7 @@ export class Presentation extends Versioned {
credVerifParams.set(i, v);
});
}

const statements = new Statements();
const metaStatements = new MetaStatements();

Expand Down Expand Up @@ -609,7 +614,7 @@ export class Presentation extends Versioned {
}

/**
* Get delegated proof for
* Get delegated proofs for credentials and there statuses where applicable.
* @returns - The key in the returned map is the credential index
*/
getDelegatedProofs(): Map<number, DelegatedProof> {
Expand Down
8 changes: 8 additions & 0 deletions src/bddt16-mac/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@ export class BDDT16KeypairG1 {
const pk = sk.generatePublicKeyG1(params);
return new BDDT16KeypairG1(sk, pk);
}

get secretKey(): BDDT16MacSecretKey {
return this.sk;
}

get publicKey(): BDDT16MacPublicKeyG1 {
return this.pk;
}
}
6 changes: 3 additions & 3 deletions tests/anonymous-credentials/blind-issuance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS
secret: 'my-secret-that-wont-tell-anyone'
};
const reqBuilder = newReqBuilder(schema2, blindedSubject);
expect(reqBuilder.addCredentialToPresentation(credential1, pk1)).toEqual(0);
expect(reqBuilder.addCredentialToPresentation(credential1, isPS() ? pk1 : undefined)).toEqual(0);
reqBuilder.markCredentialAttributesRevealed(
0,
new Set<string>([
Expand Down Expand Up @@ -499,8 +499,8 @@ skipIfPS.each([true, false])(`${Scheme} Blind issuance of credentials with withS
];

const reqBuilder = newReqBuilder(schema3, blindedSubject);
expect(reqBuilder.addCredentialToPresentation(credential1, pk1)).toEqual(0);
expect(reqBuilder.addCredentialToPresentation(credential2, pk2)).toEqual(1);
expect(reqBuilder.addCredentialToPresentation(credential1, isPS() ? pk1 : undefined)).toEqual(0);
expect(reqBuilder.addCredentialToPresentation(credential2, isPS() ? pk2 : undefined)).toEqual(1);

reqBuilder.markCredentialAttributesRevealed(
0,
Expand Down
Loading

0 comments on commit 0b407ed

Please sign in to comment.