@owlmeans/basic-keys 0.1.18-rc.45 → 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 +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/basic-keys/SKILL.md +1 -1
- package/build/plugins/ed25519.js +3 -3
- package/build/plugins/ed25519.js.map +1 -1
- package/build/plugins/xchacha.js +2 -2
- package/build/plugins/xchacha.js.map +1 -1
- package/build/utils.js +1 -1
- package/build/utils.js.map +1 -1
- package/package.json +9 -9
- package/src/plugins/ed25519.ts +3 -3
- package/src/plugins/xchacha.ts +2 -2
- package/src/utils.ts +1 -1
- package/tests/known-answers.spec.ts +68 -0
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.
|
|
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.
|
|
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
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/basic-keys",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
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
|
{
|
package/build/plugins/ed25519.js
CHANGED
|
@@ -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.
|
|
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,
|
|
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"}
|
package/build/plugins/xchacha.js
CHANGED
|
@@ -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/
|
|
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,
|
|
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
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
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.
|
|
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
|
-
"@types/bun": "^1.4.
|
|
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": "^
|
|
50
|
-
"@noble/curves": "^
|
|
51
|
-
"@noble/hashes": "^
|
|
52
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
53
|
-
"@scure/base": "^2.
|
|
54
|
-
"canonicalize": "^
|
|
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"
|
package/src/plugins/ed25519.ts
CHANGED
|
@@ -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.
|
|
10
|
+
random: () => ed25519.utils.randomSecretKey(),
|
|
11
11
|
|
|
12
12
|
sign: (data, pk) => ed25519.sign(data, pk),
|
|
13
13
|
|
package/src/plugins/xchacha.ts
CHANGED
|
@@ -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/
|
|
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
|
@@ -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
|
+
})
|