@owlmeans/basic-keys 0.1.18-rc.46 → 0.1.18-rc.47

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/README.md CHANGED
@@ -12,7 +12,7 @@ ED25519 and XChaCha20 cryptographic key operations: generation, signing, verific
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/basic-keys@^0.1.18-rc.46
15
+ bun add @owlmeans/basic-keys@^0.1.18-rc.47
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -89,7 +89,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
89
89
  your project's skill store (`.agents/skills/`):
90
90
 
91
91
  ```sh
92
- npx @owlmeans/agent-skills@^0.1.18-rc.47
92
+ npx @owlmeans/agent-skills@^0.1.18-rc.48
93
93
  ```
94
94
 
95
95
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/basic-keys",
4
- "version": "0.1.18-rc.46",
5
- "generatedAt": "2026-10-03T20:05:07.581Z",
4
+ "version": "0.1.18-rc.47",
5
+ "generatedAt": "2026-10-05T08:32:19.086Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/basic-keys
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/basic-keys": "^0.1.18-rc.46"` in `dependencies`
11
+ **Install:** `"@owlmeans/basic-keys": "^0.1.18-rc.47"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
package/build/bin.js CHANGED
File without changes
@@ -1,10 +1,10 @@
1
1
  import { KeyType } from '../consts.js';
2
- import { ed25519 } from '@noble/curves/ed25519';
2
+ import { ed25519 } from '@noble/curves/ed25519.js';
3
3
  import { base58 } from '@scure/base';
4
- import { keccak_256 } from '@noble/hashes/sha3';
4
+ import { keccak_256 } from '@noble/hashes/sha3.js';
5
5
  export const ed25519Plugin = {
6
6
  type: KeyType.ED25519,
7
- random: () => ed25519.utils.randomPrivateKey(),
7
+ random: () => ed25519.utils.randomSecretKey(),
8
8
  sign: (data, pk) => ed25519.sign(data, pk),
9
9
  verify: (data, signature, pub) => ed25519.verify(signature, data, pub),
10
10
  toPublic: pk => ed25519.getPublicKey(pk),
@@ -1 +1 @@
1
- {"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../../src/plugins/ed25519.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,OAAO,CAAC,OAAO;IAErB,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE;IAE9C,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IAE1C,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC;IAEtE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;IAExC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAEnE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAA,CAAC,CAAC;IAE9E,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAA,CAAC,CAAC;CAC/E,CAAA"}
1
+ {"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../../src/plugins/ed25519.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAElD,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,OAAO,CAAC,OAAO;IAErB,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE;IAE7C,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IAE1C,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC;IAEtE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;IAExC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAEnE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAA,CAAC,CAAC;IAE9E,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAA,CAAC,CAAC;CAC/E,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { KeyType } from '../consts.js';
2
- import { xchacha20poly1305 } from '@noble/ciphers/chacha';
3
- import { randomBytes, managedNonce } from '@noble/ciphers/webcrypto';
2
+ import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';
3
+ import { randomBytes, managedNonce } from '@noble/ciphers/utils.js';
4
4
  export const xChahaPlugin = {
5
5
  type: KeyType.XCHACHA,
6
6
  random: () => randomBytes(32),
@@ -1 +1 @@
1
- {"version":3,"file":"xchacha.js","sourceRoot":"","sources":["../../src/plugins/xchacha.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGpE,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,OAAO,CAAC,OAAO;IAErB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IAE7B,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,UAAU,CAAC,CAAA,CAAC,CAAC;IAE/D,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,eAAe,CAAC,CAAA,CAAC,CAAC;IAEtE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;IAElB,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY;IAE5B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAExE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACzE,CAAA"}
1
+ {"version":3,"file":"xchacha.js","sourceRoot":"","sources":["../../src/plugins/xchacha.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAGnE,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,OAAO,CAAC,OAAO;IAErB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IAE7B,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,UAAU,CAAC,CAAA,CAAC,CAAC;IAE/D,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,eAAe,CAAC,CAAA,CAAC,CAAC;IAEtE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;IAElB,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY;IAE5B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAExE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACzE,CAAA"}
package/build/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { keccak_256 } from '@noble/hashes/sha3';
1
+ import { keccak_256 } from '@noble/hashes/sha3.js';
2
2
  import { base64, utf8 } from '@scure/base';
3
3
  import { plugins } from './plugins/index.js';
4
4
  import canonicalize from 'canonicalize';
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,YAAY,MAAM,cAAc,CAAA;AAEvC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAqB,EAAc,EAAE,CAC7D,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAc,EAAE,CACpD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAEpB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAa,EAAc,EAAE;IACvD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;SAAM,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAa,EAAQ,EAAE;IAChD,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,YAAY,MAAM,cAAc,CAAA;AAEvC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAqB,EAAc,EAAE,CAC7D,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAc,EAAE,CACpD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAEpB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAa,EAAc,EAAE;IACvD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;SAAM,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAa,EAAQ,EAAE;IAChD,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/basic-keys",
3
- "version": "0.1.18-rc.46",
3
+ "version": "0.1.18-rc.47",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -40,18 +40,18 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@owlmeans/dep-config": "workspace:*",
43
- "@owlmeans/test-auth": "^0.1.18-rc.44",
44
- "@types/bun": "^1.4.0",
43
+ "@owlmeans/test-auth": "^0.1.18-rc.45",
44
+ "@types/bun": "^1.4.2",
45
45
  "nodemon": "^3.1.14",
46
46
  "typescript": "^7.0.2"
47
47
  },
48
48
  "dependencies": {
49
- "@noble/ciphers": "^1.2.1",
50
- "@noble/curves": "^1.6.0",
51
- "@noble/hashes": "^1.5.0",
52
- "@owlmeans/auth": "^0.1.18-rc.38",
53
- "@scure/base": "^2.3.0",
54
- "canonicalize": "^2.0.0"
49
+ "@noble/ciphers": "^2.4.0",
50
+ "@noble/curves": "^2.4.0",
51
+ "@noble/hashes": "^2.4.0",
52
+ "@owlmeans/auth": "^0.1.18-rc.39",
53
+ "@scure/base": "^2.4.0",
54
+ "canonicalize": "^5.1.0"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public"
@@ -1,13 +1,13 @@
1
1
  import { KeyType } from '../consts.js'
2
2
  import type { KeyPlugin } from './types.js'
3
- import { ed25519 } from '@noble/curves/ed25519'
3
+ import { ed25519 } from '@noble/curves/ed25519.js'
4
4
  import { base58 } from '@scure/base'
5
- import { keccak_256 } from '@noble/hashes/sha3'
5
+ import { keccak_256 } from '@noble/hashes/sha3.js'
6
6
 
7
7
  export const ed25519Plugin: KeyPlugin = {
8
8
  type: KeyType.ED25519,
9
9
 
10
- random: () => ed25519.utils.randomPrivateKey(),
10
+ random: () => ed25519.utils.randomSecretKey(),
11
11
 
12
12
  sign: (data, pk) => ed25519.sign(data, pk),
13
13
 
@@ -1,7 +1,7 @@
1
1
  import { KeyType } from '../consts.js'
2
2
  import type { KeyPlugin } from './types.js'
3
- import { xchacha20poly1305 } from '@noble/ciphers/chacha'
4
- import { randomBytes, managedNonce } from '@noble/ciphers/webcrypto'
3
+ import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'
4
+ import { randomBytes, managedNonce } from '@noble/ciphers/utils.js'
5
5
 
6
6
 
7
7
  export const xChahaPlugin: KeyPlugin = {
package/src/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { keccak_256 } from '@noble/hashes/sha3'
1
+ import { keccak_256 } from '@noble/hashes/sha3.js'
2
2
  import { base64, utf8 } from '@scure/base'
3
3
  import { plugins } from './plugins/index.js'
4
4
  import canonicalize from 'canonicalize'
@@ -0,0 +1,68 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'
3
+ import { ed25519 } from '@noble/curves/ed25519.js'
4
+ import { hmac } from '@noble/hashes/hmac.js'
5
+ import { sha256, sha512 } from '@noble/hashes/sha2.js'
6
+ import { keccak_256 } from '@noble/hashes/sha3.js'
7
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'
8
+ import { base58, base64 } from '@scure/base'
9
+ import canonicalize from 'canonicalize'
10
+ import { ed25519Plugin } from '../src/plugins/ed25519.js'
11
+
12
+ /**
13
+ * Answers computed with @noble/hashes 1.8, @noble/curves 1.9, @noble/ciphers 1.3, @scure/base 1.2 and
14
+ * canonicalize 2.1 — the versions this package ran before the v2 line. A round trip passes whatever the
15
+ * library does to its bytes; these do not, so a derivation, an address or a signature that moved fails here.
16
+ */
17
+ const enc = new TextEncoder()
18
+ const SEED = hexToBytes('0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20')
19
+ const PUB = '79b5562e8fe654f94078b112e8a98ba7901f853ae695bed7e0e3910bad049664'
20
+
21
+ describe('@owlmeans/basic-keys — known answers of the crypto primitives', () => {
22
+ test('hashes', () => {
23
+ expect(bytesToHex(sha256(enc.encode('owlmeans')))).toBe('03321b0b5c45f6146418c0aedbf69e6c171002fbd11f13c3c7edff8b1499dbf7')
24
+ expect(bytesToHex(sha512(enc.encode('owlmeans')))).toBe('25c101a119c1f9333f6d2d96c908dc71cc407ba30184c885179c53e7ad4b265c3dcccc1db293f2574d91b615626a91e00526b72c3d5206b8b42dd5153c3ea652')
25
+ expect(bytesToHex(keccak_256(enc.encode('owlmeans')))).toBe('859b6703a20c79d0a3a2ab79f69cd1ed8c5268b1537ee1c433431102ee488563')
26
+ expect(bytesToHex(hmac(sha512, enc.encode('key'), enc.encode('owlmeans')))).toBe('3e0c8942c110583b9c25f03be8e666d55c81393e61d335f486ff3cb5a9c1daf0154e68f79414a49f9c92801c05d01e21f95410fa70af37fe7d17e8108ea5b137')
27
+ })
28
+
29
+ test('an ed25519 key derives the same public key, address and signature', () => {
30
+ const pub = ed25519Plugin.toPublic(SEED)
31
+ expect(bytesToHex(pub)).toBe(PUB)
32
+ expect(base58.encode(pub)).toBe('9C6hybhQ6Aycep9jaUnP6uL9ZYvDjUp1aSkFWPUFJtpj')
33
+ expect(base64.encode(pub)).toBe('ebVWLo/mVPlAeLES6KmLp5AfhTrmlb7X4OORC60ElmQ=')
34
+ expect(ed25519Plugin.toAdress(pub)).toBe('25ypesVVjyxzsRPzbQs8ejHnokbP')
35
+
36
+ const message = enc.encode('hello owlmeans')
37
+ const signature = ed25519Plugin.sign(message, SEED)
38
+ expect(bytesToHex(signature)).toBe('154297b3ce7ecc748bfad553b10e564b0034e857b127a8012d6585fdd4cd2f62348c7ec2a3a9cb20e7c9f3a6681348c2af7ec7c18482ae4def296c6a4423ed0a')
39
+ expect(ed25519Plugin.verify(message, signature, pub)).toBe(true)
40
+ expect(ed25519.verify(signature, enc.encode('hello owlmeans!'), pub)).toBe(false)
41
+ })
42
+
43
+ test('a random ed25519 secret key is 32 bytes and signs verifiably', () => {
44
+ const secret = ed25519Plugin.random()
45
+ expect(secret.length).toBe(32)
46
+ const message = enc.encode('fresh')
47
+ expect(ed25519Plugin.verify(message, ed25519Plugin.sign(message, secret), ed25519Plugin.toPublic(secret))).toBe(true)
48
+ })
49
+
50
+ test('xchacha20-poly1305 opens a ciphertext sealed before the upgrade, and seals the same bytes', () => {
51
+ const key = hexToBytes('fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0')
52
+ const nonce = hexToBytes('000306090c0f1215181b1e2124272a2d303336393c3f4245')
53
+ const sealed = 'e003dd72872ec24f237d31da2ec1f62c870582997ad3c5002b0775362bb8'
54
+ expect(new TextDecoder().decode(xchacha20poly1305(key, nonce).decrypt(hexToBytes(sealed)))).toBe('secret payload')
55
+ expect(bytesToHex(xchacha20poly1305(key, nonce).encrypt(enc.encode('secret payload')))).toBe(sealed)
56
+ })
57
+
58
+ test('canonical JSON keeps its key order, escapes and unicode', () => {
59
+ expect(canonicalize({ b: [3, { z: 1, a: 'é' }], a: 1, n: null, u: 'ü
' })).toBe('{"a":1,"b":[3,{"a":"é","z":1}],"n":null,"u":"ü
"}')
60
+ })
61
+
62
+ test('canonical JSON drops undefined properties, nulls undefined array items and serializes dates and numbers as before', () => {
63
+ expect(canonicalize({ a: 1, b: undefined, c: [1, undefined, 3] })).toBe('{"a":1,"c":[1,null,3]}')
64
+ expect(canonicalize({ z: { y: undefined, x: 1 } })).toBe('{"z":{"x":1}}')
65
+ expect(canonicalize({ d: new Date(0) })).toBe('{"d":"1970-01-01T00:00:00.000Z"}')
66
+ expect(canonicalize({ n: [1e21, 1e-7, -0, 0.1] })).toBe('{"n":[1e+21,1e-7,0,0.1]}')
67
+ })
68
+ })