From ec43b6a5bf4f8064aaad7fc303a10c7f585a110e Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 1 Sep 2022 22:26:22 +0200 Subject: wallet-core: fix issue with crock encoding of age restrictions --- packages/taler-util/src/talerCrypto.ts | 46 ++++++++++++++++++++++++---------- packages/taler-util/src/talerTypes.ts | 28 ++++++++++----------- 2 files changed, 47 insertions(+), 27 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/talerCrypto.ts b/packages/taler-util/src/talerCrypto.ts index d7734707a..8d2e41793 100644 --- a/packages/taler-util/src/talerCrypto.ts +++ b/packages/taler-util/src/talerCrypto.ts @@ -857,6 +857,13 @@ export type Edx25519PublicKey = FlavorP; export type Edx25519PrivateKey = FlavorP; export type Edx25519Signature = FlavorP; +export type Edx25519PublicKeyEnc = FlavorP; +export type Edx25519PrivateKeyEnc = FlavorP< + string, + "Edx25519PrivateKeyEnc", + 64 +>; + /** * Convert a big integer to a fixed-size, little-endian array. */ @@ -958,7 +965,7 @@ export interface AgeCommitment { /** * Public keys, one for each age group specified in the age mask. */ - publicKeys: Edx25519PublicKey[]; + publicKeys: Edx25519PublicKeyEnc[]; } export interface AgeProof { @@ -966,7 +973,7 @@ export interface AgeProof { * Private keys. Typically smaller than the number of public keys, * because we drop private keys from age groups that are restricted. */ - privateKeys: Edx25519PrivateKey[]; + privateKeys: Edx25519PrivateKeyEnc[]; } export interface AgeCommitmentProof { @@ -984,7 +991,7 @@ export namespace AgeRestriction { export function hashCommitment(ac: AgeCommitment): HashCodeString { const hc = new nacl.HashState(); for (const pub of ac.publicKeys) { - hc.update(pub); + hc.update(decodeCrock(pub)); } return encodeCrock(hc.finish().subarray(0, 32)); } @@ -1042,10 +1049,10 @@ export namespace AgeRestriction { return { commitment: { mask: ageMask, - publicKeys: pubs, + publicKeys: pubs.map((x) => encodeCrock(x)), }, proof: { - privateKeys: privs, + privateKeys: privs.map((x) => encodeCrock(x)), }, }; } @@ -1062,8 +1069,11 @@ export namespace AgeRestriction { 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); + const k1 = decodeCrock(c1.publicKeys[i]); + const k2 = await Edx25519.publicKeyDerive( + decodeCrock(c2.publicKeys[i]), + salt, + ); if (k1 != k2) { return false; } @@ -1079,20 +1089,22 @@ export namespace AgeRestriction { const newPubs: Edx25519PublicKey[] = []; for (const oldPub of commitmentProof.commitment.publicKeys) { - newPubs.push(await Edx25519.publicKeyDerive(oldPub, salt)); + newPubs.push(await Edx25519.publicKeyDerive(decodeCrock(oldPub), salt)); } for (const oldPriv of commitmentProof.proof.privateKeys) { - newPrivs.push(await Edx25519.privateKeyDerive(oldPriv, salt)); + newPrivs.push( + await Edx25519.privateKeyDerive(decodeCrock(oldPriv), salt), + ); } return { commitment: { mask: commitmentProof.commitment.mask, - publicKeys: newPubs, + publicKeys: newPubs.map((x) => encodeCrock(x)), }, proof: { - privateKeys: newPrivs, + privateKeys: newPrivs.map((x) => encodeCrock(x)), }, }; } @@ -1112,7 +1124,11 @@ export namespace AgeRestriction { } const priv = commitmentProof.proof.privateKeys[group - 1]; const pub = commitmentProof.commitment.publicKeys[group - 1]; - const sig = nacl.crypto_edx25519_sign_detached(d, priv, pub); + const sig = nacl.crypto_edx25519_sign_detached( + d, + decodeCrock(priv), + decodeCrock(pub), + ); return sig; } @@ -1131,7 +1147,11 @@ export namespace AgeRestriction { return true; } const pub = commitment.publicKeys[group - 1]; - return nacl.crypto_edx25519_sign_detached_verify(d, decodeCrock(sig), pub); + return nacl.crypto_edx25519_sign_detached_verify( + d, + decodeCrock(sig), + decodeCrock(pub), + ); } } diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts index e36236085..014631ad7 100644 --- a/packages/taler-util/src/talerTypes.ts +++ b/packages/taler-util/src/talerTypes.ts @@ -25,29 +25,29 @@ * Imports. */ +import { codecForAmountString } from "./amounts.js"; import { buildCodecForObject, - codecForString, - codecForList, - codecOptional, + buildCodecForUnion, + Codec, codecForAny, - codecForNumber, codecForBoolean, - codecForMap, - Codec, codecForConstNumber, - buildCodecForUnion, codecForConstString, + codecForList, + codecForMap, + codecForNumber, + codecForString, + codecOptional, } from "./codec.js"; +import { strcmp } from "./helpers.js"; +import { AgeCommitmentProof, Edx25519PublicKeyEnc } from "./talerCrypto.js"; import { - codecForTimestamp, codecForDuration, - TalerProtocolTimestamp, + codecForTimestamp, TalerProtocolDuration, + TalerProtocolTimestamp, } from "./time.js"; -import { codecForAmountString } from "./amounts.js"; -import { strcmp } from "./helpers.js"; -import { AgeCommitmentProof, Edx25519PublicKey } from "./talerCrypto.js"; /** * Denomination as found in the /keys response from the exchange. @@ -287,7 +287,7 @@ export interface CoinDepositPermission { minimum_age_sig?: EddsaSignatureString; - age_commitment?: Edx25519PublicKey[]; + age_commitment?: Edx25519PublicKeyEnc[]; } /** @@ -1755,7 +1755,7 @@ export interface ExchangeRefreshRevealRequest { * the client MUST provide the original age commitment, i.e. the vector * of public keys. */ - old_age_commitment?: Edx25519PublicKey[]; + old_age_commitment?: Edx25519PublicKeyEnc[]; } export interface DepositSuccess { -- cgit v1.2.3