이 번역은 참고용입니다. 정식 기준은 영어판이며, 내용이 다를 경우 영어판이 우선합니다. 영어판 읽기

보안 모델

Label 309 검증자가 신뢰하는 것과 신뢰하지 않는 것 — 독립 검증 가능성이라는 불변 원칙, 봉인된 PoE의 프라이버시 보장, 모든 구현이 지켜야 하는 규범적 암호 규칙, 그리고 와이어 포맷이 안고 있는 알려진 한계.

Label 309의 보안은 단 하나의 발상 위에 서 있습니다. 증명이란 그것에 의존하는 측이 스스로 확인하는 것이라는 발상입니다. 검증자가 신뢰하는 것은 공개된 Cardano 블록체인과, 콘텐츠에 관한 주장을 확인할 때에 한해 손에 쥔 바이트뿐입니다. 그 밖에는 아무것도 신뢰하지 않습니다. 게시자도, 도메인도, 서버도, 어쩌다 트랜잭션을 읽어 온 게이트웨이의 운영자도 신뢰 대상이 아닙니다. 이 페이지의 모든 보장은 이 입장에서 도출되거나, 그 경계를 표시하거나, 그 범위 밖에 남는 잔여 위험을 명시하거나, 셋 중 하나입니다.

이 페이지는 표준 그 자체에 대한 위협 모델입니다. 적합한 검증자가 전제하는 신뢰 모델, 서명 없는 봉인된 PoE의 프라이버시 특성, 모든 구현이 지켜야 하는(MUST) 암호상의 의무, 그리고 와이어 포맷이 극복하지 못하는 — 또한 극복할 수 없는 — 한계를 다룹니다. 특정 배포 환경의 운영 보안을 기술하지는 않습니다. 올바르게 구현한 누구에게나 포맷이 무엇을 보장하는지를 기술합니다.

신뢰 모델

Label 309 증명을 확인하는 의존측이 던지는 물음은 매우 좁습니다. 이 바이트는 이 블록의 시각 또는 그 이전에 존재했는가, 그리고 이 판정은 Cardano 외의 누군가가 올바르게 행동하는지에 좌우되는가? 표준은 후자의 물음에 대한 답이 언제나 "아니오"가 되도록 설계되어 있습니다. 어떤 단계에도 발행자가 지배하는 중개자는 존재하지 않습니다. 검증자가 참조하는 체인 게이트웨이와 스토리지 게이트웨이는 신뢰되지 않는 데이터 출처이며, 가능한 곳에서는 암호학적으로 검증되고, 포함성과 확정성에 대해서는 교차 대조됩니다.

검증자가 신뢰하는 것:

  • 공개된 Cardano 블록체인. 트랜잭션, 라벨 309 아래에 놓인 그 메타데이터, 그리고 블록 시각은 모든 Cardano 노드에 복제된 사실입니다. 검증자는 스스로 선택한 게이트웨이를 통해 이것들을 읽으며, 여러 게이트웨이로 교차 대조할 수도 있습니다.
  • 콘텐츠 주장을 확인할 때의 그 콘텐츠 바이트. 레코드 안의 다이제스트는 특정 바이트 시퀀스에 커밋합니다. 그 바이트를 손에 쥔 검증자는 해시를 다시 계산해 대조합니다. 바이트가 일치한다는 남의 말을 곧이곧대로 받아들이지 않습니다.

검증자가 신뢰하지 않는 것:

  • 게시자. Label 309에는 issuer 필드가 없습니다. 어떤 지갑이든 어떤 레코드든 게시할 수 있으며, 레코드의 유효성은 누가 제출했는지와 무관합니다. 검증자는 결코 "이 게시자는 평판이 좋은가?"라고 묻지 않습니다. 그 물음 자체가 이 모델에는 설 자리가 없습니다. 소개에서 다루는 발행자 비의존 불변 원칙을 참조하십시오.
  • 서버나 도메인. 검증의 어떤 단계에서도 게시자가 운영하는 서비스에 접속하지 않습니다. 참조해야 할 정규 레지스트리도, 상태를 폴링할 엔드포인트도, 키를 대조할 아이덴티티 권위 기관도 존재하지 않습니다.
  • 게이트웨이 운영자. 검증자가 읽기에 쓰는 Cardano, Arweave, IPFS 게이트웨이는 서로 교체 가능하며, 반환된 내용은 콘텐츠로서 검증됩니다(아래 참조). 게이트웨이는 전송로일 뿐 신뢰의 뿌리가 아닙니다.

독립 검증 가능성이 핵심 보안 속성입니다

Label 309 증명은 그것을 만든 모든 당사자 — 게시자, 그들의 서버, 그들의 회사 — 가 사라져도 여전히 확인 가능해야 합니다. 트랜잭션 참조와, 공개된 Cardano 게이트웨이와, 그리고 (콘텐츠 주장의 경우) 바이트만 주어지면, 적합한 어떤 구현이든 공개된 블록체인만으로 동일한 판정에 도달합니다. 어떤 검증 경로가 특정 운영자의 협력을 슬며시 필요로 한다면, 그 경로는 적합하지 않습니다.

게이트웨이가 신뢰의 뿌리가 아닌 이유

