105 lines
3.8 KiB
TypeScript
105 lines
3.8 KiB
TypeScript
|
|
// Copyright (C) 2026 Whiterun LLC,
|
||
|
|
// This software is licensed under the GNU Lesser General Public License (LGPL), version 3.0 or later.
|
||
|
|
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/lgpl-3.0.html
|
||
|
|
|
||
|
|
import { describe, it, expect } from "vitest";
|
||
|
|
import {
|
||
|
|
deriveNostrPublicKey,
|
||
|
|
deriveNostrPublicKeyBytes,
|
||
|
|
} from "./utilnostr.js";
|
||
|
|
import {
|
||
|
|
generatePrivateKey,
|
||
|
|
hexToBin,
|
||
|
|
binToHex,
|
||
|
|
secp256k1,
|
||
|
|
} from "@bitauth/libauth";
|
||
|
|
|
||
|
|
describe("utilnostr", () => {
|
||
|
|
describe("deriveNostrPublicKey", () => {
|
||
|
|
it("should derive a valid Nostr public key from a private key", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKey = deriveNostrPublicKey(privateKey);
|
||
|
|
|
||
|
|
// Nostr public key should be 64 hex characters (32 bytes)
|
||
|
|
expect(publicKey).toHaveLength(64);
|
||
|
|
expect(/^[0-9a-f]+$/.test(publicKey)).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should produce the same public key for the same private key", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKey1 = deriveNostrPublicKey(privateKey);
|
||
|
|
const publicKey2 = deriveNostrPublicKey(privateKey);
|
||
|
|
|
||
|
|
expect(publicKey1).toBe(publicKey2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should produce different public keys for different private keys", () => {
|
||
|
|
const privateKey1 = generatePrivateKey();
|
||
|
|
const privateKey2 = generatePrivateKey();
|
||
|
|
const publicKey1 = deriveNostrPublicKey(privateKey1);
|
||
|
|
const publicKey2 = deriveNostrPublicKey(privateKey2);
|
||
|
|
|
||
|
|
expect(publicKey1).not.toBe(publicKey2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should handle private key from hex string", () => {
|
||
|
|
const privateKeyHex =
|
||
|
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||
|
|
const privateKey = hexToBin(privateKeyHex);
|
||
|
|
const publicKey = deriveNostrPublicKey(privateKey);
|
||
|
|
|
||
|
|
expect(publicKey).toHaveLength(64);
|
||
|
|
expect(/^[0-9a-f]+$/.test(publicKey)).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should match the pattern used in key-exchange", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKey = deriveNostrPublicKey(privateKey);
|
||
|
|
|
||
|
|
// Verify it's the same as the manual pattern
|
||
|
|
const result = secp256k1.derivePublicKeyCompressed(privateKey);
|
||
|
|
if (typeof result === "string") throw new Error(result);
|
||
|
|
const publicKeyNostr = result.slice(1);
|
||
|
|
const publicKeyHex = binToHex(publicKeyNostr);
|
||
|
|
|
||
|
|
expect(publicKey).toBe(publicKeyHex);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe("deriveNostrPublicKeyBytes", () => {
|
||
|
|
it("should derive a valid Nostr public key as bytes", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKeyBytes = deriveNostrPublicKeyBytes(privateKey);
|
||
|
|
|
||
|
|
// Nostr public key should be 32 bytes
|
||
|
|
expect(publicKeyBytes).toHaveLength(32);
|
||
|
|
expect(publicKeyBytes).toBeInstanceOf(Uint8Array);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should match the hex version when converted", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKeyHex = deriveNostrPublicKey(privateKey);
|
||
|
|
const publicKeyBytes = deriveNostrPublicKeyBytes(privateKey);
|
||
|
|
|
||
|
|
expect(binToHex(publicKeyBytes)).toBe(publicKeyHex);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should produce the same bytes for the same private key", () => {
|
||
|
|
const privateKey = generatePrivateKey();
|
||
|
|
const publicKeyBytes1 = deriveNostrPublicKeyBytes(privateKey);
|
||
|
|
const publicKeyBytes2 = deriveNostrPublicKeyBytes(privateKey);
|
||
|
|
|
||
|
|
expect(publicKeyBytes1).toEqual(publicKeyBytes2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("should produce different bytes for different private keys", () => {
|
||
|
|
const privateKey1 = generatePrivateKey();
|
||
|
|
const privateKey2 = generatePrivateKey();
|
||
|
|
const publicKeyBytes1 = deriveNostrPublicKeyBytes(privateKey1);
|
||
|
|
const publicKeyBytes2 = deriveNostrPublicKeyBytes(privateKey2);
|
||
|
|
|
||
|
|
expect(publicKeyBytes1).not.toEqual(publicKeyBytes2);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|