지난 한 주간(2026/06/01 - 2026/06/07), 블록체인 생태계 전반에 걸쳐 다수의 공격 사례가 관찰되었습니다. 이번 주 보고서는 Zcash의 Orchard 실드 풀에서 발견된 치명적인 건전성(soundness) 취약점의 공개 공시에 초점을 맞추고 있으며, 해당 취약점은 ZEC의 탐지 불가능한 위조를 가능하게 했을 수 있습니다. 온체인 익스플로잇은 확인되지 않았으나, 공시로 인해 긴급 네트워크 업그레이드가 촉발되었고 ZEC는 40% 이상의 가치를 상실했습니다.
| 날짜 | 사건 | 유형 | 추정 피해액 |
|---|---|---|---|
| 2026/06/04 | Zcash Orchard | ZK 건전성 버그 | 익스플로잇 미확인 |
Web3 최고의 보안 감사 기관
출시 전에 설계, 코드, 비즈니스 로직을 검증하세요
주간 하이라이트: Zcash Orchard 건전성 버그
이 사건은 실제 운영 환경에서 발견된 가장 심각한 ZK 취약점 중 하나이기 때문에 이번 주 하이라이트로 선정되었습니다. 누락된 회로 제약 조건은 여러 차례의 감사에도 불구하고 4년 이상 탐지되지 않았으며, 최종적으로 AI 보조 보안 검토를 통해 발견되었습니다. 해당 취약점 유형(ZK 회로에서의 제약 부족 관계)은 ZK 회로 기반으로 구축된 모든 프로토콜에 존재할 수 있습니다.
2026년 6월 4일, Zcash는 Orchard 실드 풀 회로에서 발견된 치명적인 건전성 버그를 공개적으로 공시했습니다 [1]. 영지식 증명 회로의 누락된 제약 조건으로 인해 이중 지출을 방지하는 암호학적 바인딩이 손상되어, 동일한 실드 노트가 탐지 없이 여러 번 사용될 가능성이 있었습니다. 해당 취약점은 2022년 5월 Orchard 활성화 이후부터 존재했으며, 2026년 5월 29일 보안 연구원 Taylor Hornby가 AI 보조 감사를 통해 발견했습니다. 긴급 네트워크 업그레이드(NU6.2)가 2026년 6월 3일 회로를 패치했습니다. 익스플로잇의 증거는 발견되지 않았습니다.
배경
Zcash는 프라이버시 중심의 레이어-1 블록체인으로, 네이티브 토큰은 ZEC입니다. 모든 거래 내역이 공개적으로 표시되는 비트코인과 달리, Zcash는 영지식 증명을 통해 실드 트랜잭션을 지원하여 송신자 주소, 수신자 주소, 거래 금액을 숨깁니다. Zcash에는 여러 실드 풀이 있으며, 각각 다른 세대의 프라이버시 프로토콜에 해당합니다. Orchard는 최신 세대로, 2022년 5월 NU5 네트워크 업그레이드와 함께 활성화되었으며, halo2 영지식 증명 시스템 [2]을 사용하여 트랜잭션을 검증합니다. 사용자가 실드 트랜잭션을 수행할 때 증명자(prover) 역할을 합니다. 즉, Orchard 회로를 사용하여 노트를 소유하고 있고, 널리파이어가 올바르게 도출되며, 금액이 균형을 이룬다는 것을 어떠한 개인 정보도 공개하지 않고 증명하는 영지식 증명을 구성합니다. 네트워크 노드는 검증자(verifier) 역할을 하여 기반 데이터를 보지 않고 증명을 확인합니다. Orchard 회로는 모든 유효한 증명이 충족해야 하는 제약 조건을 정의합니다. 취약점은 이 회로 구현에 있으며, Zcash의 네 가지 핵심 개념인 키, 주소, 노트, 널리파이어와 관련됩니다.
키. Zcash의 키 계층은 대부분의 블록체인보다 복잡합니다. 하나의 지출 키(지갑 비밀)에서 여러 하위 키가 파생됩니다: ask(지출 인증 비밀 키), nk(널리파이어 파생 키), rivk(무작위화 키). 이로부터 시스템은 ak(인증 공개 키)와 ivk(수신 조회 키, ivk = Commit(ak, nk, rivk) 방식으로)를 계산합니다. 키 ivk는 수신 자금을 식별하고 받는 데 사용됩니다.
주소. Orchard 주소를 생성하기 위해 사용자는 다양화 기저점 g_d = DiversifyHash(d)를 결정하는 다양화 인자 d(11바이트 값)를 선택합니다. 주소는 (d, pk_d) 쌍으로, 다양화된 전송 키 pk_d는 타원 곡선 스칼라 곱셈으로 계산됩니다: pk_d = [ivk] g_d. 이는 주소가 사용자의 조회 키에 암호학적으로 바인딩됨을 의미합니다.
노트. 노트는 수신된 자금을 나타내는 자산 기록입니다. 프라이버시를 위해 온체인에 저장되는 것은 노트 자체가 아니라 노트 커밋먼트 cm(pk_d, 금액 및 기타 데이터를 포함한 노트 내용에 대한 암호학적 커밋먼트)입니다. 노트는 수신자의 주소에 잠겨 있습니다.
널리파이어. 노트를 지출할 때, 지출자는 노트의 데이터와 널리파이어 키 nk로부터 계산된 널리파이어 nf를 공개합니다: nf = Extract_P([(F_nk(ρ) + ψ) mod p]G + cm). 핵심 보안 속성은 각 노트가 정확히 하나의 널리파이어를 생성해야 한다는 것입니다. 널리파이어가 온체인에 나타나면, 해당 노트는 영구적으로 사용된 것으로 간주됩니다. 동일한 노트가 서로 다른 널리파이어를 생성할 수 있다면, 아무도 모르게 여러 번 지출될 수 있습니다.
바인딩 체인. 이러한 개념들은 암호학적 바인딩 체인으로 연결됩니다:

