@yielded/crypto 0.1.0-beta.28 → 0.1.0-beta.30

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 +1 @@
1
- {"version":3,"file":"hmac.mjs","names":[],"sources":["../../src/internal/hmac.ts"],"sourcesContent":["import { Effect, Exit, Fiber, Redacted, Schema, Scope } from \"effect\";\n\nimport { CryptoUnavailable } from \"../Errors\";\nimport { Hmac, Input, type Key, KeyInput, VerifyInput } from \"../Hmac\";\nimport { copy, decode, importError, nativeError, withSecret } from \"./common\";\n\nconst keyBytes = Schema.Uint8Array.check(Schema.isMinLength(1));\n\nexport const makeHmac = (subtle: SubtleCrypto): Hmac[\"Service\"] => {\n const importKey = Effect.fnUntraced(function* (input: KeyInput) {\n const value = yield* decode(KeyInput, input, \"key\");\n\n yield* decode(keyBytes, Redacted.value(value.key), \"key\");\n\n // A sequential child joins every native call before dropping the key, even\n // when the caller's Scope runs its other finalizers in parallel.\n const scope = yield* Scope.fork(yield* Effect.scope, \"sequential\");\n let imported: CryptoKey | undefined;\n\n yield* Scope.addFinalizer(\n scope,\n Effect.sync(() => {\n imported = undefined;\n }),\n );\n\n const available = Effect.suspend(() =>\n scope.state._tag === \"Closed\" ? Effect.fail(CryptoUnavailable.make({})) : Effect.void,\n );\n\n const run = <A, E>(operation: Effect.Effect<A, E>) =>\n Effect.acquireUseRelease(\n available.pipe(Effect.andThen(Effect.forkIn(operation, scope, { uninterruptible: false }))),\n (fiber) =>\n Effect.gen(function* () {\n const exit = yield* Fiber.await(fiber);\n\n yield* available;\n\n return yield* exit;\n }),\n Fiber.interrupt,\n );\n\n yield* run(\n withSecret(value.key, (material) =>\n Effect.tryPromise({\n try: () =>\n subtle.importKey(\"raw\", material, { name: \"HMAC\", hash: value.algorithm }, false, [\n \"sign\",\n \"verify\",\n ]),\n catch: importError,\n }).pipe(\n Effect.tap((key) =>\n Effect.sync(() => {\n imported = key;\n }),\n ),\n Effect.uninterruptible,\n ),\n ),\n ).pipe(\n Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void)),\n );\n\n const use = <A>(operation: (key: CryptoKey) => Promise<A>) =>\n run(\n Effect.suspend(() => {\n const key = imported;\n\n return key === undefined\n ? Effect.fail(CryptoUnavailable.make({}))\n : Effect.tryPromise({ try: () => operation(key), catch: nativeError });\n }).pipe(Effect.uninterruptible),\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 return new Uint8Array(yield* use((key) => subtle.sign(\"HMAC\", key, data)));\n }),\n verify: Effect.fnUntraced(function* (input, signature) {\n const data = yield* decode(Schema.Uint8Array, input, \"data\").pipe(Effect.flatMap(copy));\n const tag = yield* decode(Schema.Uint8Array, signature, \"data\").pipe(Effect.flatMap(copy));\n\n return yield* use((key) => subtle.verify(\"HMAC\", key, tag, data));\n }),\n } satisfies Key;\n });\n\n return Hmac.of({\n importKey,\n sign: Effect.fnUntraced(function* (input) {\n const value = yield* decode(Input, input, \"data\");\n const data = yield* copy(value.data);\n const key = yield* importKey(value);\n\n return yield* key.sign(data);\n }, Effect.scoped),\n verify: Effect.fnUntraced(function* (input) {\n const value = yield* decode(VerifyInput, input, \"data\");\n const data = yield* copy(value.data);\n const tag = yield* copy(value.tag);\n const key = yield* importKey(value);\n\n return yield* key.verify(data, tag);\n }, Effect.scoped),\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"hmac.mjs","names":[],"sources":["../../src/internal/hmac.ts"],"sourcesContent":["import { Effect, Redacted, Schema } from \"effect\";\n\nimport { Hmac, Input, type Key, KeyInput, VerifyInput } from \"../Hmac\";\nimport { copy, decode, importError, nativeError, withSecret } from \"./common\";\nimport { makeScopedKey } from \"./scoped-key\";\n\nconst keyBytes = Schema.Uint8Array.check(Schema.isMinLength(1));\n\nexport const makeHmac = (subtle: SubtleCrypto): Hmac[\"Service\"] => {\n const importKey = Effect.fnUntraced(function* (input: KeyInput) {\n const value = yield* decode(KeyInput, input, \"key\");\n\n yield* decode(keyBytes, Redacted.value(value.key), \"key\");\n\n const use = yield* makeScopedKey(\n withSecret(value.key, (material) =>\n Effect.tryPromise({\n try: () =>\n subtle.importKey(\"raw\", material, { name: \"HMAC\", hash: value.algorithm }, false, [\n \"sign\",\n \"verify\",\n ]),\n catch: importError,\n }),\n ),\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 return new Uint8Array(\n yield* use((key) =>\n Effect.tryPromise({ try: () => subtle.sign(\"HMAC\", key, data), catch: nativeError }),\n ),\n );\n }),\n verify: Effect.fnUntraced(function* (input, signature) {\n const data = yield* decode(Schema.Uint8Array, input, \"data\").pipe(Effect.flatMap(copy));\n const tag = yield* decode(Schema.Uint8Array, signature, \"data\").pipe(Effect.flatMap(copy));\n\n return yield* use((key) =>\n Effect.tryPromise({\n try: () => subtle.verify(\"HMAC\", key, tag, data),\n catch: nativeError,\n }),\n );\n }),\n } satisfies Key;\n });\n\n return Hmac.of({\n importKey,\n sign: Effect.fnUntraced(function* (input) {\n const value = yield* decode(Input, input, \"data\");\n const data = yield* copy(value.data);\n const key = yield* importKey(value);\n\n return yield* key.sign(data);\n }, Effect.scoped),\n verify: Effect.fnUntraced(function* (input) {\n const value = yield* decode(VerifyInput, input, \"data\");\n const data = yield* copy(value.data);\n const tag = yield* copy(value.tag);\n const key = yield* importKey(value);\n\n return yield* key.verify(data, tag);\n }, Effect.scoped),\n });\n};\n"],"mappings":";;;;;AAMA,MAAM,WAAW,OAAO,WAAW,MAAM,OAAO,YAAY,CAAC,CAAC;AAE9D,MAAa,YAAY,WAA0C;CACjE,MAAM,YAAY,OAAO,WAAW,WAAW,OAAiB;EAC9D,MAAM,QAAQ,OAAO,OAAO,UAAU,OAAO,KAAK;EAElD,OAAO,OAAO,UAAU,SAAS,MAAM,MAAM,GAAG,GAAG,KAAK;EAExD,MAAM,MAAM,OAAO,cACjB,WAAW,MAAM,MAAM,aACrB,OAAO,WAAW;GAChB,WACE,OAAO,UAAU,OAAO,UAAU;IAAE,MAAM;IAAQ,MAAM,MAAM;GAAU,GAAG,OAAO,CAChF,QACA,QACF,CAAC;GACH,OAAO;EACT,CAAC,CACH,CACF;EAEA,OAAO;GACL,MAAM,OAAO,WAAW,WAAW,OAAO;IACxC,MAAM,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;IAEtF,OAAO,IAAI,WACT,OAAO,KAAK,QACV,OAAO,WAAW;KAAE,WAAW,OAAO,KAAK,QAAQ,KAAK,IAAI;KAAG,OAAO;IAAY,CAAC,CACrF,CACF;GACF,CAAC;GACD,QAAQ,OAAO,WAAW,WAAW,OAAO,WAAW;IACrD,MAAM,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;IACtF,MAAM,MAAM,OAAO,OAAO,OAAO,YAAY,WAAW,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;IAEzF,OAAO,OAAO,KAAK,QACjB,OAAO,WAAW;KAChB,WAAW,OAAO,OAAO,QAAQ,KAAK,KAAK,IAAI;KAC/C,OAAO;IACT,CAAC,CACH;GACF,CAAC;EACH;CACF,CAAC;CAED,OAAO,KAAK,GAAG;EACb;EACA,MAAM,OAAO,WAAW,WAAW,OAAO;GACxC,MAAM,QAAQ,OAAO,OAAO,OAAO,OAAO,MAAM;GAChD,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GAGnC,OAAO,QAAO,OAFK,UAAU,KAAK,EAAA,CAEhB,KAAK,IAAI;EAC7B,GAAG,OAAO,MAAM;EAChB,QAAQ,OAAO,WAAW,WAAW,OAAO;GAC1C,MAAM,QAAQ,OAAO,OAAO,aAAa,OAAO,MAAM;GACtD,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI;GACnC,MAAM,MAAM,OAAO,KAAK,MAAM,GAAG;GAGjC,OAAO,QAAO,OAFK,UAAU,KAAK,EAAA,CAEhB,OAAO,MAAM,GAAG;EACpC,GAAG,OAAO,MAAM;CAClB,CAAC;AACH"}
@@ -0,0 +1,31 @@
1
+ import { CryptoUnavailable } from "../Errors.mjs";
2
+ import { Effect, Exit, Fiber, Scope } from "effect";
3
+ //#region src/internal/scoped-key.ts
4
+ /** Join native calls before releasing a key, including parallel parent closure. */
5
+ const makeScopedKey = Effect.fnUntraced(function* (acquire) {
6
+ const scope = yield* Scope.fork(yield* Effect.scope, "sequential");
7
+ let imported;
8
+ yield* Scope.addFinalizer(scope, Effect.sync(() => {
9
+ imported = void 0;
10
+ }));
11
+ const available = Effect.suspend(() => scope.state._tag === "Closed" ? Effect.fail(CryptoUnavailable.make({})) : Effect.void);
12
+ const run = (operation) => Effect.acquireUseRelease(available.pipe(Effect.andThen(Effect.forkIn(operation, scope, {
13
+ uninterruptible: false,
14
+ startImmediately: true
15
+ }))), (fiber) => Effect.gen(function* () {
16
+ const exit = yield* Fiber.await(fiber);
17
+ yield* available;
18
+ return yield* exit;
19
+ }), Fiber.interrupt);
20
+ yield* run(acquire.pipe(Effect.tap((key) => Effect.sync(() => {
21
+ imported = key;
22
+ })), Effect.uninterruptible)).pipe(Effect.onExit((exit) => Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void));
23
+ return (operation) => run(Effect.suspend(() => {
24
+ const key = imported;
25
+ return key === void 0 ? Effect.fail(CryptoUnavailable.make({})) : operation(key);
26
+ }).pipe(Effect.uninterruptible));
27
+ });
28
+ //#endregion
29
+ export { makeScopedKey };
30
+
31
+ //# sourceMappingURL=scoped-key.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoped-key.mjs","names":[],"sources":["../../src/internal/scoped-key.ts"],"sourcesContent":["import { Effect, Exit, Fiber, Scope } from \"effect\";\n\nimport { CryptoUnavailable, type OperationError } from \"../Errors\";\n\n/** Join native calls before releasing a key, including parallel parent closure. */\nexport const makeScopedKey = Effect.fnUntraced(function* (\n acquire: Effect.Effect<CryptoKey, OperationError>,\n) {\n const scope = yield* Scope.fork(yield* Effect.scope, \"sequential\");\n let imported: CryptoKey | undefined;\n\n yield* Scope.addFinalizer(\n scope,\n Effect.sync(() => {\n imported = undefined;\n }),\n );\n\n const available = Effect.suspend(() =>\n scope.state._tag === \"Closed\" ? Effect.fail(CryptoUnavailable.make({})) : Effect.void,\n );\n\n const run = <A, E>(operation: Effect.Effect<A, E>) =>\n Effect.acquireUseRelease(\n available.pipe(\n Effect.andThen(\n Effect.forkIn(operation, scope, { uninterruptible: false, startImmediately: true }),\n ),\n ),\n (fiber) =>\n Effect.gen(function* () {\n const exit = yield* Fiber.await(fiber);\n\n yield* available;\n\n return yield* exit;\n }),\n Fiber.interrupt,\n );\n\n yield* run(\n acquire.pipe(\n Effect.tap((key) =>\n Effect.sync(() => {\n imported = key;\n }),\n ),\n Effect.uninterruptible,\n ),\n ).pipe(Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(scope, exit) : Effect.void)));\n\n return <A, E>(operation: (key: CryptoKey) => Effect.Effect<A, E>) =>\n run(\n Effect.suspend((): Effect.Effect<A, E | CryptoUnavailable> => {\n const key = imported;\n\n return key === undefined ? Effect.fail(CryptoUnavailable.make({})) : operation(key);\n }).pipe(Effect.uninterruptible),\n );\n});\n"],"mappings":";;;;AAKA,MAAa,gBAAgB,OAAO,WAAW,WAC7C,SACA;CACA,MAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,OAAO,OAAO,YAAY;CACjE,IAAI;CAEJ,OAAO,MAAM,aACX,OACA,OAAO,WAAW;EAChB,WAAW,KAAA;CACb,CAAC,CACH;CAEA,MAAM,YAAY,OAAO,cACvB,MAAM,MAAM,SAAS,WAAW,OAAO,KAAK,kBAAkB,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,IACnF;CAEA,MAAM,OAAa,cACjB,OAAO,kBACL,UAAU,KACR,OAAO,QACL,OAAO,OAAO,WAAW,OAAO;EAAE,iBAAiB;EAAO,kBAAkB;CAAK,CAAC,CACpF,CACF,IACC,UACC,OAAO,IAAI,aAAa;EACtB,MAAM,OAAO,OAAO,MAAM,MAAM,KAAK;EAErC,OAAO;EAEP,OAAO,OAAO;CAChB,CAAC,GACH,MAAM,SACR;CAEF,OAAO,IACL,QAAQ,KACN,OAAO,KAAK,QACV,OAAO,WAAW;EAChB,WAAW;CACb,CAAC,CACH,GACA,OAAO,eACT,CACF,CAAC,CAAC,KAAK,OAAO,QAAQ,SAAU,KAAK,UAAU,IAAI,IAAI,MAAM,MAAM,OAAO,IAAI,IAAI,OAAO,IAAK,CAAC;CAE/F,QAAc,cACZ,IACE,OAAO,cAAuD;EAC5D,MAAM,MAAM;EAEZ,OAAO,QAAQ,KAAA,IAAY,OAAO,KAAK,kBAAkB,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG;CACpF,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,CAChC;AACJ,CAAC"}
@@ -1,11 +1,32 @@
1
- import { InvalidInput } from "../Errors.mjs";
2
- import { PrivateKeyParameters, PublicKeyParameters, SignInput, Signature, VerifyInput } from "../Signature.mjs";
1
+ import { CryptoUnavailable, InvalidInput } from "../Errors.mjs";
2
+ import { GenerateKeyPairInput, 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
7
8
  const derBytes = Schema.Uint8Array.check(Schema.isMinLength(1), Schema.isMaxLength(16384));
8
9
  const RsaAlgorithm = Schema.Struct({ modulusLength: Schema.Int.check(Schema.isGreaterThanOrEqualTo(2048)) });
10
+ const component = Schema.Uint8ArrayFromBase64Url;
11
+ const GeneratedEc = Schema.Struct({
12
+ x: component,
13
+ y: component,
14
+ d: component
15
+ });
16
+ const GeneratedEd = Schema.Struct({
17
+ x: component,
18
+ d: component
19
+ });
20
+ const GeneratedRsa = Schema.Struct({
21
+ n: component,
22
+ e: component,
23
+ d: component,
24
+ p: component,
25
+ q: component,
26
+ dp: component,
27
+ dq: component,
28
+ qi: component
29
+ });
9
30
  const importAlgorithm = (algorithm) => {
10
31
  switch (algorithm) {
11
32
  case "ECDSA-P256-SHA256": return {
@@ -89,6 +110,99 @@ const makeSignature = (subtle) => {
89
110
  return key;
90
111
  });
91
112
  return Signature.of({
113
+ importPrivateKey: Effect.fnUntraced(function* (input) {
114
+ const value = yield* decode(PrivateKeyInput, input, "key");
115
+ const algorithm = value.algorithm;
116
+ const use = yield* makeScopedKey(withSecret(value.privateKey, (material) => importKey(algorithm, "pkcs8", material)));
117
+ return { sign: Effect.fnUntraced(function* (input) {
118
+ const data = yield* decode(Schema.Uint8Array, input, "data").pipe(Effect.flatMap(copy));
119
+ const result = yield* use((key) => Effect.tryPromise({
120
+ try: () => subtle.sign(operationAlgorithm(algorithm), key, data),
121
+ catch: nativeError
122
+ }));
123
+ return new Uint8Array(result);
124
+ }) };
125
+ }),
126
+ importPublicKey: Effect.fnUntraced(function* (input) {
127
+ const value = yield* decode(PublicKeyInput, input, "key");
128
+ const algorithm = value.algorithm;
129
+ const material = yield* copy(value.publicKey);
130
+ const use = yield* makeScopedKey(importKey(algorithm, "spki", material));
131
+ return { verify: Effect.fnUntraced(function* (input, signature) {
132
+ const data = yield* decode(Schema.Uint8Array, input, "data").pipe(Effect.flatMap(copy));
133
+ const tag = yield* decode(Schema.Uint8Array, signature, "data").pipe(Effect.flatMap(copy));
134
+ return yield* use((key) => {
135
+ if ((algorithm === "ECDSA-P256-SHA256" || algorithm === "Ed25519") && tag.length !== 64) return Effect.succeed(false);
136
+ return Effect.tryPromise({
137
+ try: () => subtle.verify(operationAlgorithm(algorithm), key, tag, data),
138
+ catch: nativeError
139
+ });
140
+ });
141
+ }) };
142
+ }),
143
+ generateKeyPair: Effect.fnUntraced(function* (input) {
144
+ const value = yield* decode(GenerateKeyPairInput, input, "parameters");
145
+ const pair = yield* Effect.tryPromise({
146
+ try: () => {
147
+ switch (value.algorithm) {
148
+ case "ECDSA-P256-SHA256": return subtle.generateKey({
149
+ name: "ECDSA",
150
+ namedCurve: "P-256"
151
+ }, true, ["sign", "verify"]);
152
+ case "Ed25519": return subtle.generateKey("Ed25519", true, ["sign", "verify"]);
153
+ case "RSASSA-PKCS1-v1_5-SHA256":
154
+ case "RSA-PSS-SHA256": return subtle.generateKey({
155
+ name: value.algorithm === "RSA-PSS-SHA256" ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
156
+ hash: "SHA-256",
157
+ modulusLength: value.modulusLength ?? 2048,
158
+ publicExponent: new Uint8Array([
159
+ 1,
160
+ 0,
161
+ 1
162
+ ])
163
+ }, true, ["sign", "verify"]);
164
+ }
165
+ },
166
+ catch: nativeError
167
+ });
168
+ const jwk = yield* Effect.tryPromise({
169
+ try: () => subtle.exportKey("jwk", pair.privateKey),
170
+ catch: nativeError
171
+ });
172
+ const parameters = yield* Effect.gen(function* () {
173
+ switch (value.algorithm) {
174
+ case "ECDSA-P256-SHA256": return {
175
+ algorithm: value.algorithm,
176
+ ...yield* Schema.decodeUnknownEffect(GeneratedEc)(jwk, { reportInput: false })
177
+ };
178
+ case "Ed25519": return {
179
+ algorithm: value.algorithm,
180
+ ...yield* Schema.decodeUnknownEffect(GeneratedEd)(jwk, { reportInput: false })
181
+ };
182
+ case "RSASSA-PKCS1-v1_5-SHA256":
183
+ case "RSA-PSS-SHA256": return {
184
+ algorithm: value.algorithm,
185
+ ...yield* Schema.decodeUnknownEffect(GeneratedRsa)(jwk, { reportInput: false })
186
+ };
187
+ }
188
+ }).pipe(Effect.mapError(() => CryptoUnavailable.make({})));
189
+ yield* decode(PrivateKeyParameters, parameters, "key");
190
+ return {
191
+ publicKey: "n" in parameters ? {
192
+ algorithm: parameters.algorithm,
193
+ n: parameters.n.slice(),
194
+ e: parameters.e.slice()
195
+ } : "y" in parameters ? {
196
+ algorithm: parameters.algorithm,
197
+ x: parameters.x.slice(),
198
+ y: parameters.y.slice()
199
+ } : {
200
+ algorithm: "Ed25519",
201
+ x: parameters.x.slice()
202
+ },
203
+ privateKey: Redacted.make(parameters)
204
+ };
205
+ }, Effect.uninterruptible),
92
206
  encodePublicKey: Effect.fnUntraced(function* (input) {
93
207
  const parameters = yield* decode(PublicKeyParameters, input, "key");
94
208
  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 { CryptoUnavailable, InvalidInput } from \"../Errors\";\nimport {\n type Algorithm,\n type PrivateKey,\n PrivateKeyInput,\n GenerateKeyPairInput,\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 component = Schema.Uint8ArrayFromBase64Url;\nconst GeneratedEc = Schema.Struct({ x: component, y: component, d: component });\nconst GeneratedEd = Schema.Struct({ x: component, d: component });\n\nconst GeneratedRsa = Schema.Struct({\n n: component,\n e: component,\n d: component,\n p: component,\n q: component,\n dp: component,\n dq: component,\n qi: component,\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 generateKeyPair: Effect.fnUntraced(function* (input) {\n const value = yield* decode(GenerateKeyPairInput, input, \"parameters\");\n\n const pair = yield* Effect.tryPromise({\n try: () => {\n switch (value.algorithm) {\n case \"ECDSA-P256-SHA256\":\n return subtle.generateKey({ name: \"ECDSA\", namedCurve: \"P-256\" }, true, [\n \"sign\",\n \"verify\",\n ]);\n case \"Ed25519\":\n return subtle.generateKey(\"Ed25519\", true, [\"sign\", \"verify\"]);\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\":\n return subtle.generateKey(\n {\n name: value.algorithm === \"RSA-PSS-SHA256\" ? \"RSA-PSS\" : \"RSASSA-PKCS1-v1_5\",\n hash: \"SHA-256\",\n modulusLength: value.modulusLength ?? 2048,\n publicExponent: new Uint8Array([1, 0, 1]),\n },\n true,\n [\"sign\", \"verify\"],\n );\n }\n },\n catch: nativeError,\n });\n\n const jwk = yield* Effect.tryPromise({\n try: () => subtle.exportKey(\"jwk\", pair.privateKey),\n catch: nativeError,\n });\n\n // JsonWebKey does not guarantee algorithm-specific fields. Decode only at\n // this native boundary; callers receive typed components, never loose JWKs.\n const parameters: PrivateKeyParameters = yield* Effect.gen(function* () {\n switch (value.algorithm) {\n case \"ECDSA-P256-SHA256\":\n return {\n algorithm: value.algorithm,\n ...(yield* Schema.decodeUnknownEffect(GeneratedEc)(jwk, { reportInput: false })),\n };\n case \"Ed25519\":\n return {\n algorithm: value.algorithm,\n ...(yield* Schema.decodeUnknownEffect(GeneratedEd)(jwk, { reportInput: false })),\n };\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\":\n return {\n algorithm: value.algorithm,\n ...(yield* Schema.decodeUnknownEffect(GeneratedRsa)(jwk, { reportInput: false })),\n };\n }\n }).pipe(Effect.mapError(() => CryptoUnavailable.make({})));\n\n yield* decode(PrivateKeyParameters, parameters, \"key\");\n\n const publicKey: PublicKeyParameters =\n \"n\" in parameters\n ? { algorithm: parameters.algorithm, n: parameters.n.slice(), e: parameters.e.slice() }\n : \"y\" in parameters\n ? { algorithm: parameters.algorithm, x: parameters.x.slice(), y: parameters.y.slice() }\n : { algorithm: \"Ed25519\", x: parameters.x.slice() };\n\n return { publicKey, privateKey: Redacted.make(parameters) };\n }, Effect.uninterruptible),\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: /* @__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.30","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,68 @@ 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 RsaModulusLength = Schema.Literals([2048, 3072, 4096]);
54
+
55
+ /** RSA defaults to 2048 bits and exponent 65537; curves are fixed by algorithm. */
56
+ export const GenerateKeyPairInput = Schema.Union([
57
+ Schema.Struct({ algorithm: Schema.Literals(["ECDSA-P256-SHA256", "Ed25519"]) }),
58
+ Schema.Struct({
59
+ algorithm: Schema.Literals(["RSASSA-PKCS1-v1_5-SHA256", "RSA-PSS-SHA256"]),
60
+ modulusLength: Schema.optionalKey(RsaModulusLength),
61
+ }),
62
+ ]);
63
+
64
+ export type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;
65
+
66
+ export const KeyPairParameters = Schema.Struct({
67
+ publicKey: PublicKeyParameters,
68
+ privateKey: Schema.Redacted(PrivateKeyParameters, { disallowJsonEncode: true }),
69
+ });
70
+
71
+ export type KeyPairParameters = typeof KeyPairParameters.Type;
72
+
73
+ export const PrivateKeyInput = Schema.Struct({
54
74
  algorithm: Algorithm,
55
75
  privateKey: Schema.Redacted(Schema.Uint8Array, { disallowJsonEncode: true }),
76
+ });
77
+
78
+ export type PrivateKeyInput = typeof PrivateKeyInput.Type;
79
+
80
+ export const PublicKeyInput = Schema.Struct({
81
+ algorithm: Algorithm,
82
+ publicKey: Schema.Uint8Array,
83
+ });
84
+
85
+ export type PublicKeyInput = typeof PublicKeyInput.Type;
86
+
87
+ export const SignInput = Schema.Struct({
88
+ ...PrivateKeyInput.fields,
56
89
  data: Schema.Uint8Array,
57
90
  });
58
91
 
59
92
  export type SignInput = typeof SignInput.Type;
60
93
 
61
94
  export const VerifyInput = Schema.Struct({
62
- algorithm: Algorithm,
63
- publicKey: Schema.Uint8Array,
95
+ ...PublicKeyInput.fields,
64
96
  data: Schema.Uint8Array,
65
97
  signature: Schema.Uint8Array,
66
98
  });
67
99
 
68
100
  export type VerifyInput = typeof VerifyInput.Type;
69
101
 
102
+ /** A nonextractable signing key with its algorithm fixed at import. */
103
+ export interface PrivateKey {
104
+ readonly sign: (data: Uint8Array) => Effect.Effect<Uint8Array, OperationError>;
105
+ }
106
+
107
+ /** A verification key with its algorithm fixed at import. */
108
+ export interface PublicKey {
109
+ readonly verify: (
110
+ data: Uint8Array,
111
+ signature: Uint8Array,
112
+ ) => Effect.Effect<boolean, OperationError>;
113
+ }
114
+
70
115
  /**
71
116
  * Private keys are PKCS8 DER; public keys are SPKI DER. ECDSA signatures are
72
117
  * 64-byte IEEE P1363 (r || s), not ASN.1 DER. RSA requires at least 2048 bits;
@@ -75,6 +120,18 @@ export type VerifyInput = typeof VerifyInput.Type;
75
120
  export class Signature extends Context.Service<
76
121
  Signature,
77
122
  {
123
+ /** Snapshot PKCS8 once; the imported key is usable only inside its owning Scope. */
124
+ readonly importPrivateKey: (
125
+ input: PrivateKeyInput,
126
+ ) => Effect.Effect<PrivateKey, OperationError, Scope.Scope>;
127
+ /** Snapshot SPKI once; scope closure joins native work and rejects later use. */
128
+ readonly importPublicKey: (
129
+ input: PublicKeyInput,
130
+ ) => Effect.Effect<PublicKey, OperationError, Scope.Scope>;
131
+ /** Generate exportable components. The caller owns the returned secret bytes. */
132
+ readonly generateKeyPair: (
133
+ input: GenerateKeyPairInput,
134
+ ) => Effect.Effect<KeyPairParameters, OperationError>;
78
135
  readonly encodePublicKey: (
79
136
  input: PublicKeyParameters,
80
137
  ) => Effect.Effect<Uint8Array, OperationError>;