@matter/general 0.15.0-alpha.0-20250613-a55f991d4 → 0.15.0-alpha.0-20250616-4b3754906

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.
Files changed (63) hide show
  1. package/dist/cjs/crypto/Crypto.d.ts +21 -47
  2. package/dist/cjs/crypto/Crypto.d.ts.map +1 -1
  3. package/dist/cjs/crypto/Crypto.js +24 -101
  4. package/dist/cjs/crypto/Crypto.js.map +1 -1
  5. package/dist/cjs/crypto/MockCrypto.d.ts +24 -0
  6. package/dist/cjs/crypto/MockCrypto.d.ts.map +1 -0
  7. package/dist/cjs/crypto/MockCrypto.js +61 -0
  8. package/dist/cjs/crypto/MockCrypto.js.map +6 -0
  9. package/dist/cjs/crypto/Spake2p.d.ts +6 -7
  10. package/dist/cjs/crypto/Spake2p.d.ts.map +1 -1
  11. package/dist/cjs/crypto/Spake2p.js +29 -24
  12. package/dist/cjs/crypto/Spake2p.js.map +1 -1
  13. package/dist/cjs/crypto/StandardCrypto.d.ts +2 -2
  14. package/dist/cjs/crypto/StandardCrypto.d.ts.map +1 -1
  15. package/dist/cjs/crypto/StandardCrypto.js +4 -8
  16. package/dist/cjs/crypto/StandardCrypto.js.map +1 -1
  17. package/dist/cjs/crypto/index.d.ts +1 -1
  18. package/dist/cjs/crypto/index.d.ts.map +1 -1
  19. package/dist/cjs/crypto/index.js +1 -1
  20. package/dist/cjs/crypto/index.js.map +1 -1
  21. package/dist/cjs/util/Bytes.d.ts +1 -0
  22. package/dist/cjs/util/Bytes.d.ts.map +1 -1
  23. package/dist/cjs/util/Bytes.js +22 -0
  24. package/dist/cjs/util/Bytes.js.map +1 -1
  25. package/dist/esm/crypto/Crypto.d.ts +21 -47
  26. package/dist/esm/crypto/Crypto.d.ts.map +1 -1
  27. package/dist/esm/crypto/Crypto.js +24 -101
  28. package/dist/esm/crypto/Crypto.js.map +1 -1
  29. package/dist/esm/crypto/MockCrypto.d.ts +24 -0
  30. package/dist/esm/crypto/MockCrypto.d.ts.map +1 -0
  31. package/dist/esm/crypto/MockCrypto.js +41 -0
  32. package/dist/esm/crypto/MockCrypto.js.map +6 -0
  33. package/dist/esm/crypto/Spake2p.d.ts +6 -7
  34. package/dist/esm/crypto/Spake2p.d.ts.map +1 -1
  35. package/dist/esm/crypto/Spake2p.js +30 -25
  36. package/dist/esm/crypto/Spake2p.js.map +1 -1
  37. package/dist/esm/crypto/StandardCrypto.d.ts +2 -2
  38. package/dist/esm/crypto/StandardCrypto.d.ts.map +1 -1
  39. package/dist/esm/crypto/StandardCrypto.js +4 -8
  40. package/dist/esm/crypto/StandardCrypto.js.map +1 -1
  41. package/dist/esm/crypto/index.d.ts +1 -1
  42. package/dist/esm/crypto/index.d.ts.map +1 -1
  43. package/dist/esm/crypto/index.js +1 -1
  44. package/dist/esm/util/Bytes.d.ts +1 -0
  45. package/dist/esm/util/Bytes.d.ts.map +1 -1
  46. package/dist/esm/util/Bytes.js +22 -0
  47. package/dist/esm/util/Bytes.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/crypto/Crypto.ts +46 -146
  50. package/src/crypto/MockCrypto.ts +64 -0
  51. package/src/crypto/Spake2p.ts +30 -24
  52. package/src/crypto/StandardCrypto.ts +6 -10
  53. package/src/crypto/index.ts +1 -1
  54. package/src/util/Bytes.ts +22 -0
  55. package/dist/cjs/crypto/nonentropic.d.ts +0 -16
  56. package/dist/cjs/crypto/nonentropic.d.ts.map +0 -1
  57. package/dist/cjs/crypto/nonentropic.js +0 -70
  58. package/dist/cjs/crypto/nonentropic.js.map +0 -6
  59. package/dist/esm/crypto/nonentropic.d.ts +0 -16
  60. package/dist/esm/crypto/nonentropic.d.ts.map +0 -1
  61. package/dist/esm/crypto/nonentropic.js +0 -50
  62. package/dist/esm/crypto/nonentropic.js.map +0 -6
  63. package/src/crypto/nonentropic.ts +0 -65
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Project CHIP Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { ImplementationError } from "#MatterError.js";
8
+ import { Crypto, ec } from "./Crypto.js";
9
+ import { CurveType, Key, KeyType, PrivateKey } from "./Key.js";
10
+ import { StandardCrypto } from "./StandardCrypto.js";
11
+
12
+ /**
13
+ * WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
14
+ *
15
+ * A {@link Crypto} with sources of entropy replaced to produce stable values based on an input index.
16
+ *
17
+ * This is useful in testing environments where Matter logic is difficult to test with true entropy.
18
+ *
19
+ * Depending on implementation some methods may need further mocking to remove entropy entirely. Mocking is sufficient
20
+ * for current testing purposes.
21
+ */
22
+ export interface MockCrypto extends Crypto {
23
+ /**
24
+ * The index of the random space. May be modified to adjust computations going forward.
25
+ */
26
+ index: number;
27
+ }
28
+
29
+ export function MockCrypto(index: number = 0x80, implementation: new () => Crypto = StandardCrypto) {
30
+ if (index < 0 || index > 255) {
31
+ throw new ImplementationError(`Index for stable crypto must be 0-255`);
32
+ }
33
+
34
+ const crypto = new implementation();
35
+
36
+ // Create random data consisting of index repeated
37
+ crypto.randomBytes = function getRandomDataNONENTROPIC(length) {
38
+ const result = new Uint8Array(length);
39
+ result.fill(index);
40
+ return result;
41
+ };
42
+
43
+ // Ensure EC key generation uses our own "entropy" source rather than the platform's
44
+ crypto.createKeyPair = function getRandomDataNONENTROPIC() {
45
+ const privateBits = ec.mapHashToField(new Uint8Array(crypto.randomBytes(48)), ec.p256.CURVE.n);
46
+ return Key({
47
+ kty: KeyType.EC,
48
+ crv: CurveType.p256,
49
+ privateBits,
50
+ }) as PrivateKey;
51
+ };
52
+
53
+ Object.defineProperty(crypto, "index", {
54
+ get() {
55
+ return index;
56
+ },
57
+
58
+ set(newIndex: number) {
59
+ index = newIndex % 256;
60
+ },
61
+ });
62
+
63
+ return crypto as MockCrypto;
64
+ }
@@ -29,39 +29,45 @@ export interface PbkdfParameters {
29
29
  }