검증자는 같은 트랜잭션을 어느 Cardano 게이트웨이를 통해서도 읽을 수 있고, 같은 콘텐츠를 어느 Arweave나 IPFS 게이트웨이를 통해서도 읽을 수 있습니다. 이들 중 어느 것도 정직한 데이터를 반환하리라고 신뢰되지 않습니다. 반환되는 내용은 독립적으로 확인 가능하기 때문입니다.

  • 게이트웨이는 유효한 서명을 지닌 레코드를 위조할 수 없습니다. 서명자의 개인 키를 가지고 있지 않으며, 검증자가 서명 대상 바이트를 스스로 다시 계산해 직접 확인합니다. 서명을 참조하십시오.
  • 게이트웨이는 콘텐츠 주소 지정 URI 아래의 콘텐츠를 탐지되지 않은 채 바꿔치기할 수 없습니다. ipfs:// CID는 검증자가 가져온 바이트로부터 다시 계산하는 멀티해시이며, ar:// 트랜잭션 id는 Arweave 합의 아래에서 데이터에 커밋합니다. 적합한 항목에서는 온체인 hashes 맵이 평문에 대한 두 번째의, 독립된 결속이 되어 가져오는 시점에 다시 계산됩니다.
  • 트랜잭션을 숨기거나 그것이 얼마나 깊이 묻혀 있는지를 거짓으로 보고하는 게이트웨이는 위조가 아니라 서비스 거부의 형태입니다. 둘 이상의 게이트웨이를 통해 읽고 불일치가 있으면 처리를 중단하는 검증자에게, "하나의 부정직한 게이트웨이"라는 문제는 "자신이 선택한 모든 게이트웨이에 걸친 공모"로 모습을 바꿉니다. 그리고 그 선택은 검증자 자신이 쥐고 있습니다.

블록 깊이 — 검증자가 레코드를 확정된 것으로 취급하기까지 요구하는 확인 수 — 는 Label 309가 정하는 값이 아니라 검증자 정책입니다. 표준은 구체적인 깊이 수치를 일절 고정하지 않습니다. 의존측이 자신의 위험 허용도에 맞춰 임계값을 정합니다. 검증을 참조하십시오.

봉인된 PoE의 프라이버시 특성

봉인된 PoE는 타임스탬프를 블록체인에 기록하면서도 평문을 기밀로 유지합니다. 기밀성에 더해, 이 구성은 메시지에 관해서는 블록체인에 가능한 한 적게 누설하고, 그 수신 대상에 관해서는 아무것도 누설하지 않도록 설계되어 있습니다. 이것들은 와이어 포맷 차원의 보장입니다. 특정 배포 환경의 성질이 아니라 바이트 그 자체의 성질이므로, 올바르게 구현한 어떤 구현에서도 성립합니다.

서명 없는 봉인된 PoE의 송신자 익명성

서명 없는 봉인된 PoE — enc를 지니고 sigs지니지 않는 레코드 — 는 송신자의 아이덴티티를 블록체인에 노출해서는 안 됩니다(MUST NOT). 그 와이어상의 바이트는 송신자의 장기 키와 독립적이어야 합니다(MUST).

이것은 구조적으로 성립합니다.

  • 와이어상에 서명자 키가 실리지 않는다. 송신자의 아이덴티티 키가 블록체인에 도달하는 것은 오직 sigs 항목을 통해서뿐입니다. sigs가 없는 레코드에는 송신자 측 바이트가 하나도 들어 있지 않습니다. 저작자성은 옵트인이며, 익명성이 기본값입니다. 송신자의 장기 X25519 키와 Ed25519 키는 서명 없는 레코드에 결코 나타나지 않습니다.
  • 슬롯마다 새로운 캡슐화. 각 수신자 슬롯은 봉인 시점에 새로 생성된, 레코드별·슬롯별 KEM 재료를 지닙니다. x25519 경로에서는 slot.epk의 X25519 임시 공개 키, mlkem768x25519 경로에서는 slot.kem_ct의 X-Wing 암호문입니다. 이것은 송신자의 장기 키와 무관하며, 여러 레코드를 동일한 작성자에게 연결하는 단서를 아무것도 드러내지 않습니다.
  • 뒤섞인 슬롯. 슬롯 배열은 게시 전에 CSPRNG로 뒤섞입니다. 그래서 "주된 수신자가 맨 앞에 온다"와 같은 위치 순서가 아무런 신호를 담지 않습니다.

나중에 레코드에 서명하는 게시자는 레코드에 한해 아이덴티티 키를 노출할 뿐입니다. 그 키는 그 이전의 서명 없는 레코드에는 나타나지 않으며, 이전 레코드들의 슬롯별 KEM 재료로부터 작성자를 거슬러 매핑하는 연산도 존재하지 않습니다. 아이덴티티 X25519 키와 Ed25519 키는 마스터 시드로부터 서로 다른 HKDF 컨텍스트 문자열을 통해 도출되며, 게다가 Ed25519 공개 키로는 X25519 공개 키를 도출하거나 일치시킬 수 없으므로, 한 레코드에 서명해도 서명 없는 레코드들과 연결되는 일은 결코 없습니다. 저작자성을 택하는 것은 앞으로 향한 행위이지, 과거로 거슬러 익명성을 해제하는 것이 아닙니다.

이 불변 원칙이 대상으로 삼는 것은 label-309 레코드 바이트뿐입니다. 트랜잭션 입력에 담긴 수수료 지불용 Cardano 주소, 게이트웨이가 보는 게시자의 네트워크 차원 아이덴티티, 오프체인 암호문 블롭에 담긴 어떤 메타데이터도 모두 와이어 포맷의 범위 밖입니다. Label 309는 메타데이터 안에 존재하지 트랜잭션 입력 안에는 존재하지 않으므로, 수수료 지불자 상관 관계를 막을 수 없습니다. 수수료 지불자 익명성이 필요한 게시자는 트랜잭션 구성 계층에서 이에 대처해야 합니다.

수신자 비연결성

