Skip to content

Commit 5819137

Browse files
vveerrggclaude
andcommitted
fix: prevent private key leak in createDelegation return value
CRITICAL: createDelegation() was returning the delegator's private key in the Delegation object. Now derives and returns the public key instead. Also fixed verifyDelegationSignature() parameter order to match schnorr.verify(signature, message, publicKey) convention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 78020bf commit 5819137

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

src/nips/nip-26.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import { sha256 } from '@noble/hashes/sha256';
77
import { NostrEvent } from '../types';
88
import { signSchnorr, verifySchnorrSignature } from '../crypto';
9-
import { bytesToHex } from '@noble/curves/abstract/utils';
9+
import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils';
10+
import { schnorr } from '@noble/curves/secp256k1';
1011

1112
export interface DelegationConditions {
1213
kind?: number;
@@ -23,21 +24,24 @@ export interface Delegation {
2324

2425
/**
2526
* Create a delegation token
26-
* @param delegator Delegator's private key
27+
* @param delegatorPrivateKey Delegator's private key (used for signing only, never returned)
2728
* @param delegatee Delegatee's public key
2829
* @param conditions Delegation conditions
29-
* @returns Delegation token
30+
* @returns Delegation token (delegator field contains the PUBLIC key, not the private key)
3031
*/
3132
export function createDelegation(
32-
delegator: string,
33+
delegatorPrivateKey: string,
3334
delegatee: string,
3435
conditions: DelegationConditions
3536
): Delegation {
3637
const conditionsString = serializeConditions(conditions);
37-
const token = signDelegation(delegator, delegatee, conditionsString);
38+
const token = signDelegation(delegatorPrivateKey, delegatee, conditionsString);
39+
40+
// Derive the public key from the private key — NEVER return the private key
41+
const delegatorPublicKey = bytesToHex(schnorr.getPublicKey(hexToBytes(delegatorPrivateKey)));
3842

3943
return {
40-
delegator,
44+
delegator: delegatorPublicKey,
4145
delegatee,
4246
conditions,
4347
token
@@ -179,5 +183,5 @@ async function verifyDelegationSignature(
179183
): Promise<boolean> {
180184
const msgHash = sha256(new TextEncoder().encode(`nostr:delegation:${delegatee}:${conditions}`));
181185

182-
return verifySchnorrSignature(msgHash, delegator, signature);
186+
return verifySchnorrSignature(signature, msgHash, delegator);
183187
}

0 commit comments

Comments
 (0)