@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.
@@ -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":";;;;;;AAcA,MAAM,WAAW,OAAO,WAAW,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,KAAK,CAAC;AAEzF,MAAM,eAAe,OAAO,OAAO,EACjC,eAAe,OAAO,IAAI,MAAM,OAAO,uBAAuB,IAAI,CAAC,EACrE,CAAC;AAED,MAAM,mBAAmB,cAAyB;CAChD,QAAQ,WAAR;EACE,KAAK,qBACH,OAAO;GAAE,MAAM;GAAS,YAAY;EAAQ;EAC9C,KAAK,kBACH,OAAO;GAAE,MAAM;GAAW,MAAM;EAAU;EAC5C,KAAK,4BACH,OAAO;GAAE,MAAM;GAAqB,MAAM;EAAU;EACtD,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,MAAM,sBAAsB,cAAyB;CACnD,QAAQ,WAAR;EACE,KAAK,qBACH,OAAO;GAAE,MAAM;GAAS,MAAM;EAAU;EAC1C,KAAK,kBACH,OAAO;GAAE,MAAM;GAAW,YAAY;EAAG;EAC3C,KAAK,4BACH,OAAO,EAAE,MAAM,oBAAoB;EACrC,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,MAAa,iBAAiB,WAA+C;CAG3E,MAAM,mBAAmB,OAAO,WAAW,WACzC,YACA,OACA;EACA,IAAI;EAEJ,QAAQ,WAAW,WAAnB;GACE,KAAK;IACH,MAAM;KACJ,KAAK;KACL,KAAK;KACL,GAAG,UAAU,OAAO,WAAW,CAAC;KAChC,GAAG,UAAU,OAAO,WAAW,CAAC;IAClC;IACA;GACF,KAAK;IACH,MAAM;KAAE,KAAK;KAAO,KAAK;KAAW,GAAG,UAAU,OAAO,WAAW,CAAC;IAAE;IACtE;GACF,KAAK;GACL,KAAK;IACH,MAAM;KAAE,KAAK;KAAO,GAAG,UAAU,OAAO,WAAW,CAAC;KAAG,GAAG,UAAU,OAAO,WAAW,CAAC;IAAE;IACzF,IAAI,OAAO,YAAY;KACrB,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;KACrC,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;KACrC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;KACvC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;KACvC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;IACzC;EACJ;EACA,IAAI,OAAO,YAAY,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;EAE5D,MAAM,MAAM,OAAO,OAAO,WAAW;GACnC,WAAW,OAAO,UAAU,OAAO,KAAK,gBAAgB,WAAW,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;GAC5F,OAAO;EACT,CAAC;EAED,IACE,WAAW,cAAc,oBACzB,WAAW,cAAc,4BAEzB,OAAO,OAAO,oBAAoB,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAC7D,OAAO,eAAe,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,CAC5D;EAGF,OAAO;CACT,CAAC;CAED,MAAM,YAAY,OAAO,WAAW,WAClC,WACA,QACA,UACA;EACA,OAAO,OAAO,UAAU,UAAU,KAAK;EAEvC,MAAM,MAAM,OAAO,OAAO,WAAW;GACnC,WACE,OAAO,UAAU,QAAQ,UAAU,gBAAgB,SAAS,GAAG,OAAO,CACpE,WAAW,UAAU,SAAS,QAChC,CAAC;GACH,OAAO;EACT,CAAC;EAED,IAAI,cAAc,oBAAoB,cAAc,4BAElD,OAAO,OAAO,oBAAoB,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAC7D,OAAO,eAAe,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,CAC5D;EAGF,OAAO;CACT,CAAC;CAED,OAAO,UAAU,GAAG;EAClB,iBAAiB,OAAO,WAAW,WAAW,OAAO;GACnD,MAAM,aAAa,OAAO,OAAO,qBAAqB,OAAO,KAAK;GAClE,MAAM,MAAM,OAAO,iBAAiB,YAAY,QAAQ;GAExD,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,OAAO,UAAU,QAAQ,GAAG;IACvC,OAAO;GACT,CAAC;GAED,OAAO,IAAI,WAAW,OAAO;EAC/B,CAAC;EACD,kBAAkB,OAAO,WAAW,WAAW,OAAO;GACpD,MAAM,UAAU,OAAO,OACrB,OAAO,SAAS,sBAAsB,EAAE,oBAAoB,KAAK,CAAC,GAClE,OACA,KACF;GAEA,MAAM,aAAa,SAAS,MAAM,OAAO;GACzC,MAAM,MAAM,OAAO,iBAAiB,YAAY,MAAM;GAEtD,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,OAAO,UAAU,SAAS,GAAG;IACxC,OAAO;GACT,CAAC;GAED,OAAO,SAAS,KAAK,IAAI,WAAW,OAAO,CAAC;EAC9C,CAAC;EACD,MAAM,OAAO,WAAW,WAAW,OAAO;GACxC,MAAM,QAAQ,OAAO,OAAO,WAAW,OAAO,MAAM;GACpD,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GAEnC,OAAO,OAAO,WAAW,MAAM,aAAa,aAC1C,OAAO,IAAI,aAAa;IACtB,MAAM,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,QAAQ;IAE/D,MAAM,SAAS,OAAO,OAAO,WAAW;KACtC,WAAW,OAAO,KAAK,mBAAmB,MAAM,SAAS,GAAG,KAAK,IAAI;KACrE,OAAO;IACT,CAAC;IAED,OAAO,IAAI,WAAW,MAAM;GAC9B,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,CAChC;EACF,CAAC;EACD,QAAQ,OAAO,WAAW,WAAW,OAAO;GAC1C,MAAM,QAAQ,OAAO,OAAO,aAAa,OAAO,MAAM;GACtD,MAAM,WAAW,OAAO,KAAK,MAAM,SAAS;GAC5C,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GACnC,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS;GAC7C,MAAM,MAAM,OAAO,UAAU,MAAM,WAAW,QAAQ,QAAQ;GAE9D,KACG,MAAM,cAAc,uBAAuB,MAAM,cAAc,cAChE,UAAU,WAAW,IAErB,OAAO;GAET,OAAO,OAAO,OAAO,WAAW;IAC9B,WAAW,OAAO,OAAO,mBAAmB,MAAM,SAAS,GAAG,KAAK,WAAW,IAAI;IAClF,OAAO;GACT,CAAC;EACH,CAAC;CACH,CAAC;AACH"}
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":";;;;;;;AAmBA,MAAM,WAAW,OAAO,WAAW,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,KAAK,CAAC;AAEzF,MAAM,eAAe,OAAO,OAAO,EACjC,eAAe,OAAO,IAAI,MAAM,OAAO,uBAAuB,IAAI,CAAC,EACrE,CAAC;AAED,MAAM,mBAAmB,cAAyB;CAChD,QAAQ,WAAR;EACE,KAAK,qBACH,OAAO;GAAE,MAAM;GAAS,YAAY;EAAQ;EAC9C,KAAK,kBACH,OAAO;GAAE,MAAM;GAAW,MAAM;EAAU;EAC5C,KAAK,4BACH,OAAO;GAAE,MAAM;GAAqB,MAAM;EAAU;EACtD,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,MAAM,sBAAsB,cAAyB;CACnD,QAAQ,WAAR;EACE,KAAK,qBACH,OAAO;GAAE,MAAM;GAAS,MAAM;EAAU;EAC1C,KAAK,kBACH,OAAO;GAAE,MAAM;GAAW,YAAY;EAAG;EAC3C,KAAK,4BACH,OAAO,EAAE,MAAM,oBAAoB;EACrC,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,MAAa,iBAAiB,WAA+C;CAG3E,MAAM,mBAAmB,OAAO,WAAW,WACzC,YACA,OACA;EACA,IAAI;EAEJ,QAAQ,WAAW,WAAnB;GACE,KAAK;IACH,MAAM;KACJ,KAAK;KACL,KAAK;KACL,GAAG,UAAU,OAAO,WAAW,CAAC;KAChC,GAAG,UAAU,OAAO,WAAW,CAAC;IAClC;IACA;GACF,KAAK;IACH,MAAM;KAAE,KAAK;KAAO,KAAK;KAAW,GAAG,UAAU,OAAO,WAAW,CAAC;IAAE;IACtE;GACF,KAAK;GACL,KAAK;IACH,MAAM;KAAE,KAAK;KAAO,GAAG,UAAU,OAAO,WAAW,CAAC;KAAG,GAAG,UAAU,OAAO,WAAW,CAAC;IAAE;IACzF,IAAI,OAAO,YAAY;KACrB,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;KACrC,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;KACrC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;KACvC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;KACvC,IAAI,KAAK,UAAU,OAAO,WAAW,EAAE;IACzC;EACJ;EACA,IAAI,OAAO,YAAY,IAAI,IAAI,UAAU,OAAO,WAAW,CAAC;EAE5D,MAAM,MAAM,OAAO,OAAO,WAAW;GACnC,WAAW,OAAO,UAAU,OAAO,KAAK,gBAAgB,WAAW,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;GAC5F,OAAO;EACT,CAAC;EAED,IACE,WAAW,cAAc,oBACzB,WAAW,cAAc,4BAEzB,OAAO,OAAO,oBAAoB,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAC7D,OAAO,eAAe,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,CAC5D;EAGF,OAAO;CACT,CAAC;CAED,MAAM,YAAY,OAAO,WAAW,WAClC,WACA,QACA,UACA;EACA,OAAO,OAAO,UAAU,UAAU,KAAK;EAEvC,MAAM,MAAM,OAAO,OAAO,WAAW;GACnC,WACE,OAAO,UAAU,QAAQ,UAAU,gBAAgB,SAAS,GAAG,OAAO,CACpE,WAAW,UAAU,SAAS,QAChC,CAAC;GACH,OAAO;EACT,CAAC;EAED,IAAI,cAAc,oBAAoB,cAAc,4BAElD,OAAO,OAAO,oBAAoB,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,KAC7D,OAAO,eAAe,aAAa,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,CAC5D;EAGF,OAAO;CACT,CAAC;CAED,OAAO,UAAU,GAAG;EAClB,kBAAkB,OAAO,WAAW,WAAW,OAAO;GACpD,MAAM,QAAQ,OAAO,OAAO,iBAAiB,OAAO,KAAK;GACzD,MAAM,YAAY,MAAM;GAExB,MAAM,MAAM,OAAO,cACjB,WAAW,MAAM,aAAa,aAAa,UAAU,WAAW,SAAS,QAAQ,CAAC,CACpF;GAEA,OAAO,EACL,MAAM,OAAO,WAAW,WAAW,OAAO;IACxC,MAAM,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;IAEtF,MAAM,SAAS,OAAO,KAAK,QACzB,OAAO,WAAW;KAChB,WAAW,OAAO,KAAK,mBAAmB,SAAS,GAAG,KAAK,IAAI;KAC/D,OAAO;IACT,CAAC,CACH;IAEA,OAAO,IAAI,WAAW,MAAM;GAC9B,CAAC,EACH;EACF,CAAC;EACD,iBAAiB,OAAO,WAAW,WAAW,OAAO;GACnD,MAAM,QAAQ,OAAO,OAAO,gBAAgB,OAAO,KAAK;GACxD,MAAM,YAAY,MAAM;GACxB,MAAM,WAAW,OAAO,KAAK,MAAM,SAAS;GAC5C,MAAM,MAAM,OAAO,cAAc,UAAU,WAAW,QAAQ,QAAQ,CAAC;GAEvE,OAAO,EACL,QAAQ,OAAO,WAAW,WAAW,OAAO,WAAW;IACrD,MAAM,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;IAEtF,MAAM,MAAM,OAAO,OAAO,OAAO,YAAY,WAAW,MAAM,CAAC,CAAC,KAC9D,OAAO,QAAQ,IAAI,CACrB;IAEA,OAAO,OAAO,KAAK,QAAQ;KACzB,KAAK,cAAc,uBAAuB,cAAc,cAAc,IAAI,WAAW,IACnF,OAAO,OAAO,QAAQ,KAAK;KAE7B,OAAO,OAAO,WAAW;MACvB,WAAW,OAAO,OAAO,mBAAmB,SAAS,GAAG,KAAK,KAAK,IAAI;MACtE,OAAO;KACT,CAAC;IACH,CAAC;GACH,CAAC,EACH;EACF,CAAC;EACD,iBAAiB,OAAO,WAAW,WAAW,OAAO;GACnD,MAAM,aAAa,OAAO,OAAO,qBAAqB,OAAO,KAAK;GAClE,MAAM,MAAM,OAAO,iBAAiB,YAAY,QAAQ;GAExD,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,OAAO,UAAU,QAAQ,GAAG;IACvC,OAAO;GACT,CAAC;GAED,OAAO,IAAI,WAAW,OAAO;EAC/B,CAAC;EACD,kBAAkB,OAAO,WAAW,WAAW,OAAO;GACpD,MAAM,UAAU,OAAO,OACrB,OAAO,SAAS,sBAAsB,EAAE,oBAAoB,KAAK,CAAC,GAClE,OACA,KACF;GAEA,MAAM,aAAa,SAAS,MAAM,OAAO;GACzC,MAAM,MAAM,OAAO,iBAAiB,YAAY,MAAM;GAEtD,MAAM,UAAU,OAAO,OAAO,WAAW;IACvC,WAAW,OAAO,UAAU,SAAS,GAAG;IACxC,OAAO;GACT,CAAC;GAED,OAAO,SAAS,KAAK,IAAI,WAAW,OAAO,CAAC;EAC9C,CAAC;EACD,MAAM,OAAO,WAAW,WAAW,OAAO;GACxC,MAAM,QAAQ,OAAO,OAAO,WAAW,OAAO,MAAM;GACpD,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GAEnC,OAAO,OAAO,WAAW,MAAM,aAAa,aAC1C,OAAO,IAAI,aAAa;IACtB,MAAM,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,QAAQ;IAE/D,MAAM,SAAS,OAAO,OAAO,WAAW;KACtC,WAAW,OAAO,KAAK,mBAAmB,MAAM,SAAS,GAAG,KAAK,IAAI;KACrE,OAAO;IACT,CAAC;IAED,OAAO,IAAI,WAAW,MAAM;GAC9B,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,CAChC;EACF,CAAC;EACD,QAAQ,OAAO,WAAW,WAAW,OAAO;GAC1C,MAAM,QAAQ,OAAO,OAAO,aAAa,OAAO,MAAM;GACtD,MAAM,WAAW,OAAO,KAAK,MAAM,SAAS;GAC5C,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GACnC,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS;GAC7C,MAAM,MAAM,OAAO,UAAU,MAAM,WAAW,QAAQ,QAAQ;GAE9D,KACG,MAAM,cAAc,uBAAuB,MAAM,cAAc,cAChE,UAAU,WAAW,IAErB,OAAO;GAET,OAAO,OAAO,OAAO,WAAW;IAC9B,WAAW,OAAO,OAAO,mBAAmB,MAAM,SAAS,GAAG,KAAK,WAAW,IAAI;IAClF,OAAO;GACT,CAAC;EACH,CAAC;CACH,CAAC;AACH"}
@@ -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: /* @__PURE__ */ new Uint8Array(64)
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 = new DataView(state.stream.buffer, state.stream.byteOffset, state.stream.byteLength);
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.28","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"}}
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 SignInput = Schema.Struct({
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
- algorithm: Algorithm,
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>;
@@ -1,16 +1,28 @@
1
1
  import { Effect, Redacted, Schema } from "effect";
2
2
 
3
- import { Aead, DecryptInput, EncryptInput } from "../Aead";
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 CipherInput {
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
- export const makeAead = (subtle: SubtleCrypto, xchacha?: XChaCha): Aead["Service"] =>
24
- Aead.of({
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
- const encrypted = yield* Effect.tryPromise({
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
- const decrypted = yield* Effect.tryPromise({
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
+ };
@@ -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 bounded batches; admission remains held through buffer cleanup. */
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
- for (let batch = 0; batch < 256; batch++) {
17
- if (blocks.next().done) return output(state, input);
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
  }