수학의 숨은 거리

그래프 서고

ja· en· ko
처음 오신 분께쓰는 방식만 다를 뿐 뜻은 같은 문서를, 같은 모양으로 다시 맞추는 이야기예요.

이 서고를 알아 두면, "뜻은 같은데 서명이 맞지 않는다"라는 연합의 이상한 사고를 읽어낼 수 있어요. 같은 뜻을 담은 문서는 얼마든지 다르게 쓸 수 있어요 — 그래서 서명하기 전에, 뜻이 같으면 반드시 같은 바이트 열이 되도록 다시 늘어놓아요(정규화).

"같은 그래프인가"를 가리는 문제는, 계산 복잡도 이론에서도 자리를 못 잡는 유명한 난제와 사촌 사이예요. 평소 아무도 안 보는 마루 밑에, 이런 거물이 살고 있어요.

볼거리

  • 이 서고(URDNA2015)를 지나는 건 옛 LD 서명(RsaSignature2017)이에요. 새 FEP-8b32는 더 가벼운 재배열 — JCS(RFC 8785, 키를 사전순으로 늘어놓기만 해요) — 로 끝내요. 강한 연장일수록 무겁다는, 마루 밑의 경제 원리죠
  • HTTP 서명(봉투의 도장)은 애초에 재배열을 하지 않고, 그림자(digest)에 찍어요. 세 가지 의전이 저마다 다른 깊이로 이 문제와 어울리고 있어요
  • 뜻은 같고 쓰는 방식만 다른 문서가 같은 그림자가 돼요 — 문(SHA-256) 앞에, 이 서고의 재배열이 끼어들어요
  • 명세는 W3C의 "RDF Dataset Canonicalization"이에요. 2024년에 정식 권고가 된, 꽤 젊은 정전이죠

경문 한 구절

async function hashJsonLd(
  jsonLd: unknown,
  contextLoader: DocumentLoader | undefined,
): Promise<string> {
  const canon = await jsonld.canonize(jsonLd, {
    format: "application/n-quads",
    documentLoader: contextLoader ?? getDocumentLoader(),
  });
  const encoder = new TextEncoder();
  const hash = await crypto.subtle.digest("SHA-256", encoder.encode(canon));
  return encodeHex(hash);
}
packages/fedify/src/sig/ld.ts L1207-L1218— 재배열하고(canonize) 나서, 그림자(SHA-256)로 만들어요

만져 보기

{"type":"Note","content":"hello","to":["as:Public"]}
{"to":["as:Public"],"content":"hello","type":"Note"}
뜻이 같은 문서 둘. 쓰는 순서(키 순서)만 달라요.

배치도

packages/fedify/src/sig/ld.ts
서고의 현장. jsonld.canonize(URDNA2015)

옆방

바깥 링크