봉인된 레코드는 결코 수신자를 명시하지 않습니다. 수신자는 어떤 슬롯의 시험 복호화에 성공함으로써만 어떤 메시지가 자신에게 온 것임을 알아차립니다. 읽어 낼 수신인 필드는 존재하지 않습니다. 여기서 서로 다른 두 가지 보장이 따라 나오며, 둘을 혼동해서는 안 됩니다.

첫 번째는 두 KEM 모두에 대해, 그리고 어떤 관찰자에 대해서도 성립합니다.

  • 수신자끼리는 서로를 볼 수 없다. 각 슬롯은 독립적으로 감싸인 키입니다. 자신의 슬롯을 연 수신자는 다른 어떤 슬롯에 대해서도 아무것도 알아낼 수 없으며, 또 누가 수신 대상이었는지도 알 수 없습니다.
  • 와이어상에 수신자 공개 키가 없다. 나타나는 것은 슬롯별 캡슐화(epk 또는 kem_ct)와 감싸인 키뿐입니다. 후보 키를 갖지 않은 관찰자는 수신자를 열거할 수 없으며, 알 수 있는 것은 슬롯 수, KEM 패밀리(enc.kem), 그리고 봉인 대 비봉인의 구분뿐입니다.

두 번째 — 후보 수신자 공개 키 집합을 이미 손에 쥔 적대자가 어떤 슬롯이 그중 누군가에게 온 것인지 시험하려는 경우의 보장 — 는 더 강한, KEM에 특정한 성질이며, 표준은 이것을 고전 경로에 대해서만 주장합니다.

  • x25519는 키 비밀성을 갖는다. 슬롯별 epk는 수신자 키와 통계적으로 독립인 새로운 임시 공개 키입니다. epkwrap만으로는, 키를 쥔 적대자라 해도 일치하는 개인 키 없이는 어떤 후보(있다면)에게 그 슬롯이 향하는지 판정할 수 없습니다.
  • mlkem768x25519는 이것을 주장하지 않는다. 키를 쥔 적대자에 대한 수신자 익명성은 하이브리드 KEM의 IND-CCA 안전성으로부터 함의되지 않는 별개의 성질이며, X-Wing에 대해 독립적으로 정당화되지 않는 한 X-Wing 경로에 대해서는 주장되지 않습니다. 키를 쥔 적대자에 대한 수신자 익명성을 위협 모델이 요구하는 배포 환경은, 그 성질을 위해 하이브리드 경로에 의존해서는 안 됩니다(MUST NOT). 위의 정직한 누설 — 슬롯 수, KEM 패밀리, 봉인 대 비봉인 — 은 두 KEM에서 동일하며, 수신자에 관해 그 이상의 것은 어느 경로에서도 노출되지 않습니다.

평문 결속

온체인 다이제스트가 커밋하는 것은 평문이지 암호문이 아닙니다. 봉인된 PoE를 복호화한 수신자는 평문 해시를 다시 계산해 온체인 hashes 맵과 대조합니다. 이는 변조된 암호문을 제공하는 스토리지 계층이 URI 자체의 무결성 모델과 독립적으로 복호화 이후에 반드시 잡힌다는 것을 뜻합니다. 타임스탬프 주장은 송신자가 커밋한 평문에 관한 주장이며, 게이트웨이가 무엇을 하든 다른 바이트로 이 주장을 충족시킬 수는 없습니다.

재방송 독립성

레코드의 서명은 그 트랜잭션이 제출되는 순간에 확정됩니다. 블록체인에는 트랜잭션을 넘나들며 쌓여 가는 "확장된 서명자 집합"이라는 개념이 없습니다.

동일한 레코드 본문을 다른 sigs 집합과 함께 별개의 트랜잭션으로 재방송하면, 그것은 자체의 블록 시각을 갖는 별개의 독립된 레코드를 만들어 낼 뿐, 결코 원래 레코드의 확장이 되지 않습니다.

이미 게시된 레코드를 지지하려는 측은 자기 자신의 레코드를 게시합니다. 같은 콘텐츠를 참조하거나, supersedes로 선행 트랜잭션을 가리키며, 자신의 키로 서명합니다. 남의 레코드에 증인으로 서명을 덧붙이는 것이 아닙니다. 따라서 서명된 레코드의 바이트를 새로운 트랜잭션으로 복제한 공격자가 원래 레코드의 공동 서명자가 되는 일은 없습니다. 공격자는 자신이 선택한 sigs를 동반한, 더 늦은 중복 주장을 만들어 낼 뿐이며, 원래 레코드의 더 이른 블록 시각이 존재를 가리키는 정규 기록으로 남습니다. 검증자와 인덱서는 동일한 레코드 본문을 지닌 두 트랜잭션을 하나의 "서명자를 병합한" 뷰로 합쳐서는 안 됩니다(MUST NOT). 그렇게 하면 하류 소비자가 의존하는, 레코드별 블록 시각 의미를 왜곡하게 되기 때문입니다.

구현에 대한 규범적 규칙

다음은 언어나 플랫폼을 불문하고 어떤 적합한 구현에 대해서도 보안상 규범적입니다. RFC 2119 / RFC 8174의 키워드는 규범적 의미로 사용됩니다.

