Skip to content

Commit

Permalink
Carol receive from Alice
Browse files Browse the repository at this point in the history
  • Loading branch information
lollerfirst committed Nov 1, 2024
1 parent e7c6501 commit 2379ed5
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/CashuWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
BlindingData,
SerializedDLEQ
} from './model/types/index.js';
import { bytesToNumber, getDecodedToken, splitAmount, sumProofs, getKeepAmounts } from './utils.js';
import { bytesToNumber, getDecodedToken, splitAmount, sumProofs, getKeepAmounts, hexToNumber } from './utils.js';
import { validateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
import { hashToCurve, pointFromHex } from '@cashu/crypto/modules/common';
Expand Down Expand Up @@ -247,6 +247,7 @@ class CashuWallet {
* @param options.counter? optionally set counter to derive secret deterministically. CashuWallet class must be initialized with seed phrase to take effect
* @param options.pubkey? optionally locks ecash to pubkey. Will not be deterministic, even if counter is set!
* @param options.privkey? will create a signature on the @param token secrets if set
* @param options.requireDleq? will check each proof for DLEQ proofs. Reject the token if any one of them can't be verified.
* @returns New token with newly created proofs, token entries that had errors
*/
async receive(
Expand All @@ -258,12 +259,16 @@ class CashuWallet {
counter?: number;
pubkey?: string;
privkey?: string;
requireDleq?: boolean;
}
): Promise<Array<Proof>> {
if (typeof token === 'string') {
token = getDecodedToken(token);
}
const keys = await this.getKeys(options?.keysetId);
if (options?.requireDleq) {
this.requireDLEQ(token, keys);
}
const amount = sumProofs(token.proofs) - this.getFeesForProofs(token.proofs);
const { payload, blindingData } = this.createSwapPayload(
amount,
Expand Down Expand Up @@ -1024,6 +1029,34 @@ class CashuWallet {
return serializedProof;
});
}

/**
* Checks that each proof in `token` has a valid DLEQ proof according to
* keyset `keys`
* @param token The token subject to the verification
* @param keys The Mint's keyset to be used for verification
*/
private requireDLEQ(token: Token, keys: MintKeys) {
token.proofs.forEach((p: Proof, i: number) => {
if (p.dleq == undefined) {
throw new Error(`${i}-th proof is missing DLEQ proof`);
}
const dleq = {
e: hexToBytes(p.dleq.e),
s: hexToBytes(p.dleq.s),
r: hexToNumber(p.dleq.r ?? "00"),
} as DLEQ;
const key = keys.keys[p.amount];
if (!verifyDLEQProof_reblind(
new TextEncoder().encode(p.secret),
dleq,
pointFromHex(p.C),
pointFromHex(key)
)) {
throw new Error(`${i}-th DLEQ proof is invalid for key ${key}`);
}
});
}
}

export { CashuWallet };

0 comments on commit 2379ed5

Please sign in to comment.