-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Specification
We'd like to canonicalise the representation of a keynode's node ID.
Recall that the node ID of a node is based on the public key of a keynode: it is a public key fingerprint. At the moment, we produce a SHA-256 hash of the public key, resulting in an array of 32 bytes. This array of bytes can be currently seen as the primitive canonicalised representation of the node ID.
The representation needs to provide:
- fixed size encodings: the Kademlia system for node ID resolution requires a fixed-size representation of a node ID, such that we can perform bitwise XOR operations between node IDs.
- URL-safe characters
Previously, we were using base64 as the encoding choice for a human-readable version of the node ID. This produced fixed-size node IDs of 44 characters, but used unsafe characters (e.g. /, +).
After that, we were then looking at base58btc. This has the advantage of no longer producing URL-unsafe characters, as well as some quality-of-life improvements by not including visually-similar characters. However, it can produce different sized node IDs. See below:
import * as keysUtils from './src/keys/utils';
import {
util as forgeUtil,
} from 'node-forge';
import { base58btc } from "multiformats/bases/base58";
async function main() {
const pemPublicKey43 = `-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0dTpU0P4AMR3bWs9t4KQ
WWkQZZsjqMLj4Hr2c3n6bYhqCl4e69P7tFUG6mrIGomUb/JCqZ5cik+IyDoKz/rw
wB6vJ51ajT4nLgiCgKbiMeU3gdlXKDpJSBxi85sFFjprbmJiO41r2ZezE7bS62Sl
k8vkPI2IPhH4H/Zun60iO0lRBMd/aWSZ03hNZHGBe1JVTzkoxLneaNOd5XRQ90KO
TPButem2+5tU91oQsFH4VZONHuJbHEuYeiJUbFtgKNvwDe8w/0BmDoV5r9R7oEjI
busgF0SQv6DkQILL2PfhJAsYQdY3azd07q3Nhm4YgQJg3r7XbN4+goPUwCr3073d
rM1Ulc2zh9Oukx7iqzlGjjQWJ7q6bd2ewn/E9dlQDNc8KP4Fq08aMo1bRGSX1Pl8
h5E5lr/FjKgNmxLwe+gBqo/iMvGYISo6IedEpw2xLcWxQrZ6yu9MzCi+6l6mr/M7
PQqye8FzMXMxaaqIBi0WUkgg3qTynqAM/jde64GcBdLv4UfkbSkgSRlJb5srmcrc
jckqpjeP4yRO0ex0ynkMMi78LT0yG3E/XYqFx+XD6EGEpEKMbVPwBmOyEapRbVVI
DLBEmR6e6WuvdnyiJksCUpZhuDrVyJuVOImL8FJMFtanpPxwZe3FpNaGJQxa0m1d
VQE/QpKzYZL0pMhBhHr/JBkCAwEAAQ==
-----END PUBLIC KEY-----`;
const pemPublicKey44 = `-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3SABwHq1vJ9ydCl2eW/Q
r3guKAPdesaxkm85k4EhJ2ywvDcw0wjh39KbcU5ymexxDGzKa3DkhrGzzHbQmS37
Ee0Nvm6VR2PI+rhmRtJAVztAPPTMj3YHJXaqpoffILXt508jAnvQ38477tZ8hxSR
/NfZ2OYCLJrCENXvIy6NOPWBwcXPJUL02fDPpaZsvcnoLpIptOnIEuQXL3YJHjKd
w6yYT4g0sy0MSqp8NFPzzlcY4k5gKO1KR/G2/o2DFErd0n2a7k+SY/ChuUaZpk6U
q88zfLSRdUCM4pe469ZRrlz7lRoQUemBrmDx0g00MS9GsSEgOZFz3xqt+/3jE+vg
vt9Ul4929z+9onK5NvjwVR3gRDAl9IFW6P3YVdnyPUo3tNkgQ3Q9Pew/cmulGVf3
js/DiS9QVjivscfWGbVnkRPuNlUQ0WX4mNEDtYUEGsuYIRkgvBwHYFO1TGQWn3P3
vEfUg61LzP8WHoYxb/nmYcd14t8zt9reQnCOk+/ON+Btp1Q1ZhIiy7uxG0IGE7m2
Nawvql9YGFheFC56TYnikm3jfw4boyaqwCeVmqRBAe/NCXcIzDK76AmEvfjzitOl
2f8rtFMcRE9LFzAYf0bGMbtLEWmE3tMbxDeO3B+DXKtUjeRun6TWca1biyK8niI0
xsGTzpaAygxgj5DHF8OjP9ECAwEAAQ==
-----END PUBLIC KEY-----`;
const publicKey43 = keysUtils.publicKeyFromPem(pemPublicKey43);
const publicKey44 = keysUtils.publicKeyFromPem(pemPublicKey44);
const bytes43 = keysUtils.publicKeyToFingerprintBytes(publicKey43);
const bytes44 = keysUtils.publicKeyToFingerprintBytes(publicKey44);
console.log('publicKeyToFingerprintBytes length 43:', bytes43.length);
console.log('publicKeyToFingerprintBytes length 44:', bytes44.length);
const fTypedArray43 = forgeUtil.binary.raw.decode(bytes43);
const fTypedArray44 = forgeUtil.binary.raw.decode(bytes44);
console.log('fTypedArray 43:', fTypedArray43);
console.log('fTypedArray 44:', fTypedArray44);
console.log('Hex string 43:', Buffer.from(fTypedArray43).toString('hex'));
console.log(base58btc.baseEncode(fTypedArray43));
console.log(keysUtils.publicKeyToFingerprint(publicKey43));
}
main();[nix-shell:~/Documents/MatrixAI/js-polykey]$ npm run ts-node -- nodeIds.ts
> @matrixai/[email protected] ts-node /home/josh/Documents/MatrixAI/js-polykey
> ts-node -r tsconfig-paths/register "nodeIds.ts"
publicKeyToFingerprintBytes length 43: 32
publicKeyToFingerprintBytes length 44: 32
fTypedArray 43: Uint8Array(32) [
10, 45, 47, 45, 125, 109, 40, 40,
20, 160, 60, 163, 101, 100, 189, 222,
38, 35, 246, 172, 73, 251, 232, 221,
13, 97, 139, 151, 240, 251, 129, 201
]
fTypedArray 44: Uint8Array(32) [
233, 254, 155, 220, 4, 146, 225, 43,
130, 201, 87, 50, 52, 141, 221, 156,
15, 162, 131, 58, 120, 191, 146, 36,
49, 133, 50, 92, 203, 95, 232, 13
]
Hex string 43: 0a2d2f2d7d6d282814a03ca36564bdde2623f6ac49fbe8dd0d618b97f0fb81c9
gj3DUVjzAGHvmP9ZRFB5geWLVRwXUSdEUtMcVvxozLx
gj3DUVjzAGHvmP9ZRFB5geWLVRwXUSdEUtMcVvxozLx
As a temporary solution, we've adopted a base32hex encoding, producing a fixed fixed 53 character node ID, such as v6n7m9vuf44pfqq133re8v91ju7a8968h4nkirjt8r7r9pbcoqqq0 (with a prepended v character from multibase): https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/205#note_711237922
Additional context
- Refactor
NodeIdas a proxy/singleton instance #254 - will need to look at this issue concurrently - discussions on
base58andbase58btc
Tasks
- Choose a standard means of representing the node ID
- Change all current usages of node ID to be this new standard (e.g. within
NodeGraph(kademlia), across GRPC, etc)