규칙의무
독자적 암호를 만들지 않는다모든 프리미티브는 감사받은 라이브러리에 수록된, 문서화된 IETF / NIST / W3C 표준입니다. 자체 제작한 암호, KDF, 서명 방식, 스탠자는 인정하지 않습니다.
인증된 암호화만모든 대칭 암호화는 AEAD입니다. 태그 검증 실패는 형(型)이 지정된 오류를 일으켜야 하며(MUST), 평문 일부를 조용히 반환해서는 안 됩니다(MUST NOT).
비밀 값 비교는 상수 시간으로MAC 태그, AEAD 태그, 그리고 비밀에서 도출한 바이트는 상수 시간으로 비교합니다. 이들 면에서 데이터에 의존하는 비교를 하면 인증 오라클이 됩니다.
엄격한 Ed25519 검증서명을 정규(엄격) 모드로 검증합니다. 코팩터를 포함한 느슨한 검증자는 엄격한 검증자가 거부하는 경계 사례 서명을 받아들여 참조 구현과 어긋납니다.
비밀이나 평문을 절대 로그에 남기지 않는다키 재료, 도출된 키, 복호화된 평문은 어떤 레벨에서도 로그에 나타나서는 안 됩니다(MUST NOT). 바이트 형 값은 무조건 가려집니다.

독자적 암호를 만들지 않는다

Label 309는 의도적으로 충분히 분석된 프리미티브만을 받아들이며, 각각 알고리즘 레지스트리에 이름이 올라 있고 감사받은 라이브러리로 구현되어 있습니다. 구현은 맞춤형 대칭 암호, KDF, 서명 구성, 키 래핑 스탠자를 도입해서는 안 됩니다(MUST NOT). 와이어 포맷을 표준 부품의 조합으로 구성한 것은, 바로 그 안전성을 그 부품들의 안전성으로 환원하기 위함입니다.

인증된 암호화만

Label 309의 모든 대칭 암호화는 — 콘텐츠 계층도, 슬롯별 키 래핑도 — AEAD입니다. 이 포맷의 어디에도 인증되지 않은 암호 모드는 존재하지 않습니다. AEAD 태그 검사에 실패한 복호화기는 안정된 코드 판별자를 동반한 구조화된 오류를 표면화해야 하며(MUST), 인증되지 않은 바이트를 반환하는 처리로 흘러 내려가서는 안 됩니다(MUST NOT). 추가 인증 데이터는 태그 계산의 일부이므로, 잘못된 AAD는 잘못된 키와 똑같이 실패합니다. 탐색할 수 있는 부분 성공 상태는 존재하지 않습니다.

비밀 값의 상수 시간 비교

실행 시간이 비밀 바이트에 의존하는 비교 루프는 오라클이 됩니다. 비밀, 또는 MAC / AEAD 태그에 대한 모든 동등성 검사는 상수 시간이어야 합니다(MUST).

  • 슬롯 집합 MAC 및 모든 HMAC 태그 — 32바이트 MAC에 대한 바이트별 타이밍 누설은, 적대자가 반복하면 태그 복원으로 이어질 수 있습니다.
  • AEAD 태그 검증 — 기반 라이브러리의 decrypt는 어느 바이트가 일치하지 않았는지 드러내지 않고 실패를 반환합니다. 구현은 이 검사를 자체적으로 다시 구현해서는 안 됩니다(MUST NOT).
  • 서명 검증 — 자체 제작한 등식이 아니라 라이브러리의 verify를 사용하십시오.

이들 면에 닿는 바이트 배열에 대해 맨손으로 == / ===를 쓰는 것은 결함입니다. 그러한 모든 비교를 단일한 형 지정 헬퍼에 통과시키면 이 성질을 감사 가능하게 만들 수 있습니다.

상수 시간의 규율은 개별 비교뿐 아니라 시험 복호화 루프의 형태에도 미칩니다. 수신자를 숨기는 성질을 지키기 위해, 수신자 검증자는 단일 개인 키의 한 패스 안에서 모든 슬롯을 처리해야 합니다(MUST). 키당 일정한 횟수의 슬롯 연산으로, 첫 일치에서의 조기 이탈은 없습니다. 그래서 타이밍을 관찰할 수 있는 네트워크 차원 관찰자가 어떤 키가 어느 슬롯 인덱스를 언래핑했는지, 또는 일치한 슬롯이 있었는지조차 추론할 수 없습니다. 후보 키는 상수 시간으로 선택됩니다. X25519 셰어의 유효성은 비밀에 의존하지 않는 비트 kem_ok = NOT constantTimeEqual(shared, 0^32)로 포착되며, 이는 조기 분기가 아니라 상수 시간 비교로 계산됩니다. 이어서 KEK는 진짜 KEK와, 같은 salt와 info 아래 모두 0인 공유 비밀에서 도출한 더미 KEK 사이의 상수 시간 선택이 되고, kem_ok는 슬롯의 수락(ok = kem_ok AND open_ok AND mac_ok)에 짜 넣어집니다. 그래서 ECDH가 무효인 슬롯은 결코 수락되지 않는 한편, 루프는 여전히 동일한 작업을 수행합니다. 슬롯 배열은 CSPRNG로 뒤섞인 순서로 게시되므로, 와이어상의 위치는 이미 "주된 수신자가 맨 앞"이라는 신호를 담지 않습니다. 상수 시간 패스와 결합되면 관찰자가 알 수 있는 것은 슬롯 수뿐입니다. 여러 개인 키를 가진 수신자(예컨대 아이덴티티 회전을 넘나들며 보관된 키)는 키 × 슬롯을 순회하며, 키 사이에서 단락(short-circuit)해도 됩니다(MAY). 이는 "어느 키가 일치했는가"라는 약한 신호만 누설하지만, 어느 단일 키의 슬롯들을 넘나드는 동안에는 상수 시간을 유지해야 하며(MUST), 키마다 KEK salt의 수신자 키 절반을 다시 도출합니다. 두 KEM 모두 salt를 그 키의 정규 와이어 인코딩(정확히 32바이트 X25519 공개 키, 또는 정확히 고정된 1216바이트 X-Wing 공개 키 바이트 — 비정규한 재인코딩은 결코 쓰지 않습니다)에 커밋하기 때문입니다.

