@matter/general 0.15.0-alpha.0-20250612-ddd428561 → 0.15.0-alpha.0-20250614-b9829e223
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/crypto/Crypto.d.ts +21 -47
- package/dist/cjs/crypto/Crypto.d.ts.map +1 -1
- package/dist/cjs/crypto/Crypto.js +24 -101
- package/dist/cjs/crypto/Crypto.js.map +1 -1
- package/dist/cjs/crypto/MockCrypto.d.ts +24 -0
- package/dist/cjs/crypto/MockCrypto.d.ts.map +1 -0
- package/dist/cjs/crypto/MockCrypto.js +61 -0
- package/dist/cjs/crypto/MockCrypto.js.map +6 -0
- package/dist/cjs/crypto/Spake2p.d.ts +9 -7
- package/dist/cjs/crypto/Spake2p.d.ts.map +1 -1
- package/dist/cjs/crypto/Spake2p.js +28 -20
- package/dist/cjs/crypto/Spake2p.js.map +1 -1
- package/dist/cjs/crypto/StandardCrypto.d.ts +2 -2
- package/dist/cjs/crypto/StandardCrypto.d.ts.map +1 -1
- package/dist/cjs/crypto/StandardCrypto.js +4 -8
- package/dist/cjs/crypto/StandardCrypto.js.map +1 -1
- package/dist/cjs/crypto/index.d.ts +1 -1
- package/dist/cjs/crypto/index.d.ts.map +1 -1
- package/dist/cjs/crypto/index.js +1 -1
- package/dist/cjs/crypto/index.js.map +1 -1
- package/dist/cjs/util/Bytes.d.ts +1 -0
- package/dist/cjs/util/Bytes.d.ts.map +1 -1
- package/dist/cjs/util/Bytes.js +22 -0
- package/dist/cjs/util/Bytes.js.map +1 -1
- package/dist/esm/crypto/Crypto.d.ts +21 -47
- package/dist/esm/crypto/Crypto.d.ts.map +1 -1
- package/dist/esm/crypto/Crypto.js +24 -101
- package/dist/esm/crypto/Crypto.js.map +1 -1
- package/dist/esm/crypto/MockCrypto.d.ts +24 -0
- package/dist/esm/crypto/MockCrypto.d.ts.map +1 -0
- package/dist/esm/crypto/MockCrypto.js +41 -0
- package/dist/esm/crypto/MockCrypto.js.map +6 -0
- package/dist/esm/crypto/Spake2p.d.ts +9 -7
- package/dist/esm/crypto/Spake2p.d.ts.map +1 -1
- package/dist/esm/crypto/Spake2p.js +29 -21
- package/dist/esm/crypto/Spake2p.js.map +1 -1
- package/dist/esm/crypto/StandardCrypto.d.ts +2 -2
- package/dist/esm/crypto/StandardCrypto.d.ts.map +1 -1
- package/dist/esm/crypto/StandardCrypto.js +4 -8
- package/dist/esm/crypto/StandardCrypto.js.map +1 -1
- package/dist/esm/crypto/index.d.ts +1 -1
- package/dist/esm/crypto/index.d.ts.map +1 -1
- package/dist/esm/crypto/index.js +1 -1
- package/dist/esm/util/Bytes.d.ts +1 -0
- package/dist/esm/util/Bytes.d.ts.map +1 -1
- package/dist/esm/util/Bytes.js +22 -0
- package/dist/esm/util/Bytes.js.map +1 -1
- package/package.json +2 -2
- package/src/crypto/Crypto.ts +46 -146
- package/src/crypto/MockCrypto.ts +64 -0
- package/src/crypto/Spake2p.ts +34 -23
- package/src/crypto/StandardCrypto.ts +6 -10
- package/src/crypto/index.ts +1 -1
- package/src/util/Bytes.ts +22 -0
- package/dist/cjs/crypto/nonentropic.d.ts +0 -16
- package/dist/cjs/crypto/nonentropic.d.ts.map +0 -1
- package/dist/cjs/crypto/nonentropic.js +0 -70
- package/dist/cjs/crypto/nonentropic.js.map +0 -6
- package/dist/esm/crypto/nonentropic.d.ts +0 -16
- package/dist/esm/crypto/nonentropic.d.ts.map +0 -1
- package/dist/esm/crypto/nonentropic.js +0 -50
- package/dist/esm/crypto/nonentropic.js.map +0 -6
- 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
|
+
}
|
package/src/crypto/Spake2p.ts
CHANGED
|
@@ -29,39 +29,50 @@ export interface PbkdfParameters {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export class Spake2p {
|
|
32
|
-
|
|
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
|
|
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 =
|
|
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
57
|
constructor(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
crypto: Crypto,
|
|
59
|
+
readonly context: Uint8Array,
|
|
60
|
+
readonly random: bigint,
|
|
61
|
+
readonly w0: bigint,
|
|
62
|
+
) {
|
|
63
|
+
this.#crypto = crypto;
|
|
64
|
+
this.#context = context;
|
|
65
|
+
this.#random = random;
|
|
66
|
+
this.#w0 = w0;
|
|
67
|
+
}
|
|
57
68
|
|
|
58
69
|
computeX(): Uint8Array {
|
|
59
|
-
const X = ProjectivePoint.BASE.multiply(this
|
|
70
|
+
const X = ProjectivePoint.BASE.multiply(this.#random).add(M.multiply(this.#w0));
|
|
60
71
|
return X.toRawBytes(false);
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
computeY(): Uint8Array {
|
|
64
|
-
const Y = ProjectivePoint.BASE.multiply(this
|
|
75
|
+
const Y = ProjectivePoint.BASE.multiply(this.#random).add(N.multiply(this.#w0));
|
|
65
76
|
return Y.toRawBytes(false);
|
|
66
77
|
}
|
|
67
78
|
|
|
@@ -72,8 +83,8 @@ export class Spake2p {
|
|
|
72
83
|
} catch (error) {
|
|
73
84
|
throw new InternalError(`Y is not on the curve: ${(error as any).message}`);
|
|
74
85
|
}
|
|
75
|
-
const yNwo = YPoint.add(N.multiply(this
|
|
76
|
-
const Z = yNwo.multiply(this
|
|
86
|
+
const yNwo = YPoint.add(N.multiply(this.#w0).negate());
|
|
87
|
+
const Z = yNwo.multiply(this.#random);
|
|
77
88
|
const V = yNwo.multiply(w1);
|
|
78
89
|
return this.computeSecretAndVerifiers(X, Y, Z.toRawBytes(false), V.toRawBytes(false));
|
|
79
90
|
}
|
|
@@ -86,8 +97,8 @@ export class Spake2p {
|
|
|
86
97
|
} catch (error) {
|
|
87
98
|
throw new InternalError(`X is not on the curve: ${(error as any).message}`);
|
|
88
99
|
}
|
|
89
|
-
const Z = XPoint.add(M.multiply(this
|
|
90
|
-
const V = LPoint.multiply(this
|
|
100
|
+
const Z = XPoint.add(M.multiply(this.#w0).negate()).multiply(this.#random);
|
|
101
|
+
const V = LPoint.multiply(this.#random);
|
|
91
102
|
return this.computeSecretAndVerifiers(X, Y, Z.toRawBytes(false), V.toRawBytes(false));
|
|
92
103
|
}
|
|
93
104
|
|
|
@@ -96,19 +107,19 @@ export class Spake2p {
|
|
|
96
107
|
const Ka = TT_HASH.slice(0, 16);
|
|
97
108
|
const Ke = TT_HASH.slice(16, 32);
|
|
98
109
|
|
|
99
|
-
const KcAB = await
|
|
110
|
+
const KcAB = await this.#crypto.createHkdfKey(Ka, new Uint8Array(0), Bytes.fromString("ConfirmationKeys"), 32);
|
|
100
111
|
const KcA = KcAB.slice(0, 16);
|
|
101
112
|
const KcB = KcAB.slice(16, 32);
|
|
102
113
|
|
|
103
|
-
const hAY = await
|
|
104
|
-
const hBX = await
|
|
114
|
+
const hAY = await this.#crypto.signHmac(KcA, Y);
|
|
115
|
+
const hBX = await this.#crypto.signHmac(KcB, X);
|
|
105
116
|
|
|
106
117
|
return { Ke, hAY, hBX };
|
|
107
118
|
}
|
|
108
119
|
|
|
109
120
|
private computeTranscriptHash(X: Uint8Array, Y: Uint8Array, Z: Uint8Array, V: Uint8Array) {
|
|
110
121
|
const TTwriter = new DataWriter(Endian.Little);
|
|
111
|
-
this.addToContext(TTwriter, this
|
|
122
|
+
this.addToContext(TTwriter, this.#context);
|
|
112
123
|
this.addToContext(TTwriter, Bytes.fromString(""));
|
|
113
124
|
this.addToContext(TTwriter, Bytes.fromString(""));
|
|
114
125
|
this.addToContext(TTwriter, M.toRawBytes(false));
|
|
@@ -117,8 +128,8 @@ export class Spake2p {
|
|
|
117
128
|
this.addToContext(TTwriter, Y);
|
|
118
129
|
this.addToContext(TTwriter, Z);
|
|
119
130
|
this.addToContext(TTwriter, V);
|
|
120
|
-
this.addToContext(TTwriter, numberToBytesBE(this
|
|
121
|
-
return
|
|
131
|
+
this.addToContext(TTwriter, numberToBytesBE(this.#w0, 32));
|
|
132
|
+
return this.#crypto.computeSha256(TTwriter.toByteArray());
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
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 {
|
|
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
|
|
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
|
-
|
|
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());
|
package/src/crypto/index.ts
CHANGED
|
@@ -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 "./
|
|
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
|
-
}
|