Skip to content

Commit

Permalink
fix: nostr unit tests (#6462)
Browse files Browse the repository at this point in the history
  • Loading branch information
sidmorizon authored Jan 9, 2025
1 parent 834ae5b commit f09d10f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
74 changes: 74 additions & 0 deletions packages/core/src/chains/nostr/sdkNostr/__tests__/nostr.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { decrypt, encrypt } from '..';

describe('Nostr Crypto Functions', () => {
const testPrivateKey =
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
const testPublicKey =
'a8b5e5163c1d78754dd9229a42047f3ff4b069b99868580da3bb915960e7e9d8';
const testPlaintext = 'Hello, Nostr!';

it('should encrypt data with correct format', async () => {
const encrypted = await encrypt(
testPrivateKey,
testPublicKey,
testPlaintext,
);
const [ciphertext, iv] = encrypted.split('?iv=');

// Validate format
expect(encrypted).toMatch(/^[A-Za-z0-9+/]+=*\?iv=[A-Za-z0-9+/]+=*$/);

// Validate IV length (16 bytes)
const ivBuffer = Buffer.from(iv, 'base64');
expect(ivBuffer.length).toBe(16);

// Validate ciphertext is non-empty and base64
expect(ciphertext.length).toBeGreaterThan(0);
expect(() => Buffer.from(ciphertext, 'base64')).not.toThrow();
});

it('should decrypt encrypted data correctly', async () => {
const encrypted = await encrypt(
testPrivateKey,
testPublicKey,
testPlaintext,
);
const decrypted = await decrypt(testPrivateKey, testPublicKey, encrypted);
expect(decrypted).toBe(testPlaintext);
});

it('should perform round-trip encryption/decryption', async () => {
const encrypted = await encrypt(
testPrivateKey,
testPublicKey,
testPlaintext,
);
const decrypted = await decrypt(testPrivateKey, testPublicKey, encrypted);
expect(decrypted).toBe(testPlaintext);

// Verify encrypted data format
expect(encrypted).toContain('?iv=');
const [ciphertext, iv] = encrypted.split('?iv=');
expect(Buffer.from(iv, 'base64').length).toBe(16);
expect(ciphertext.length).toBeGreaterThan(0);
});

it('should generate unique IVs for each encryption', async () => {
const encrypted1 = await encrypt(
testPrivateKey,
testPublicKey,
testPlaintext,
);
const encrypted2 = await encrypt(
testPrivateKey,
testPublicKey,
testPlaintext,
);

const [, iv1] = encrypted1.split('?iv=');
const [, iv2] = encrypted2.split('?iv=');

// IVs should be different for each encryption
expect(iv1).not.toBe(iv2);
});
});
8 changes: 4 additions & 4 deletions packages/core/src/chains/nostr/sdkNostr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ export function getPrivateEncodedByNip19(privateKey: Buffer) {
return bech32.encode('nsec', words, 1000);
}

export function encrypt(
export async function encrypt(
privateKey: string,
pubkey: string,
plaintext: string,
): string {
): Promise<string> {
const key = secp256k1.getSharedSecret(privateKey, `02${pubkey}`);
const normalizedKey = key.slice(1, 33);
const iv = crypto.randomBytes(16);
Expand All @@ -84,11 +84,11 @@ export function encrypt(
).toString('base64')}`;
}

export function decrypt(
export async function decrypt(
privateKey: string,
pubkey: string,
ciphertext: string,
) {
): Promise<string> {
const key = secp256k1.getSharedSecret(privateKey, `02${pubkey}`);
const [cip, iv] = ciphertext.split('?iv=');
const normalizedKey = key.slice(1, 33);
Expand Down

0 comments on commit f09d10f

Please sign in to comment.