엄격한 Ed25519 검증

Label 309 서명은 엄격(정규) 모드로 검증해야 합니다(MUST). 느슨한, 코팩터를 포함한 검증자는 엄격한 검증자라면 거부할 가단성 있는 서명이나 저위수 키에 의한 서명 일부를 받아들입니다. 이는 적합한 두 구현이 같은 레코드에 대해 어긋나도록 허용해, 표준 전체가 의존하는 단일 판정 성질을 깨뜨립니다. 언어를 넘나드는 적합성 코퍼스는 느슨한 모드에 빠진 검증자를 잡아내기 위해 저위수 테스트 벡터를 정확히 고정합니다. 서명을 참조하십시오.

비밀 재료를 절대 로그에 남기지 않는다

시드 바이트, 도출된 개인 키, 키 암호화 키, 콘텐츠 암호화 키, 패스프레이즈에서 도출한 재료, 그리고 복호화된 평문은 어떤 레벨에서도 로그에 도달해서는 안 됩니다(MUST NOT). 로거 설정에서의 경로 기반 가림 처리는 필요하지만 그것만으로는 충분하지 않습니다. 가림 처리의 글롭이 닿는 것보다 더 깊이 중첩된 값은 빠져나갈 수 있으므로, 구현은 모든 바이트 형 값(Uint8Array, bytes 등)을, 논스처럼 프로토콜상 공개해도 되는 값이라 할지라도, 무조건 불투명하게 가린 것으로 취급해야 합니다(MUST). 보호하기에 가장 품이 덜 드는 비밀은, 애초에 로그 줄에 들어가지 않는 비밀입니다.

봉인된 PoE 구성 보장

세 가지 추가 성질이 봉인된 PoE 구성에 고유합니다. 이것들은 봉인된 레코드를 생성하거나 여는 모든 구현에 대해 보안상 규범적입니다.

슬롯 집합 MAC은 ~128비트 커밋먼트다

슬롯 집합 MAC은 회수된 콘텐츠 키를 수신자가 일치시킨 슬롯 집합에 대한 커밋먼트로 만드는 것입니다. 악의적인 송신자는 단일 수신자가 "자기 것"으로 받아들이는 서로 다른 두 슬롯 집합을 구성할 수 없습니다. 요구되는 성질은 봉투의 콘텐츠 키에 대한 RFC 9771의 의미에서의 제한된 키 커밋먼트입니다. 즉 회수된 키는 단일 슬롯 트랜스크립트에 결속되며, 임의의 입력에 대한 완전한 커밋형 AEAD가 아닙니다. 수신자는 슬롯에서 키를 도출한 뒤, 그것을 자기 슬롯으로 취급하기 전에 그 같은 키가 슬롯 트랜스크립트 해시에 대해 slots_mac을 재현할 것을 요구합니다. 구체적으로 이 커밋먼트는 다음 사상의 다중 키 충돌 저항성에 의존합니다.

CEK ↦ HMAC-SHA-256( HKDF-SHA-256(CEK, info="cardano-poe-slots-mac-v1"), slots_hash )

이는 적대적으로 선택된 CEK와 트랜스크립트에 대한 저항성입니다. 적대자가 CEK와 트랜스크립트를 모두 통제하므로, 관련 한계는 256비트 HMAC 출력에 대한 일반 충돌(생일) 한계입니다. 즉 같은 slots_mac을 낳는 두 (CEK, transcript) 쌍을 찾는 것은 256비트 제2 역상 수준이 아니라 ~128비트 탐색입니다. 128비트의 일반 충돌 여유가 이 커밋먼트가 의존하는 안전 수준이며, 위협 모델에 대해 충분합니다.

HMAC 전에 트랜스크립트를 32바이트 slots_hash로 사전 해시해도 이것은 약화되지 않습니다. slots_mac 충돌은 slots_hash 충돌(SHA-256 충돌)이나, 동일한 slots_hash 위에서의 키 부착 HMAC 충돌 중 하나를 함의하며, 둘 다 ~128비트 수준입니다. 트랜스크립트 자체의 위변조가 드러나는 성질은 SHA-256의 2^128 충돌 한계를 물려받습니다. 커밋된 헤더 필드나 슬롯 바이트에 대한 어떤 변경도 slots_hash를 바꾸며, 다른 트랜스크립트에 대해 변하지 않은 slots_hash를 위조하는 것은 바로 그 ~128비트 충돌 탐색입니다. 그 직접적 귀결로 슬롯별 래핑은 커밋형 AEAD일 필요가 없습니다. 커밋먼트는 래핑이 아니라 slots_mac이 공급하므로, 비커밋형 래핑(기본값 ChaCha20-Poly1305)도 여기서는 건전합니다.

영 논스 래핑의 안전성은 슬롯별 키 유일성에 의존한다

각 슬롯은 콘텐츠 키를 슬롯별 키 암호화 키 아래에서 ChaCha20-Poly1305로 영 논스를 써서 래핑합니다. 영 논스가 안전한 것은 오직 키 암호화 키가 슬롯별이며 정확히 한 번의 래핑에만 쓰일 때뿐입니다. 모든 슬롯이 새로운 KEM 난수를 뽑으므로, 래핑 키는 슬롯별로 무시할 만한 충돌 확률로 유일합니다. 안전 조건은 바로 슬롯별 키 유일성이며, 생성자는 (key, nonce) 쌍을 반복시킬 수 있는 어떤 것도 도입해서는 안 됩니다(MUST NOT). KEM 난수를 반복하는 CSPRNG 고장, 결정론적이거나 충돌하는 캡슐화, 레코드를 넘나든 슬롯 재사용, (recipient, ephemeral)로 도출 키를 캐시하는 것, 동일 수신자의 두 출현을 하나의 슬롯으로 중복 제거하는 것 모두가 그렇습니다.

