OverviewFilesCommitsIssuesDocsReleasesPeers

git-remote-punch / lib / derive-topic.js

33 lines · javascript ref:
import crypto from 'hypercore-crypto'

/**
 * Derive a 32-byte Hyperswarm topic from a server's public key and a
 * repo name.
 *
 *   topic = hash(serverKey + repoName).subarray(0, 32)
 *
 * Deterministic and reproducible — clients and servers must compute the
 * same topic without any shared state beyond the key + name.
 *
 * @param {string|Buffer} serverKey - Server's public key (hex string or bytes)
 * @param {string} repoName - Repository name
 * @returns {Buffer} - 32-byte topic hash
 */
export function deriveTopicFromKey (serverKey, repoName) {
  const keyBuffer = typeof serverKey === 'string'
    ? Buffer.from(serverKey, 'hex')
    : serverKey

  // crypto.data (NOT crypto.hash) — has a domain-separation prefix so
  // per-repo topics don't collide with crypto.hash-based topics used
  // elsewhere (e.g. pear-git-v3's daemon-level identity swarm topic
  // hashes (identity.publicKey + 'pear-git-v3') with crypto.hash —
  // any repo named 'pear-git-v3' on the same server would collide).
  // MUST match hyper-sync/lib/topics.js — both must produce identical
  // topics for the same (serverKey, repoName) input.
  return crypto.data(Buffer.concat([
    keyBuffer,
    Buffer.from(repoName, 'utf-8')
  ]))
}