OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-base / lib / sign.js

20 lines · javascript ref:
// Generic deterministic DAG-CBOR signer/verifier — used by the LABEL projection (the commit path
// reuses atproto-repo's byte-exact signCommit). ECDSA secp256k1 low-S over sha256(DAG-CBOR(obj)),
// RFC6979-deterministic, raw 64-byte compact sig — the same primitive shape as commit/label sigs.
// DAG-CBOR canonicalises map keys, so object field order never affects the bytes → deterministic.

import { secp256k1 } from '@noble/curves/secp256k1'
import { sha256 } from '@noble/hashes/sha2'
import { cidForValue } from 'atproto-repo/lib/cid.js' // reuse the exact DAG-CBOR encoder (proven)

async function dagCborBytes (obj) { return (await cidForValue(obj)).bytes }

export async function signObject (obj, privateKey) {
  const sig = secp256k1.sign(sha256(await dagCborBytes(obj)), privateKey, { lowS: true })
  return sig.toCompactRawBytes() // 64-byte raw, like atproto commit/label sigs
}

export async function verifyObject (obj, sig, publicKey) {
  return secp256k1.verify(sig, sha256(await dagCborBytes(obj)), publicKey, { lowS: true })
}