Skip to content

Commit

Permalink
Add proof of validity of MAC
Browse files Browse the repository at this point in the history
Signed-off-by: lovesh <lovesh.bond@gmail.com>
  • Loading branch information
lovesh committed Mar 7, 2024
1 parent 5c25167 commit 25d1ede
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 19 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@docknetwork/crypto-wasm-ts",
"version": "0.52.0",
"version": "0.53.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 Expand Up @@ -31,7 +31,7 @@
"@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-new": "npm:@docknetwork/crypto-wasm@0.25.0",
"crypto-wasm-old": "npm:@docknetwork/crypto-wasm@0.23.0",
"flat": "^5.0.2",
"json-pointer": "^0.6.2",
Expand Down
19 changes: 18 additions & 1 deletion src/anonymous-credentials/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ 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';
import {
BDDT16Mac,
BDDT16MacParams,
BDDT16MacProofOfValidity,
BDDT16MacPublicKeyG1,
BDDT16MacSecretKey
} from '../bddt16-mac';

export abstract class Credential<PublicKey, Signature, SignatureParams> extends CredentialCommon<Signature> {
abstract verify(publicKey: PublicKey, signatureParams?: SignatureParams): VerifyResult;
Expand Down Expand Up @@ -233,6 +239,17 @@ export class BDDT16Credential extends Credential<undefined, BDDT16Mac, BDDT16Mac
);
}