30
30
 
31
31
  export class Spake2p {
32
- static async computeW0W1({ iterations, salt }: PbkdfParameters, pin: number) {
32
+ readonly #crypto: Crypto;
33
+ readonly #context: Uint8Array;
34
+ readonly #random: bigint;
35
+ readonly #w0: bigint;
36
+
37
+ static async computeW0W1(crypto: Crypto, { iterations, salt }: PbkdfParameters, pin: number) {
33
38
  const pinWriter = new DataWriter(Endian.Little);
34
39
  pinWriter.writeUInt32(pin);
35
- const ws = await Crypto.createPbkdf2Key(pinWriter.toByteArray(), salt, iterations, CRYPTO_W_SIZE_BYTES * 2);
40
+ const ws = await crypto.createPbkdf2Key(pinWriter.toByteArray(), salt, iterations, CRYPTO_W_SIZE_BYTES * 2);
36
41
  const w0 = mod(bytesToNumberBE(ws.slice(0, 40)), P256_CURVE.n);
37
42
  const w1 = mod(bytesToNumberBE(ws.slice(40, 80)), P256_CURVE.n);
38
43
  return { w0, w1 };
39
44
  }
40
45
 
41
- static async computeW0L(pbkdfParameters: PbkdfParameters, pin: number) {
42
- const { w0, w1 } = await this.computeW0W1(pbkdfParameters, pin);
46
+ static async computeW0L(crypto: Crypto, pbkdfParameters: PbkdfParameters, pin: number) {
47
+ const { w0, w1 } = await this.computeW0W1(crypto, pbkdfParameters, pin);
43
48
  const L = ProjectivePoint.BASE.multiply(w1).toRawBytes(false);
44
49
  return { w0, L };
45
50
  }
46
51
 
47
- static create(context: Uint8Array, w0: bigint) {
48
- const random = Crypto.getRandomBigInt(32, P256_CURVE.Fp.ORDER);
49
- return new Spake2p(context, random, w0);
52
+ static create(crypto: Crypto, context: Uint8Array, w0: bigint) {
53
+ const random = crypto.randomBigInt(32, P256_CURVE.Fp.ORDER);
54
+ return new Spake2p(crypto, context, random, w0);
50
55
  }
51
56
 
52
- constructor(
53
- private readonly context: Uint8Array,
54
- private readonly random: bigint,
55
- private readonly w0: bigint,
56
- ) {}
57
+ constructor(crypto: Crypto, context: Uint8Array, random: bigint, w0: bigint) {
58
+ this.#crypto = crypto;
59
+ this.#context = context;
60
+ this.#random = random;
61
+ this.#w0 = w0;
62
+ }
57
63
 
58
64
  computeX(): Uint8Array {
59
- const X = ProjectivePoint.BASE.multiply(this.random).add(M.multiply(this.w0));
65
+ const X = ProjectivePoint.BASE.multiply(this.#random).add(M.multiply(this.#w0));
60
66
  return X.toRawBytes(false);
61
67
  }
62
68
 
63
69
  computeY(): Uint8Array {
64
- const Y = ProjectivePoint.BASE.multiply(this.random).add(N.multiply(this.w0));
70
+ const Y = ProjectivePoint.BASE.multiply(this.#random).add(N.multiply(this.#w0));
65
71
  return Y.toRawBytes(false);
66
72
  }
67
73
 
@@ -72,8 +78,8 @@ export class Spake2p {
72
78
  } catch (error) {
73
79
  throw new InternalError(`Y is not on the curve: ${(error as any).message}`);
74
80
  }
75
- const yNwo = YPoint.add(N.multiply(this.w0).negate());
76
- const Z = yNwo.multiply(this.random);
81
+ const yNwo = YPoint.add(N.multiply(this.#w0).negate());
82
+ const Z = yNwo.multiply(this.#random);
77
83
  const V = yNwo.multiply(w1);
78
84
  return this.computeSecretAndVerifiers(X, Y, Z.toRawBytes(false), V.toRawBytes(false));
79
85
  }
@@ -86,8 +92,8 @@ export class Spake2p {
86
92
  } catch (error) {
87
93
  throw new InternalError(`X is not on the curve: ${(error as any).message}`);
88
94
  }
89
- const Z = XPoint.add(M.multiply(this.w0).negate()).multiply(this.random);
90
- const V = LPoint.multiply(this.random);
95
+ const Z = XPoint.add(M.multiply(this.#w0).negate()).multiply(this.#random);
96
+ const V = LPoint.multiply(this.#random);
91
97
  return this.computeSecretAndVerifiers(X, Y, Z.toRawBytes(false), V.toRawBytes(false));
92
98
  }
93
99
 
@@ -96,19 +102,19 @@ export class Spake2p {
96
102
  const Ka = TT_HASH.slice(0, 16);
97
103
  const Ke = TT_HASH.slice(16, 32);
98
104
 
99
- const KcAB = await Crypto.createHkdfKey(Ka, new Uint8Array(0), Bytes.fromString("ConfirmationKeys"), 32);
105
+ const KcAB = await this.#crypto.createHkdfKey(Ka, new Uint8Array(0), Bytes.fromString("ConfirmationKeys"), 32);
100
106
  const KcA = KcAB.slice(0, 16);
101
107
  const KcB = KcAB.slice(16, 32);
102
108
 
103
- const hAY = await Crypto.signHmac(KcA, Y);
104
- const hBX = await Crypto.signHmac(KcB, X);
109
+ const hAY = await this.#crypto.signHmac(KcA, Y);
110
+ const hBX = await this.#crypto.signHmac(KcB, X);
105
111
 
106
112
  return { Ke, hAY, hBX };
107
113
  }
108
114
 
109
115
  private computeTranscriptHash(X: Uint8Array, Y: Uint8Array, Z: Uint8Array, V: Uint8Array) {
110
116
  const TTwriter = new DataWriter(Endian.Little);
111
- this.addToContext(TTwriter, this.context);
117
+ this.addToContext(TTwriter, this.#context);
112
118
  this.addToContext(TTwriter, Bytes.fromString(""));
113
119
  this.addToContext(TTwriter, Bytes.fromString(""));
114
120
  this.addToContext(TTwriter, M.toRawBytes(false));
@@ -117,8 +123,8 @@ export class Spake2p {
117
123
  this.addToContext(TTwriter, Y);
118
124
  this.addToContext(TTwriter, Z);
119
125
  this.addToContext(TTwriter, V);
120
- this.addToContext(TTwriter, numberToBytesBE(this.w0, 32));
121
- return Crypto.computeSha256(TTwriter.toByteArray());
126
+ this.addToContext(TTwriter, numberToBytesBE(this.#w0, 32));
127
+ return this.#crypto.computeSha256(TTwriter.toByteArray());
122
128
  }
123
129
 
124
130
  private addToContext(TTwriter: DataWriter<Endian.Little>, data: Uint8Array) {
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { DerBigUint, DerCodec, DerError } from "#codec/DerCodec.js";
9
- import { Boot } from "#util/Boot.js";
9
+ import { Environment } from "#environment/Environment.js";
10
10
  import { Bytes } from "#util/Bytes.js";
11
11
  import { Ccm } from "./aes/Ccm.js";
12
12
  import { Crypto, CRYPTO_SYMMETRIC_KEY_LENGTH, CryptoDsaEncoding } from "./Crypto.js";
@@ -30,14 +30,14 @@ const SIGNATURE_ALGORITHM = <EcdsaParams>{
30
30
  * Web Crypto doesn't support AES-CCM required by Matter so fall back to a JS implementation for that. See relevant
31
31
  * warnings in the "aes" subdirectory.
32
32
  */
33
- export class StandardCrypto implements Crypto {
33
+ export class StandardCrypto extends Crypto {
34
34
  implementationName = "JS";
35
35
 
36
36
  static provider() {
37
37
  return new StandardCrypto();
38
38
  }
39
39
 
40
- getRandomData(length: number): Uint8Array {
40
+ randomBytes(length: number): Uint8Array {
41
41
  const result = new Uint8Array(length);
42
42
  crypto.getRandomValues(result);
43
43
  return result;
@@ -221,13 +221,6 @@ export class StandardCrypto implements Crypto {
221
221
  }
222
222
  }
223
223
 
224
- // Only install if VM supports Web Crypto
225
- if ((globalThis.crypto as any)?.subtle?.[Symbol.toStringTag] === "SubtleCrypto") {
226
- Boot.init(() => {
227
- Crypto.provider = StandardCrypto.provider;
228
- });
229
- }
230
-
231
224
  function importKey(
232
225
  format: "jwk",
233
226
  keyData: JsonWebKey,
@@ -250,3 +243,6 @@ async function importKey(...params: unknown[]) {
250
243
  throw new KeyInputError("Invalid key", { cause });
251
244
  }
252
245
  }
246
+
247
+ // Unconditionally add to Environment as it has not been exported yet so there can be no other implementation present
248
+ Environment.default.set(Crypto, new StandardCrypto());
@@ -8,6 +8,6 @@ export * from "./Crypto.js";
8
8
  export * from "./CryptoConstants.js";
9
9
  export * from "./CryptoError.js";
10
10
  export * from "./Key.js";
11
- export * from "./nonentropic.js";
11
+ export * from "./MockCrypto.js";
12
12
  export * from "./Spake2p.js";
13
13
  export * from "./StandardCrypto.js";
package/src/util/Bytes.ts CHANGED
@@ -89,4 +89,26 @@ export namespace Bytes {
89
89
  });
90
90
  return result;
91
91
  }
92
+
93
+ export function asBigInt(bytes: Uint8Array) {
94
+ const view = new DataView(bytes.buffer);
95
+ let result = 0n;
96
+ for (let i = 0; i < bytes.length; ) {
97
+ const remaining = bytes.length - i;
98
+ if (remaining >= 8) {
99
+ result = (result << 64n) + view.getBigUint64(i);
100
+ i += 8;
101
+ } else if (remaining >= 4) {
102
+ result = (result << 32n) + BigInt(view.getUint32(i));
103
+ i += 4;
104
+ } else if (remaining >= 2) {
105
+ result = (result << 16n) + BigInt(view.getUint16(i));
106
+ i += 2;
107
+ } else {
108
+ result = (result << 8n) + BigInt(view.getUint8(i));
109
+ i++;
110
+ }
111
+ }
112
+ return result;
113
+ }
92
114
  }
@@ -1,16 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2022-2025 Project CHIP Authors
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- /**
7
- * WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
8
- *
9
- * Execute {@link actor} with sources of entropy replaced to produce stable values based on an input index.
10
- *
11
- * This is useful in testing environments where Matter logic is difficult to test with true entropy.
12
- *
13
- * I believe there are some crypto functions that are not fully mocked here but this covers current test cases.
14
- */
15
- export declare function nonentropic<T>(index: number, actor: () => T): T;
16
- //# sourceMappingURL=nonentropic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nonentropic.d.ts","sourceRoot":"","sources":["../../../src/crypto/nonentropic.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CA4C/D"}
@@ -1,70 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var nonentropic_exports = {};
20
- __export(nonentropic_exports, {
21
- nonentropic: () => nonentropic
22
- });
23
- module.exports = __toCommonJS(nonentropic_exports);
24
- var import_MatterError = require("#MatterError.js");
25
- var import_Promises = require("#util/Promises.js");
26
- var import_Crypto = require("./Crypto.js");
27
- var import_Key = require("./Key.js");
28
- /**
29
- * @license
30
- * Copyright 2022-2025 Project CHIP Authors
31
- * SPDX-License-Identifier: Apache-2.0
32
- */
33
- function nonentropic(index, actor) {
34
- if (index < 0 || index > 255) {
35
- throw new import_MatterError.ImplementationError(`Index for stable crypto must be 0-255`);
36
- }
37
- const crypto = import_Crypto.Crypto.default;
38
- const { getRandomData, createKeyPair } = crypto;
39
- let isAsync = false;
40
- try {
41
- crypto.getRandomData = function getRandomDataNONENTROPIC(length) {
42
- const result2 = new Uint8Array(length);
43
- result2.fill(index);
44
- return result2;
45
- };
46
- crypto.createKeyPair = function getRandomDataNONENTROPIC() {
47
- const privateBits = import_Crypto.ec.mapHashToField(crypto.getRandomData(48), import_Crypto.ec.p256.CURVE.n);
48
- return (0, import_Key.Key)({
49
- kty: import_Key.KeyType.EC,
50
- crv: import_Key.CurveType.p256,
51
- privateBits
52
- });
53
- };
54
- let result = actor();
55
- if (import_Promises.MaybePromise.is(result)) {
56
- isAsync = true;
57
- result = Promise.resolve(result).finally(revert);
58
- }
59
- return result;
60
- } finally {
61
- if (!isAsync) {
62
- revert();
63
- }
64
- }
65
- function revert() {
66
- crypto.getRandomData = getRandomData;
67
- crypto.createKeyPair = createKeyPair;
68
- }
69
- }
70
- //# sourceMappingURL=nonentropic.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/crypto/nonentropic.ts"],
4
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,yBAAoC;AACpC,sBAA6B;AAC7B,oBAA2B;AAC3B,iBAAoD;AATpD;AAAA;AAAA;AAAA;AAAA;AAoBO,SAAS,YAAe,OAAe,OAAmB;AAC7D,MAAI,QAAQ,KAAK,QAAQ,KAAK;AAC1B,UAAM,IAAI,uCAAoB,uCAAuC;AAAA,EACzE;AAEA,QAAM,SAAS,qBAAO;AACtB,QAAM,EAAE,eAAe,cAAc,IAAI;AACzC,MAAI,UAAU;AAEd,MAAI;AAEA,WAAO,gBAAgB,SAAS,yBAAyB,QAAQ;AAC7D,YAAMA,UAAS,IAAI,WAAW,MAAM;AACpC,MAAAA,QAAO,KAAK,KAAK;AACjB,aAAOA;AAAA,IACX;AAGA,WAAO,gBAAgB,SAAS,2BAA2B;AACvD,YAAM,cAAc,iBAAG,eAAe,OAAO,cAAc,EAAE,GAAG,iBAAG,KAAK,MAAM,CAAC;AAC/E,iBAAO,gBAAI;AAAA,QACP,KAAK,mBAAQ;AAAA,QACb,KAAK,qBAAU;AAAA,QACf;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,QAAI,SAAS,MAAM;AACnB,QAAI,6BAAa,GAAG,MAAM,GAAG;AACzB,gBAAU;AACV,eAAS,QAAQ,QAAQ,MAAM,EAAE,QAAQ,MAAM;AAAA,IACnD;AAEA,WAAO;AAAA,EACX,UAAE;AACE,QAAI,CAAC,SAAS;AACV,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,WAAS,SAAS;AACd,WAAO,gBAAgB;AACvB,WAAO,gBAAgB;AAAA,EAC3B;AACJ;",
5
- "names": ["result"]
6
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2022-2025 Project CHIP Authors
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- /**
7
- * WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
8
- *
9
- * Execute {@link actor} with sources of entropy replaced to produce stable values based on an input index.
10
- *
11
- * This is useful in testing environments where Matter logic is difficult to test with true entropy.
12
- *
13
- * I believe there are some crypto functions that are not fully mocked here but this covers current test cases.
14
- */
15
- export declare function nonentropic<T>(index: number, actor: () => T): T;
16
- //# sourceMappingURL=nonentropic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nonentropic.d.ts","sourceRoot":"","sources":["../../../src/crypto/nonentropic.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CA4C/D"}
@@ -1,50 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2022-2025 Project CHIP Authors
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- import { ImplementationError } from "#MatterError.js";
7
- import { MaybePromise } from "#util/Promises.js";
8
- import { Crypto, ec } from "./Crypto.js";
9
- import { CurveType, Key, KeyType } from "./Key.js";
10
- function nonentropic(index, actor) {
11
- if (index < 0 || index > 255) {
12
- throw new ImplementationError(`Index for stable crypto must be 0-255`);
13
- }
14
- const crypto = Crypto.default;
15
- const { getRandomData, createKeyPair } = crypto;
16
- let isAsync = false;
17
- try {
18
- crypto.getRandomData = function getRandomDataNONENTROPIC(length) {
19
- const result2 = new Uint8Array(length);
20
- result2.fill(index);
21
- return result2;
22
- };
23
- crypto.createKeyPair = function getRandomDataNONENTROPIC() {
24
- const privateBits = ec.mapHashToField(crypto.getRandomData(48), ec.p256.CURVE.n);
25
- return Key({
26
- kty: KeyType.EC,
27
- crv: CurveType.p256,
28
- privateBits
29
- });
30
- };
31
- let result = actor();
32
- if (MaybePromise.is(result)) {
33
- isAsync = true;
34
- result = Promise.resolve(result).finally(revert);
35
- }
36
- return result;
37
- } finally {
38
- if (!isAsync) {
39
- revert();
40
- }
41
- }
42
- function revert() {
43
- crypto.getRandomData = getRandomData;
44
- crypto.createKeyPair = createKeyPair;
45
- }
46
- }
47
- export {
48
- nonentropic
49
- };
50
- //# sourceMappingURL=nonentropic.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/crypto/nonentropic.ts"],
4
- "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAC7B,SAAS,QAAQ,UAAU;AAC3B,SAAS,WAAW,KAAK,eAA2B;AAW7C,SAAS,YAAe,OAAe,OAAmB;AAC7D,MAAI,QAAQ,KAAK,QAAQ,KAAK;AAC1B,UAAM,IAAI,oBAAoB,uCAAuC;AAAA,EACzE;AAEA,QAAM,SAAS,OAAO;AACtB,QAAM,EAAE,eAAe,cAAc,IAAI;AACzC,MAAI,UAAU;AAEd,MAAI;AAEA,WAAO,gBAAgB,SAAS,yBAAyB,QAAQ;AAC7D,YAAMA,UAAS,IAAI,WAAW,MAAM;AACpC,MAAAA,QAAO,KAAK,KAAK;AACjB,aAAOA;AAAA,IACX;AAGA,WAAO,gBAAgB,SAAS,2BAA2B;AACvD,YAAM,cAAc,GAAG,eAAe,OAAO,cAAc,EAAE,GAAG,GAAG,KAAK,MAAM,CAAC;AAC/E,aAAO,IAAI;AAAA,QACP,KAAK,QAAQ;AAAA,QACb,KAAK,UAAU;AAAA,QACf;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,QAAI,SAAS,MAAM;AACnB,QAAI,aAAa,GAAG,MAAM,GAAG;AACzB,gBAAU;AACV,eAAS,QAAQ,QAAQ,MAAM,EAAE,QAAQ,MAAM;AAAA,IACnD;AAEA,WAAO;AAAA,EACX,UAAE;AACE,QAAI,CAAC,SAAS;AACV,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,WAAS,SAAS;AACd,WAAO,gBAAgB;AACvB,WAAO,gBAAgB;AAAA,EAC3B;AACJ;",
5
- "names": ["result"]
6
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2022-2025 Project CHIP Authors
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import { ImplementationError } from "#MatterError.js";
8
- import { MaybePromise } from "#util/Promises.js";
9
- import { Crypto, ec } from "./Crypto.js";
10
- import { CurveType, Key, KeyType, PrivateKey } from "./Key.js";
11
-
12
- /**
13
- * WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
14
- *
15
- * Execute {@link actor} with sources of entropy replaced to produce stable values based on an input index.
16
- *
17
- * This is useful in testing environments where Matter logic is difficult to test with true entropy.
18
- *
19
- * I believe there are some crypto functions that are not fully mocked here but this covers current test cases.
20
- */
21
- export function nonentropic<T>(index: number, actor: () => T): T {
22
- if (index < 0 || index > 255) {
23
- throw new ImplementationError(`Index for stable crypto must be 0-255`);
24
- }
25
-
26
- const crypto = Crypto.default;
27
- const { getRandomData, createKeyPair } = crypto;
28
- let isAsync = false;
29
-
30
- try {
31
- // Create random data consisting of index repeated
32
- crypto.getRandomData = function getRandomDataNONENTROPIC(length) {
33
- const result = new Uint8Array(length);
34
- result.fill(index);
35
- return result;
36
- };
37
-
38
- // Ensure EC key generation uses our own "entropy" source rather than the platform's
39
- crypto.createKeyPair = function getRandomDataNONENTROPIC() {
40
- const privateBits = ec.mapHashToField(crypto.getRandomData(48), ec.p256.CURVE.n);
41
- return Key({
42
- kty: KeyType.EC,
43
- crv: CurveType.p256,
44
- privateBits,
45
- }) as PrivateKey;
46
- };
47
-
48
- let result = actor();
49
- if (MaybePromise.is(result)) {
50
- isAsync = true;
51
- result = Promise.resolve(result).finally(revert) as T;
52
- }
53
-
54
- return result;
55
- } finally {
56
- if (!isAsync) {
57
- revert();
58
- }
59
- }
60
-
61
- function revert() {
62
- crypto.getRandomData = getRandomData;
63
- crypto.createKeyPair = createKeyPair;
64
- }
65
- }