@sebastienrousseau/crypto-cli 0.0.9 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +360 -0
- package/dist/program/hpke.d.ts +4 -0
- package/dist/program/hpke.d.ts.map +1 -0
- package/dist/program/hpke.js +111 -0
- package/dist/program/index.d.ts.map +1 -1
- package/dist/program/index.js +8 -0
- package/dist/program/kms.d.ts +8 -0
- package/dist/program/kms.d.ts.map +1 -0
- package/dist/program/kms.js +247 -0
- package/dist/program/opaque.d.ts +4 -0
- package/dist/program/opaque.d.ts.map +1 -0
- package/dist/program/opaque.js +209 -0
- package/dist/program/stream-multi.d.ts +7 -0
- package/dist/program/stream-multi.d.ts.map +1 -0
- package/dist/program/stream-multi.js +163 -0
- package/dist/program/stream.d.ts +6 -0
- package/dist/program/stream.d.ts.map +1 -0
- package/dist/program/stream.js +102 -0
- package/package.json +8 -13
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStream = exports.parseCiphertext = exports.parseChunkSize = void 0;
|
|
4
|
+
const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
|
|
5
|
+
const streaming_1 = require("@sebastienrousseau/crypto-lib/streaming");
|
|
6
|
+
const io_1 = require("./io");
|
|
7
|
+
const stream_multi_1 = require("./stream-multi");
|
|
8
|
+
const BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
9
|
+
const parseChunkSize = (value) => {
|
|
10
|
+
if (value === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
const size = Number(value);
|
|
13
|
+
if (!Number.isSafeInteger(size) || size < 64) {
|
|
14
|
+
throw new io_1.UsageError("--chunk-size must be an integer >= 64");
|
|
15
|
+
}
|
|
16
|
+
return size;
|
|
17
|
+
};
|
|
18
|
+
exports.parseChunkSize = parseChunkSize;
|
|
19
|
+
const parseCiphertext = (input) => {
|
|
20
|
+
const text = (0, io_1.valueOrJsonField)(input, "ciphertext");
|
|
21
|
+
if (!BASE64.test(text)) {
|
|
22
|
+
throw new Error("the input is not base64 from crypto-cli stream encrypt");
|
|
23
|
+
}
|
|
24
|
+
return Buffer.from(text, "base64");
|
|
25
|
+
};
|
|
26
|
+
exports.parseCiphertext = parseCiphertext;
|
|
27
|
+
const registerStreamEncrypt = (stream, ctx) => {
|
|
28
|
+
stream
|
|
29
|
+
.command("encrypt")
|
|
30
|
+
.description("Encrypt with post-quantum hybrid STREAM AEAD (X25519 + ML-KEM-768)")
|
|
31
|
+
.argument("[file]", "file to encrypt; '-' or omitted reads standard input")
|
|
32
|
+
.option("-x, --x25519-public <hex>", "recipient X25519 public key (hex)")
|
|
33
|
+
.option("-m, --ml-kem-public <hex>", "recipient ML-KEM-768 public key (hex)")
|
|
34
|
+
.option("-c, --chunk-size <bytes>", "chunk size in bytes (minimum 64, default 65536)")
|
|
35
|
+
.option("--json", "print the result as one line of JSON")
|
|
36
|
+
.action(async (file, opts) => {
|
|
37
|
+
if (!opts.x25519Public || !opts.mlKemPublic) {
|
|
38
|
+
throw new io_1.UsageError("missing recipient public key: both --x25519-public and --ml-kem-public are required");
|
|
39
|
+
}
|
|
40
|
+
const chunkSize = (0, exports.parseChunkSize)(opts.chunkSize);
|
|
41
|
+
const input = await (0, io_1.readInput)(file, ctx.io);
|
|
42
|
+
const result = (0, streaming_1.streamPqEncrypt)({
|
|
43
|
+
recipientX25519Public: opts.x25519Public,
|
|
44
|
+
recipientMlKemPublic: opts.mlKemPublic,
|
|
45
|
+
plaintext: input,
|
|
46
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
47
|
+
});
|
|
48
|
+
const b64 = Buffer.from(result.ciphertext).toString("base64");
|
|
49
|
+
(0, io_1.emit)(ctx.io, Boolean(opts.json), { ciphertext: b64, algorithm: result.algorithm }, b64);
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const registerStreamDecrypt = (stream, ctx) => {
|
|
53
|
+
stream
|
|
54
|
+
.command("decrypt")
|
|
55
|
+
.description("Decrypt post-quantum hybrid STREAM ciphertext; exits 1 on error")
|
|
56
|
+
.argument("[file]", "output of stream encrypt (base64 or its --json line)")
|
|
57
|
+
.option("-x, --x25519-secret <hex>", "recipient X25519 secret key (hex)")
|
|
58
|
+
.option("-m, --ml-kem-secret <hex>", "recipient ML-KEM-768 secret key (hex)")
|
|
59
|
+
.option("-c, --chunk-size <bytes>", "chunk size in bytes")
|
|
60
|
+
.option("--json", "print the result as one line of JSON")
|
|
61
|
+
.action(async (file, opts) => {
|
|
62
|
+
if (!opts.x25519Secret || !opts.mlKemSecret) {
|
|
63
|
+
throw new io_1.UsageError("missing recipient secret key: both --x25519-secret and --ml-kem-secret are required");
|
|
64
|
+
}
|
|
65
|
+
const chunkSize = (0, exports.parseChunkSize)(opts.chunkSize);
|
|
66
|
+
const ciphertext = (0, exports.parseCiphertext)(await (0, io_1.readInput)(file, ctx.io));
|
|
67
|
+
let plaintext;
|
|
68
|
+
try {
|
|
69
|
+
plaintext = (0, streaming_1.streamPqDecrypt)({
|
|
70
|
+
recipientX25519Secret: opts.x25519Secret,
|
|
71
|
+
recipientMlKemSecret: opts.mlKemSecret,
|
|
72
|
+
ciphertext,
|
|
73
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
throw new Error("decryption failed: wrong key, or the input was modified or truncated");
|
|
78
|
+
}
|
|
79
|
+
if (!opts.json) {
|
|
80
|
+
ctx.io.stdout(plaintext);
|
|
81
|
+
(0, crypto_lib_1.wipeMemory)(plaintext);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const b64 = Buffer.from(plaintext).toString("base64");
|
|
85
|
+
(0, crypto_lib_1.wipeMemory)(plaintext);
|
|
86
|
+
(0, io_1.emit)(ctx.io, true, {
|
|
87
|
+
plaintext: b64,
|
|
88
|
+
encoding: "base64",
|
|
89
|
+
algorithm: "x25519-ml-kem-768-xchacha20-poly1305",
|
|
90
|
+
}, "");
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
const registerStream = (program, ctx) => {
|
|
94
|
+
const stream = program
|
|
95
|
+
.command("stream")
|
|
96
|
+
.description("Post-quantum hybrid streaming AEAD operations");
|
|
97
|
+
registerStreamEncrypt(stream, ctx);
|
|
98
|
+
registerStreamDecrypt(stream, ctx);
|
|
99
|
+
(0, stream_multi_1.registerStreamMulti)(stream, ctx);
|
|
100
|
+
};
|
|
101
|
+
exports.registerStream = registerStream;
|
|
102
|
+
//# sourceMappingURL=stream.js.map
|
package/package.json
CHANGED
|
@@ -24,22 +24,22 @@
|
|
|
24
24
|
"url": "https://github.com/sebastienrousseau/crypto-service/issues"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"commander": "^
|
|
28
|
-
"figlet": "^1.
|
|
27
|
+
"commander": "^15.0.0",
|
|
28
|
+
"figlet": "^1.12.0",
|
|
29
29
|
"kleur": "^4.1.5",
|
|
30
30
|
"prompts": "^2.4.2",
|
|
31
|
-
"@sebastienrousseau/crypto-
|
|
32
|
-
"@sebastienrousseau/crypto-lib": "0.0.
|
|
31
|
+
"@sebastienrousseau/crypto-kms": "0.0.24",
|
|
32
|
+
"@sebastienrousseau/crypto-lib": "0.0.24",
|
|
33
|
+
"@sebastienrousseau/crypto-cbom": "0.0.24"
|
|
33
34
|
},
|
|
34
35
|
"description": "The Crypto Lib Command Line Interface (CLI) is a unified tool to perform common cryptographic operations such as key generation, data encryption, digital signing, and signature verification which are invoked from the command prompt or terminal.",
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@sebastienrousseau/c8-config": "^0.0.7",
|
|
37
38
|
"@sebastienrousseau/eslint-config": "^0.0.7",
|
|
38
39
|
"@sebastienrousseau/jsdoc-config": "^0.0.7",
|
|
39
|
-
"@sebastienrousseau/markdownlint-config": "^0.0.
|
|
40
|
-
"@sebastienrousseau/mocha-config": "^0.0.
|
|
40
|
+
"@sebastienrousseau/markdownlint-config": "^0.0.7",
|
|
41
|
+
"@sebastienrousseau/mocha-config": "^0.0.7",
|
|
41
42
|
"@sebastienrousseau/prettier-config": "^0.0.7",
|
|
42
|
-
"@sebastienrousseau/remark-config": "^0.0.7",
|
|
43
43
|
"@types/chai": "^5.2.3",
|
|
44
44
|
"@types/chai-as-promised": "^8.0.2",
|
|
45
45
|
"@types/figlet": "^1.5.6",
|
|
@@ -52,11 +52,6 @@
|
|
|
52
52
|
"filesizes": "^0.1.2",
|
|
53
53
|
"mocha": "^12.0.3",
|
|
54
54
|
"prettier": "^3.9.9",
|
|
55
|
-
"remark-cli": "^12.0.0",
|
|
56
|
-
"remark-footnotes": "^5.0.0",
|
|
57
|
-
"remark-preset-lint-consistent": "^6.0.1",
|
|
58
|
-
"remark-preset-lint-markdown-style-guide": "^5.1.3",
|
|
59
|
-
"remark-preset-lint-recommended": "^7.0.1",
|
|
60
55
|
"rimraf": "^6.1.3",
|
|
61
56
|
"ts-node": "^10.9.1",
|
|
62
57
|
"typedoc": "^0.28.20",
|
|
@@ -102,7 +97,7 @@
|
|
|
102
97
|
"access": "public"
|
|
103
98
|
},
|
|
104
99
|
"sideEffects": false,
|
|
105
|
-
"version": "0.0.
|
|
100
|
+
"version": "0.0.24",
|
|
106
101
|
"scripts": {
|
|
107
102
|
"build": "tsc --build tsconfig.json",
|
|
108
103
|
"clean": "rimraf ./coverage ./dist ./docs",
|