chacha — ChaCha20 스트림 암호
키와 논스에서 키스트림을 만들어 입력과 XOR 한다(RFC 8439 §2.4). 대칭이라 같은 호출이 암호화이자 복호화다.
이것만으로는 안전하지 않다
aead 다. 특별한 이유가 없으면 aead 를 쓴다. 논스 재사용은 치명적이다 — 같은 (키, 논스)로 두 번 흘리면 두 평문의 XOR 이 드러난다. 상수 시간을 약속하지 않고 감사받지 않았다.32 비트 덧셈·XOR·회전만 쓰는 순수 계산이라 언어로 표현된다 — qround · rounds · keystream 이 그 글이고, 그것이 이 모듈이 말하는 뜻의 정의다. 다만 stream 은 낱말 chacha20 을 부른다: ChaCha 의 블록들은 서로 독립이라 넷·여덟을 한 레지스터에 나란히 실으면 그대로 넷·여덟 배가 되는데, 그 폭이 이 언어에 없다(실측 89 → 2439 MB/s). 답은 같고, 회귀 시험이 낱말과 위의 정의를 같은 입력으로 맞댄다. 32 비트 산술을 u64 위에서 한다. 이 언어의 add 는 넘치면 멈추므로, 감김이 필요한 자리는 마스크를 명시한다(bit_and … 4294967295). 감김을 원하면 이름으로 말하라는 규율이 암호 구현에서 그대로 값을 낸다 — 조용한 감김은 조용한 결함이다.
| op | 하는 일 | 요구 |
|---|---|---|
prep | 키·논스·카운터로 상태 16 워드를 세운다 | key ≥ 32 · nonce ≥ 12 |
rounds | 20 라운드(더블 라운드 10)를 돌린다 | work 는 16 워드 |
keystream | 상태에서 64 바이트 블록을 낸다 | ks ≥ 64 |
stream | 입력 전체를 흘려 out 에 쓴다 | out ≥ len(inp) |
표 50.1 — chacha 의 op
보통 쓰는 얼굴은 stream 이다. 답은 처리한 바이트 수이고 0 이면 실패다.
확인하는 것 — RFC 8439 §2.3.2 블록 함수 벡터와 §2.4.2 암호화 벡터. 블록 함수를 따로 재는 까닭은, 흐름만 맞추면 상태 배치가 틀려도 우연히 맞을 수 있고 그러면 다음 사람이 그 위에 지을 때 틀리기 때문이다. 짓지 않은 것 — 인증(aead), XChaCha20(확장 논스), 카운터 소진 감지, 상수 시간 보장.