cojson 0.10.4 → 0.10.6
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/crypto/PureJSCrypto.js +18 -9
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.js +30 -67
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.js +4 -0
- package/dist/crypto/crypto.js.map +1 -1
- package/package.json +2 -3
- package/src/crypto/PureJSCrypto.ts +21 -19
- package/src/crypto/WasmCrypto.ts +82 -131
- package/src/crypto/crypto.ts +4 -1
- package/src/tests/crypto.test.ts +43 -1
- package/src/tests/cryptoImpl.test.ts +1 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { xsalsa20, xsalsa20_poly1305 } from "@noble/ciphers/salsa";
|
|
2
|
-
import { randomBytes } from "@noble/ciphers/webcrypto/utils";
|
|
3
2
|
import { ed25519, x25519 } from "@noble/curves/ed25519";
|
|
4
3
|
import { blake3 } from "@noble/hashes/blake3";
|
|
5
4
|
import { base58 } from "@scure/base";
|
|
@@ -7,17 +6,21 @@ import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
|
7
6
|
import { stableStringify } from "../jsonStringify.js";
|
|
8
7
|
import { logger } from "../logger.js";
|
|
9
8
|
import { CryptoProvider, textDecoder, textEncoder, } from "./crypto.js";
|
|
9
|
+
/**
|
|
10
|
+
* Pure JavaScript implementation of the CryptoProvider interface using noble-curves and noble-ciphers libraries.
|
|
11
|
+
* This provides a fallback implementation that doesn't require WebAssembly, offering:
|
|
12
|
+
* - Signing/verifying (Ed25519)
|
|
13
|
+
* - Encryption/decryption (XSalsa20)
|
|
14
|
+
* - Sealing/unsealing (X25519 + XSalsa20-Poly1305)
|
|
15
|
+
* - Hashing (BLAKE3)
|
|
16
|
+
*/
|
|
10
17
|
export class PureJSCrypto extends CryptoProvider {
|
|
11
18
|
static async create() {
|
|
12
19
|
return new PureJSCrypto();
|
|
13
20
|
}
|
|
14
|
-
randomBytes(length) {
|
|
15
|
-
return randomBytes(length);
|
|
16
|
-
}
|
|
17
21
|
emptyBlake3State() {
|
|
18
22
|
return blake3.create({});
|
|
19
23
|
}
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
24
|
cloneBlake3State(state) {
|
|
22
25
|
return state.clone();
|
|
23
26
|
}
|
|
@@ -33,6 +36,12 @@ export class PureJSCrypto extends CryptoProvider {
|
|
|
33
36
|
blake3DigestForState(state) {
|
|
34
37
|
return state.clone().digest();
|
|
35
38
|
}
|
|
39
|
+
generateNonce(input) {
|
|
40
|
+
return this.blake3HashOnce(input).slice(0, 24);
|
|
41
|
+
}
|
|
42
|
+
generateJsonNonce(material) {
|
|
43
|
+
return this.generateNonce(textEncoder.encode(stableStringify(material)));
|
|
44
|
+
}
|
|
36
45
|
newEd25519SigningKey() {
|
|
37
46
|
return ed25519.utils.randomPrivateKey();
|
|
38
47
|
}
|
|
@@ -54,20 +63,20 @@ export class PureJSCrypto extends CryptoProvider {
|
|
|
54
63
|
}
|
|
55
64
|
encrypt(value, keySecret, nOnceMaterial) {
|
|
56
65
|
const keySecretBytes = base58.decode(keySecret.substring("keySecret_z".length));
|
|
57
|
-
const nOnce = this.
|
|
66
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
58
67
|
const plaintext = textEncoder.encode(stableStringify(value));
|
|
59
68
|
const ciphertext = xsalsa20(keySecretBytes, nOnce, plaintext);
|
|
60
69
|
return `encrypted_U${bytesToBase64url(ciphertext)}`;
|
|
61
70
|
}
|
|
62
71
|
decryptRaw(encrypted, keySecret, nOnceMaterial) {
|
|
63
72
|
const keySecretBytes = base58.decode(keySecret.substring("keySecret_z".length));
|
|
64
|
-
const nOnce = this.
|
|
73
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
65
74
|
const ciphertext = base64URLtoBytes(encrypted.substring("encrypted_U".length));
|
|
66
75
|
const plaintext = xsalsa20(keySecretBytes, nOnce, ciphertext);
|
|
67
76
|
return textDecoder.decode(plaintext);
|
|
68
77
|
}
|
|
69
78
|
seal({ message, from, to, nOnceMaterial, }) {
|
|
70
|
-
const nOnce = this.
|
|
79
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
71
80
|
const sealerPub = base58.decode(to.substring("sealer_z".length));
|
|
72
81
|
const senderPriv = base58.decode(from.substring("sealerSecret_z".length));
|
|
73
82
|
const plaintext = textEncoder.encode(stableStringify(message));
|
|
@@ -76,7 +85,7 @@ export class PureJSCrypto extends CryptoProvider {
|
|
|
76
85
|
return `sealed_U${bytesToBase64url(sealedBytes)}`;
|
|
77
86
|
}
|
|
78
87
|
unseal(sealed, sealer, from, nOnceMaterial) {
|
|
79
|
-
const nOnce = this.
|
|
88
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
80
89
|
const sealerPriv = base58.decode(sealer.substring("sealerSecret_z".length));
|
|
81
90
|
const senderPub = base58.decode(from.substring("sealer_z".length));
|
|
82
91
|
const sealedBytes = base64URLtoBytes(sealed.substring("sealed_U".length));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PureJSCrypto.js","sourceRoot":"","sources":["../../src/crypto/PureJSCrypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PureJSCrypto.js","sourceRoot":"","sources":["../../src/crypto/PureJSCrypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,114 +1,77 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { xsalsa20, xsalsa20_poly1305 } from "@noble/ciphers/salsa";
|
|
3
|
-
import { randomBytes } from "@noble/ciphers/webcrypto/utils";
|
|
4
|
-
import { base58 } from "@scure/base";
|
|
5
|
-
import { createBLAKE3 } from "hash-wasm";
|
|
1
|
+
import { blake3_empty_state, blake3_hash_once, blake3_hash_once_with_context, decrypt, encrypt, get_sealer_id, get_signer_id, new_ed25519_signing_key, new_x25519_private_key, seal, sign, unseal, verify, } from "jazz-crypto-rs";
|
|
6
2
|
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
7
3
|
import { stableStringify } from "../jsonStringify.js";
|
|
8
4
|
import { logger } from "../logger.js";
|
|
9
5
|
import { CryptoProvider, textDecoder, textEncoder, } from "./crypto.js";
|
|
6
|
+
/**
|
|
7
|
+
* WebAssembly implementation of the CryptoProvider interface using jazz-crypto-rs.
|
|
8
|
+
* This provides the primary implementation using WebAssembly for optimal performance, offering:
|
|
9
|
+
* - Signing/verifying (Ed25519)
|
|
10
|
+
* - Encryption/decryption (XSalsa20)
|
|
11
|
+
* - Sealing/unsealing (X25519 + XSalsa20-Poly1305)
|
|
12
|
+
* - Hashing (BLAKE3)
|
|
13
|
+
*/
|
|
10
14
|
export class WasmCrypto extends CryptoProvider {
|
|
11
|
-
constructor(
|
|
15
|
+
constructor() {
|
|
12
16
|
super();
|
|
13
|
-
this.blake3Instance = blake3Instance;
|
|
14
17
|
}
|
|
15
18
|
static async create() {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
randomBytes(length) {
|
|
19
|
-
return randomBytes(length);
|
|
19
|
+
return new WasmCrypto();
|
|
20
20
|
}
|
|
21
21
|
emptyBlake3State() {
|
|
22
|
-
return
|
|
22
|
+
return blake3_empty_state();
|
|
23
23
|
}
|
|
24
24
|
cloneBlake3State(state) {
|
|
25
|
-
return
|
|
25
|
+
return state.clone();
|
|
26
26
|
}
|
|
27
27
|
blake3HashOnce(data) {
|
|
28
|
-
return
|
|
28
|
+
return blake3_hash_once(data);
|
|
29
29
|
}
|
|
30
30
|
blake3HashOnceWithContext(data, { context }) {
|
|
31
|
-
return
|
|
32
|
-
.init()
|
|
33
|
-
.update(context)
|
|
34
|
-
.update(data)
|
|
35
|
-
.digest("binary");
|
|
31
|
+
return blake3_hash_once_with_context(data, context);
|
|
36
32
|
}
|
|
37
33
|
blake3IncrementalUpdate(state, data) {
|
|
38
|
-
|
|
34
|
+
state.update(data);
|
|
35
|
+
return state;
|
|
39
36
|
}
|
|
40
37
|
blake3DigestForState(state) {
|
|
41
|
-
return
|
|
38
|
+
return state.finalize();
|
|
42
39
|
}
|
|
43
40
|
newEd25519SigningKey() {
|
|
44
|
-
return
|
|
41
|
+
return new_ed25519_signing_key();
|
|
45
42
|
}
|
|
46
43
|
getSignerID(secret) {
|
|
47
|
-
return
|
|
48
|
-
.public()
|
|
49
|
-
.to_bytes()
|
|
50
|
-
.copyAndDispose())}`;
|
|
44
|
+
return get_signer_id(textEncoder.encode(secret));
|
|
51
45
|
}
|
|
52
46
|
sign(secret, message) {
|
|
53
|
-
|
|
54
|
-
.sign(new Memory(textEncoder.encode(stableStringify(message))))
|
|
55
|
-
.to_bytes()
|
|
56
|
-
.copyAndDispose();
|
|
57
|
-
return `signature_z${base58.encode(signature)}`;
|
|
47
|
+
return sign(textEncoder.encode(stableStringify(message)), textEncoder.encode(secret));
|
|
58
48
|
}
|
|
59
49
|
verify(signature, message, id) {
|
|
60
|
-
return
|
|
50
|
+
return verify(textEncoder.encode(signature), textEncoder.encode(stableStringify(message)), textEncoder.encode(id));
|
|
61
51
|
}
|
|
62
52
|
newX25519StaticSecret() {
|
|
63
|
-
return
|
|
53
|
+
return new_x25519_private_key();
|
|
64
54
|
}
|
|
65
55
|
getSealerID(secret) {
|
|
66
|
-
return
|
|
67
|
-
.to_public()
|
|
68
|
-
.to_bytes()
|
|
69
|
-
.copyAndDispose())}`;
|
|
56
|
+
return get_sealer_id(textEncoder.encode(secret));
|
|
70
57
|
}
|
|
71
58
|
encrypt(value, keySecret, nOnceMaterial) {
|
|
72
|
-
|
|
73
|
-
const nOnce = this.blake3HashOnce(textEncoder.encode(stableStringify(nOnceMaterial))).slice(0, 24);
|
|
74
|
-
const plaintext = textEncoder.encode(stableStringify(value));
|
|
75
|
-
const ciphertext = xsalsa20(keySecretBytes, nOnce, plaintext);
|
|
76
|
-
return `encrypted_U${bytesToBase64url(ciphertext)}`;
|
|
59
|
+
return `encrypted_U${bytesToBase64url(encrypt(textEncoder.encode(stableStringify(value)), keySecret, textEncoder.encode(stableStringify(nOnceMaterial))))}`;
|
|
77
60
|
}
|
|
78
61
|
decryptRaw(encrypted, keySecret, nOnceMaterial) {
|
|
79
|
-
|
|
80
|
-
const nOnce = this.blake3HashOnce(textEncoder.encode(stableStringify(nOnceMaterial))).slice(0, 24);
|
|
81
|
-
const ciphertext = base64URLtoBytes(encrypted.substring("encrypted_U".length));
|
|
82
|
-
const plaintext = xsalsa20(keySecretBytes, nOnce, ciphertext);
|
|
83
|
-
return textDecoder.decode(plaintext);
|
|
62
|
+
return textDecoder.decode(decrypt(base64URLtoBytes(encrypted.substring("encrypted_U".length)), keySecret, textEncoder.encode(stableStringify(nOnceMaterial))));
|
|
84
63
|
}
|
|
85
64
|
seal({ message, from, to, nOnceMaterial, }) {
|
|
86
|
-
|
|
87
|
-
const sealerPub = base58.decode(to.substring("sealer_z".length));
|
|
88
|
-
const senderPriv = base58.decode(from.substring("sealerSecret_z".length));
|
|
89
|
-
const plaintext = textEncoder.encode(stableStringify(message));
|
|
90
|
-
const sharedSecret = X25519StaticSecret.from_bytes(new Memory(senderPriv))
|
|
91
|
-
.diffie_hellman(X25519PublicKey.from_bytes(new Memory(sealerPub)))
|
|
92
|
-
.to_bytes()
|
|
93
|
-
.copyAndDispose();
|
|
94
|
-
const sealedBytes = xsalsa20_poly1305(sharedSecret, nOnce).encrypt(plaintext);
|
|
95
|
-
return `sealed_U${bytesToBase64url(sealedBytes)}`;
|
|
65
|
+
return `sealed_U${bytesToBase64url(seal(textEncoder.encode(stableStringify(message)), from, to, textEncoder.encode(stableStringify(nOnceMaterial))))}`;
|
|
96
66
|
}
|
|
97
67
|
unseal(sealed, sealer, from, nOnceMaterial) {
|
|
98
|
-
const
|
|
99
|
-
const sealerPriv = base58.decode(sealer.substring("sealerSecret_z".length));
|
|
100
|
-
const senderPub = base58.decode(from.substring("sealer_z".length));
|
|
101
|
-
const sealedBytes = base64URLtoBytes(sealed.substring("sealed_U".length));
|
|
102
|
-
const sharedSecret = X25519StaticSecret.from_bytes(new Memory(sealerPriv))
|
|
103
|
-
.diffie_hellman(X25519PublicKey.from_bytes(new Memory(senderPub)))
|
|
104
|
-
.to_bytes()
|
|
105
|
-
.copyAndDispose();
|
|
106
|
-
const plaintext = xsalsa20_poly1305(sharedSecret, nOnce).decrypt(sealedBytes);
|
|
68
|
+
const plaintext = textDecoder.decode(unseal(base64URLtoBytes(sealed.substring("sealed_U".length)), sealer, from, textEncoder.encode(stableStringify(nOnceMaterial))));
|
|
107
69
|
try {
|
|
108
|
-
return JSON.parse(
|
|
70
|
+
return JSON.parse(plaintext);
|
|
109
71
|
}
|
|
110
72
|
catch (e) {
|
|
111
73
|
logger.error("Failed to decrypt/parse sealed message: " + e?.message);
|
|
74
|
+
return undefined;
|
|
112
75
|
}
|
|
113
76
|
}
|
|
114
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WasmCrypto.js","sourceRoot":"","sources":["../../src/crypto/WasmCrypto.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"WasmCrypto.js","sourceRoot":"","sources":["../../src/crypto/WasmCrypto.ts"],"names":[],"mappings":"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"}
|
package/dist/crypto/crypto.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomBytes } from "@noble/ciphers/webcrypto/utils";
|
|
1
2
|
import { base58 } from "@scure/base";
|
|
2
3
|
import { parseJSON, stableStringify } from "../jsonStringify.js";
|
|
3
4
|
import { logger } from "../logger.js";
|
|
@@ -5,6 +6,9 @@ export const textEncoder = new TextEncoder();
|
|
|
5
6
|
export const textDecoder = new TextDecoder();
|
|
6
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
8
|
export class CryptoProvider {
|
|
9
|
+
randomBytes(length) {
|
|
10
|
+
return randomBytes(length);
|
|
11
|
+
}
|
|
8
12
|
newRandomSigner() {
|
|
9
13
|
return `signerSecret_z${base58.encode(this.newEd25519SigningKey())}`;
|
|
10
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAe,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAYtC,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAE7C,8DAA8D;AAC9D,MAAM,OAAgB,cAAc;
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto/crypto.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -25,20 +25,19 @@
|
|
|
25
25
|
},
|
|
26
26
|
"type": "module",
|
|
27
27
|
"license": "MIT",
|
|
28
|
-
"version": "0.10.
|
|
28
|
+
"version": "0.10.6",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@opentelemetry/sdk-metrics": "^1.29.0",
|
|
31
31
|
"typescript": "~5.6.2",
|
|
32
32
|
"vitest": "3.0.5"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@hazae41/berith": "^1.2.6",
|
|
36
35
|
"@noble/ciphers": "^0.1.3",
|
|
37
36
|
"@noble/curves": "^1.3.0",
|
|
38
37
|
"@noble/hashes": "^1.4.0",
|
|
39
38
|
"@opentelemetry/api": "^1.0.0",
|
|
40
39
|
"@scure/base": "1.2.1",
|
|
41
|
-
"
|
|
40
|
+
"jazz-crypto-rs": "0.0.3",
|
|
42
41
|
"neverthrow": "^7.0.1",
|
|
43
42
|
"queueueue": "^4.1.2"
|
|
44
43
|
},
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { xsalsa20, xsalsa20_poly1305 } from "@noble/ciphers/salsa";
|
|
2
|
-
import { randomBytes } from "@noble/ciphers/webcrypto/utils";
|
|
3
2
|
import { ed25519, x25519 } from "@noble/curves/ed25519";
|
|
4
3
|
import { blake3 } from "@noble/hashes/blake3";
|
|
5
4
|
import { base58 } from "@scure/base";
|
|
@@ -24,21 +23,24 @@ import {
|
|
|
24
23
|
|
|
25
24
|
type Blake3State = ReturnType<typeof blake3.create>;
|
|
26
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Pure JavaScript implementation of the CryptoProvider interface using noble-curves and noble-ciphers libraries.
|
|
28
|
+
* This provides a fallback implementation that doesn't require WebAssembly, offering:
|
|
29
|
+
* - Signing/verifying (Ed25519)
|
|
30
|
+
* - Encryption/decryption (XSalsa20)
|
|
31
|
+
* - Sealing/unsealing (X25519 + XSalsa20-Poly1305)
|
|
32
|
+
* - Hashing (BLAKE3)
|
|
33
|
+
*/
|
|
27
34
|
export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
28
35
|
static async create(): Promise<PureJSCrypto> {
|
|
29
36
|
return new PureJSCrypto();
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
randomBytes(length: number): Uint8Array {
|
|
33
|
-
return randomBytes(length);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
39
|
emptyBlake3State(): Blake3State {
|
|
37
40
|
return blake3.create({});
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
cloneBlake3State(state: any): Blake3State {
|
|
43
|
+
cloneBlake3State(state: Blake3State): Blake3State {
|
|
42
44
|
return state.clone();
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -61,6 +63,14 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
|
61
63
|
return state.clone().digest();
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
generateNonce(input: Uint8Array): Uint8Array {
|
|
67
|
+
return this.blake3HashOnce(input).slice(0, 24);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private generateJsonNonce(material: JsonValue): Uint8Array {
|
|
71
|
+
return this.generateNonce(textEncoder.encode(stableStringify(material)));
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
newEd25519SigningKey(): Uint8Array {
|
|
65
75
|
return ed25519.utils.randomPrivateKey();
|
|
66
76
|
}
|
|
@@ -109,9 +119,7 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
|
109
119
|
const keySecretBytes = base58.decode(
|
|
110
120
|
keySecret.substring("keySecret_z".length),
|
|
111
121
|
);
|
|
112
|
-
const nOnce = this.
|
|
113
|
-
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
114
|
-
).slice(0, 24);
|
|
122
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
115
123
|
|
|
116
124
|
const plaintext = textEncoder.encode(stableStringify(value));
|
|
117
125
|
const ciphertext = xsalsa20(keySecretBytes, nOnce, plaintext);
|
|
@@ -126,9 +134,7 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
|
126
134
|
const keySecretBytes = base58.decode(
|
|
127
135
|
keySecret.substring("keySecret_z".length),
|
|
128
136
|
);
|
|
129
|
-
const nOnce = this.
|
|
130
|
-
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
131
|
-
).slice(0, 24);
|
|
137
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
132
138
|
|
|
133
139
|
const ciphertext = base64URLtoBytes(
|
|
134
140
|
encrypted.substring("encrypted_U".length),
|
|
@@ -149,9 +155,7 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
|
149
155
|
to: SealerID;
|
|
150
156
|
nOnceMaterial: { in: RawCoID; tx: TransactionID };
|
|
151
157
|
}): Sealed<T> {
|
|
152
|
-
const nOnce = this.
|
|
153
|
-
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
154
|
-
).slice(0, 24);
|
|
158
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
155
159
|
|
|
156
160
|
const sealerPub = base58.decode(to.substring("sealer_z".length));
|
|
157
161
|
|
|
@@ -174,9 +178,7 @@ export class PureJSCrypto extends CryptoProvider<Blake3State> {
|
|
|
174
178
|
from: SealerID,
|
|
175
179
|
nOnceMaterial: { in: RawCoID; tx: TransactionID },
|
|
176
180
|
): T | undefined {
|
|
177
|
-
const nOnce = this.
|
|
178
|
-
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
179
|
-
).slice(0, 24);
|
|
181
|
+
const nOnce = this.generateJsonNonce(nOnceMaterial);
|
|
180
182
|
|
|
181
183
|
const sealerPriv = base58.decode(sealer.substring("sealerSecret_z".length));
|
|
182
184
|
|
package/src/crypto/WasmCrypto.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
Blake3Hasher,
|
|
3
|
+
blake3_empty_state,
|
|
4
|
+
blake3_hash_once,
|
|
5
|
+
blake3_hash_once_with_context,
|
|
6
|
+
decrypt,
|
|
7
|
+
encrypt,
|
|
8
|
+
get_sealer_id,
|
|
9
|
+
get_signer_id,
|
|
10
|
+
new_ed25519_signing_key,
|
|
11
|
+
new_x25519_private_key,
|
|
12
|
+
seal,
|
|
13
|
+
sign,
|
|
14
|
+
unseal,
|
|
15
|
+
verify,
|
|
16
|
+
} from "jazz-crypto-rs";
|
|
14
17
|
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
15
18
|
import { RawCoID, TransactionID } from "../ids.js";
|
|
16
19
|
import { Stringified, stableStringify } from "../jsonStringify.js";
|
|
@@ -30,103 +33,82 @@ import {
|
|
|
30
33
|
textEncoder,
|
|
31
34
|
} from "./crypto.js";
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
type Blake3State = Blake3Hasher;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* WebAssembly implementation of the CryptoProvider interface using jazz-crypto-rs.
|
|
40
|
+
* This provides the primary implementation using WebAssembly for optimal performance, offering:
|
|
41
|
+
* - Signing/verifying (Ed25519)
|
|
42
|
+
* - Encryption/decryption (XSalsa20)
|
|
43
|
+
* - Sealing/unsealing (X25519 + XSalsa20-Poly1305)
|
|
44
|
+
* - Hashing (BLAKE3)
|
|
45
|
+
*/
|
|
46
|
+
export class WasmCrypto extends CryptoProvider<Blake3State> {
|
|
47
|
+
private constructor() {
|
|
37
48
|
super();
|
|
38
49
|
}
|
|
39
50
|
|
|
40
51
|
static async create(): Promise<WasmCrypto> {
|
|
41
|
-
return
|
|
42
|
-
([blake3instance]) => new WasmCrypto(blake3instance),
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
randomBytes(length: number): Uint8Array {
|
|
47
|
-
return randomBytes(length);
|
|
52
|
+
return new WasmCrypto();
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
emptyBlake3State():
|
|
51
|
-
return
|
|
55
|
+
emptyBlake3State(): Blake3State {
|
|
56
|
+
return blake3_empty_state();
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
cloneBlake3State(state:
|
|
55
|
-
return
|
|
59
|
+
cloneBlake3State(state: Blake3State): Blake3State {
|
|
60
|
+
return state.clone();
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
blake3HashOnce(data: Uint8Array) {
|
|
59
|
-
return
|
|
64
|
+
return blake3_hash_once(data);
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
blake3HashOnceWithContext(
|
|
63
68
|
data: Uint8Array,
|
|
64
69
|
{ context }: { context: Uint8Array },
|
|
65
70
|
) {
|
|
66
|
-
return
|
|
67
|
-
.init()
|
|
68
|
-
.update(context)
|
|
69
|
-
.update(data)
|
|
70
|
-
.digest("binary");
|
|
71
|
+
return blake3_hash_once_with_context(data, context);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
blake3IncrementalUpdate(state:
|
|
74
|
-
|
|
74
|
+
blake3IncrementalUpdate(state: Blake3State, data: Uint8Array): Blake3State {
|
|
75
|
+
state.update(data);
|
|
76
|
+
return state;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
blake3DigestForState(state:
|
|
78
|
-
return
|
|
79
|
+
blake3DigestForState(state: Blake3State): Uint8Array {
|
|
80
|
+
return state.finalize();
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
newEd25519SigningKey(): Uint8Array {
|
|
82
|
-
return
|
|
84
|
+
return new_ed25519_signing_key();
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
getSignerID(secret: SignerSecret): SignerID {
|
|
86
|
-
return
|
|
87
|
-
Ed25519SigningKey.from_bytes(
|
|
88
|
-
new Memory(base58.decode(secret.substring("signerSecret_z".length))),
|
|
89
|
-
)
|
|
90
|
-
.public()
|
|
91
|
-
.to_bytes()
|
|
92
|
-
.copyAndDispose(),
|
|
93
|
-
)}`;
|
|
88
|
+
return get_signer_id(textEncoder.encode(secret)) as SignerID;
|
|
94
89
|
}
|
|
95
90
|
|
|
96
91
|
sign(secret: SignerSecret, message: JsonValue): Signature {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.to_bytes()
|
|
102
|
-
.copyAndDispose();
|
|
103
|
-
return `signature_z${base58.encode(signature)}`;
|
|
92
|
+
return sign(
|
|
93
|
+
textEncoder.encode(stableStringify(message)),
|
|
94
|
+
textEncoder.encode(secret),
|
|
95
|
+
) as Signature;
|
|
104
96
|
}
|
|
105
97
|
|
|
106
98
|
verify(signature: Signature, message: JsonValue, id: SignerID): boolean {
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
new Ed25519Signature(
|
|
112
|
-
new Memory(base58.decode(signature.substring("signature_z".length))),
|
|
113
|
-
),
|
|
99
|
+
return verify(
|
|
100
|
+
textEncoder.encode(signature),
|
|
101
|
+
textEncoder.encode(stableStringify(message)),
|
|
102
|
+
textEncoder.encode(id),
|
|
114
103
|
);
|
|
115
104
|
}
|
|
116
105
|
|
|
117
106
|
newX25519StaticSecret(): Uint8Array {
|
|
118
|
-
return
|
|
107
|
+
return new_x25519_private_key();
|
|
119
108
|
}
|
|
120
109
|
|
|
121
110
|
getSealerID(secret: SealerSecret): SealerID {
|
|
122
|
-
return
|
|
123
|
-
X25519StaticSecret.from_bytes(
|
|
124
|
-
new Memory(base58.decode(secret.substring("sealerSecret_z".length))),
|
|
125
|
-
)
|
|
126
|
-
.to_public()
|
|
127
|
-
.to_bytes()
|
|
128
|
-
.copyAndDispose(),
|
|
129
|
-
)}`;
|
|
111
|
+
return get_sealer_id(textEncoder.encode(secret)) as SealerID;
|
|
130
112
|
}
|
|
131
113
|
|
|
132
114
|
encrypt<T extends JsonValue, N extends JsonValue>(
|
|
@@ -134,16 +116,13 @@ export class WasmCrypto extends CryptoProvider<Uint8Array> {
|
|
|
134
116
|
keySecret: KeySecret,
|
|
135
117
|
nOnceMaterial: N,
|
|
136
118
|
): Encrypted<T, N> {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const plaintext = textEncoder.encode(stableStringify(value));
|
|
145
|
-
const ciphertext = xsalsa20(keySecretBytes, nOnce, plaintext);
|
|
146
|
-
return `encrypted_U${bytesToBase64url(ciphertext)}` as Encrypted<T, N>;
|
|
119
|
+
return `encrypted_U${bytesToBase64url(
|
|
120
|
+
encrypt(
|
|
121
|
+
textEncoder.encode(stableStringify(value)),
|
|
122
|
+
keySecret,
|
|
123
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
124
|
+
),
|
|
125
|
+
)}` as Encrypted<T, N>;
|
|
147
126
|
}
|
|
148
127
|
|
|
149
128
|
decryptRaw<T extends JsonValue, N extends JsonValue>(
|
|
@@ -151,19 +130,13 @@ export class WasmCrypto extends CryptoProvider<Uint8Array> {
|
|
|
151
130
|
keySecret: KeySecret,
|
|
152
131
|
nOnceMaterial: N,
|
|
153
132
|
): Stringified<T> {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const ciphertext = base64URLtoBytes(
|
|
162
|
-
encrypted.substring("encrypted_U".length),
|
|
163
|
-
);
|
|
164
|
-
const plaintext = xsalsa20(keySecretBytes, nOnce, ciphertext);
|
|
165
|
-
|
|
166
|
-
return textDecoder.decode(plaintext) as Stringified<T>;
|
|
133
|
+
return textDecoder.decode(
|
|
134
|
+
decrypt(
|
|
135
|
+
base64URLtoBytes(encrypted.substring("encrypted_U".length)),
|
|
136
|
+
keySecret,
|
|
137
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
138
|
+
),
|
|
139
|
+
) as Stringified<T>;
|
|
167
140
|
}
|
|
168
141
|
|
|
169
142
|
seal<T extends JsonValue>({
|
|
@@ -177,26 +150,14 @@ export class WasmCrypto extends CryptoProvider<Uint8Array> {
|
|
|
177
150
|
to: SealerID;
|
|
178
151
|
nOnceMaterial: { in: RawCoID; tx: TransactionID };
|
|
179
152
|
}): Sealed<T> {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const plaintext = textEncoder.encode(stableStringify(message));
|
|
189
|
-
|
|
190
|
-
const sharedSecret = X25519StaticSecret.from_bytes(new Memory(senderPriv))
|
|
191
|
-
.diffie_hellman(X25519PublicKey.from_bytes(new Memory(sealerPub)))
|
|
192
|
-
.to_bytes()
|
|
193
|
-
.copyAndDispose();
|
|
194
|
-
|
|
195
|
-
const sealedBytes = xsalsa20_poly1305(sharedSecret, nOnce).encrypt(
|
|
196
|
-
plaintext,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
return `sealed_U${bytesToBase64url(sealedBytes)}` as Sealed<T>;
|
|
153
|
+
return `sealed_U${bytesToBase64url(
|
|
154
|
+
seal(
|
|
155
|
+
textEncoder.encode(stableStringify(message)),
|
|
156
|
+
from,
|
|
157
|
+
to,
|
|
158
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
159
|
+
),
|
|
160
|
+
)}` as Sealed<T>;
|
|
200
161
|
}
|
|
201
162
|
|
|
202
163
|
unseal<T extends JsonValue>(
|
|
@@ -205,31 +166,21 @@ export class WasmCrypto extends CryptoProvider<Uint8Array> {
|
|
|
205
166
|
from: SealerID,
|
|
206
167
|
nOnceMaterial: { in: RawCoID; tx: TransactionID },
|
|
207
168
|
): T | undefined {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const sealedBytes = base64URLtoBytes(sealed.substring("sealed_U".length));
|
|
217
|
-
|
|
218
|
-
const sharedSecret = X25519StaticSecret.from_bytes(new Memory(sealerPriv))
|
|
219
|
-
.diffie_hellman(X25519PublicKey.from_bytes(new Memory(senderPub)))
|
|
220
|
-
.to_bytes()
|
|
221
|
-
.copyAndDispose();
|
|
222
|
-
|
|
223
|
-
const plaintext = xsalsa20_poly1305(sharedSecret, nOnce).decrypt(
|
|
224
|
-
sealedBytes,
|
|
169
|
+
const plaintext = textDecoder.decode(
|
|
170
|
+
unseal(
|
|
171
|
+
base64URLtoBytes(sealed.substring("sealed_U".length)),
|
|
172
|
+
sealer,
|
|
173
|
+
from,
|
|
174
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
175
|
+
),
|
|
225
176
|
);
|
|
226
|
-
|
|
227
177
|
try {
|
|
228
|
-
return JSON.parse(
|
|
178
|
+
return JSON.parse(plaintext) as T;
|
|
229
179
|
} catch (e) {
|
|
230
180
|
logger.error(
|
|
231
181
|
"Failed to decrypt/parse sealed message: " + (e as Error)?.message,
|
|
232
182
|
);
|
|
183
|
+
return undefined;
|
|
233
184
|
}
|
|
234
185
|
}
|
|
235
186
|
}
|
package/src/crypto/crypto.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomBytes } from "@noble/ciphers/webcrypto/utils";
|
|
1
2
|
import { base58 } from "@scure/base";
|
|
2
3
|
import { RawAccountID } from "../coValues/account.js";
|
|
3
4
|
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
|
@@ -21,7 +22,9 @@ export const textDecoder = new TextDecoder();
|
|
|
21
22
|
|
|
22
23
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
24
|
export abstract class CryptoProvider<Blake3State = any> {
|
|
24
|
-
|
|
25
|
+
randomBytes(length: number): Uint8Array {
|
|
26
|
+
return randomBytes(length);
|
|
27
|
+
}
|
|
25
28
|
|
|
26
29
|
abstract newEd25519SigningKey(): Uint8Array;
|
|
27
30
|
|
package/src/tests/crypto.test.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { xsalsa20_poly1305 } from "@noble/ciphers/salsa";
|
|
|
2
2
|
import { x25519 } from "@noble/curves/ed25519";
|
|
3
3
|
import { blake3 } from "@noble/hashes/blake3";
|
|
4
4
|
import { base58, base64url } from "@scure/base";
|
|
5
|
-
import { expect, test } from "vitest";
|
|
5
|
+
import { expect, test, vi } from "vitest";
|
|
6
6
|
import { PureJSCrypto } from "../crypto/PureJSCrypto.js";
|
|
7
7
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
8
8
|
import { SessionID } from "../ids.js";
|
|
@@ -186,4 +186,46 @@ const pureJSCrypto = await PureJSCrypto.create();
|
|
|
186
186
|
|
|
187
187
|
expect(decrypted).toBeUndefined();
|
|
188
188
|
});
|
|
189
|
+
|
|
190
|
+
test(`Unsealing malformed JSON logs error [${name}]`, () => {
|
|
191
|
+
const data = "not valid json";
|
|
192
|
+
const sender = crypto.newRandomSealer();
|
|
193
|
+
const sealer = crypto.newRandomSealer();
|
|
194
|
+
|
|
195
|
+
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
196
|
+
|
|
197
|
+
const nOnceMaterial = {
|
|
198
|
+
in: "co_zTEST",
|
|
199
|
+
tx: { sessionID: "co_zTEST_session_zTEST" as SessionID, txIndex: 0 },
|
|
200
|
+
} as const;
|
|
201
|
+
|
|
202
|
+
// Create a sealed message with invalid JSON
|
|
203
|
+
const nOnce = blake3(
|
|
204
|
+
new TextEncoder().encode(stableStringify(nOnceMaterial)),
|
|
205
|
+
).slice(0, 24);
|
|
206
|
+
|
|
207
|
+
const senderPriv = base58.decode(sender.substring("sealerSecret_z".length));
|
|
208
|
+
const sealerPub = base58.decode(
|
|
209
|
+
crypto.getSealerID(sealer).substring("sealer_z".length),
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const plaintext = new TextEncoder().encode(data);
|
|
213
|
+
const sharedSecret = x25519.getSharedSecret(senderPriv, sealerPub);
|
|
214
|
+
const sealedBytes = xsalsa20_poly1305(sharedSecret, nOnce).encrypt(
|
|
215
|
+
plaintext,
|
|
216
|
+
);
|
|
217
|
+
const sealed = `sealed_U${base64url.encode(sealedBytes)}`;
|
|
218
|
+
|
|
219
|
+
const result = crypto.unseal(
|
|
220
|
+
sealed as any,
|
|
221
|
+
sealer,
|
|
222
|
+
crypto.getSealerID(sender),
|
|
223
|
+
nOnceMaterial,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
expect(result).toBeUndefined();
|
|
227
|
+
expect(consoleSpy.mock.lastCall?.[0]).toContain(
|
|
228
|
+
"Failed to decrypt/parse sealed message",
|
|
229
|
+
);
|
|
230
|
+
});
|
|
189
231
|
});
|
|
@@ -7,7 +7,7 @@ import { SessionID } from "../ids.js";
|
|
|
7
7
|
describe.each([
|
|
8
8
|
{ impl: await WasmCrypto.create(), name: "Wasm" },
|
|
9
9
|
{ impl: await PureJSCrypto.create(), name: "PureJS" },
|
|
10
|
-
])("
|
|
10
|
+
])("$name implementation", ({ impl, name }) => {
|
|
11
11
|
test("randomBytes", () => {
|
|
12
12
|
expect(impl.randomBytes(32).length).toEqual(32);
|
|
13
13
|
});
|