11# pq-key-encoder
22
3- Post-quantum key encoding utilities.
3+ Post-quantum key encoding utilities for NIST PQC algorithms .
44
55## Installation
66
@@ -10,12 +10,152 @@ npm install pq-key-encoder
1010
1111## Usage
1212
13+ ### Basic Encoding/Decoding
14+
15+ ``` typescript
16+ import {
17+ fromDER ,
18+ fromPEM ,
19+ fromJWK ,
20+ fromSPKI ,
21+ fromPKCS8 ,
22+ toDER ,
23+ toPEM ,
24+ toJWK ,
25+ toSPKI ,
26+ toPKCS8 ,
27+ type KeyData ,
28+ type PQJwk ,
29+ } from ' pq-key-encoder' ;
30+
31+ // KeyData is the core type: { alg, type, bytes }
32+ const publicKey: KeyData = {
33+ alg: ' ML-KEM-768' ,
34+ type: ' public' ,
35+ bytes: publicKeyBytes , // Uint8Array from key generation
36+ };
37+
38+ const privateKey: KeyData = {
39+ alg: ' ML-KEM-768' ,
40+ type: ' private' ,
41+ bytes: privateKeyBytes ,
42+ };
43+ ```
44+
45+ ### DER (SPKI / PKCS8)
46+
47+ ``` typescript
48+ // Encode to DER (auto-selects SPKI for public, PKCS8 for private)
49+ const publicDer = toDER (publicKey );
50+ const privateDer = toDER (privateKey );
51+
52+ // Decode from DER (auto-detects key type)
53+ const parsedPublic = fromDER (publicDer );
54+ const parsedPrivate = fromDER (privateDer );
55+
56+ // Explicit SPKI/PKCS8 functions
57+ const spki = toSPKI (publicKey );
58+ const pkcs8 = toPKCS8 (privateKey );
59+ const fromSpki = fromSPKI (spki );
60+ const fromPkcs8 = fromPKCS8 (pkcs8 );
61+ ```
62+
63+ ### PEM
64+
1365``` typescript
14- import { } from ' pq-key-encoder' ;
66+ // Encode to PEM (PUBLIC KEY / PRIVATE KEY labels)
67+ const publicPem = toPEM (publicKey );
68+ const privatePem = toPEM (privateKey );
1569
16- // Coming soon
70+ // Decode from PEM
71+ const parsedPublicPem = fromPEM (publicPem );
72+ const parsedPrivatePem = fromPEM (privatePem );
1773```
1874
75+ ### JWK
76+
77+ ``` typescript
78+ // Public key to JWK
79+ const publicJwk = toJWK (publicKey );
80+ // { kty: 'PQC', alg: 'ML-KEM-768', x: '<base64url>' }
81+
82+ // Private key to JWK (requires public key bytes)
83+ const privateJwk = toJWK (privateKey , {
84+ includePrivate: true ,
85+ publicKey: publicKey .bytes ,
86+ });
87+ // { kty: 'PQC', alg: 'ML-KEM-768', x: '<base64url>', d: '<base64url>' }
88+
89+ // Decode from JWK
90+ const fromPublicJwk = fromJWK (publicJwk );
91+ const fromPrivateJwk = fromJWK (privateJwk );
92+ ```
93+
94+ ## Supported Algorithms
95+
96+ Algorithms are validated against ` pq-oid ` metadata (OID + key sizes):
97+
98+ | Family | Algorithms |
99+ | --------| ------------|
100+ | ML-KEM | ML-KEM-512, ML-KEM-768, ML-KEM-1024 |
101+ | ML-DSA | ML-DSA-44, ML-DSA-65, ML-DSA-87 |
102+ | SLH-DSA | SHA2/SHAKE variants (128s/f, 192s/f, 256s/f) |
103+
104+ ## Error Handling
105+
106+ ``` typescript
107+ import {
108+ KeyEncoderError ,
109+ InvalidInputError ,
110+ InvalidEncodingError ,
111+ UnsupportedAlgorithmError ,
112+ KeySizeMismatchError ,
113+ } from ' pq-key-encoder' ;
114+
115+ try {
116+ const key = fromDER (malformedData );
117+ } catch (error ) {
118+ if (error instanceof KeySizeMismatchError ) {
119+ console .error (` Expected ${error .expected } bytes, got ${error .actual } ` );
120+ } else if (error instanceof UnsupportedAlgorithmError ) {
121+ console .error (' Unknown algorithm OID' );
122+ } else if (error instanceof InvalidEncodingError ) {
123+ console .error (' Malformed DER structure' );
124+ }
125+ }
126+ ```
127+
128+ ## Types
129+
130+ ``` typescript
131+ type AlgorithmName = ' ML-KEM-512' | ' ML-KEM-768' | ... ;
132+ type KeyType = ' public' | ' private' ;
133+
134+ interface KeyData {
135+ alg: AlgorithmName ;
136+ type: KeyType ;
137+ bytes: Uint8Array ;
138+ }
139+
140+ interface PQJwk {
141+ kty: ' PQC' ;
142+ alg: AlgorithmName ;
143+ x: string ; // base64url public key
144+ d? : string ; // base64url private key (optional)
145+ }
146+ ```
147+
148+ ## Notes
149+
150+ - Inputs are validated for correct key size and encoding structure
151+ - DER encoding uses AlgorithmIdentifier with absent parameters (per NIST PQ specs); decoder accepts both absent and NULL for interoperability
152+ - JWK uses non-standard ` kty: 'PQC' ` for post-quantum keys
153+ - ` fromJWK ` returns only private key bytes when both ` x ` and ` d ` are present (public key is validated but not returned). To get both keys, parse separately:
154+ ``` typescript
155+ const privateKey = fromJWK (jwk );
156+ const publicKey = fromJWK ({ kty: jwk .kty , alg: jwk .alg , x: jwk .x });
157+ ```
158+
19159## License
20160
21161MIT
0 commit comments