From c12a366d4937a5ede3dfe8cef3111e12fc39f23a Mon Sep 17 00:00:00 2001 From: Özgür Kesim Date: Thu, 3 Aug 2023 21:44:53 +0200 Subject: adjustment of age-commitment and -proof generation age-withdraw requires that the public keys in the age groups that are too large for the commitment are derived from a published public key. --- packages/taler-util/src/taler-crypto.ts | 30 +++++++++++++++++----- .../src/crypto/cryptoImplementation.ts | 3 ++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/taler-util/src/taler-crypto.ts b/packages/taler-util/src/taler-crypto.ts index 408b7e7c2..d52edc1e5 100644 --- a/packages/taler-util/src/taler-crypto.ts +++ b/packages/taler-util/src/taler-crypto.ts @@ -1280,6 +1280,9 @@ export namespace AgeRestriction { }; } + const PublishedAgeRestrictionBaseKey: Edx25519PublicKey = decodeCrock( + "CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG"); + export async function restrictionCommitSeeded( ageMask: number, age: number, @@ -1292,19 +1295,32 @@ export namespace AgeRestriction { const pubs: Edx25519PublicKey[] = []; const privs: Edx25519PrivateKey[] = []; - for (let i = 0; i < numPubs; i++) { + for (let i = 0; i < numPrivs; i++) { const privSeed = await kdfKw({ outputLength: 32, ikm: seed, - info: stringToBytes("age-restriction-commit"), + info: stringToBytes("age-commitment"), salt: bufferForUint32(i), }); + const priv = await Edx25519.keyCreateFromSeed(privSeed); const pub = await Edx25519.getPublic(priv); pubs.push(pub); - if (i < numPrivs) { - privs.push(priv); - } + privs.push(priv); + } + + for (let i = numPrivs; i < numPubs; i++) { + const deriveSeed = await kdfKw({ + outputLength: 32, + ikm: seed, + info: stringToBytes("age-factor"), + salt: bufferForUint32(i), + }); + const pub = await Edx25519.publicKeyDerive( + PublishedAgeRestrictionBaseKey, + deriveSeed, + ); + pubs.push(pub); } return { @@ -1604,7 +1620,9 @@ export function amountToBuffer(amount: AmountLike): Uint8Array { return u8buf; } -export function timestampRoundedToBuffer(ts: TalerProtocolTimestamp): Uint8Array { +export function timestampRoundedToBuffer( + ts: TalerProtocolTimestamp, +): Uint8Array { const b = new ArrayBuffer(8); const v = new DataView(b); // The buffer we sign over represents the timestamp in microseconds. diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index 16d96eaa9..01d2677dc 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -720,9 +720,10 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { if (denomPub.age_mask) { const age = req.restrictAge || AgeRestriction.AGE_UNRESTRICTED; logger.info(`creating age-restricted planchet (age ${age})`); - maybeAcp = await AgeRestriction.restrictionCommit( + maybeAcp = await AgeRestriction.restrictionCommitSeeded( denomPub.age_mask, age, + stringToBytes(req.secretSeed) ); maybeAgeCommitmentHash = AgeRestriction.hashCommitment( maybeAcp.commitment, -- cgit v1.2.3