이것은 검증자가 확인할 수 있는 부분과 생성자만의 의무로 깔끔하게 나뉩니다.

  • 레코드 내부의 중복은 검증자가 거부한다. 검증자는 캡슐화 재료가 단일 slots[] 안에서 서로 다를 것을 요구해야 합니다(MUST). x25519 경로에서는 모든 epk 값이, mlkem768x25519 경로에서는 모든 kem_ct 값이 서로 달라야 합니다. 중복은 어떤 KEM이나 AEAD 프리미티브가 실행되기 전에 형 지정 코드 ENC_SLOTS_DUPLICATE_KEM_MATERIAL로 거부됩니다. 적합성 코퍼스는 epk(또는 kem_ct)를 공유하는 두 슬롯을 지닌 레코드로 이를 검사하며 그 거부를 요구합니다. 이 거부는 반복된 epk / kem_ct에 대해서만 발화합니다. 같은 수신자에게 두 번 봉인하는 것을 금지하지는 않습니다. 정직한 중복은 출현마다 새로운 슬롯별 KEM 난수를 뽑기 때문입니다(아래의 다중 일치 슬롯 규칙 참조).
  • 레코드를 넘나드는, 키를 넘나드는 재사용은 생성자의 의무다. 생성자가 서로 다른 두 레코드나 수신자에 걸쳐 KEM 재료를 재사용했음을 어떤 검증자도 탐지할 수 없습니다. 그것은 단일 레코드의 바이트 밖에 있으며 생성자의 책임으로 남습니다. 가령 미래의 개정판이 키 재사용을 허용한다면, 같은 변경 안에서 영 논스를 새로운 논스로 교체해야 할 것입니다.

다중 일치 슬롯: 패딩은 허용되고, CEK 충돌은 허용되지 않는다

수신자의 개인 키가 둘 이상의 슬롯에 정당하게 일치할 수도 있습니다(MAY). 같은 콘텐츠 키를 같은 수신자에게 여러 슬롯에 걸쳐 — 각각 새로운 슬롯별 임시 키와 함께 — 봉인하는 것은, 두 슬롯이 수신자를 공유한다는 것을 드러내지 않으면서 눈에 보이는 슬롯 수를 늘리는 정당한 패딩 및 프라이버시 기법입니다. 이것은 위의 레코드 내부 중복 캡슐화 거부와는 별개입니다. 정직한 중복은 새로운 KEM 난수를 뽑으므로 그 epk / kem_ct가 서로 다르고, 결코 ENC_SLOTS_DUPLICATE_KEM_MATERIAL을 건드리지 않습니다. 따라서 검증자는 첫 번째 일치 슬롯의 콘텐츠 키를 선택해야 하며(MUST), 단지 둘 이상의 슬롯이 일치했다는 이유만으로 거부해서는 안 됩니다(MUST NOT).

검증자가 거부해야 하는(MUST) 유일한 이상 현상은 서로 다른 콘텐츠 키를 회수하는 두 일치 슬롯입니다(상수 시간으로 비교합니다). 시험 복호화 루프는 모든 슬롯에 걸쳐 cek_conflict 비트를 지니며, 이후의 어떤 일치가 이미 선택된 키와 다른 키를 회수하면 단일한 일반 실패를 표면화합니다. 이것은 심층 방어입니다. 위의 커밋먼트 성질 아래에서 서로 다른 키의 일치는 이미 실현 불가능하며 — 그것은 바로 그 성질이 배제하는 다중 키 충돌입니다 — 따라서 이 검사는 결함 있는 구현이나 그 가정의 미래 약화에 대해 안전하게 닫히며 실패합니다. 서로 다른 키라는 부정 사례는 바이트 벡터로 구성할 수 없으므로(하나를 구성한다는 것은 커밋먼트 충돌 그 자체가 됩니다), 이 성질은 픽스처가 아니라 구현 차원의 행위 테스트로 고정되며, 정당한 수신자 중복을 위한 긍정 픽스처가 함께 마련됩니다.

어떤 프리미티브보다 앞선 파서 자원 한계

검증자는 어떤 KEM이나 AEAD 프리미티브를 호출하기 전에 파서의 자원 사용을 제한해야 합니다(MUST). 과대한 봉투가 거부되기 전에 작업을 강요할 수 없도록 하기 위함입니다. 참조 한계는 MAX_SLOTS = 1024 슬롯과, 디코딩된 enc 봉투에 대한 65536 바이트이며, 둘 다 정직한 레코드를 제약하는 약 16 KiB의 Cardano 트랜잭션 메타데이터 천장을 훨씬 웃돕니다. 따라서 어느 한쪽 한계를 넘는 레코드는 형식이 어긋난 것입니다. 개수 초과는 ENC_SLOTS_TOO_MANY로, 크기 초과 봉투는 ENC_ENVELOPE_TOO_LARGE로 거부됩니다. 이것들은 와이어 필드가 아니라 검증자가 강제하는, 배포 시점에 고정된 상수이며, 배포 측에서 더 빡빡하게 죌 수도 있습니다(MAY). 패스프레이즈 경로의 대응 가드는 정규화와 Argon2id 전에 강제되는 원시 패스프레이즈 입력 최대 길이입니다(참조 한계 4096 UTF-8 바이트, MAX_PASSPHRASE_INPUT_BYTES). 그래서 병적인 패스프레이즈가 KDF 이전의 서비스 거부를 일으킬 수 없습니다.

