Repository navigation
Expand file tree
/
Copy pathWebCryptPQCIntegration.test.js
More file actions
130 lines (100 loc) · 4.33 KB
/
Copy pathWebCryptPQCIntegration.test.js
File metadata and controls
130 lines (100 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { WebCryptPQC } from "../src/WebCryptPQC.js";
import { WebCryptAsym } from "../src/WebCryptAsym.js";
import { WebCrypt } from "../src/WebCrypt.js";
describe("WebCryptPQC - Integration Tests", () => {
let pqc;
let asym;
let crypt;
beforeEach(() => {
pqc = new WebCryptPQC();
asym = new WebCryptAsym();
crypt = new WebCrypt();
});
test("Hybrid key exchange between two parties", async () => {
// Alice generates hybrid keys
const aliceRsa = await asym.generateKeyPair(2048);
const aliceKyber = await pqc.generateKyberKeyPair("Kyber768");
// Bob generates hybrid keys
const bobRsa = await asym.generateKeyPair(2048);
const bobKyber = await pqc.generateKyberKeyPair("Kyber768");
// Alice → Bob: hybrid encapsulate
const aliceToBob = await pqc.hybridEncapsulate(
bobRsa.publicKey,
bobKyber.publicKey,
"Kyber768"
);
// Bob decrypts
const bobReceived = await pqc.hybridDecapsulate(
aliceToBob.kyberCiphertext,
aliceToBob.rsaWrappedSharedSecret,
bobRsa.privateKey,
bobKyber.privateKey,
"Kyber768"
);
expect(bobReceived).toBeInstanceOf(Uint8Array);
expect(bobReceived.byteLength).toBe(32);
});
test("Secure document signing and verification", async () => {
const author = await pqc.generateDilithiumKeyPair("Dilithium3");
const document = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); // "Hello World"
// Author signs
const signature = await pqc.dilithiumSign(document, author.privateKey, "Dilithium3");
// Reader verifies
const verified = await pqc.dilithiumVerify(document, signature, author.publicKey, "Dilithium3");
expect(verified).toBe(true);
});
test("Key derivation from password with lower iterations", async () => {
const userPassword = "secure-password";
// Derive key with low iterations to avoid timeout
const baseKey = await asym.deriveKeySHA3(userPassword, 10, "SHA3-256");
expect(baseKey.type).toBeTruthy();
// Expand into additional key material
const masterSecret = crypto.getRandomValues(new Uint8Array(32));
const salt = crypto.getRandomValues(new Uint8Array(16));
const derivedKey = await asym.deriveKeyHKDFSHA3(masterSecret, salt);
expect(derivedKey.type).toBeTruthy();
});
test("Authenticated encryption with HMAC", async () => {
const sharedPassword = "shared-key";
// Derive keys (using fast iterations)
const aesKey = await asym.deriveKeySHA3(sharedPassword + ":enc", 10, "SHA3-256");
const hmacKey = await crypt.generateHmacKeySHA3();
// Encrypt
const plaintext = new Uint8Array([1, 2, 3, 4, 5]);
const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, aesKey, plaintext);
// Compute HMAC
const ciphertextBytes = new Uint8Array(ciphertext);
const tag = await crypt.computeHmacSHA3(ciphertextBytes, hmacKey);
// Verify HMAC
const authValid = await crypt.verifyHmacSHA3(ciphertextBytes, tag, hmacKey);
expect(authValid).toBe(true);
// Decrypt
const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, aesKey, ciphertext);
expect(new Uint8Array(decrypted)).toEqual(plaintext);
});
test("All three Kyber security levels work end-to-end", async () => {
for (const level of ["Kyber512", "Kyber768", "Kyber1024"]) {
const rsa = await asym.generateKeyPair(2048);
const kyber = await pqc.generateKyberKeyPair(level);
const encapsulated = await pqc.hybridEncapsulate(rsa.publicKey, kyber.publicKey, level);
const decapsulated = await pqc.hybridDecapsulate(
encapsulated.kyberCiphertext,
encapsulated.rsaWrappedSharedSecret,
rsa.privateKey,
kyber.privateKey,
level
);
expect(decapsulated.byteLength).toBe(32);
}
}, 15000);
test("All three Dilithium security levels work end-to-end", async () => {
const document = new Uint8Array([1, 2, 3, 4, 5]);
for (const level of ["Dilithium2", "Dilithium3", "Dilithium5"]) {
const keys = await pqc.generateDilithiumKeyPair(level);
const signature = await pqc.dilithiumSign(document, keys.privateKey, level);
const verified = await pqc.dilithiumVerify(document, signature, keys.publicKey, level);
expect(verified).toBe(true);
}
});
});