@yielded/crypto 0.1.0-beta.28 → 0.1.0-beta.29
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 +4 -4
- package/dist/Aead.d.mts +26 -1
- package/dist/Aead.mjs +16 -1
- package/dist/Aead.mjs.map +1 -1
- package/dist/Signature.d.mts +23 -1
- package/dist/Signature.mjs +11 -5
- package/dist/Signature.mjs.map +1 -1
- package/dist/internal/aead.mjs +112 -68
- package/dist/internal/aead.mjs.map +1 -1
- package/dist/internal/argon2.mjs +8 -3
- package/dist/internal/argon2.mjs.map +1 -1
- package/dist/internal/hmac.mjs +12 -26
- package/dist/internal/hmac.mjs.map +1 -1
- package/dist/internal/scoped-key.mjs +31 -0
- package/dist/internal/scoped-key.mjs.map +1 -0
- package/dist/internal/signature.mjs +32 -1
- package/dist/internal/signature.mjs.map +1 -1
- package/dist/internal/xchacha-core.mjs +4 -2
- package/dist/internal/xchacha-core.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Aead.ts +35 -1
- package/src/Signature.ts +37 -4
- package/src/internal/aead.ts +97 -31
- package/src/internal/argon2.ts +13 -4
- package/src/internal/hmac.ts +15 -56
- package/src/internal/scoped-key.ts +60 -0
- package/src/internal/signature.ts +54 -0
- package/src/internal/xchacha-core.ts +6 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InvalidInput } from "../Errors.mjs";
|
|
2
|
-
import { PrivateKeyParameters, PublicKeyParameters, SignInput, Signature, VerifyInput } from "../Signature.mjs";
|
|
2
|
+
import { PrivateKeyInput, PrivateKeyParameters, PublicKeyInput, PublicKeyParameters, SignInput, Signature, VerifyInput } from "../Signature.mjs";
|
|
3
3
|
import { copy, decode, importError, nativeError, withSecret } from "./common.mjs";
|
|
4
|
+
import { makeScopedKey } from "./scoped-key.mjs";
|
|
4
5
|
import { Effect, Redacted, Schema } from "effect";
|
|
5
6
|
import { Base64Url } from "effect/encoding";
|
|
6
7
|
//#region src/internal/signature.ts
|
|
@@ -89,6 +90,36 @@ const makeSignature = (subtle) => {
|
|
|
89
90
|
return key;
|
|
90
91
|
});
|
|
91
92
|
return Signature.of({
|
|
93
|
+
importPrivateKey: Effect.fnUntraced(function* (input) {
|
|
94
|
+
const value = yield* decode(PrivateKeyInput, input, "key");
|
|
95
|
+
const algorithm = value.algorithm;
|
|
96
|
+
const use = yield* makeScopedKey(withSecret(value.privateKey, (material) => importKey(algorithm, "pkcs8", material)));
|
|
97
|
+
return { sign: Effect.fnUntraced(function* (input) {
|
|
98
|
+
const data = yield* decode(Schema.Uint8Array, input, "data").pipe(Effect.flatMap(copy));
|
|
99
|
+
const result = yield* use((key) => Effect.tryPromise({
|
|
100
|
+
try: () => subtle.sign(operationAlgorithm(algorithm), key, data),
|
|
101
|
+
catch: nativeError
|
|
102
|
+
}));
|
|
103
|
+
return new Uint8Array(result);
|
|
104
|
+
}) };
|
|
105
|
+
}),
|
|
106
|
+
importPublicKey: Effect.fnUntraced(function* (input) {
|
|
107
|
+
const value = yield* decode(PublicKeyInput, input, "key");
|
|
108
|
+
const algorithm = value.algorithm;
|
|
109
|
+
const material = yield* copy(value.publicKey);
|
|
110
|
+
const use = yield* makeScopedKey(importKey(algorithm, "spki", material));
|
|
111
|
+
return { verify: Effect.fnUntraced(function* (input, signature) {
|
|
112
|
+
const data = yield* decode(Schema.Uint8Array, input, "data").pipe(Effect.flatMap(copy));
|
|
113
|
+
const tag = yield* decode(Schema.Uint8Array, signature, "data").pipe(Effect.flatMap(copy));
|
|
114
|
+
return yield* use((key) => {
|
|
115
|
+
if ((algorithm === "ECDSA-P256-SHA256" || algorithm === "Ed25519") && tag.length !== 64) return Effect.succeed(false);
|
|
116
|
+
return Effect.tryPromise({
|
|
117
|
+
try: () => subtle.verify(operationAlgorithm(algorithm), key, tag, data),
|
|
118
|
+
catch: nativeError
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}) };
|
|
122
|
+
}),
|
|
92
123
|
encodePublicKey: Effect.fnUntraced(function* (input) {
|
|
93
124
|
const parameters = yield* decode(PublicKeyParameters, input, "key");
|
|
94
125
|
const key = yield* importComponents(parameters, "verify");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature.mjs","names":[],"sources":["../../src/internal/signature.ts"],"sourcesContent":["import { Effect, Redacted, Schema } from \"effect\";\nimport { Base64Url } from \"effect/encoding\";\n\nimport { InvalidInput } from \"../Errors\";\nimport {\n type Algorithm,\n PrivateKeyParameters,\n PublicKeyParameters,\n SignInput,\n Signature,\n VerifyInput,\n} from \"../Signature\";\nimport { copy, decode, importError, nativeError, withSecret } from \"./common\";\n\nconst derBytes = Schema.Uint8Array.check(Schema.isMinLength(1), Schema.isMaxLength(16384));\n\nconst RsaAlgorithm = Schema.Struct({\n modulusLength: Schema.Int.check(Schema.isGreaterThanOrEqualTo(2048)),\n});\n\nconst importAlgorithm = (algorithm: Algorithm) => {\n switch (algorithm) {\n case \"ECDSA-P256-SHA256\":\n return { name: \"ECDSA\", namedCurve: \"P-256\" };\n case \"RSA-PSS-SHA256\":\n return { name: \"RSA-PSS\", hash: \"SHA-256\" };\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n return { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" };\n case \"Ed25519\":\n return { name: \"Ed25519\" };\n }\n};\n\nconst operationAlgorithm = (algorithm: Algorithm) => {\n switch (algorithm) {\n case \"ECDSA-P256-SHA256\":\n return { name: \"ECDSA\", hash: \"SHA-256\" };\n case \"RSA-PSS-SHA256\":\n return { name: \"RSA-PSS\", saltLength: 32 };\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n return { name: \"RSASSA-PKCS1-v1_5\" };\n case \"Ed25519\":\n return { name: \"Ed25519\" };\n }\n};\n\nexport const makeSignature = (subtle: SubtleCrypto): Signature[\"Service\"] => {\n // JOSE owns JWK metadata and policy. The adapter translates validated raw\n // components through its platform key parser.\n const importComponents = Effect.fnUntraced(function* (\n parameters: PublicKeyParameters | PrivateKeyParameters,\n usage: \"sign\" | \"verify\",\n ) {\n let jwk: JsonWebKey;\n\n switch (parameters.algorithm) {\n case \"ECDSA-P256-SHA256\":\n jwk = {\n kty: \"EC\",\n crv: \"P-256\",\n x: Base64Url.encode(parameters.x),\n y: Base64Url.encode(parameters.y),\n };\n break;\n case \"Ed25519\":\n jwk = { kty: \"OKP\", crv: \"Ed25519\", x: Base64Url.encode(parameters.x) };\n break;\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\":\n jwk = { kty: \"RSA\", n: Base64Url.encode(parameters.n), e: Base64Url.encode(parameters.e) };\n if (\"p\" in parameters) {\n jwk.p = Base64Url.encode(parameters.p);\n jwk.q = Base64Url.encode(parameters.q);\n jwk.dp = Base64Url.encode(parameters.dp);\n jwk.dq = Base64Url.encode(parameters.dq);\n jwk.qi = Base64Url.encode(parameters.qi);\n }\n }\n if (\"d\" in parameters) jwk.d = Base64Url.encode(parameters.d);\n\n const key = yield* Effect.tryPromise({\n try: () => subtle.importKey(\"jwk\", jwk, importAlgorithm(parameters.algorithm), true, [usage]),\n catch: importError,\n });\n\n if (\n parameters.algorithm === \"RSA-PSS-SHA256\" ||\n parameters.algorithm === \"RSASSA-PKCS1-v1_5-SHA256\"\n ) {\n yield* Schema.decodeUnknownEffect(RsaAlgorithm)(key.algorithm).pipe(\n Effect.mapError(() => InvalidInput.make({ reason: \"key\" })),\n );\n }\n\n return key;\n });\n\n const importKey = Effect.fnUntraced(function* (\n algorithm: Algorithm,\n format: \"pkcs8\" | \"spki\",\n material: Uint8Array<ArrayBuffer>,\n ) {\n yield* decode(derBytes, material, \"key\");\n\n const key = yield* Effect.tryPromise({\n try: () =>\n subtle.importKey(format, material, importAlgorithm(algorithm), false, [\n format === \"pkcs8\" ? \"sign\" : \"verify\",\n ]),\n catch: importError,\n });\n\n if (algorithm === \"RSA-PSS-SHA256\" || algorithm === \"RSASSA-PKCS1-v1_5-SHA256\") {\n // The platform parsed this DER key. Validate its actual modulus, not caller metadata.\n yield* Schema.decodeUnknownEffect(RsaAlgorithm)(key.algorithm).pipe(\n Effect.mapError(() => InvalidInput.make({ reason: \"key\" })),\n );\n }\n\n return key;\n });\n\n return Signature.of({\n encodePublicKey: Effect.fnUntraced(function* (input) {\n const parameters = yield* decode(PublicKeyParameters, input, \"key\");\n const key = yield* importComponents(parameters, \"verify\");\n\n const encoded = yield* Effect.tryPromise({\n try: () => subtle.exportKey(\"spki\", key),\n catch: nativeError,\n });\n\n return new Uint8Array(encoded);\n }),\n encodePrivateKey: Effect.fnUntraced(function* (input) {\n const wrapped = yield* decode(\n Schema.Redacted(PrivateKeyParameters, { disallowJsonEncode: true }),\n input,\n \"key\",\n );\n\n const parameters = Redacted.value(wrapped);\n const key = yield* importComponents(parameters, \"sign\");\n\n const encoded = yield* Effect.tryPromise({\n try: () => subtle.exportKey(\"pkcs8\", key),\n catch: nativeError,\n });\n\n return Redacted.make(new Uint8Array(encoded));\n }),\n sign: Effect.fnUntraced(function* (input) {\n const value = yield* decode(SignInput, input, \"data\");\n const data = yield* copy(value.data);\n\n return yield* withSecret(value.privateKey, (material) =>\n Effect.gen(function* () {\n const key = yield* importKey(value.algorithm, \"pkcs8\", material);\n\n const result = yield* Effect.tryPromise({\n try: () => subtle.sign(operationAlgorithm(value.algorithm), key, data),\n catch: nativeError,\n });\n\n return new Uint8Array(result);\n }).pipe(Effect.uninterruptible),\n );\n }),\n verify: Effect.fnUntraced(function* (input) {\n const value = yield* decode(VerifyInput, input, \"data\");\n const material = yield* copy(value.publicKey);\n const data = yield* copy(value.data);\n const signature = yield* copy(value.signature);\n const key = yield* importKey(value.algorithm, \"spki\", material);\n\n if (\n (value.algorithm === \"ECDSA-P256-SHA256\" || value.algorithm === \"Ed25519\") &&\n signature.length !== 64\n )\n return false;\n\n return yield* Effect.tryPromise({\n try: () => subtle.verify(operationAlgorithm(value.algorithm), key, signature, data),\n catch: nativeError,\n });\n }),\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"signature.mjs","names":[],"sources":["../../src/internal/signature.ts"],"sourcesContent":["import { Effect, Redacted, Schema } from \"effect\";\nimport { Base64Url } from \"effect/encoding\";\n\nimport { InvalidInput } from \"../Errors\";\nimport {\n type Algorithm,\n type PrivateKey,\n PrivateKeyInput,\n PrivateKeyParameters,\n type PublicKey,\n PublicKeyInput,\n PublicKeyParameters,\n SignInput,\n Signature,\n VerifyInput,\n} from \"../Signature\";\nimport { copy, decode, importError, nativeError, withSecret } from \"./common\";\nimport { makeScopedKey } from \"./scoped-key\";\n\nconst derBytes = Schema.Uint8Array.check(Schema.isMinLength(1), Schema.isMaxLength(16384));\n\nconst RsaAlgorithm = Schema.Struct({\n modulusLength: Schema.Int.check(Schema.isGreaterThanOrEqualTo(2048)),\n});\n\nconst importAlgorithm = (algorithm: Algorithm) => {\n switch (algorithm) {\n case \"ECDSA-P256-SHA256\":\n return { name: \"ECDSA\", namedCurve: \"P-256\" };\n case \"RSA-PSS-SHA256\":\n return { name: \"RSA-PSS\", hash: \"SHA-256\" };\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n return { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" };\n case \"Ed25519\":\n return { name: \"Ed25519\" };\n }\n};\n\nconst operationAlgorithm = (algorithm: Algorithm) => {\n switch (algorithm) {\n case \"ECDSA-P256-SHA256\":\n return { name: \"ECDSA\", hash: \"SHA-256\" };\n case \"RSA-PSS-SHA256\":\n return { name: \"RSA-PSS\", saltLength: 32 };\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n return { name: \"RSASSA-PKCS1-v1_5\" };\n case \"Ed25519\":\n return { name: \"Ed25519\" };\n }\n};\n\nexport const makeSignature = (subtle: SubtleCrypto): Signature[\"Service\"] => {\n // JOSE owns JWK metadata and policy. The adapter translates validated raw\n // components through its platform key parser.\n const importComponents = Effect.fnUntraced(function* (\n parameters: PublicKeyParameters | PrivateKeyParameters,\n usage: \"sign\" | \"verify\",\n ) {\n let jwk: JsonWebKey;\n\n switch (parameters.algorithm) {\n case \"ECDSA-P256-SHA256\":\n jwk = {\n kty: \"EC\",\n crv: \"P-256\",\n x: Base64Url.encode(parameters.x),\n y: Base64Url.encode(parameters.y),\n };\n break;\n case \"Ed25519\":\n jwk = { kty: \"OKP\", crv: \"Ed25519\", x: Base64Url.encode(parameters.x) };\n break;\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\":\n jwk = { kty: \"RSA\", n: Base64Url.encode(parameters.n), e: Base64Url.encode(parameters.e) };\n if (\"p\" in parameters) {\n jwk.p = Base64Url.encode(parameters.p);\n jwk.q = Base64Url.encode(parameters.q);\n jwk.dp = Base64Url.encode(parameters.dp);\n jwk.dq = Base64Url.encode(parameters.dq);\n jwk.qi = Base64Url.encode(parameters.qi);\n }\n }\n if (\"d\" in parameters) jwk.d = Base64Url.encode(parameters.d);\n\n const key = yield* Effect.tryPromise({\n try: () => subtle.importKey(\"jwk\", jwk, importAlgorithm(parameters.algorithm), true, [usage]),\n catch: importError,\n });\n\n if (\n parameters.algorithm === \"RSA-PSS-SHA256\" ||\n parameters.algorithm === \"RSASSA-PKCS1-v1_5-SHA256\"\n ) {\n yield* Schema.decodeUnknownEffect(RsaAlgorithm)(key.algorithm).pipe(\n Effect.mapError(() => InvalidInput.make({ reason: \"key\" })),\n );\n }\n\n return key;\n });\n\n const importKey = Effect.fnUntraced(function* (\n algorithm: Algorithm,\n format: \"pkcs8\" | \"spki\",\n material: Uint8Array<ArrayBuffer>,\n ) {\n yield* decode(derBytes, material, \"key\");\n\n const key = yield* Effect.tryPromise({\n try: () =>\n subtle.importKey(format, material, importAlgorithm(algorithm), false, [\n format === \"pkcs8\" ? \"sign\" : \"verify\",\n ]),\n catch: importError,\n });\n\n if (algorithm === \"RSA-PSS-SHA256\" || algorithm === \"RSASSA-PKCS1-v1_5-SHA256\") {\n // The platform parsed this DER key. Validate its actual modulus, not caller metadata.\n yield* Schema.decodeUnknownEffect(RsaAlgorithm)(key.algorithm).pipe(\n Effect.mapError(() => InvalidInput.make({ reason: \"key\" })),\n );\n }\n\n return key;\n });\n\n return Signature.of({\n importPrivateKey: Effect.fnUntraced(function* (input) {\n const value = yield* decode(PrivateKeyInput, input, \"key\");\n const algorithm = value.algorithm;\n\n const use = yield* makeScopedKey(\n withSecret(value.privateKey, (material) => importKey(algorithm, \"pkcs8\", material)),\n );\n\n return {\n sign: Effect.fnUntraced(function* (input) {\n const data = yield* decode(Schema.Uint8Array, input, \"data\").pipe(Effect.flatMap(copy));\n\n const result = yield* use((key) =>\n Effect.tryPromise({\n try: () => subtle.sign(operationAlgorithm(algorithm), key, data),\n catch: nativeError,\n }),\n );\n\n return new Uint8Array(result);\n }),\n } satisfies PrivateKey;\n }),\n importPublicKey: Effect.fnUntraced(function* (input) {\n const value = yield* decode(PublicKeyInput, input, \"key\");\n const algorithm = value.algorithm;\n const material = yield* copy(value.publicKey);\n const use = yield* makeScopedKey(importKey(algorithm, \"spki\", material));\n\n return {\n verify: Effect.fnUntraced(function* (input, signature) {\n const data = yield* decode(Schema.Uint8Array, input, \"data\").pipe(Effect.flatMap(copy));\n\n const tag = yield* decode(Schema.Uint8Array, signature, \"data\").pipe(\n Effect.flatMap(copy),\n );\n\n return yield* use((key) => {\n if ((algorithm === \"ECDSA-P256-SHA256\" || algorithm === \"Ed25519\") && tag.length !== 64)\n return Effect.succeed(false);\n\n return Effect.tryPromise({\n try: () => subtle.verify(operationAlgorithm(algorithm), key, tag, data),\n catch: nativeError,\n });\n });\n }),\n } satisfies PublicKey;\n }),\n encodePublicKey: Effect.fnUntraced(function* (input) {\n const parameters = yield* decode(PublicKeyParameters, input, \"key\");\n const key = yield* importComponents(parameters, \"verify\");\n\n const encoded = yield* Effect.tryPromise({\n try: () => subtle.exportKey(\"spki\", key),\n catch: nativeError,\n });\n\n return new Uint8Array(encoded);\n }),\n encodePrivateKey: Effect.fnUntraced(function* (input) {\n const wrapped = yield* decode(\n Schema.Redacted(PrivateKeyParameters, { disallowJsonEncode: true }),\n input,\n \"key\",\n );\n\n const parameters = Redacted.value(wrapped);\n const key = yield* importComponents(parameters, \"sign\");\n\n const encoded = yield* Effect.tryPromise({\n try: () => subtle.exportKey(\"pkcs8\", key),\n catch: nativeError,\n });\n\n return Redacted.make(new Uint8Array(encoded));\n }),\n sign: Effect.fnUntraced(function* (input) {\n const value = yield* decode(SignInput, input, \"data\");\n const data = yield* copy(value.data);\n\n return yield* withSecret(value.privateKey, (material) =>\n Effect.gen(function* () {\n const key = yield* importKey(value.algorithm, \"pkcs8\", material);\n\n const result = yield* Effect.tryPromise({\n try: () => subtle.sign(operationAlgorithm(value.algorithm), key, data),\n catch: nativeError,\n });\n\n return new Uint8Array(result);\n }).pipe(Effect.uninterruptible),\n );\n }),\n verify: Effect.fnUntraced(function* (input) {\n const value = yield* decode(VerifyInput, input, \"data\");\n const material = yield* copy(value.publicKey);\n const data = yield* copy(value.data);\n const signature = yield* copy(value.signature);\n const key = yield* importKey(value.algorithm, \"spki\", material);\n\n if (\n (value.algorithm === \"ECDSA-P256-SHA256\" || value.algorithm === \"Ed25519\") &&\n signature.length !== 64\n )\n return false;\n\n return yield* Effect.tryPromise({\n try: () => subtle.verify(operationAlgorithm(value.algorithm), key, signature, data),\n catch: nativeError,\n });\n }),\n });\n};\n"],"mappings":"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"}
|
|
@@ -189,11 +189,13 @@ const readWords = (data, words) => {
|
|
|
189
189
|
function withState(key, nonce, operation) {
|
|
190
190
|
const original = /* @__PURE__ */ new Uint32Array(8);
|
|
191
191
|
const extendedNonce = /* @__PURE__ */ new Uint32Array(4);
|
|
192
|
+
const stream = /* @__PURE__ */ new Uint8Array(64);
|
|
192
193
|
const state = {
|
|
193
194
|
key: /* @__PURE__ */ new Uint32Array(8),
|
|
194
195
|
nonce: /* @__PURE__ */ new Uint32Array(3),
|
|
195
196
|
words: /* @__PURE__ */ new Uint32Array(16),
|
|
196
|
-
stream
|
|
197
|
+
stream,
|
|
198
|
+
streamView: new DataView(stream.buffer)
|
|
197
199
|
};
|
|
198
200
|
try {
|
|
199
201
|
readWords(key, original);
|
|
@@ -214,7 +216,7 @@ function withState(key, nonce, operation) {
|
|
|
214
216
|
}
|
|
215
217
|
const blockAt = (state, counter) => {
|
|
216
218
|
chachaCore(sigma, state.key, state.nonce, state.words, counter);
|
|
217
|
-
const view =
|
|
219
|
+
const view = state.streamView;
|
|
218
220
|
for (let i = 0; i < 16; i++) view.setUint32(i * 4, state.words[i], true);
|
|
219
221
|
};
|
|
220
222
|
const xor = (state, data, out) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xchacha-core.mjs","names":[],"sources":["../../src/internal/xchacha-core.ts"],"sourcesContent":["/**\n * Adapted from noble-ciphers, Copyright (c) 2022 Paul Miller.\n * MIT; source revision 785181b0772ba84afbe812025714163e4e48262f.\n * Poly1305 arithmetic derives from the public-domain poly1305-donna implementation.\n * See ../../THIRD_PARTY_NOTICES.md for source mapping and licenses.\n */\nimport { Poly1305 } from \"./poly1305\";\n\nconst rotl = (word: number, shift: number): number => (word << shift) | (word >>> (32 - shift));\n\nfunction chachaCore(\n s: Uint32Array,\n k: Uint32Array,\n n: Uint32Array,\n out: Uint32Array,\n cnt: number,\n rounds = 20,\n): void {\n let y00 = s[0],\n y01 = s[1],\n y02 = s[2],\n y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0],\n y05 = k[1],\n y06 = k[2],\n y07 = k[3], // Key Key Key Key\n y08 = k[4],\n y09 = k[5],\n y10 = k[6],\n y11 = k[7], // Key Key Key Key\n y12 = cnt,\n y13 = n[0],\n y14 = n[1],\n y15 = n[2]; // Counter Counter\tNonce Nonce\n\n // Save state to temporary variables\n let x00 = y00,\n x01 = y01,\n x02 = y02,\n x03 = y03,\n x04 = y04,\n x05 = y05,\n x06 = y06,\n x07 = y07,\n x08 = y08,\n x09 = y09,\n x10 = y10,\n x11 = y11,\n x12 = y12,\n x13 = y13,\n x14 = y14,\n x15 = y15;\n\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n // Write output\n let oi = 0;\n\n out[oi++] = (y00 + x00) | 0;\n out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0;\n out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0;\n out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0;\n out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0;\n out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0;\n out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0;\n out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0;\n out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha hashes key and nonce into key' and nonce' for xchacha20.\n */\nfunction hchacha(s: Uint32Array, k: Uint32Array, i: Uint32Array, out: Uint32Array): void {\n let x00 = s[0],\n x01 = s[1],\n x02 = s[2],\n x03 = s[3],\n x04 = k[0],\n x05 = k[1],\n x06 = k[2],\n x07 = k[3],\n x08 = k[4],\n x09 = k[5],\n x10 = k[6],\n x11 = k[7],\n x12 = i[0],\n x13 = i[1],\n x14 = i[2],\n x15 = i[3];\n\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n let oi = 0;\n\n out[oi++] = x00;\n out[oi++] = x01;\n out[oi++] = x02;\n out[oi++] = x03;\n out[oi++] = x12;\n out[oi++] = x13;\n out[oi++] = x14;\n out[oi++] = x15;\n}\n\nconst sigma = Uint32Array.from([0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]);\nconst padding = new Uint8Array(16);\n\ninterface State {\n readonly key: Uint32Array;\n readonly nonce: Uint32Array;\n readonly words: Uint32Array;\n readonly stream: Uint8Array;\n}\n\nconst readWords = (data: Uint8Array, words: Uint32Array): void => {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n for (let i = 0; i < words.length; i++) words[i] = view.getUint32(i * 4, true);\n};\n\nfunction withState<A>(key: Uint8Array, nonce: Uint8Array, operation: (state: State) => A): A {\n const original = new Uint32Array(8);\n const extendedNonce = new Uint32Array(4);\n\n const state: State = {\n key: new Uint32Array(8),\n nonce: new Uint32Array(3),\n words: new Uint32Array(16),\n stream: new Uint8Array(64),\n };\n\n try {\n readWords(key, original);\n readWords(nonce.subarray(0, 16), extendedNonce);\n hchacha(sigma, original, extendedNonce, state.key);\n // XChaCha uses HChaCha(key, nonce[0..16]), then 0 || nonce[16..24].\n const view = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);\n\n state.nonce[1] = view.getUint32(16, true);\n state.nonce[2] = view.getUint32(20, true);\n\n return operation(state);\n } finally {\n original.fill(0);\n extendedNonce.fill(0);\n state.key.fill(0);\n state.nonce.fill(0);\n state.words.fill(0);\n state.stream.fill(0);\n }\n}\n\nconst blockAt = (state: State, counter: number): void => {\n chachaCore(sigma, state.key, state.nonce, state.words, counter);\n const view = new DataView(state.stream.buffer, state.stream.byteOffset, state.stream.byteLength);\n\n for (let i = 0; i < 16; i++) view.setUint32(i * 4, state.words[i], true);\n};\n\nconst xor = (state: State, data: Uint8Array, out: Uint8Array): void => {\n for (let offset = 0, counter = 1; offset < data.length; offset += 64, counter++) {\n blockAt(state, counter);\n const length = Math.min(64, data.length - offset);\n\n for (let i = 0; i < length; i++) out[offset + i] = data[offset + i] ^ state.stream[i];\n }\n};\n\nconst padded = (mac: Poly1305, data: Uint8Array): void => {\n mac.update(data);\n const remainder = data.length % 16;\n\n if (remainder !== 0) mac.update(padding.subarray(remainder));\n};\n\nconst tag = (state: State, ciphertext: Uint8Array, additionalData: Uint8Array): Uint8Array => {\n const lengths = new Uint8Array(16);\n const view = new DataView(lengths.buffer);\n\n // RFC 8439 authenticates little-endian 64-bit byte lengths, AAD first.\n view.setUint32(0, additionalData.length >>> 0, true);\n view.setUint32(4, Math.floor(additionalData.length / 0x100000000), true);\n view.setUint32(8, ciphertext.length >>> 0, true);\n view.setUint32(12, Math.floor(ciphertext.length / 0x100000000), true);\n blockAt(state, 0);\n const mac = new Poly1305(state.stream.subarray(0, 32));\n\n try {\n padded(mac, additionalData);\n padded(mac, ciphertext);\n\n return mac.update(lengths).digest();\n } finally {\n mac.destroy();\n lengths.fill(0);\n state.stream.fill(0);\n }\n};\n\nexport const encrypt = (\n key: Uint8Array,\n nonce: Uint8Array,\n additionalData: Uint8Array,\n plaintext: Uint8Array,\n): Uint8Array =>\n withState(key, nonce, (state) => {\n const out = new Uint8Array(plaintext.length + 16);\n const ciphertext = out.subarray(0, plaintext.length);\n\n try {\n xor(state, plaintext, ciphertext);\n const authentication = tag(state, ciphertext, additionalData);\n\n out.set(authentication, plaintext.length);\n authentication.fill(0);\n\n return out;\n } catch (error) {\n out.fill(0);\n throw error;\n }\n });\n\n/** Authenticate the complete input before allocating or producing plaintext. */\nexport const decrypt = (\n key: Uint8Array,\n nonce: Uint8Array,\n additionalData: Uint8Array,\n sealed: Uint8Array,\n): Uint8Array | undefined =>\n withState(key, nonce, (state) => {\n const ciphertext = sealed.subarray(0, -16);\n const authentication = tag(state, ciphertext, additionalData);\n let difference = 0;\n\n for (let i = 0; i < 16; i++) difference |= authentication[i] ^ sealed[ciphertext.length + i];\n authentication.fill(0);\n if (difference !== 0) return undefined;\n const out = new Uint8Array(ciphertext.length);\n\n try {\n xor(state, ciphertext, out);\n\n return out;\n } catch (error) {\n out.fill(0);\n throw error;\n }\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xchacha-core.mjs","names":[],"sources":["../../src/internal/xchacha-core.ts"],"sourcesContent":["/**\n * Adapted from noble-ciphers, Copyright (c) 2022 Paul Miller.\n * MIT; source revision 785181b0772ba84afbe812025714163e4e48262f.\n * Poly1305 arithmetic derives from the public-domain poly1305-donna implementation.\n * See ../../THIRD_PARTY_NOTICES.md for source mapping and licenses.\n */\nimport { Poly1305 } from \"./poly1305\";\n\nconst rotl = (word: number, shift: number): number => (word << shift) | (word >>> (32 - shift));\n\nfunction chachaCore(\n s: Uint32Array,\n k: Uint32Array,\n n: Uint32Array,\n out: Uint32Array,\n cnt: number,\n rounds = 20,\n): void {\n let y00 = s[0],\n y01 = s[1],\n y02 = s[2],\n y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0],\n y05 = k[1],\n y06 = k[2],\n y07 = k[3], // Key Key Key Key\n y08 = k[4],\n y09 = k[5],\n y10 = k[6],\n y11 = k[7], // Key Key Key Key\n y12 = cnt,\n y13 = n[0],\n y14 = n[1],\n y15 = n[2]; // Counter Counter\tNonce Nonce\n\n // Save state to temporary variables\n let x00 = y00,\n x01 = y01,\n x02 = y02,\n x03 = y03,\n x04 = y04,\n x05 = y05,\n x06 = y06,\n x07 = y07,\n x08 = y08,\n x09 = y09,\n x10 = y10,\n x11 = y11,\n x12 = y12,\n x13 = y13,\n x14 = y14,\n x15 = y15;\n\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n // Write output\n let oi = 0;\n\n out[oi++] = (y00 + x00) | 0;\n out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0;\n out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0;\n out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0;\n out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0;\n out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0;\n out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0;\n out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0;\n out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha hashes key and nonce into key' and nonce' for xchacha20.\n */\nfunction hchacha(s: Uint32Array, k: Uint32Array, i: Uint32Array, out: Uint32Array): void {\n let x00 = s[0],\n x01 = s[1],\n x02 = s[2],\n x03 = s[3],\n x04 = k[0],\n x05 = k[1],\n x06 = k[2],\n x07 = k[3],\n x08 = k[4],\n x09 = k[5],\n x10 = k[6],\n x11 = k[7],\n x12 = i[0],\n x13 = i[1],\n x14 = i[2],\n x15 = i[3];\n\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0;\n x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0;\n x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0;\n x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0;\n x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0;\n x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0;\n x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0;\n x15 = rotl(x15 ^ x03, 8);\n x11 = (x11 + x15) | 0;\n x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0;\n x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0;\n x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0;\n x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0;\n x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0;\n x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0;\n x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 16);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0;\n x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0;\n x04 = rotl(x04 ^ x09, 7);\n }\n let oi = 0;\n\n out[oi++] = x00;\n out[oi++] = x01;\n out[oi++] = x02;\n out[oi++] = x03;\n out[oi++] = x12;\n out[oi++] = x13;\n out[oi++] = x14;\n out[oi++] = x15;\n}\n\nconst sigma = Uint32Array.from([0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]);\nconst padding = new Uint8Array(16);\n\ninterface State {\n readonly key: Uint32Array;\n readonly nonce: Uint32Array;\n readonly words: Uint32Array;\n readonly stream: Uint8Array;\n readonly streamView: DataView;\n}\n\nconst readWords = (data: Uint8Array, words: Uint32Array): void => {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n for (let i = 0; i < words.length; i++) words[i] = view.getUint32(i * 4, true);\n};\n\nfunction withState<A>(key: Uint8Array, nonce: Uint8Array, operation: (state: State) => A): A {\n const original = new Uint32Array(8);\n const extendedNonce = new Uint32Array(4);\n\n const stream = new Uint8Array(64);\n\n const state: State = {\n key: new Uint32Array(8),\n nonce: new Uint32Array(3),\n words: new Uint32Array(16),\n stream,\n streamView: new DataView(stream.buffer),\n };\n\n try {\n readWords(key, original);\n readWords(nonce.subarray(0, 16), extendedNonce);\n hchacha(sigma, original, extendedNonce, state.key);\n // XChaCha uses HChaCha(key, nonce[0..16]), then 0 || nonce[16..24].\n const view = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);\n\n state.nonce[1] = view.getUint32(16, true);\n state.nonce[2] = view.getUint32(20, true);\n\n return operation(state);\n } finally {\n original.fill(0);\n extendedNonce.fill(0);\n state.key.fill(0);\n state.nonce.fill(0);\n state.words.fill(0);\n state.stream.fill(0);\n }\n}\n\nconst blockAt = (state: State, counter: number): void => {\n chachaCore(sigma, state.key, state.nonce, state.words, counter);\n const view = state.streamView;\n\n for (let i = 0; i < 16; i++) view.setUint32(i * 4, state.words[i], true);\n};\n\nconst xor = (state: State, data: Uint8Array, out: Uint8Array): void => {\n for (let offset = 0, counter = 1; offset < data.length; offset += 64, counter++) {\n blockAt(state, counter);\n const length = Math.min(64, data.length - offset);\n\n for (let i = 0; i < length; i++) out[offset + i] = data[offset + i] ^ state.stream[i];\n }\n};\n\nconst padded = (mac: Poly1305, data: Uint8Array): void => {\n mac.update(data);\n const remainder = data.length % 16;\n\n if (remainder !== 0) mac.update(padding.subarray(remainder));\n};\n\nconst tag = (state: State, ciphertext: Uint8Array, additionalData: Uint8Array): Uint8Array => {\n const lengths = new Uint8Array(16);\n const view = new DataView(lengths.buffer);\n\n // RFC 8439 authenticates little-endian 64-bit byte lengths, AAD first.\n view.setUint32(0, additionalData.length >>> 0, true);\n view.setUint32(4, Math.floor(additionalData.length / 0x100000000), true);\n view.setUint32(8, ciphertext.length >>> 0, true);\n view.setUint32(12, Math.floor(ciphertext.length / 0x100000000), true);\n blockAt(state, 0);\n const mac = new Poly1305(state.stream.subarray(0, 32));\n\n try {\n padded(mac, additionalData);\n padded(mac, ciphertext);\n\n return mac.update(lengths).digest();\n } finally {\n mac.destroy();\n lengths.fill(0);\n state.stream.fill(0);\n }\n};\n\nexport const encrypt = (\n key: Uint8Array,\n nonce: Uint8Array,\n additionalData: Uint8Array,\n plaintext: Uint8Array,\n): Uint8Array =>\n withState(key, nonce, (state) => {\n const out = new Uint8Array(plaintext.length + 16);\n const ciphertext = out.subarray(0, plaintext.length);\n\n try {\n xor(state, plaintext, ciphertext);\n const authentication = tag(state, ciphertext, additionalData);\n\n out.set(authentication, plaintext.length);\n authentication.fill(0);\n\n return out;\n } catch (error) {\n out.fill(0);\n throw error;\n }\n });\n\n/** Authenticate the complete input before allocating or producing plaintext. */\nexport const decrypt = (\n key: Uint8Array,\n nonce: Uint8Array,\n additionalData: Uint8Array,\n sealed: Uint8Array,\n): Uint8Array | undefined =>\n withState(key, nonce, (state) => {\n const ciphertext = sealed.subarray(0, -16);\n const authentication = tag(state, ciphertext, additionalData);\n let difference = 0;\n\n for (let i = 0; i < 16; i++) difference |= authentication[i] ^ sealed[ciphertext.length + i];\n authentication.fill(0);\n if (difference !== 0) return undefined;\n const out = new Uint8Array(ciphertext.length);\n\n try {\n xor(state, ciphertext, out);\n\n return out;\n } catch (error) {\n out.fill(0);\n throw error;\n }\n });\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@yielded/crypto","version":"0.1.0-beta.
|
|
1
|
+
{"name":"@yielded/crypto","version":"0.1.0-beta.29","devDependencies":{"@effect/vitest":"4.0.0","@types/node":"26.1.2","effect":"4.0.0","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Aead":{"types":"./dist/Aead.d.mts","default":"./dist/Aead.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Hmac":{"types":"./dist/Hmac.d.mts","default":"./dist/Hmac.mjs"},"./Kdf":{"types":"./dist/Kdf.d.mts","default":"./dist/Kdf.mjs"},"./KdfAdmission":{"types":"./dist/KdfAdmission.d.mts","default":"./dist/KdfAdmission.mjs"},"./Signature":{"types":"./dist/Signature.d.mts","default":"./dist/Signature.mjs"},"./WebCrypto":{"types":"./dist/WebCrypto.d.mts","default":"./dist/WebCrypto.mjs"},"./platform-node":{"types":"./dist/platform-node.d.mts","default":"./dist/platform-node.mjs"},"./platform-bun":{"types":"./dist/platform-bun.d.mts","default":"./dist/platform-bun.mjs"},"./Portable":{"types":"./dist/Portable.d.mts","default":"./dist/Portable.mjs"}},"description":"Effect cryptography services with explicit native and portable backends.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/crypto"},"files":["dist","src","THIRD_PARTY_NOTICES.md"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
|
package/src/Aead.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context, type Effect, type Redacted, Schema } from "effect";
|
|
1
|
+
import { Context, type Effect, type Redacted, Schema, type Scope } from "effect";
|
|
2
2
|
|
|
3
3
|
import type { AuthenticationFailed, OperationError } from "./Errors";
|
|
4
4
|
|
|
@@ -22,6 +22,38 @@ export type EncryptInput = typeof EncryptInput.Type;
|
|
|
22
22
|
export const DecryptInput = Schema.Struct({ ...context, ciphertext: Schema.Uint8Array });
|
|
23
23
|
export type DecryptInput = typeof DecryptInput.Type;
|
|
24
24
|
|
|
25
|
+
/** Native AES keys can be imported once for repeated encryption and decryption. */
|
|
26
|
+
export const KeyInput = Schema.Struct({
|
|
27
|
+
algorithm: Schema.Literal("AES-256-GCM"),
|
|
28
|
+
key: context.key,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type KeyInput = typeof KeyInput.Type;
|
|
32
|
+
|
|
33
|
+
export const KeyEncryptInput = Schema.Struct({
|
|
34
|
+
nonce: context.nonce,
|
|
35
|
+
additionalData: context.additionalData,
|
|
36
|
+
plaintext: EncryptInput.fields.plaintext,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export type KeyEncryptInput = typeof KeyEncryptInput.Type;
|
|
40
|
+
|
|
41
|
+
export const KeyDecryptInput = Schema.Struct({
|
|
42
|
+
nonce: context.nonce,
|
|
43
|
+
additionalData: context.additionalData,
|
|
44
|
+
ciphertext: DecryptInput.fields.ciphertext,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export type KeyDecryptInput = typeof KeyDecryptInput.Type;
|
|
48
|
+
|
|
49
|
+
/** A nonextractable AES-256-GCM key owned by the import's Scope. */
|
|
50
|
+
export interface Key {
|
|
51
|
+
readonly encrypt: (input: KeyEncryptInput) => Effect.Effect<Uint8Array, OperationError>;
|
|
52
|
+
readonly decrypt: (
|
|
53
|
+
input: KeyDecryptInput,
|
|
54
|
+
) => Effect.Effect<Redacted.Redacted<Uint8Array>, OperationError | AuthenticationFailed>;
|
|
55
|
+
}
|
|
56
|
+
|
|
25
57
|
/**
|
|
26
58
|
* Both algorithms use a 32-byte key and append a 16-byte tag to ciphertext.
|
|
27
59
|
* AES-GCM uses a 12-byte nonce; XChaCha uses 24. The caller MUST supply a unique
|
|
@@ -31,6 +63,8 @@ export type DecryptInput = typeof DecryptInput.Type;
|
|
|
31
63
|
export class Aead extends Context.Service<
|
|
32
64
|
Aead,
|
|
33
65
|
{
|
|
66
|
+
/** Snapshot once; scope closure joins native work and rejects later use. */
|
|
67
|
+
readonly importKey: (input: KeyInput) => Effect.Effect<Key, OperationError, Scope.Scope>;
|
|
34
68
|
readonly encrypt: (input: EncryptInput) => Effect.Effect<Uint8Array, OperationError>;
|
|
35
69
|
readonly decrypt: (
|
|
36
70
|
input: DecryptInput,
|
package/src/Signature.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context, type Effect, type Redacted, Schema } from "effect";
|
|
1
|
+
import { Context, type Effect, type Redacted, Schema, type Scope } from "effect";
|
|
2
2
|
|
|
3
3
|
import type { OperationError } from "./Errors";
|
|
4
4
|
|
|
@@ -50,23 +50,48 @@ export const PrivateKeyParameters = Schema.Union([
|
|
|
50
50
|
|
|
51
51
|
export type PrivateKeyParameters = typeof PrivateKeyParameters.Type;
|
|
52
52
|
|
|
53
|
-
export const
|
|
53
|
+
export const PrivateKeyInput = Schema.Struct({
|
|
54
54
|
algorithm: Algorithm,
|
|
55
55
|
privateKey: Schema.Redacted(Schema.Uint8Array, { disallowJsonEncode: true }),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export type PrivateKeyInput = typeof PrivateKeyInput.Type;
|
|
59
|
+
|
|
60
|
+
export const PublicKeyInput = Schema.Struct({
|
|
61
|
+
algorithm: Algorithm,
|
|
62
|
+
publicKey: Schema.Uint8Array,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export type PublicKeyInput = typeof PublicKeyInput.Type;
|
|
66
|
+
|
|
67
|
+
export const SignInput = Schema.Struct({
|
|
68
|
+
...PrivateKeyInput.fields,
|
|
56
69
|
data: Schema.Uint8Array,
|
|
57
70
|
});
|
|
58
71
|
|
|
59
72
|
export type SignInput = typeof SignInput.Type;
|
|
60
73
|
|
|
61
74
|
export const VerifyInput = Schema.Struct({
|
|
62
|
-
|
|
63
|
-
publicKey: Schema.Uint8Array,
|
|
75
|
+
...PublicKeyInput.fields,
|
|
64
76
|
data: Schema.Uint8Array,
|
|
65
77
|
signature: Schema.Uint8Array,
|
|
66
78
|
});
|
|
67
79
|
|
|
68
80
|
export type VerifyInput = typeof VerifyInput.Type;
|
|
69
81
|
|
|
82
|
+
/** A nonextractable signing key with its algorithm fixed at import. */
|
|
83
|
+
export interface PrivateKey {
|
|
84
|
+
readonly sign: (data: Uint8Array) => Effect.Effect<Uint8Array, OperationError>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** A verification key with its algorithm fixed at import. */
|
|
88
|
+
export interface PublicKey {
|
|
89
|
+
readonly verify: (
|
|
90
|
+
data: Uint8Array,
|
|
91
|
+
signature: Uint8Array,
|
|
92
|
+
) => Effect.Effect<boolean, OperationError>;
|
|
93
|
+
}
|
|
94
|
+
|
|
70
95
|
/**
|
|
71
96
|
* Private keys are PKCS8 DER; public keys are SPKI DER. ECDSA signatures are
|
|
72
97
|
* 64-byte IEEE P1363 (r || s), not ASN.1 DER. RSA requires at least 2048 bits;
|
|
@@ -75,6 +100,14 @@ export type VerifyInput = typeof VerifyInput.Type;
|
|
|
75
100
|
export class Signature extends Context.Service<
|
|
76
101
|
Signature,
|
|
77
102
|
{
|
|
103
|
+
/** Snapshot PKCS8 once; the imported key is usable only inside its owning Scope. */
|
|
104
|
+
readonly importPrivateKey: (
|
|
105
|
+
input: PrivateKeyInput,
|
|
106
|
+
) => Effect.Effect<PrivateKey, OperationError, Scope.Scope>;
|
|
107
|
+
/** Snapshot SPKI once; scope closure joins native work and rejects later use. */
|
|
108
|
+
readonly importPublicKey: (
|
|
109
|
+
input: PublicKeyInput,
|
|
110
|
+
) => Effect.Effect<PublicKey, OperationError, Scope.Scope>;
|
|
78
111
|
readonly encodePublicKey: (
|
|
79
112
|
input: PublicKeyParameters,
|
|
80
113
|
) => Effect.Effect<Uint8Array, OperationError>;
|
package/src/internal/aead.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import { Effect, Redacted, Schema } from "effect";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Aead,
|
|
5
|
+
DecryptInput,
|
|
6
|
+
EncryptInput,
|
|
7
|
+
type Key,
|
|
8
|
+
KeyDecryptInput,
|
|
9
|
+
KeyEncryptInput,
|
|
10
|
+
KeyInput,
|
|
11
|
+
} from "../Aead";
|
|
4
12
|
import { AuthenticationFailed, type OperationError, UnsupportedAlgorithm } from "../Errors";
|
|
5
13
|
import { copy, decode, importError, nativeError, nativeErrorName, withSecret } from "./common";
|
|
14
|
+
import { makeScopedKey } from "./scoped-key";
|
|
6
15
|
|
|
7
|
-
interface
|
|
8
|
-
readonly key: Uint8Array<ArrayBuffer>;
|
|
16
|
+
interface CipherData {
|
|
9
17
|
readonly nonce: Uint8Array<ArrayBuffer>;
|
|
10
18
|
readonly additionalData: Uint8Array<ArrayBuffer>;
|
|
11
19
|
readonly data: Uint8Array<ArrayBuffer>;
|
|
12
20
|
}
|
|
13
21
|
|
|
22
|
+
interface CipherInput extends CipherData {
|
|
23
|
+
readonly key: Uint8Array<ArrayBuffer>;
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
export interface XChaCha {
|
|
15
27
|
readonly encrypt: (input: CipherInput) => Effect.Effect<Uint8Array, OperationError>;
|
|
16
28
|
readonly decrypt: (
|
|
@@ -19,9 +31,86 @@ export interface XChaCha {
|
|
|
19
31
|
}
|
|
20
32
|
|
|
21
33
|
const keyBytes = Schema.Uint8Array.check(Schema.isBetweenLength(32, 32));
|
|
34
|
+
const aesNonce = Schema.Uint8Array.check(Schema.isBetweenLength(12, 12));
|
|
35
|
+
|
|
36
|
+
export const makeAead = (subtle: SubtleCrypto, xchacha?: XChaCha): Aead["Service"] => {
|
|
37
|
+
const encryptAes = (key: CryptoKey, input: CipherData) =>
|
|
38
|
+
Effect.tryPromise({
|
|
39
|
+
try: () =>
|
|
40
|
+
subtle.encrypt(
|
|
41
|
+
{
|
|
42
|
+
name: "AES-GCM",
|
|
43
|
+
iv: input.nonce,
|
|
44
|
+
additionalData: input.additionalData,
|
|
45
|
+
tagLength: 128,
|
|
46
|
+
},
|
|
47
|
+
key,
|
|
48
|
+
input.data,
|
|
49
|
+
),
|
|
50
|
+
catch: nativeError,
|
|
51
|
+
}).pipe(Effect.map((encrypted) => new Uint8Array(encrypted)));
|
|
52
|
+
|
|
53
|
+
const decryptAes = (key: CryptoKey, input: CipherData) =>
|
|
54
|
+
Effect.tryPromise({
|
|
55
|
+
try: () =>
|
|
56
|
+
subtle.decrypt(
|
|
57
|
+
{
|
|
58
|
+
name: "AES-GCM",
|
|
59
|
+
iv: input.nonce,
|
|
60
|
+
additionalData: input.additionalData,
|
|
61
|
+
tagLength: 128,
|
|
62
|
+
},
|
|
63
|
+
key,
|
|
64
|
+
input.data,
|
|
65
|
+
),
|
|
66
|
+
// WebCrypto specifies OperationError for a rejected GCM tag.
|
|
67
|
+
catch: (cause) =>
|
|
68
|
+
nativeErrorName(cause) === "OperationError"
|
|
69
|
+
? AuthenticationFailed.make({})
|
|
70
|
+
: nativeError(cause),
|
|
71
|
+
}).pipe(Effect.map((decrypted) => new Uint8Array(decrypted)));
|
|
72
|
+
|
|
73
|
+
return Aead.of({
|
|
74
|
+
importKey: Effect.fnUntraced(function* (input) {
|
|
75
|
+
const value = yield* decode(KeyInput, input, "key");
|
|
76
|
+
|
|
77
|
+
yield* decode(keyBytes, Redacted.value(value.key), "key");
|
|
78
|
+
|
|
79
|
+
const use = yield* makeScopedKey(
|
|
80
|
+
withSecret(value.key, (material) =>
|
|
81
|
+
Effect.tryPromise({
|
|
82
|
+
try: () => subtle.importKey("raw", material, "AES-GCM", false, ["encrypt", "decrypt"]),
|
|
83
|
+
catch: importError,
|
|
84
|
+
}),
|
|
85
|
+
),
|
|
86
|
+
);
|
|
22
87
|
|
|
23
|
-
|
|
24
|
-
|
|
88
|
+
return {
|
|
89
|
+
encrypt: Effect.fnUntraced(function* (input) {
|
|
90
|
+
const value = yield* decode(KeyEncryptInput, input, "data");
|
|
91
|
+
const nonce = yield* decode(aesNonce, value.nonce, "nonce").pipe(Effect.flatMap(copy));
|
|
92
|
+
const additionalData = yield* copy(value.additionalData ?? new Uint8Array());
|
|
93
|
+
|
|
94
|
+
return yield* withSecret(value.plaintext, (data) =>
|
|
95
|
+
use((key) => encryptAes(key, { nonce, additionalData, data })),
|
|
96
|
+
);
|
|
97
|
+
}),
|
|
98
|
+
decrypt: Effect.fnUntraced(function* (input) {
|
|
99
|
+
const value = yield* decode(KeyDecryptInput, input, "data");
|
|
100
|
+
const nonce = yield* decode(aesNonce, value.nonce, "nonce").pipe(Effect.flatMap(copy));
|
|
101
|
+
const additionalData = yield* copy(value.additionalData ?? new Uint8Array());
|
|
102
|
+
const data = yield* copy(value.ciphertext);
|
|
103
|
+
|
|
104
|
+
const plaintext = yield* use((key) =>
|
|
105
|
+
data.length < 16
|
|
106
|
+
? Effect.fail(AuthenticationFailed.make({}))
|
|
107
|
+
: decryptAes(key, { nonce, additionalData, data }),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return Redacted.make(plaintext);
|
|
111
|
+
}),
|
|
112
|
+
} satisfies Key;
|
|
113
|
+
}),
|
|
25
114
|
encrypt: Effect.fnUntraced(function* (input) {
|
|
26
115
|
const value = yield* decode(EncryptInput, input, "data");
|
|
27
116
|
const nonceLength = value.algorithm === "AES-256-GCM" ? 12 : 24;
|
|
@@ -51,17 +140,7 @@ export const makeAead = (subtle: SubtleCrypto, xchacha?: XChaCha): Aead["Service
|
|
|
51
140
|
catch: importError,
|
|
52
141
|
});
|
|
53
142
|
|
|
54
|
-
|
|
55
|
-
try: () =>
|
|
56
|
-
subtle.encrypt(
|
|
57
|
-
{ name: "AES-GCM", iv: nonce, additionalData, tagLength: 128 },
|
|
58
|
-
imported,
|
|
59
|
-
data,
|
|
60
|
-
),
|
|
61
|
-
catch: nativeError,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return new Uint8Array(encrypted);
|
|
143
|
+
return yield* encryptAes(imported, { nonce, additionalData, data });
|
|
65
144
|
}).pipe(Effect.uninterruptible);
|
|
66
145
|
}),
|
|
67
146
|
);
|
|
@@ -96,24 +175,11 @@ export const makeAead = (subtle: SubtleCrypto, xchacha?: XChaCha): Aead["Service
|
|
|
96
175
|
catch: importError,
|
|
97
176
|
});
|
|
98
177
|
|
|
99
|
-
|
|
100
|
-
try: () =>
|
|
101
|
-
subtle.decrypt(
|
|
102
|
-
{ name: "AES-GCM", iv: nonce, additionalData, tagLength: 128 },
|
|
103
|
-
imported,
|
|
104
|
-
data,
|
|
105
|
-
),
|
|
106
|
-
// WebCrypto specifies OperationError for a rejected GCM tag.
|
|
107
|
-
catch: (cause) =>
|
|
108
|
-
nativeErrorName(cause) === "OperationError"
|
|
109
|
-
? AuthenticationFailed.make({})
|
|
110
|
-
: nativeError(cause),
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
return new Uint8Array(decrypted);
|
|
178
|
+
return yield* decryptAes(imported, { nonce, additionalData, data });
|
|
114
179
|
}).pipe(Effect.uninterruptible);
|
|
115
180
|
});
|
|
116
181
|
|
|
117
182
|
return Redacted.make(plaintext);
|
|
118
183
|
}),
|
|
119
184
|
});
|
|
185
|
+
};
|
package/src/internal/argon2.ts
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
2
|
|
|
3
3
|
import { allocate, destroy, fill, initialize, output } from "./argon2-core";
|
|
4
4
|
import type { Argon2 } from "./kdf";
|
|
5
5
|
|
|
6
|
-
/** Effect schedules
|
|
6
|
+
/** Effect schedules time slices; admission remains held through buffer cleanup. */
|
|
7
7
|
export const argon2: Argon2 = (input) =>
|
|
8
8
|
Effect.acquireUseRelease(
|
|
9
9
|
Effect.sync(() => allocate(input)),
|
|
10
10
|
(state) =>
|
|
11
11
|
Effect.gen(function* () {
|
|
12
|
+
const clock = yield* Clock.Clock;
|
|
13
|
+
|
|
12
14
|
initialize(state, input);
|
|
13
15
|
const blocks = fill(state, input);
|
|
14
16
|
|
|
15
17
|
for (;;) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const started = clock.monotonicTimeNanosUnsafe();
|
|
19
|
+
|
|
20
|
+
// Workers freeze clocks during CPU work. Cap each slice as well so
|
|
21
|
+
// interruption and other fibers still get a turn on those runtimes.
|
|
22
|
+
for (let processed = 0; processed < 2048; processed += 256) {
|
|
23
|
+
for (let batch = 0; batch < 256; batch++) {
|
|
24
|
+
if (blocks.next().done) return output(state, input);
|
|
25
|
+
}
|
|
26
|
+
if (clock.monotonicTimeNanosUnsafe() - started >= 8_000_000n) break;
|
|
18
27
|
}
|
|
19
28
|
yield* Effect.yieldNow;
|
|
20
29
|
}
|