X-Wing 공개 키 유효성이 하이브리드 하한을 떠받친다

하이브리드 mlkem768x25519 KEM은 하한으로서 X25519의 고전적 안전성 아래로 결코 떨어지지 않습니다 — 하지만 그 하한은 정당하게 생성된 수신자 키로 한정됩니다. XWing.Encapsulate는 고정된 X-Wing 개정판의 공개 키 유효성 검사를 수신자 키에 적용해야 하며(MUST), 그것을 통과하지 못하는 키를 마치 고전적 보장을 지닌 것처럼 다루는 대신 그 키로의 캡슐화를 거부해야 합니다. 검사를 건너뛰는 생성자는 그 수신자에 대해 하한을 잃습니다. 그 검사가 하한이 성립하는 전제 조건입니다.

한계 지어진 페이로드 크기

콘텐츠 계층은 세그먼트화된 STREAM입니다. 평문은 65536바이트 청크로 나뉘고, 각 청크는 콘텐츠 키 아래에서 서로 다른 카운터 논스로 봉인됩니다. 88비트 청크별 카운터는 2^88개의 청크를 허용하며 각 청크는 RFC 8439의 단일 호출 한계 안에 넉넉히 들어가므로 — 평문 전체에 대한 단발(single-shot) AEAD와 달리 — 경계해야 할 카운터 오버플로 키스트림 충돌이 없고, 포맷은 어떤 암호학적 페이로드 천장도 부과하지 않습니다. 따라서 배포 환경이 강제하는 최대치는 암호학적 한계가 아니라 서비스 거부 정책입니다. 생성자와 검증자는 페이로드 크기를 자신의 자원에 맞게 상한을 두어야 하며(SHOULD), 스트림이 쓰이거나 읽히는 동안 점진적으로 그것을 강제해 과대한 페이로드가 버퍼링되기 전에 중단해야 합니다. 절단은 크기 검사가 아니라 청크별 최종 플래그에 의해 구조적으로 포착됩니다. 즉 누락된 최종 청크, 후행 데이터, 또는 짧은 비최종 청크는 모두 복호화에 실패합니다. 이 자세는 슬롯 경로와 패스프레이즈 경로에서 동일합니다.

보안 속성으로서의 알고리즘 민첩성

Label 309 레코드의 모든 암호학적 선택은 — 해시, AEAD, KEM, KDF, 서명 방식 — 확장 가능한 레지스트리의 문자열로 명명됩니다. 이것은 양식상의 취향이 아니라, 포맷이 어떤 단일 알고리즘보다 오래 살아남게 하는 이행의 기반입니다.

어떤 프리미티브가 암호 분석으로 약화되면 다음과 같이 대처합니다.

  1. 해당 레지스트리에 후속 식별자가 추가됩니다. 기존 포맷의 어떤 것도 바뀌지 않습니다 — 새 이름은 추가적입니다.
  2. 기존 레코드는 유효한 채로 남습니다. 검증자는 과거 레코드에 대해 계속해서 옛 식별자를 인식합니다. 더 새로운 알고리즘이 존재한다고 해서 그것들의 블록 시각 주장이 증발하지 않습니다. 구현은 이미 약화된 알고리즘에만 의존하는 레코드를 더 낮은 보증으로 제시할 수도 있지만(MAY), 그것만을 이유로 지우거나 거부해서는 안 됩니다(MUST NOT).
  3. 새 레코드는 후속 식별자 아래에서 게시됩니다. 심층 방어를 원하는 게시자는 설계 계열이 다른 두 알고리즘으로 콘텐츠 해시를 커밋할 수도 있으므로(MAY), 한 계열이 깨져도 레코드의 증거적 가치가 무너지지 않습니다 — 다만 단일 알고리즘 레코드도 완전히 적합한 채로 남습니다.

식별자가 문자열이고 레지스트리가 열려 있으므로, 포스트 양자 해시, KEM, 서명으로 이행하는 것은 호환성을 깨뜨리는 포맷 개정이 아니라 추가적인 레지스트리 변경입니다. 이미 레지스트리에 있는 하이브리드 포스트 양자 KEM은 이 성질이 실제로 작동하는 한 사례이지, 나중에 덧붙인 특례가 아닙니다.

표준의 알려진 한계

이것들은 나중 개정에서 고쳐야 할 결함이 아닙니다. 영속적이고 공개된 원장에 증명을 기록하는 것, 그리고 장기 키로의 공개 키 암호화 그 자체에 본질적으로 따르는 성질입니다. 정직한 보안 모델은 이것들을 솔직하게 명시합니다.

온체인 영속성

Cardano 메타데이터는 영속적이며 전 세계에 복제됩니다. 게시된 Label 309 레코드는 삭제도, 편집을 통한 비공개 처리도, 무효화도 할 수 없습니다 — 그 지속성이 바로 존재 증명의 존재 의의 그 자체입니다. 그 귀결로 게시 시점의 책임이 생깁니다. 콘텐츠 해시, 스테이크에 연결된 서명, 그 밖에 라벨 309 아래에 커밋한 무엇이든 영원히 블록체인에 남습니다. Label 309는 온체인 점유 공간을 최소로 유지하기 위해 자유 형식의 설명적 메타데이터를 레코드에서 의도적으로 빼지만, 게시자는 자신이 게시하는 것이 철회 불가능하다는 것을 게시하기 전에 이해해야 합니다(MUST).

수신자 수가 보인다