verifyUsingValidityProof(proof: BDDT16MacProofOfValidity, publicKey: BDDT16MacPublicKeyG1, signatureParams: BDDT16MacParams) : VerifyResult {
const cred = this.serializeForSigning();
return proof.verifyMessageObject(
this.signature,
cred,
publicKey,
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.
Expand Down
1 change: 1 addition & 0 deletions src/anonymous-credentials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './blinded-credential-request-builder';
export * from './blinded-credential-request';
export * from './blinded-credential-builder';
export * from './blinded-credential';
export * from './delegated-proof';
33 changes: 32 additions & 1 deletion src/bddt16-mac/keys.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { BytearrayWrapper } from '../bytearray-wrapper';
import { bddt16MacGenerateSecretKey } from 'crypto-wasm-new';
import {
bddt16MacGenerateSecretKey,
bddt16MacGeneratePublicKeyG1,
bddt16MacIsPublicKeyG1Valid,
} from 'crypto-wasm-new';
import { BDDT16MacParams } from './params';

/**
* BDDT16 MAC secret key.
Expand All @@ -8,4 +13,30 @@ export class BDDT16MacSecretKey extends BytearrayWrapper {
static generate(seed?: Uint8Array) {
return new this(bddt16MacGenerateSecretKey(seed));
}

generatePublicKeyG1(params: BDDT16MacParams): BDDT16MacPublicKeyG1 {
return new BDDT16MacPublicKeyG1(bddt16MacGeneratePublicKeyG1(this.value, params.value));
}
}

export class BDDT16MacPublicKeyG1 extends BytearrayWrapper {
isValid(): boolean {
return bddt16MacIsPublicKeyG1Valid(this.value)
}
}

export class BDDT16KeypairG1 {
sk: BDDT16MacSecretKey;
pk: BDDT16MacPublicKeyG1;

constructor(sk: BDDT16MacSecretKey, pk: BDDT16MacPublicKeyG1) {
this.sk = sk;
this.pk = pk;
}

static generate(params: BDDT16MacParams, seed?: Uint8Array): BDDT16KeypairG1 {
const sk = BDDT16MacSecretKey.generate(seed);
const pk = sk.generatePublicKeyG1(params);
return new BDDT16KeypairG1(sk, pk)
}
}
45 changes: 44 additions & 1 deletion src/bddt16-mac/mac.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { BytearrayWrapper } from '../bytearray-wrapper';
import { Encoder, MessageEncoder } from '../encoder';
import {
bddt16BlindMacGenerate,
bddt16MacGenerate,
bddt16MacVerify, bddt16UnblindMac,
bddt16MacProofOfValidity, bddt16MacVerifyProofOfValidity,
VerifyResult
} from 'crypto-wasm-new';
import { MessageStructure, SignedMessages } from '../types';
import { BDDT16MacParams } from './params';
import { BDDT16MacSecretKey } from './keys';
import { BDDT16MacSecretKey, BDDT16MacPublicKeyG1 } from './keys';
import { encodeRevealedMessageObject, getBlindedIndicesAndRevealedMessages } from '../sign-verify-js-objs';

/**
Expand Down Expand Up @@ -232,3 +234,44 @@ export interface BDDT16BlindMacRequest {
*/
revealedMessages?: Map<number, Uint8Array>;
}

/**
* This MAC cannot be verified without the secret key but the signer can give a proof to the user that the MAC is
* correct, i.e. it was created with the public key of the secret key.
*/
export class BDDT16MacProofOfValidity extends BytearrayWrapper {
constructor(mac: BDDT16Mac, secretKey: BDDT16MacSecretKey, publicKey: BDDT16MacPublicKeyG1, params: BDDT16MacParams) {
const proof = bddt16MacProofOfValidity(mac.value, secretKey.value, publicKey.value, params.value);
super(proof);
}

verify(mac: BDDT16Mac,
messages: Uint8Array[],
publicKey: BDDT16MacPublicKeyG1,
params: BDDT16MacParams,
encodeMessages: boolean
): VerifyResult {
if (messages.length !== params.supportedMessageCount()) {
throw new Error(
`Number of messages ${
messages.length
} is different from ${params.supportedMessageCount()} supported by the MAC params`
);
}
return bddt16MacVerifyProofOfValidity(this.value, mac.value, messages, publicKey.value, params.value, encodeMessages);
}

verifyMessageObject(
mac: BDDT16Mac,
messages: object,
publicKey: BDDT16MacPublicKeyG1,
labelOrParams: Uint8Array | BDDT16MacParams,
encoder: Encoder
): VerifyResult {
const [_, encodedValues] = encoder.encodeMessageObject(messages);
const msgCount = encodedValues.length;

const params = BDDT16MacParams.getMacParamsOfRequiredSize(msgCount, labelOrParams);
return this.verify(mac, encodedValues, publicKey, params, false)
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { initializeWasm, isWasmInitialized, requireWasmInitialized } from './ini
export * from './util';
export * from './bbs-plus';
export * from './bbs';
export * from './bddt16-mac';
export * from './accumulator';
export * from './composite-proof';
export * from './saver';
Expand All @@ -17,3 +18,4 @@ export * from './types';
export { getR1CS } from './r1cs/file';
export { processParsedR1CSFile } from './r1cs/file';
export { ParsedR1CSFile } from './r1cs/file';
export * from './delegated-proofs';
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import {
PSKeypair,
PSPublicKey,
PSSecretKey,
PSSignatureParams, SignatureType, BDDT16Credential, BDDT16_MAC_PARAMS_LABEL_BYTES, BDDT16CredentialBuilder
PSSignatureParams,
SignatureType,
BDDT16Credential,
BDDT16_MAC_PARAMS_LABEL_BYTES,
BDDT16CredentialBuilder,
BDDT16MacProofOfValidity, BDDT16MacPublicKeyG1, BDDT16KeypairG1
} from '../../src';
import { checkResult, stringToBytes } from '../utils';
import { checkPresentationJson, getExampleSchema } from './utils';
Expand All @@ -39,7 +44,7 @@ describe.each([true, false])(
let skBbs: BBSSecretKey, pkBbs: BBSPublicKey;
let skBbsPlus: BBSPlusSecretKey, pkBbsPlus: BBSPlusPublicKeyG2;
let skPs: PSSecretKey, pkPs: PSPublicKey;
let skBddt16: BDDT16MacSecretKey;
let skBddt16: BDDT16MacSecretKey, pkBddt16: BDDT16MacPublicKeyG1;

let credentialBbs: BBSCredential;
let credentialBbsPlus: BBSPlusCredential;
Expand All @@ -57,10 +62,13 @@ describe.each([true, false])(
const paramsBbs = BBSSignatureParams.generate(1, BBS_SIGNATURE_PARAMS_LABEL_BYTES);
const paramsBbsPlus = BBSPlusSignatureParamsG1.generate(1, BBS_PLUS_SIGNATURE_PARAMS_LABEL_BYTES);
const paramsPs = PSSignatureParams.generate(100, PS_SIGNATURE_PARAMS_LABEL_BYTES);
const paramsBddt16 = BDDT16MacParams.generate(1, BDDT16_MAC_PARAMS_LABEL_BYTES);
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'));
const keypairBddt16 = BDDT16KeypairG1.generate(paramsBddt16, stringToBytes('seed4'));
skBddt16 = keypairBddt16.sk;
pkBddt16 = keypairBddt16.pk;
skBbs = keypairBbs.sk;
pkBbs = keypairBbs.pk;
skBbsPlus = keypairBbsPlus.sk;
Expand Down Expand Up @@ -109,6 +117,10 @@ describe.each([true, false])(
checkResult(credential.verify(pk));
} else {
checkResult(credential.verifyUsingSecretKey(sk));

// Check using validity proof as well
const proof = new BDDT16MacProofOfValidity(credential.signature, skBddt16, pkBddt16, paramsBddt16);
checkResult(credential.verifyUsingValidityProof(proof, pkBddt16, paramsBddt16));
}
if (sk instanceof BBSSecretKey) {
credentialBbs = credential;
Expand All @@ -123,6 +135,7 @@ describe.each([true, false])(
credentialBddt16 = credential;
}
}

});

it('works', () => {
Expand Down
8 changes: 7 additions & 1 deletion tests/composite-proofs/msg-js-obj/scheme.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
BDDT16MacProofOfValidity,
CompositeProof,
createWitnessEqualityMetaStatement,
Encoder,
Expand All @@ -17,7 +18,7 @@ import {
Witnesses
} from '../../../src';
import { PederCommKey } from '../../../src/ped-com';
import { buildWitness, Scheme } from '../../scheme';
import { buildWitness, isBDDT16, isKvac, Scheme } from '../../scheme';
import { checkResult, getParamsAndKeys, stringToBytes } from '../../utils';
import {
attributes1,
Expand Down Expand Up @@ -63,6 +64,11 @@ describe(`Signing and proof of knowledge of ${Scheme} signatures`, () => {
expect(isValidMsgStructure(attributes, attributesStruct)).toEqual(true);

const signed = signAndVerify(attributes, encoder, label, sk, pk);
if (isBDDT16()) {
const pk = sk.generatePublicKeyG1(params);
const proof = new BDDT16MacProofOfValidity(signed.signature, sk, pk, params);
checkResult(proof.verifyMessageObject(signed.signature, attributes, pk, label, encoder));
}

// For debugging
console.log(signedToHex(signed));
Expand Down
30 changes: 27 additions & 3 deletions tests/scheme.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { encodeMessageForSigning, generateRandomG1Element } from 'crypto-wasm-new';
import { bytesToChallenge, initializeWasm, PSBlindSignature, randomFieldElement } from '../src';
import {
BDDT16MacProofOfValidity,
bytesToChallenge,
initializeWasm,
PSBlindSignature,
randomFieldElement
} from '../src';
import { checkResult, getParamsAndKeys, getRevealedUnrevealed, signAndVerify, stringToBytes } from './utils';
import {
BlindSignature,
encodeMessageForSigningIfPS,
isBBS,
isBBSPlus,
isKvac,
isPS,
isPS, KeyPair,
PoKSignatureProtocol,
PublicKey,
Scheme,
Expand Down Expand Up @@ -90,7 +96,6 @@ describe(`${Scheme} signature`, () => {
let blindings = new Map();

const label = stringToBytes('My sig params in g1');
// const params = SignatureParams.generate(messageCount, label);
const [params, sk, pk] = getParamsAndKeys(messageCount, label);

expect(params.isValid()).toEqual(true);
Expand Down Expand Up @@ -388,4 +393,23 @@ describe(`${Scheme} signature`, () => {
).verified
).toBe(true);
});

if (isKvac()) {
it('should have proof of validity of mac', () => {
const messageCount = 10;
const messages = getMessages(messageCount).map((m) => Signature.encodeMessageForSigning(m));
const label = stringToBytes('My sig params in g1');
const params = SignatureParams.generate(messageCount, label);
const keypair = KeyPair.generate(params);
const sk = keypair.sk;
const pk = keypair.pk;
expect(pk.isValid()).toEqual(true);

const [mac, result] = signAndVerify(messages, params, sk, pk, false);
checkResult(result);

const proof = new BDDT16MacProofOfValidity(mac, sk, pk, params);
checkResult(proof.verify(mac, messages, pk, params, false));
})
}
});
8 changes: 5 additions & 3 deletions tests/scheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
PS_SIGNATURE_PARAMS_LABEL_BYTES,
BDDT16_MAC_PARAMS_LABEL_BYTES,
getBDDT16StatementForBlindMacRequest,
getBDDT16WitnessForBlindMacRequest, BDDT16CredentialBuilder, BDDT16Credential
getBDDT16WitnessForBlindMacRequest, BDDT16CredentialBuilder, BDDT16Credential, BDDT16KeypairG1, BDDT16MacPublicKeyG1
} from '../src';
import { BDDT16BlindMac, BDDT16Mac, BDDT16MacParams, BDDT16MacSecretKey } from '../src/bddt16-mac';

Expand Down Expand Up @@ -73,6 +73,7 @@ export let Scheme: string = process.env.TEST_SIGNATURE_SCHEME || 'BBS',
isBBS = () => false,
isBBSPlus = () => false,
isPS = () => false,
isBDDT16 = () => false,
isKvac = () => false,
adaptKeyForParams = (key, _params) => key;

Expand Down Expand Up @@ -151,11 +152,11 @@ switch (Scheme) {
adaptKeyForParams = (key, params) => key.adaptForLess(params.supportedMessageCount());
break;
case 'BDDT16':
PublicKey = undefined;
PublicKey = BDDT16MacPublicKeyG1;
SecretKey = BDDT16MacSecretKey;
Signature = BDDT16Mac;
BlindSignature = BDDT16BlindMac;
KeyPair = undefined;
KeyPair = BDDT16KeypairG1;
SignatureParams = BDDT16MacParams;
PoKSignatureProtocol = undefined;
buildWitness = Witness.bddt16Mac;
Expand All @@ -172,6 +173,7 @@ switch (Scheme) {
SignatureLabelBytes = BDDT16_MAC_PARAMS_LABEL_BYTES;
encodeMessageForSigningIfPS = (msg) => msg;
encodeMessageForSigningIfNotPS = encodeMessageForSigning;
isBDDT16 = () => true,
isKvac = () => true;
break;
default:
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1509,10 +1509,10 @@ 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==
"crypto-wasm-new@npm:@docknetwork/crypto-wasm@0.25.0":
version "0.25.0"
resolved "https://registry.yarnpkg.com/@docknetwork/crypto-wasm/-/crypto-wasm-0.25.0.tgz#679e38d7656f11c9417b602fc6fccf239c9d116e"
integrity sha512-iKoM390iG2ohwbmaMNlYDh7hYtwoGKjj8zikU+Oh5DkFaPpPofhq1yzoPiaU2DRZiYZox/38MRattdXcaCi0Kw==
dependencies:
buffer "^6.0.3"

Expand Down

0 comments on commit 25d1ede

Please sign in to comment.