@owlmeans/basic-keys 0.1.0
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/LICENSE +21 -0
- package/README.md +474 -0
- package/build/.gitkeep +0 -0
- package/build/auth.d.ts +5 -0
- package/build/auth.d.ts.map +1 -0
- package/build/auth.js +45 -0
- package/build/auth.js.map +1 -0
- package/build/bin.d.ts +2 -0
- package/build/bin.d.ts.map +1 -0
- package/build/bin.js +9 -0
- package/build/bin.js.map +1 -0
- package/build/consts.d.ts +5 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +6 -0
- package/build/consts.js.map +1 -0
- package/build/helper.d.ts +4 -0
- package/build/helper.d.ts.map +1 -0
- package/build/helper.js +22 -0
- package/build/helper.js.map +1 -0
- package/build/index.d.ts +8 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +7 -0
- package/build/index.js.map +1 -0
- package/build/keypair.d.ts +3 -0
- package/build/keypair.d.ts.map +1 -0
- package/build/keypair.js +46 -0
- package/build/keypair.js.map +1 -0
- package/build/model.d.ts +3 -0
- package/build/model.d.ts.map +1 -0
- package/build/model.js +70 -0
- package/build/model.js.map +1 -0
- package/build/plugins/ed25519.d.ts +3 -0
- package/build/plugins/ed25519.d.ts.map +1 -0
- package/build/plugins/ed25519.js +15 -0
- package/build/plugins/ed25519.js.map +1 -0
- package/build/plugins/export.d.ts +5 -0
- package/build/plugins/export.d.ts.map +1 -0
- package/build/plugins/export.js +4 -0
- package/build/plugins/export.js.map +1 -0
- package/build/plugins/index.d.ts +3 -0
- package/build/plugins/index.d.ts.map +1 -0
- package/build/plugins/index.js +6 -0
- package/build/plugins/index.js.map +1 -0
- package/build/plugins/types.d.ts +13 -0
- package/build/plugins/types.d.ts.map +1 -0
- package/build/plugins/types.js +2 -0
- package/build/plugins/types.js.map +1 -0
- package/build/plugins/xchacha.d.ts +3 -0
- package/build/plugins/xchacha.d.ts.map +1 -0
- package/build/plugins/xchacha.js +14 -0
- package/build/plugins/xchacha.js.map +1 -0
- package/build/types.d.ts +35 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils.d.ts +5 -0
- package/build/utils.d.ts.map +1 -0
- package/build/utils.js +29 -0
- package/build/utils.js.map +1 -0
- package/package.json +56 -0
- package/src/auth.ts +60 -0
- package/src/bin.ts +13 -0
- package/src/consts.ts +5 -0
- package/src/helper.ts +27 -0
- package/src/index.ts +8 -0
- package/src/keypair.ts +44 -0
- package/src/model.ts +113 -0
- package/src/plugins/ed25519.ts +23 -0
- package/src/plugins/export.ts +5 -0
- package/src/plugins/index.ts +8 -0
- package/src/plugins/types.ts +13 -0
- package/src/plugins/xchacha.ts +23 -0
- package/src/types.ts +41 -0
- package/src/utils.ts +35 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
package/src/model.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { KeyPairModel, KeyPairModelMaker } from './types.js'
|
|
2
|
+
import { plugins } from './plugins/index.js'
|
|
3
|
+
import { base64urlnopad, utf8 } from '@scure/base'
|
|
4
|
+
import { assertType, prepareData, prepareKey } from './utils.js'
|
|
5
|
+
import { inputToKeyPair } from './keypair.js'
|
|
6
|
+
|
|
7
|
+
export const makeKeyPairModel: KeyPairModelMaker = input => {
|
|
8
|
+
const keyPair = inputToKeyPair(input)
|
|
9
|
+
|
|
10
|
+
const _model: KeyPairModel = {
|
|
11
|
+
keyPair,
|
|
12
|
+
|
|
13
|
+
sign: async (data) => {
|
|
14
|
+
data = prepareData(data)
|
|
15
|
+
assertType(_model.keyPair?.type)
|
|
16
|
+
|
|
17
|
+
if (_model.keyPair == null) {
|
|
18
|
+
throw new Error('basic.keys:missing-keypair')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (_model.keyPair.privateKey == null) {
|
|
22
|
+
throw new Error('basic.keys:missing-pk')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return base64urlnopad.encode(
|
|
26
|
+
plugins[_model.keyPair.type].sign(
|
|
27
|
+
data as Uint8Array,
|
|
28
|
+
prepareKey(_model.keyPair.privateKey)
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
verify: async (data, signature) => {
|
|
34
|
+
data = prepareData(data)
|
|
35
|
+
assertType(_model.keyPair?.type)
|
|
36
|
+
const sig = base64urlnopad.decode(signature)
|
|
37
|
+
|
|
38
|
+
if (_model.keyPair == null) {
|
|
39
|
+
throw new Error('basic.keys:missing-keypair')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return plugins[_model.keyPair.type].verify(
|
|
43
|
+
data as Uint8Array,
|
|
44
|
+
sig,
|
|
45
|
+
prepareKey(_model.keyPair.publicKey)
|
|
46
|
+
)
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
export: () => {
|
|
50
|
+
assertType(_model.keyPair?.type)
|
|
51
|
+
|
|
52
|
+
if (_model.keyPair == null) {
|
|
53
|
+
throw new Error('basic.keys:missing-keypair')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return `${_model.keyPair.type}:${_model.keyPair.privateKey}`
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
exportPublic: () => {
|
|
60
|
+
assertType(_model.keyPair?.type)
|
|
61
|
+
|
|
62
|
+
if (_model.keyPair == null) {
|
|
63
|
+
throw new Error('basic.keys:missing-keypair')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return `${_model.keyPair.type}:${_model.keyPair.publicKey}`
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
exportAddress: () => {
|
|
70
|
+
assertType(_model.keyPair?.type)
|
|
71
|
+
|
|
72
|
+
if (_model.keyPair == null) {
|
|
73
|
+
throw new Error('basic.keys:missing-keypair')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return `${_model.keyPair.type}:${_model.keyPair.address}`
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
encrypt: async data => {
|
|
80
|
+
data = prepareData(data)
|
|
81
|
+
assertType(_model.keyPair?.type)
|
|
82
|
+
|
|
83
|
+
if (_model.keyPair == null) {
|
|
84
|
+
throw new Error('basic.keys:missing-keypair')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return base64urlnopad.encode(
|
|
88
|
+
plugins[_model.keyPair.type].encrypt(
|
|
89
|
+
data as Uint8Array,
|
|
90
|
+
prepareKey(_model.keyPair.publicKey)
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
decrypt: async data => utf8.encode(await _model.dcrpt(data)),
|
|
96
|
+
|
|
97
|
+
dcrpt: async data => {
|
|
98
|
+
data = data instanceof Uint8Array ? data : base64urlnopad.decode(data as string)
|
|
99
|
+
assertType(_model.keyPair?.type)
|
|
100
|
+
|
|
101
|
+
if (_model.keyPair == null) {
|
|
102
|
+
throw new Error('basic.keys:missing-keypair')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return plugins[_model.keyPair.type].decrypt(
|
|
106
|
+
data as Uint8Array,
|
|
107
|
+
prepareKey(_model.keyPair.privateKey)
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return _model
|
|
113
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { KeyType } from '../consts.js'
|
|
2
|
+
import type { KeyPlugin } from './types.js'
|
|
3
|
+
import { ed25519 } from '@noble/curves/ed25519'
|
|
4
|
+
import { base58 } from '@scure/base'
|
|
5
|
+
import { keccak_256 } from '@noble/hashes/sha3'
|
|
6
|
+
|
|
7
|
+
export const ed25519Plugin: KeyPlugin = {
|
|
8
|
+
type: KeyType.ED25519,
|
|
9
|
+
|
|
10
|
+
random: () => ed25519.utils.randomPrivateKey(),
|
|
11
|
+
|
|
12
|
+
sign: (data, pk) => ed25519.sign(data, pk),
|
|
13
|
+
|
|
14
|
+
verify: (data, signature, pub) => ed25519.verify(signature, data, pub),
|
|
15
|
+
|
|
16
|
+
toPublic: pk => ed25519.getPublicKey(pk),
|
|
17
|
+
|
|
18
|
+
toAdress: pub => base58.encode(keccak_256(pub.slice(4)).slice(-20)),
|
|
19
|
+
|
|
20
|
+
encrypt: () => { throw new Error(`${ed25519Plugin.type}:encryption-support`) },
|
|
21
|
+
|
|
22
|
+
decrypt: () => { throw new Error(`${ed25519Plugin.type}:encryption-support`) }
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { KeyPlugin } from './types.js'
|
|
2
|
+
import { ed25519Plugin } from './ed25519.js'
|
|
3
|
+
import { xChahaPlugin } from './xchacha.js'
|
|
4
|
+
|
|
5
|
+
export const plugins: Record<string, KeyPlugin> = {}
|
|
6
|
+
|
|
7
|
+
plugins[ed25519Plugin.type] = ed25519Plugin
|
|
8
|
+
plugins[xChahaPlugin.type] = xChahaPlugin
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
export interface KeyPlugin {
|
|
3
|
+
type: string
|
|
4
|
+
random: () => Uint8Array
|
|
5
|
+
fromSeed?: (seed: Uint8Array) => Uint8Array
|
|
6
|
+
derive?: (pk: Uint8Array, path: string) => Uint8Array
|
|
7
|
+
sign: (data: Uint8Array, pk: Uint8Array) => Uint8Array
|
|
8
|
+
verify: (data: Uint8Array, signature: Uint8Array, pub: Uint8Array) => boolean
|
|
9
|
+
toPublic: (pk: Uint8Array) => Uint8Array
|
|
10
|
+
toAdress: (pub: Uint8Array) => string
|
|
11
|
+
encrypt: (data: Uint8Array, pk: Uint8Array) => Uint8Array
|
|
12
|
+
decrypt: (data: Uint8Array, pk: Uint8Array) => Uint8Array
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { KeyType } from '../consts.js'
|
|
2
|
+
import type { KeyPlugin } from './types.js'
|
|
3
|
+
import { xchacha20poly1305 } from '@noble/ciphers/chacha'
|
|
4
|
+
import { randomBytes, managedNonce } from '@noble/ciphers/webcrypto'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const xChahaPlugin: KeyPlugin = {
|
|
8
|
+
type: KeyType.XCHACHA,
|
|
9
|
+
|
|
10
|
+
random: () => randomBytes(32),
|
|
11
|
+
|
|
12
|
+
sign: () => { throw new Error(`${xChahaPlugin.type}:signing`) },
|
|
13
|
+
|
|
14
|
+
verify: () => { throw new Error(`${xChahaPlugin.type}:verification`) },
|
|
15
|
+
|
|
16
|
+
toPublic: pk => pk,
|
|
17
|
+
|
|
18
|
+
toAdress: () => 'no-address',
|
|
19
|
+
|
|
20
|
+
encrypt: (data, pk) => managedNonce(xchacha20poly1305)(pk).encrypt(data),
|
|
21
|
+
|
|
22
|
+
decrypt: (data, pk) => managedNonce(xchacha20poly1305)(pk).decrypt(data),
|
|
23
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AuthCredentials } from '@owlmeans/auth'
|
|
2
|
+
|
|
3
|
+
export interface KeyPair {
|
|
4
|
+
privateKey: string
|
|
5
|
+
publicKey: string
|
|
6
|
+
address: string
|
|
7
|
+
type: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface KeyPairModel {
|
|
11
|
+
keyPair?: KeyPair
|
|
12
|
+
sign: (data: unknown) => Promise<string>
|
|
13
|
+
verify: (data: unknown, signature: string) => Promise<boolean>
|
|
14
|
+
export: () => string
|
|
15
|
+
exportPublic: () => string
|
|
16
|
+
exportAddress: () => string
|
|
17
|
+
encrypt: (data: unknown) => Promise<string>
|
|
18
|
+
decrypt: (data: unknown) => Promise<string>
|
|
19
|
+
dcrpt: (data: unknown) => Promise<Uint8Array>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface KeyPairModelMaker {
|
|
23
|
+
(input?: KeyPair | string): KeyPairModel
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface PayloadSigner {
|
|
27
|
+
<T extends {}>(payload: T): Promise<string>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PayloadVerifier {
|
|
31
|
+
<T extends {}>(payload: T, signature: string): Promise<boolean>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface UnpackedAuthCredentials<T extends {} | undefined = undefined> {
|
|
35
|
+
unsigned: AuthCredentials | Omit<AuthCredentials, 'credential'>
|
|
36
|
+
signature: string
|
|
37
|
+
isValid?: boolean
|
|
38
|
+
extras: T
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type UnsignedAuthCredentials = AuthCredentials | Omit<AuthCredentials, "credential">
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { keccak_256 } from '@noble/hashes/sha3'
|
|
2
|
+
import { base64, utf8 } from '@scure/base'
|
|
3
|
+
import { plugins } from './plugins/index.js'
|
|
4
|
+
import canonicalize from 'canonicalize'
|
|
5
|
+
|
|
6
|
+
export const toAddress = (publicKey: Uint8Array): Uint8Array =>
|
|
7
|
+
keccak_256(publicKey.slice(4)).slice(-20)
|
|
8
|
+
|
|
9
|
+
export const prepareKey = (key: string): Uint8Array =>
|
|
10
|
+
base64.decode(key)
|
|
11
|
+
|
|
12
|
+
export const prepareData = (data: unknown): Uint8Array => {
|
|
13
|
+
if (typeof data === 'object') {
|
|
14
|
+
if (!(data instanceof Uint8Array)) {
|
|
15
|
+
data = canonicalize(data)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (typeof data === 'string') {
|
|
19
|
+
data = utf8.decode(data)
|
|
20
|
+
} else if (!(data instanceof Uint8Array)) {
|
|
21
|
+
throw new Error('basic.keys:sign-data-type')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!(data instanceof Uint8Array)) {
|
|
25
|
+
throw new Error('basic.keys:sign-data-type')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return data
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const assertType = (type?: string): void => {
|
|
32
|
+
if (type == null || !(type in plugins)) {
|
|
33
|
+
throw new Error('basic.keys:unknown-type')
|
|
34
|
+
}
|
|
35
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"../tsconfig.default.json",
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"rootDir": "./src/", /* Specify the root folder within your source files. */
|
|
7
|
+
"outDir": "./build/", /* Specify an output folder for all emitted files. */
|
|
8
|
+
},
|
|
9
|
+
"exclude": [
|
|
10
|
+
"./dist/**/*",
|
|
11
|
+
"./build/**/*",
|
|
12
|
+
"./*.ts"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/auth.ts","./src/bin.ts","./src/consts.ts","./src/helper.ts","./src/index.ts","./src/keypair.ts","./src/model.ts","./src/types.ts","./src/utils.ts","./src/plugins/ed25519.ts","./src/plugins/export.ts","./src/plugins/index.ts","./src/plugins/types.ts","./src/plugins/xchacha.ts"],"version":"5.6.3"}
|