봉인된 PoE는 결코 수신자를 명시하지 않지만, 수신자 슬롯의 는 배열의 길이이며 블록체인에 그대로 보입니다 — KEM 패밀리(enc.kem)와 봉인 대 비봉인의 구분도 마찬가지입니다. 수신자 공개 키는 와이어상에 없고 슬롯은 뒤섞이지만, 수를 숨기는 패딩은 기준선에 포함되지 않습니다. 수신자 수 자체가 민감한 송신자는 이 메타데이터 누설을 운영 면에서 감안해야 합니다 — 예컨대 직접 슬롯 집합을 패딩하거나, 레코드를 나누어 게시하는 것입니다.

수신자별 폐기는 없다

이미 게시된 봉인된 PoE에 대해 특정 수신자 한 명의 접근을 폐기하는 온체인 프리미티브는 존재하지 않습니다. 레코드가 어떤 공개 키로 암호화되어 블록체인에 기록되면, 그 결속은 영속적입니다. 이것은 포맷의 빈틈이 아니라 장기 키로의 공개 키 암호화에 본질적으로 따르는 성질입니다. 유출이 의심되는 키는 앞으로 향해 처리합니다 — 새 레코드를 새로운 키에 보내고, 필요하다면 매수인 위험 부담(caveat emptor) 신호로서 이를 대체하는 레코드를 게시하는 것이지, 이미 블록체인에 있는 것을 거슬러 바꾸는 것이 아닙니다.

수신자 전방 비밀성은 설계상 없다

수신자 개인 키를 쥔 사람은 그 키에 보내진 모든 봉인된 PoE를 언제까지나 복호화할 수 있습니다. 오프체인 암호문은 영속적이고 폐기 프리미티브도 없으므로, 봉인된 레코드는 세상에 대해서는 사적이지만 그 수신자에 대해서는 사적이지 않은 상태가 됩니다. 이것은 장기 공개 키로 암호화할 때 당연히 예상되는 동작입니다. 수신자의 미래 도달 범위를 제한해야 하는 송신자는 장기 아이덴티티 키가 아니라 단명한 수신자 키로 암호화해야 합니다 — 포맷이 허용하되 의무화하지는 않는 송신자 측의 선택입니다.

시험 복호화 실패는 키 재료를 누설하지 않는다

수신자는 시험 복호화로 자신의 슬롯을 발견합니다. 내부에서는 — 신뢰할 수 있는 로컬 호출자의 진단을 위해서만 — 실패 경로가 서로 다른 형 지정 코드를 지닙니다. "내 키로는 열린 슬롯이 없었다"(WRONG_RECIPIENT_KEY), "슬롯은 열렸으나 어떤 후보 키도 slots_mac을 재현하지 못했다"(TAMPERED_HEADER), 그리고 "키가 회수되고 MAC이 검증된 뒤에 콘텐츠 AEAD가 실패했다"(TAMPERED_CIPHERTEXT)의 셋입니다. 이 코드들은 오라클로서의 가치를 지니지 않습니다. 일치하는 개인 키가 없는 적대자는 애초에 어떤 슬롯도 열지 못하며, 모든 오류 경로는 기반이 되는 비밀 바이트(공유 비밀, 키 암호화 키, 콘텐츠 암호화 키)를 그 메시지와 원인 사슬에서 제외해야 합니다(MUST).

반면 신뢰할 수 없는 외부 호출자는 복호화가 실패한 이유와 무관하게 정확히 하나의 일반 실패 형태를 받아야 하며(MUST), 외부 응답은 그 세 원인을 형태로 구별해서는 안 되고(MUST NOT), 어느 슬롯이 일치했는지도 드러내서는 안 됩니다. 내부 코드는 로컬 디버깅을 위해 존재하며, 구별 가능한 응답을 통해 외부 관찰자에게 누설되어서는 안 됩니다(MUST NOT).

타이밍 모델은 의도적으로 범위가 좁혀져 있습니다. 검증자는 무일치 검사 시점에, 즉 콘텐츠 복호화 전에 반환해도 됩니다(MAY). 그래서 비수신자(어떤 슬롯도 열리지 않음)는, 슬롯은 열렸으나 콘텐츠 암호문 열기에 실패하는 수신자와 시간으로 구별될 수 있습니다. 그 구별이 드러내는 것은 수신자 대 비수신자뿐이며, 어느 슬롯이 일치했는지도, 어떤 키 재료도 결코 드러내지 않습니다. 비수신자 경우와 암호문이 잘못된 경우 사이의 타이밍 일치는 요구되지 않으며(NOT), 더미 콘텐츠 열기를 의무화해서는 안 됩니다(MUST NOT). 비수신자 모두에게 콘텐츠 복호화 비용을 강요해도 얻을 것이 아무것도 없기 때문입니다. 실제로 성립하는 상수 시간 보장은 슬롯 횡단 불변 원칙입니다(비밀 값의 상수 시간 비교 참조). 즉 단일 키의 한 패스 안에서 루프는 상수 시간 비교로 모든 슬롯을 훑으므로, 관찰자는 어떤 키가 어느 슬롯을 언래핑했는지(있다면)를 알 수 없으며 — 수신자 대 비수신자 구별을 넘어서는 슬롯 수만을 알 뿐입니다.

관련 페이지

  • 소개 — 발행자 비의존과 독립 검증 가능성을 포함한 다섯 가지 불변 원칙.
  • 서명 — 엄격한 Ed25519 검증과, 실패해도 무너지지 않는 저작자성 모델.
  • 봉인된 PoE — 암호화 봉투와, 여기서 요약한 프라이버시 특성.
  • 알고리즘 레지스트리 — 알고리즘 민첩성을 가능하게 하는 명명된 식별자.
  • 검증 — 파이프라인, 확인 깊이 정책, 그리고 오류 카탈로그.