Migrating to @hamradio/packet
This commit is contained in:
@@ -1,39 +1,39 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { PublicKey, PrivateKey, SharedSecret, StaticSecret } from '../src/crypto';
|
||||
import { bytesToHex, hexToBytes } from '../src/parser';
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { bytesToHex } from "@hamradio/packet";
|
||||
import { PublicKey, PrivateKey, SharedSecret, StaticSecret } from "../src/crypto";
|
||||
|
||||
const randomBytes = (len: number) => Uint8Array.from({ length: len }, () => Math.floor(Math.random() * 256));
|
||||
|
||||
describe('PublicKey', () => {
|
||||
describe("PublicKey", () => {
|
||||
const keyBytes = randomBytes(32);
|
||||
const keyHex = bytesToHex(keyBytes);
|
||||
|
||||
it('constructs from Uint8Array', () => {
|
||||
it("constructs from Uint8Array", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(pk.toBytes()).toEqual(keyBytes);
|
||||
});
|
||||
|
||||
it('constructs from string', () => {
|
||||
it("constructs from string", () => {
|
||||
const pk = new PublicKey(keyHex);
|
||||
expect(pk.toBytes()).toEqual(keyBytes);
|
||||
});
|
||||
|
||||
it('throws on invalid constructor input', () => {
|
||||
// @ts-expect-error
|
||||
it("throws on invalid constructor input", () => {
|
||||
// @ts-expect-error testing invalid input
|
||||
expect(() => new PublicKey(123)).toThrow();
|
||||
});
|
||||
|
||||
it('toHash returns a NodeHash', () => {
|
||||
it("toHash returns a NodeHash", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(typeof pk.toHash()).toBe('number');
|
||||
expect(typeof pk.toHash()).toBe("number");
|
||||
});
|
||||
|
||||
it('toString returns hex', () => {
|
||||
it("toString returns hex", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(pk.toString()).toBe(keyHex);
|
||||
});
|
||||
|
||||
it('equals works for PublicKey, Uint8Array, and string', () => {
|
||||
it("equals works for PublicKey, Uint8Array, and string", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(pk.equals(pk)).toBe(true);
|
||||
expect(pk.equals(keyBytes)).toBe(true);
|
||||
@@ -41,41 +41,41 @@ describe('PublicKey', () => {
|
||||
expect(pk.equals(randomBytes(32))).toBe(false);
|
||||
});
|
||||
|
||||
it('throws on equals with invalid type', () => {
|
||||
it("throws on equals with invalid type", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
// @ts-expect-error
|
||||
// @ts-expect-error testing invalid input
|
||||
expect(() => pk.equals(123)).toThrow();
|
||||
});
|
||||
|
||||
it('verify returns false for invalid signature', () => {
|
||||
it("verify returns false for invalid signature", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(pk.verify(new Uint8Array([1, 2, 3]), randomBytes(64))).toBe(false);
|
||||
});
|
||||
|
||||
it('throws on verify with wrong signature length', () => {
|
||||
it("throws on verify with wrong signature length", () => {
|
||||
const pk = new PublicKey(keyBytes);
|
||||
expect(() => pk.verify(new Uint8Array([1, 2, 3]), randomBytes(10))).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('PrivateKey', () => {
|
||||
describe("PrivateKey", () => {
|
||||
const seed = randomBytes(32);
|
||||
|
||||
it('constructs from Uint8Array', () => {
|
||||
it("constructs from Uint8Array", () => {
|
||||
const sk = new PrivateKey(seed);
|
||||
expect(sk.toPublicKey()).toBeInstanceOf(PublicKey);
|
||||
});
|
||||
|
||||
it('constructs from string', () => {
|
||||
it("constructs from string", () => {
|
||||
const sk = new PrivateKey(bytesToHex(seed));
|
||||
expect(sk.toPublicKey()).toBeInstanceOf(PublicKey);
|
||||
});
|
||||
|
||||
it('throws on invalid seed length', () => {
|
||||
it("throws on invalid seed length", () => {
|
||||
expect(() => new PrivateKey(randomBytes(10))).toThrow();
|
||||
});
|
||||
|
||||
it('sign and verify', () => {
|
||||
it("sign and verify", () => {
|
||||
const sk = new PrivateKey(seed);
|
||||
const pk = sk.toPublicKey();
|
||||
const msg = new Uint8Array([1, 2, 3]);
|
||||
@@ -83,7 +83,7 @@ describe('PrivateKey', () => {
|
||||
expect(pk.verify(msg, sig)).toBe(true);
|
||||
});
|
||||
|
||||
it('calculateSharedSecret returns Uint8Array', () => {
|
||||
it("calculateSharedSecret returns Uint8Array", () => {
|
||||
const sk1 = new PrivateKey(seed);
|
||||
const sk2 = PrivateKey.generate();
|
||||
const pk2 = sk2.toPublicKey();
|
||||
@@ -92,7 +92,7 @@ describe('PrivateKey', () => {
|
||||
expect(secret.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('calculateSharedSecret accepts string and Uint8Array', () => {
|
||||
it("calculateSharedSecret accepts string and Uint8Array", () => {
|
||||
const sk1 = new PrivateKey(seed);
|
||||
const sk2 = PrivateKey.generate();
|
||||
const pk2 = sk2.toPublicKey();
|
||||
@@ -100,47 +100,47 @@ describe('PrivateKey', () => {
|
||||
expect(sk1.calculateSharedSecret(pk2.toString())).toBeInstanceOf(Uint8Array);
|
||||
});
|
||||
|
||||
it('throws on calculateSharedSecret with invalid type', () => {
|
||||
it("throws on calculateSharedSecret with invalid type", () => {
|
||||
const sk = new PrivateKey(seed);
|
||||
// @ts-expect-error
|
||||
// @ts-expect-error testing invalid input
|
||||
expect(() => sk.calculateSharedSecret(123)).toThrow();
|
||||
});
|
||||
|
||||
it('generate returns PrivateKey', () => {
|
||||
it("generate returns PrivateKey", () => {
|
||||
expect(PrivateKey.generate()).toBeInstanceOf(PrivateKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SharedSecret', () => {
|
||||
describe("SharedSecret", () => {
|
||||
const secret = randomBytes(32);
|
||||
|
||||
it('constructs from 32 bytes', () => {
|
||||
it("constructs from 32 bytes", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
expect(ss.toBytes()).toEqual(secret);
|
||||
});
|
||||
|
||||
it('pads if 16 bytes', () => {
|
||||
it("pads if 16 bytes", () => {
|
||||
const short = randomBytes(16);
|
||||
const ss = new SharedSecret(short);
|
||||
expect(ss.toBytes().length).toBe(32);
|
||||
expect(Array.from(ss.toBytes()).slice(16)).toEqual(Array.from(short));
|
||||
});
|
||||
|
||||
it('throws on invalid length', () => {
|
||||
it("throws on invalid length", () => {
|
||||
expect(() => new SharedSecret(randomBytes(10))).toThrow();
|
||||
});
|
||||
|
||||
it('toHash returns number', () => {
|
||||
it("toHash returns number", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
expect(typeof ss.toHash()).toBe('number');
|
||||
expect(typeof ss.toHash()).toBe("number");
|
||||
});
|
||||
|
||||
it('toString returns hex', () => {
|
||||
it("toString returns hex", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
expect(ss.toString()).toBe(bytesToHex(secret));
|
||||
});
|
||||
|
||||
it('encrypt and decrypt roundtrip', () => {
|
||||
it("encrypt and decrypt roundtrip", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
const data = new Uint8Array([1, 2, 3, 4, 5]);
|
||||
const { hmac, ciphertext } = ss.encrypt(data);
|
||||
@@ -148,14 +148,14 @@ describe('SharedSecret', () => {
|
||||
expect(Array.from(decrypted.slice(0, data.length))).toEqual(Array.from(data));
|
||||
});
|
||||
|
||||
it('throws on decrypt with wrong hmac', () => {
|
||||
it("throws on decrypt with wrong hmac", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
const data = new Uint8Array([1, 2, 3]);
|
||||
const { ciphertext } = ss.encrypt(data);
|
||||
expect(() => ss.decrypt(new Uint8Array([0, 0]), ciphertext)).toThrow();
|
||||
});
|
||||
|
||||
it('throws on decrypt with wrong hmac length', () => {
|
||||
it("throws on decrypt with wrong hmac length", () => {
|
||||
const ss = new SharedSecret(secret);
|
||||
expect(() => ss.decrypt(new Uint8Array([1]), new Uint8Array([1, 2, 3]))).toThrow();
|
||||
});
|
||||
@@ -165,34 +165,34 @@ describe('SharedSecret', () => {
|
||||
expect(ss).toBeInstanceOf(SharedSecret);
|
||||
});
|
||||
|
||||
it('fromName with #group', () => {
|
||||
it("fromName with #group", () => {
|
||||
const ss = SharedSecret.fromName("#group");
|
||||
expect(ss).toBeInstanceOf(SharedSecret);
|
||||
});
|
||||
|
||||
it('fromName throws on invalid name', () => {
|
||||
it("fromName throws on invalid name", () => {
|
||||
expect(() => SharedSecret.fromName("foo")).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('StaticSecret', () => {
|
||||
describe("StaticSecret", () => {
|
||||
const secret = randomBytes(32);
|
||||
|
||||
it('constructs from Uint8Array', () => {
|
||||
it("constructs from Uint8Array", () => {
|
||||
const ss = new StaticSecret(secret);
|
||||
expect(ss.publicKey()).toBeInstanceOf(PublicKey);
|
||||
});
|
||||
|
||||
it('constructs from string', () => {
|
||||
it("constructs from string", () => {
|
||||
const ss = new StaticSecret(bytesToHex(secret));
|
||||
expect(ss.publicKey()).toBeInstanceOf(PublicKey);
|
||||
});
|
||||
|
||||
it('throws on invalid length', () => {
|
||||
it("throws on invalid length", () => {
|
||||
expect(() => new StaticSecret(randomBytes(10))).toThrow();
|
||||
});
|
||||
|
||||
it('diffieHellman returns SharedSecret', () => {
|
||||
it("diffieHellman returns SharedSecret", () => {
|
||||
const ss1 = new StaticSecret(secret);
|
||||
const ss2 = new StaticSecret(randomBytes(32));
|
||||
const pk2 = ss2.publicKey();
|
||||
|
||||
Reference in New Issue
Block a user