aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-05-25 13:52:39 +0200
committerFlorian Dold <florian@dold.me>2022-05-25 13:52:39 +0200
commit43d265dde5f76d64e210a6c37c63c89d287adb32 (patch)
treec2c841274db3d0dd6c30a5c79effb600ad401a9e
parent07e1818679b1ec33d506abd50f5659048997a847 (diff)
wallet-core: age restriction benchmarking
-rw-r--r--packages/taler-util/src/talerCrypto.ts47
-rw-r--r--packages/taler-wallet-cli/src/index.ts73
2 files changed, 115 insertions, 5 deletions
diff --git a/packages/taler-util/src/talerCrypto.ts b/packages/taler-util/src/talerCrypto.ts
index e27e329a9..ebbfccda5 100644
--- a/packages/taler-util/src/talerCrypto.ts
+++ b/packages/taler-util/src/talerCrypto.ts
@@ -679,7 +679,8 @@ export function hashDenomPub(pub: DenominationPubKey): Uint8Array {
return nacl.hash(uint8ArrayBuf);
} else {
throw Error(
- `unsupported cipher (${(pub as DenominationPubKey).cipher
+ `unsupported cipher (${
+ (pub as DenominationPubKey).cipher
}), unable to hash`,
);
}
@@ -783,7 +784,7 @@ export enum TalerSignaturePurpose {
export class SignaturePurposeBuilder {
private chunks: Uint8Array[] = [];
- constructor(private purposeNum: number) { }
+ constructor(private purposeNum: number) {}
put(bytes: Uint8Array): SignaturePurposeBuilder {
this.chunks.push(Uint8Array.from(bytes));
@@ -1031,6 +1032,27 @@ export namespace AgeRestriction {
};
}
+ /**
+ * Check that c1 = c2*salt
+ */
+ export async function commitCompare(
+ c1: AgeCommitment,
+ c2: AgeCommitment,
+ salt: OpaqueData,
+ ): Promise<boolean> {
+ if (c1.publicKeys.length != c2.publicKeys.length) {
+ return false;
+ }
+ for (let i = 0; i < c1.publicKeys.length; i++) {
+ const k1 = c1.publicKeys[i];
+ const k2 = await Edx25519.publicKeyDerive(c2.publicKeys[i], salt);
+ if (k1 != k2) {
+ return false;
+ }
+ }
+ return true;
+ }
+
export async function commitmentDerive(
commitmentProof: AgeCommitmentProof,
salt: OpaqueData,
@@ -1081,9 +1103,24 @@ export namespace AgeRestriction {
}
export function commitmentVerify(
- commitmentProof: AgeCommitmentProof,
+ commitment: AgeCommitment,
+ sig: string,
age: number,
- ): Edx25519Signature {
- throw Error("not implemented");
+ ): boolean {
+ const d = buildSigPS(TalerSignaturePurpose.WALLET_AGE_ATTESTATION)
+ .put(bufferForUint32(commitment.mask))
+ .put(bufferForUint32(age))
+ .build();
+ const group = getAgeGroupIndex(commitment.mask, age);
+ if (group === 0) {
+ // No attestation required.
+ return true;
+ }
+ const pub = commitment.publicKeys[group - 1];
+ return nacl.crypto_edx25519_sign_detached_verify(
+ d,
+ decodeCrock(sig),
+ decodeCrock(pub),
+ );
}
}
diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts
index 43bed3cc1..339533dfc 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -46,6 +46,9 @@ import {
LogLevel,
setGlobalLogLevelFromString,
parsePaytoUri,
+ AgeRestriction,
+ getRandomBytes,
+ encodeCrock,
} from "@gnu-taler/taler-util";
import {
NodeHttpLib,
@@ -59,6 +62,7 @@ import {
CryptoDispatcher,
SynchronousCryptoWorkerFactory,
nativeCrypto,
+ performanceNow,
} from "@gnu-taler/taler-wallet-core";
import { lintExchangeDeployment } from "./lint.js";
import { runBench1 } from "./bench1.js";
@@ -1077,6 +1081,75 @@ const testCli = walletCli.subcommand("testingArgs", "testing", {
help: "Subcommands for testing.",
});
+testCli
+ .subcommand("withdrawTestkudos", "withdraw-testkudos")
+ .action(async (args) => {
+ await withWallet(args, async (wallet) => {
+ wallet.client.call(WalletApiOperation.WithdrawTestkudos, {});
+ });
+ });
+
+testCli
+ .subcommand("benchmarkAgeRestrictions", "benchmark-age-restrictions")
+ .action(async (args) => {
+ const numReps = 100;
+ let tCommit: bigint = BigInt(0);
+ let tAttest: bigint = BigInt(0);
+ let tVerify: bigint = BigInt(0);
+ let tDerive: bigint = BigInt(0);
+ let tCompare: bigint = BigInt(0);
+ let start: bigint;
+
+ console.log("starting benchmark");
+
+ for (let i = 0; i < numReps; i++) {
+ console.log(`doing iteration ${i}`);
+ start = process.hrtime.bigint();
+ const commitProof = await AgeRestriction.restrictionCommit(
+ 0b1000001010101010101001,
+ 21,
+ );
+ tCommit = tCommit + process.hrtime.bigint() - start;
+
+ start = process.hrtime.bigint();
+ const attest = AgeRestriction.commitmentAttest(commitProof, 18);
+ tAttest = tAttest + process.hrtime.bigint() - start;
+
+ start = process.hrtime.bigint();
+ const attestRes = AgeRestriction.commitmentVerify(
+ commitProof.commitment,
+ attest,
+ 18,
+ );
+ tVerify = tVerify + process.hrtime.bigint() - start;
+ if (!attestRes) {
+ throw Error();
+ }
+
+ const salt = encodeCrock(getRandomBytes(32));
+ start = process.hrtime.bigint();
+ const deriv = await AgeRestriction.commitmentDerive(commitProof, salt);
+ tDerive = tDerive + process.hrtime.bigint() - start;
+
+ start = process.hrtime.bigint();
+ const res2 = await AgeRestriction.commitCompare(
+ deriv.commitment,
+ commitProof.commitment,
+ salt,
+ );
+ tCompare = tCompare + process.hrtime.bigint() - start;
+ if (!res2) {
+ throw Error();
+ }
+ }
+
+ console.log(`edx25519-commit (ns): ${tCommit / BigInt(numReps)}`);
+ console.log(`edx25519-attest (ns): ${tAttest / BigInt(numReps)}`);
+ console.log(`edx25519-verify (ns): ${tVerify / BigInt(numReps)}`);
+ console.log(`edx25519-derive (ns): ${tDerive / BigInt(numReps)}`);
+ console.log(`edx25519-compare (ns): ${tCompare / BigInt(numReps)}`);
+ });
+
testCli.subcommand("logtest", "logtest").action(async (args) => {
logger.trace("This is a trace message.");
logger.info("This is an info message.");