// Vector generator for the (un)announce signable, from hyperdht's OWN code path.
// Reads persistent.js's annSignable via the nested compact-encoding hyperdht
// actually uses, so the bytes are hyperdht's, not our reconstruction of them.
const sodium = require('sodium-universal')
const b4a = require('b4a')
const c = require('hyperdht/node_modules/compact-encoding')
const m = require('hyperdht/lib/messages')
const NS = require('hyperdht/lib/constants').NS
const EMPTY = b4a.alloc(0)
function annSignable (target, token, id, ann, ns) {
const signable = b4a.allocUnsafe(32 + 32)
const hash = signable.subarray(32)
signable.set(ns, 0)
sodium.crypto_generichash_batch(hash, [
target, id, token, c.encode(m.peer, ann.peer), ann.refresh || EMPTY
])
return signable
}
// Deterministic inputs.
const target = b4a.alloc(32, 0xa1)
const token = b4a.alloc(32, 0xb2)
const id = b4a.alloc(32, 0xc3)
const seed = b4a.alloc(32, 0xd4)
const publicKey = b4a.alloc(32), secretKey = b4a.alloc(64)
sodium.crypto_sign_seed_keypair(publicKey, secretKey, seed)
const ann = { peer: { publicKey, relayAddresses: [] }, refresh: null }
const peerBuf = c.encode(m.peer, ann.peer)
const out = {
target: b4a.toString(target, 'hex'),
token: b4a.toString(token, 'hex'),
id: b4a.toString(id, 'hex'),
seed: b4a.toString(seed, 'hex'),
publicKey: b4a.toString(publicKey, 'hex'),
peer_encoded: b4a.toString(peerBuf, 'hex'),
peer_encoded_len: peerBuf.length,
ns_announce: b4a.toString(NS.ANNOUNCE, 'hex'),
ns_unannounce: b4a.toString(NS.UNANNOUNCE, 'hex'),
signable_announce: b4a.toString(annSignable(target, token, id, ann, NS.ANNOUNCE), 'hex'),
signable_unannounce: b4a.toString(annSignable(target, token, id, ann, NS.UNANNOUNCE), 'hex')
}
const sigA = b4a.alloc(64), sigU = b4a.alloc(64)
sodium.crypto_sign_detached(sigA, annSignable(target, token, id, ann, NS.ANNOUNCE), secretKey)
sodium.crypto_sign_detached(sigU, annSignable(target, token, id, ann, NS.UNANNOUNCE), secretKey)
out.signature_announce = b4a.toString(sigA, 'hex')
out.signature_unannounce = b4a.toString(sigU, 'hex')
require('fs').writeFileSync('unannounce_vector.json', JSON.stringify(out, null, 1))
for (const k of Object.keys(out)) console.log(k.padEnd(22), out[k])