← 목록
기타 2026-06-11 5KB 읽기 6분

Phase4 P2 — 연합체인 Merkle root 누적 공시 + 포함증명

개요

연합 게이트웨이의 노드 등록 체인(nodes.ndjson)을 RFC 6962 근사 Merkle 트리로 묶어 root 만 서명·공시한다. 노드는 전체 체인 다운로드 없이 자기 등록 블록의 포함을 O(log n) 포함증명(inclusion proof)으로 검증할 수 있다.

라이브 게이트웨이(:8080/:8443/gateway.yaml) 무접촉. 연합 API(:9160)와 연합체인 파일(data/federation-chain/)만 사용.

무엇을 했는지

1. 신규 라이브러리 (ADDITIVE, 자동실행 없음)

/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클.한선
  • 연합머클루트() — nodes.ndjson 각 블록 hash 를 리프로 Merkle 트리 구성 → root 반환
  • 연합블록수() — 체인 블록 수
  • 연합루트서명(root,count,ts) — HMAC_SHA256(fed-shared.key, root|count|ts)
  • 연합루트공시() — root+count+ts+sig 를 federation-root.txt 에 JSON 한 줄로 기록
  • 연합루트공시읽기() — 공시 JSON 읽기(없으면 즉석 공시)
  • 포함증명(타깃해시) — 형제 경로 직렬 반환 "형제,방향;형제,방향;..." (R=오른쪽 L=왼쪽)
  • 증명검증(타깃해시, 증명, root) — 경로 재계산 후 root 일치 시 1, 아니면 0
  • (헬퍼) M블록해시목록 M리프목록 M레벨업 M리프해시 M내부해시 M값 M공백정리 M다음세미

2. Merkle 트리 구성 방식 (RFC 6962 근사)

  • 리프 해시 = SHA256("L:" + 블록해시) (RFC6962 SHA256(0x00‖data) 근사)
  • 내부 노드 = SHA256("N:" + 왼 + 오른) (RFC6962 SHA256(0x01‖L‖R) 근사)
  • 홀수 레벨 = 마지막 노드 그대로 승격(promote) — 복제 아님 (RFC6962 권장)
  • 빈 체인 root = SHA256("L:EMPTY"), 1블록이면 그 리프 = root
  • 리프 순서 = 체인 append 순서 (= nodes.ndjson 줄 순서)
  • 한선씨 배열 append-only(추가())만 사용, 맵객체 의존 안 함

3. 포함증명 형식

직렬 문자열: 형제해시,방향;형제해시,방향;...
  • 방향 R = 형제가 오른쪽 → 내부해시(현재, 형제)
  • 방향 L = 형제가 왼쪽 → 내부해시(형제, 현재)
  • 홀수 promote 레벨에서 형제 없는 노드는 그 레벨 항목 생략
  • 검증: 타깃 블록해시 → 리프해시 시작 → 경로 따라 재계산 → root 비교

4. 연합 API(:9160) 신규 엔드포인트

/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합API.한선
  • GET /root — 현재 root 재계산·공시 후 {root,count,ts,sig} 반환
  • GET /proof?hash=<블록해시>{ok,hash,root,proof,verified,format} 반환
  • 해시 미발견 404, hash 누락 400
  • 쿼리스트링 파서 경로기본() / 쿼리값() 추가, 처리() 시그니처를 전체경로 기준으로 변경
  • / 자기설명·기동 로그에 신규 엔드포인트 반영
  • 5. 단위검증 진입점 (비파괴)

    /Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클검증.한선
    • 임시 체인(/tmp/_fedm_*) 5블록 등록 → root 계산/공시/포함증명 5/5 PASS
    • 위조해시 증명 거부 PASS, 교차증명(block0 해시 + block3 증명) 거부 PASS

    검증 결과

  • 컴파일 OK (라이브러리 13KB, API 33129 큐브)
  • 단위검증: 블록수 PASS, 공시 PASS, 포함증명 5/5 PASS, 위조 거부 PASS, 교차 거부 PASS
  • 기동.sh fed-api 재기동 후 실제 4블록 체인 curl:
  • /root{root:bc19347b..,count:4,ts,sig:83220689..}
  • /proof?hash=eab011..(block0) → proof ..,R;..,R; verified=true
  • /proof?hash=c3e537..(block3) → proof ..,L;..,L; verified=true (같은 root)
  • 미발견 → 404 {ok:false,error:"hash not found in chain"}
  • hash 누락 → 400
  • /verify blocks=4 corrupted=false, /health ok
  • 라이브 게이트웨이 :8080(crownyc PID 59464)·:8443(stunnel) LISTEN 유지 = 무접촉
  • 관련 파일

    • /Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클.한선 (신규)
    • /Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클검증.한선 (신규)
    • /Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합API.한선 (수정: 머클 import + /root + /proof + 쿼리파서)
    • 데이터: /Users/ef/crowny-gateway/data/federation-chain/federation-root.txt (신규 공시), nodes.ndjson, fed-shared.key

    잔여 이슈 / 인수인계 (메인세션)

    • 한선씨 함정 발견: /proof 미발견 404 본문에 루트P(함수 반환 해시문자열)를
    여러 항목과 한 표현식으로 concat 하면 VM 이 -2147483647(문자열핸들 오류) 반환. → 미발견 응답은 정적 JSON 으로 고정해 회피함. 성공 경로(pj 2문장 분할)는 정상. 근본 원인은 crownyc 문자열핸들 관련으로 추정(누적 아님, 결정적). 추후 VM 측 조사 권장.
    • 현재 root 서명키 = fed-shared.key(부트스트랩 루트키 재사용). 운영 시 별도
    root 공시 전용키 분리 고려 가능.
    • /root 는 매 호출마다 전체 재계산+공시. 블록 수 증가 시 캐시(헤드해시 기준 무효화) 고려.
    • 노드 클라이언트 측 포함증명 자체검증 헬퍼(원격에서 root 받아 검증)는 동일
    라이브러리 증명검증() 으로 가능 — 노드 CLI 통합은 후속.