에이전트 전용 봉인 모듈(agent_seal): 완전 엔트로피 기계키 봉인 + 정보이론적 OTP - #4845
Closed
kevin9327 wants to merge 2 commits into
Closed
Conversation
사람 암호(약한 고리) 없이 에이전트가 보관하는 완전 엔트로피 기계키로 문서를 봉인하는 모듈을, security_trailer 와 독립된 자체 형식으로 추가한다. - 1번 모드(계산적 안전·양자내성): XChaCha20-Poly1305 AEAD, KDF 없음, 24바이트 난수 논스, 헤더 AAD, 호스트 뒤 트레일러(가시 계층=호스트). - 2번 모드(정보이론적 안전): 일회용 패드 XOR. 패드 길이>=메시지 강제, 같은 컨테이너에 distinct algo. 기밀성만 제공(인증 없음) — 정직한 한계 명시. - 자체 마법 RHWPAGT1/RHWPAGND, 꼬리 탐지, 엄격한 경계로 손상 입력 무패닉. - chacha20poly1305 0.10(alloc) 의존성 추가. OTP 는 XOR+getrandom 만 사용. - 단위 시험 16종(라운드트립·오키/변조 Broken·교차모드 거부·무패닉) 통과. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
CI 가 WASM32 경로 3곳에서 실패했다 (PR edwardkim#4845): Lint 의 Clippy (WASM32), Frontend package gates 의 wasm-pack 빌드, Canvas visual diff 의 wasm 빌드. 원인은 edwardkim#4826·edwardkim#4838 과 같은 **getrandom 0.2** 다. chacha20poly1305 의 기본 `getrandom` 피처가 rand_core 0.6 을 거쳐 0.2 를 끌어오는데, 0.2 는 wasm32-unknown-unknown 에서 `js` 피처 없이 compile_error! 로 죽는다. 이 저장소가 켜 둔 getrandom 0.4 + wasm_js 는 버전이 달라 그 자리를 못 덮는다. agent_seal 은 기계키·논스·OTP 패드를 전부 `getrandom::fill`(0.4)로 직접 만들므로 그 피처가 애초에 필요 없다. default-features 를 끄고 `alloc` 만 남긴다 — 암호 알고리즘·포맷·동작은 그대로다. 검증: cargo tree -i getrandom@0.2 --target wasm32-unknown-unknown 결과 없음, cargo clippy -p rhwp --lib --target wasm32-unknown-unknown -- -D warnings 통과, cargo check --target wasm32-unknown-unknown --lib 통과, agent_seal 단위 테스트 16/16 통과, cargo clippy --workspace --all-targets 통과. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jangster77
self-requested a review
August 15, 2026 13:29
Collaborator
|
통합 PR #4883(4412546)로 병합 완료했습니다. 원 head와 CI를 다시 확인해 누적 반영했고, 상세 검토·메인터너 보정·검증 근거는 archive 검토 기록에 남겼습니다. 중복 병합을 막기 위해 이 원 PR을 닫습니다. 감사합니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4843
무엇을 / 왜
문서 암호화의 약한 고리는 알고리즘이 아니라 사람이 고른 낮은 엔트로피 암호입니다.
Argon2id 같은 강한 KDF 도 이 사실을 늦출 뿐 없애지 못합니다. 반면 에이전트는 완전
엔트로피 기계 키(OS 난수 32바이트)를 직접 보관·전달할 수 있으므로 이 약한 고리를
아예 제거할 수 있습니다.
그리고 "양자내성보다 더 강한" 암호는 존재하지 않습니다 — 딱 하나 예외가 정보이론적
안전성(일회용 패드) 입니다. 이 PR 은 이 두 가지를 정직하게 제공하는 새 독립 모듈
src/agent_seal.rs를 추가합니다. 마법의 "양자 초월 암호"는 없습니다.두 가지 모드
1번 모드 — 완전 엔트로피 에이전트 키 (계산적 안전, 양자내성)
agent_keygen() -> [u8; 32]— OS 난수 32바이트. 이 원시 키 자체가 "에이전트 암호"입니다(사람 암호·Argon2id 없음). 호출자가 base64/hex 로 인코딩해 다룹니다.
seal_with_key(host, secret, key) -> Vec<u8>— XChaCha20-Poly1305 AEAD, 매 호출 새24바이트 난수 논스. 트레일러 헤더를 AAD 로 묶어 변조를 탐지합니다. 트레일러는 호스트
문서 뒤에 붙어 평범한 뷰어가 무시합니다(가시 계층 = 호스트). 인증(AEAD) 있음.
open_with_key(bytes, key) -> Opened— 꼬리에서 트레일러를 탐지해Plain/Sealed{plaintext}/Broken{reason}를 반환. 손상된 입력에도 패닉하지 않음(엄격한 경계 검사). 키 불일치·변조는 AEAD 인증 실패로
Broken.2번 모드 — 일회용 패드 (정보이론적 안전 — 유일하게 "양자보다 강한" 것)
otp_generate_pad(len) -> Vec<u8>—len바이트 진짜 난수.otp_seal(secret, pad) -> Result<Vec<u8>, AgentSealError>—pad.len() >= secret.len()을 강제(짧으면
PadTooShort오류; 잘린 봉인을 만들지 않음) →secret XOR pad.1번과 같은 트레일러 컨테이너에 distinct algo 바이트로 자기서술합니다.
otp_open(sealed, pad) -> Opened— XOR 로 복원. 엄격한 경계·무패닉.OTP 의 정직한 조건과 한계 (코드 doc 에도 기재)
OTP 가 무조건적으로 안전한 것은 오직 다음이 모두 성립할 때뿐입니다:
이 조건을 못 지키면 OTP 는 오히려 약한 XOR 암호로 전락합니다. 또한 OTP 는 기밀성만
제공하며 무결성/인증이 없어 비트 뒤집기 변조를 탐지하지 못합니다(1번 모드의 AEAD 와
대비되는 정직한 한계). 인증이 필요하면 1번 모드를 쓰십시오.
트레일러 형식 (자기서술)
의존성
chacha20poly1305 = { version = "0.10", features = ["alloc"] }추가(순수 Rust, wasm 호환).getrandom만 사용(추가 의존성 없음).검증
cargo build --bin rhwp통과.cargo test --lib agent_seal::— 16/16 통과:빈 비밀 라운드트립, 오키 →
Broken(무패닉), 서로 다른 두 무작위 키의 상호 열람 불가,변조 암호문 →
Broken(AEAD), 평문 호스트 →Plain, 손상 입력 전수 무패닉.PadTooShort오류(잘린 봉인 아님),복원 시 짧은 패드 →
Broken,ciphertext == secret XOR pad직접 검증, 손상 입력 무패닉.open_with_key로 / AEAD 블롭을otp_open으로 열면Broken.cargo test --lib— 전체 3718 passed, 0 failed, 13 ignored (회귀 없음).rustfmt --edition 2021 src/agent_seal.rs로 정렬(--check통과).cargo clippy --lib통과.