빨간색으로 강조된 노드(pk_d, nk)는 취약점이 바인딩 체인을 끊는 지점입니다. 회로는 pk_d = [ivk] g_d를 강제해야 하며, 이는 지출자를 올바른 ivk에, 따라서 해당 노트의 올바른 nk에 바인딩합니다. 이 바인딩이 깨지면, 지출자는 가짜 ivk를 위조하고 각 지출마다 다른 nk를 사용할 수 있습니다. 서로 다른 nk 값은 동일한 노트에 대해 서로 다른 널리파이어를 생성하여 이중 지출을 가능하게 합니다.
회로가 이 바인딩을 강제하는 방법. pk_d = [ivk] g_d 관계는 타원 곡선 스칼라 곱셈(Q = [k]P)으로, 이중-덧셈(double-and-add) 알고리즘을 사용하여 구현됩니다. 영지식 회로에서 검증자는 알고리즘을 직접 실행하지 않습니다. 대신, 회로는 모든 중간 단계를 제약합니다. 올바른 스칼라 곱셈 회로는 무엇보다도 내부 루프 기저점이 의도된 입력 기저점과 동일함(P_loop = P_input)을 강제해야 합니다. 이 제약 조건 없이는, 회로가 유효한 스칼라 곱셈이 수행되었음을 증명할 수 있지만 잘못된 기저점으로 수행된 것이어서 전체 바인딩 체인이 무의미해집니다.
취약점 분석
취약한 ECC 가젯은 pk_d = [ivk] g_d를 강제하는 스칼라 곱셈 관계에 사용되었으며, 여기서 Q = pk_d, k = ivk, P = g_d입니다. 취약한 코드는 halo2 저장소의 가변 기저 스칼라 곱셈 구현에 위치합니다(incomplete.rs L309-L310):
// incomplete.rs (전체 소스는 위 링크 참조)
298 for (row, k) in bits.iter().enumerate() {
299 // z_{i} = 2 * z_{i+1} + k_i
...
305 z = region.assign_advice(|| "z", self.z, row + offset, || z_val)?;
306 zs.push(Z(z.clone()));
307
308 // `x_p`, `y_p` 할당
309 region.assign_advice(|| "x_p", self.double_and_add.x_p, row + offset, || x_p)?; // 버그
310 region.assign_advice(|| "y_p", self.y_p, row + offset, || y_p)?; // 버그
311
312 // 비트가 설정된 경우 `y` 사용; 설정되지 않은 경우 `-y` 사용
313 let y_p = y_p
314 .zip(k.as_ref())
315 .map(|(y_p, k)| if !k { -y_p } else { y_p });
316
317 // lambda1 계산 및 할당
318 let lambda1 = y_a.zip(y_p).zip(x_a.value()).zip(x_p)
.map(|(((y_a, y_p), x_a), x_p)| (y_a - y_p) * (x_a - x_p).invert());
...
}
영지식 회로에서 증명자는 모든 셀 값을 채웁니다. 회로 자체는 셀 간에 값을 복사하거나 전달할 수 없으며, 검증자가 확인하는 제약 조건만 정의할 수 있습니다. 버그로 표시된 두 줄은 assign_advice()를 사용하여 기저점 좌표 x_p와 y_p(위트니스 값이라고 하는 개인 회로 입력)를 회로의 어드바이스 열(증명자의 개인 입력 영역)에 씁니다. 이 함수는 외부 기저점에 연결하는 제약 조건을 생성하지 않고 값을 채웁니다. 별도의 제약 조건이 모든 루프 반복에 걸쳐 기저 값이 동일하도록 보장하므로, 증명자는 각 반복에서 다른 기저점을 사용할 수 없습니다. 그러나 증명자는 모든 반복에 걸쳐 임의의 단일 기저점을 대입할 수 있으며, 회로의 어떤 제약 조건도 이를 거부하지 않습니다. 루프의 기저 값을 외부에서 전달된 실제 g_d에 고정하는 제약 조건이 없기 때문입니다.
올바른 함수는 copy_advice()로, 값을 채우면서 동시에 실제 기저점 g_d와 일치함을 강제하는 동등 제약 조건(복사 제약 조건)을 추가합니다. g_d는 주소마다 달라지므로(각 주소의 다양화 인자에서 파생), 회로에서 하드코딩할 수 없으며 루프의 기저점이 업스트림에서 계산된 g_d와 일치하도록 제약해야 합니다.
결과적으로, 회로는 실제로 pk_d = [ivk] g_d를 강제하지 않았습니다. 악의적인 증명자는 루프 내부에 임의의 기저점을 제공할 수 있었고(올바른 g_d 대신), 회로는 여전히 증명을 수락했습니다. 내부 계산은 대수적으로 자기 일관성을 유지했지만, 프로토콜이 지정한 다양화된 기저점에 더 이상 고정되지 않았습니다. 이러한 추가적인 자유도로 인해 증명자는 매번 다른 nk를 선택하고, 해당하는 ivk = Commit(ak, nk, rivk)를 계산하며, 제약되지 않은 스칼라 곱셈을 사용하여 위조된 ivk를 통과시킬 수 있습니다. 널리파이어가 nk에 의존하므로, 각 지출은 고유한 널리파이어를 생성합니다:
동일한 노트 N + nk_1 → nf_1
동일한 노트 N + nk_2 → nf_2
여기서: nf_1 ≠ nf_2
합의는 널리파이어가 이미 온체인에 나타났는지만 확인합니다. 각 지출이 고유하고 합법적으로 보이는 널리파이어를 생성하기 때문에, 이중 지출은 네트워크에 보이지 않습니다.
수정 사항 [3]은 루프의 첫 번째 반복(row == 0)에 copy_advice() 호출을 추가하여, 루프의 기저점을 외부에서 전달된 실제 base에 고정하는 복사 제약 조건을 생성합니다. 나머지 반복은 계속 assign_advice()를 사용하지만, 기존의 반복 간 일관성 제약 조건이 고정점을 모든 반복에 전파합니다.
영향 및 대응
익스플로잇 시나리오. 악의적인 증명자는 취약점을 이용하여 동일한 Orchard 노트를 여러 번 지출할 수 있으며, 매번 다른 널리파이어를 생성할 수 있습니다. 영지식 증명이 개인 회로 입력을 숨기기 때문에, 사기적인 널리파이어는 합법적인 것과 구별할 수 없습니다. 공격은 온체인에 결정적인 암호학적 증거를 남기지 않으므로, 실제로 익스플로잇이 이루어졌는지 확인하는 것은 불가능합니다.
취약점은 2022년 5월 Orchard 활성화(NU5 업그레이드) 이후부터 존재했으며, 총 4년 이상의 노출 기간을 가집니다. Zcash의 턴스타일 회계는 Orchard 풀에서 투명 또는 Sapling 풀로 유출될 수 있는 위조 가치의 양을 제한하여, 더 넓은 공급에 미치는 실질적인 영향을 제한합니다. 그러나 위조 노트는 실드 풀 내부에 탐지되지 않고 존재할 수 있으며, 프라이버시 속성으로 인해 취약점이 실제로 익스플로잇되었는지 암호학적으로 증명하는 것이 불가능합니다.
참고: 턴스타일은 풀의 총 유출량이 총 유입량을 초과할 때만 작동합니다. 공격자는 이 한도를 초과하지 않고 시간이 지남에 따라 소량의 위조 가치를 인출할 수 있습니다. 합법적인 사용자들이 집합적으로 풀이 실제로 보유한 것보다 더 많은 금액을 인출하려고 시도할 때만 불일치가 명백해질 것입니다.
발견 및 대응. 취약점은 2026년 5월 29일, 보안 연구원 Taylor Hornby(Shielded Labs 계약)가 하루 전 출시된 Anthropic의 Opus 4.8 모델을 사용하는 AI 보조 감사 프레임워크를 통해 발견했습니다. 동일한 회로에 대한 이전 감사에서 구형 모델들은 버그를 찾지 못했습니다. Hornby는 같은 날 ZODL에 문제를 보고했습니다. 6월 2일(UTC) 긴급 소프트 포크가 Orchard 트랜잭션을 일시적으로 비활성화했으며, 6월 3일(UTC, 블록 3,364,600) NU6.2 네트워크 업그레이드가 수정된 회로를 도입하여 Orchard 기능을 복원했습니다 [1]. 6월 4일 공개 공시 이후, ZEC는 40% 이상의 가치를 상실했으며, 청산 규모는 1억 달러를 초과했습니다 [4].
결론
Zcash Orchard 취약점은 스칼라 곱셈 회로의 누락된 동등 제약 조건으로 인해 발생했으며, 증명자가 기저점 바인딩을 우회하고 널리파이어를 위조하여 이중 지출을 할 수 있었습니다. 코드 리뷰나 테스트를 통해 종종 발견될 수 있는 전통적인 스마트 컨트랙트 버그와 달리, ZK 회로의 건전성 버그는 회로가 실제로 증명하는 것과 증명해야 하는 것 사이의 간극을 이해해야 합니다. 이 미묘한 차이는 전문 암호학자들의 4년 이상의 전문적인 감사에서도 발견되지 않았습니다.
halo2 라이브러리는 ZKP 생태계 전반에 걸쳐 사용되며, 이러한 암호학적 빌딩 블록 기반으로 구축된 다른 프로젝트에도 유사한 제약 부족 관계가 존재할 수 있습니다. 영지식 증명을 사용하는 프로토콜은 발견되지 않은 건전성 버그의 잠재적 영향을 제한하기 위해 잔액 무결성 검사(예: 턴스타일 회계)를 구현해야 합니다. Zcash의 턴스타일 메커니즘이 없었다면, 실드 풀 내부에서 생성된 위조 가치가 더 넓은 공급으로 자유롭게 흘러들어갈 수 있었을 것입니다. Shielded Labs는 Orchard 회로를 수학적으로 공식 검증하는 계획을 발표했습니다.
이번 발견은 인간-루프 포함 워크플로우의 전형적인 예시입니다. 숙련된 보안 연구원이 감사 프레임워크를 구축하고 조사를 지휘하는 동안, AI는 개별 회로 제약 조건 확인의 폭을 담당했습니다. 어느 한 구성 요소만으로는 충분하지 않았습니다. 구형 모델을 사용한 이전의 AI 단독 실행에서도 버그를 놓쳤고, 수년간의 전문가 인간 검토에서도 마찬가지였습니다. Hornby 자신이 Zcash 보안 전문가였으며, AI가 운영할 올바른 감사 범위를 설계하기 위한 도메인 전문성이 필요했습니다. BlockSec이 최근 발표한 연구에서도 밝혀진 바와 같이 [5], AI 모델은 보안 분석에서 빠른 발전을 보이고 있지만, 올바른 목표를 향해 AI를 지시하고 발견된 내용을 검증하기 위한 전문가의 안내가 여전히 필요합니다. AI에만 의존하는 것이 아니라 전문가와 AI 간의 상호 협력이 가장 효과적인 작업 모델입니다.
참고 문헌
- Orchard 위조 취약점 및 다음 단계, Zcash 커뮤니티 포럼, 2026년 6월 4일. 링크
- halo2: 영지식 증명 시스템, GitHub. 링크
- 수정: 복사 제약 조건을 통한 스칼라 곱셈 기저점 고정, halo2 GitHub. 링크
- Zcash가 실드 풀 버그를 패치한 후에도 ZEC가 40% 하락한 이유, CoinTelegraph, 2026년 6월 5일. 링크
- EVMBench 재평가: AI 에이전트는 스마트 컨트랙트 보안에 준비되었는가?, arXiv, 2026. 링크
BlockSec 소개
BlockSec은 풀스택 블록체인 보안 및 암호화폐 컴플라이언스 제공업체입니다. 당사는 고객이 코드 감사(스마트 컨트랙트, 블록체인 및 지갑 포함), 실시간 공격 차단, 사고 분석, 불법 자금 추적, AML/CFT 의무 이행을 프로토콜 및 플랫폼의 전체 라이프사이클에 걸쳐 수행할 수 있도록 지원하는 제품과 서비스를 구축합니다.
BlockSec은 권위 있는 학술 컨퍼런스에서 다수의 블록체인 보안 논문을 발표했으며, DeFi 애플리케이션의 여러 제로데이 공격을 보고했고, 다수의 해킹을 차단하여 2,000만 달러 이상을 구제했으며, 수십억 달러의 암호화폐를 보호했습니다.
-
공식 웹사이트: https://blocksec.com/
-
공식 트위터 계정: https://twitter.com/BlockSecTeam



