신규: Helius가 Light Protocol을 인수했습니다
영지식 증명: Solana에서의 활용
블로그/기초

영지식 증명: Solana에서의 활용

Developer Experience EngineerX의 0xIchigoLinkedIn의 0xIchigoGitHub의 0xIchigo
읽는 데 27분

이 시리즈의 글을 검토해 주신 Matt, Porter, Nick, Swen, bl0ckpain에게 깊이 감사드립니다.

소개

영지식 증명을 소개하는 시리즈의 두 번째 글입니다. 이 글의 분석에 필요한 이론, 수학, 암호학적 배경을 다루는 영지식 증명: 기초 원리 소개를 먼저 읽어 보시길 적극 권합니다. 이 글은 해당 내용을 알고 있다고 전제하므로 영지식 증명이 익숙하지 않다면 이전 글부터 읽어 보세요. 이 글의 목표는 독자가 Solana의 영지식 증명에 관한 논의에 참여하고, 더 나아가 새롭고 혁신적인 영지식 프리미티브를 개발하는 데 필요한 지식을 제공하는 것입니다.

이제 새롭게 얻은 지식을 바탕으로 마침내 질문할 수 있습니다. 영지식 증명이란 무엇일까요? Solana에서는 어떻게 사용할까요?

영지식 증명이란?

필요한 이론과 수학, 암호학을 모두 익혔으니 이제 물어볼 차례입니다. 영지식 증명이 정확히 무엇일까요?

영지식 증명은 한 당사자가 어떤 명제가 참이라는 사실 외에는 어떠한 추가 정보도 공개하지 않고, 그 명제가 참임을 다른 당사자에게 입증하는 암호학적 과정입니다. 이러한 증명은 통계적으로 건전하고 완전해야 하며 정보 유출로부터 안전해야 합니다.

영지식으로 증명하려는 명제는 크게 두 가지 유형으로 나뉩니다.

  • 사실에 관한 명제(예: 이 특정 그래프에는 3색 색칠이 존재함)
  • 지식에 관한 명제(예: 나는 N의 인수분해를 알고 있음)

첫 번째 명제는 궁극적으로 우주의 내재적 속성, 즉 1 + 1 = 2처럼 근본적으로 참인 사실을 다룹니다. 두 번째는 지식 증명이라고 합니다. 단순히 어떤 것이 참임을 증명하는 데 그치지 않고 증명자가 알고 있는 내용에 의존합니다.

앞서 언급했듯이 이러한 명제를 증명하는 방식은 상호작용형일 수도, 비상호작용형일 수도 있습니다. 상호작용형 영지식 증명에서는 검증자가 합리적 의심의 여지 없이 납득할 때까지 증명자와 검증자가 여러 라운드에 걸쳐 상호작용합니다. Zcash는 사용자가 익명 트랜잭션을 수행할 수 있도록 비상호작용형 영지식 증명을 사용합니다. 

반면 비상호작용형 영지식 증명에서는 증명자와 검증자가 직접 통신하지 않고 증명이 오프라인으로 전달됩니다. 증명자는 필요한 모든 정보를 담은 증명을 생성하고, 검증자는 추가 상호작용 없이 이를 독립적으로 검증할 수 있습니다. Filecoin은 데이터 자체를 공개하지 않고 사용자가 데이터를 저장했음을 증명하기 위해 비상호작용형 영지식 증명을 사용합니다. 

 zk-SNARK와 회로

zk-SNARK는 Succinct Non-interactive ARgument of Knowledge의 약자입니다. 이러한 영지식 증명은 특히 효율적이고 간결합니다. 즉, succinct합니다. 증명 크기와 검증에 필요한 시간이 모두 검증 대상 연산보다 느리게 증가하면 간결한 증명으로 봅니다. 따라서 간결한 증명을 원한다면 검증자가 해싱 라운드마다 작업을 수행하게 해서는 안 됩니다. 그러면 검증 시간이 연산량에 비례하기 때문입니다. 다항식과 Fiat-Shamir 휴리스틱 덕분에 간결한 증명이 가능합니다.

증명하려는 명제가 아무리 복잡해도 zk-SNARK는 증명 크기를 작게 유지하고 비교적 빠르게 검증할 수 있습니다. 이 특성 때문에 zk-SNARK가 롤업에 매우 매력적입니다. 특정 L2의 모든 트랜잭션이 유효함을 증명하면서도, 증명 크기는 L1에서 검증할 수 있을 만큼 작습니다. Mina 같은 프로토콜은 한 단계 더 나아가 재귀 증명을 사용합니다. 이를 통해 일정한 크기의 증명으로 체인의 전체 기록을 검증할 수 있습니다. Pickles는 Mina의 새로운 증명 시스템이자 관련 툴킷이며, 신뢰 설정 없이 재귀 합성이 가능한 최초의 실제 배포된 zk-SNARK입니다. 여기서 재귀 합성은 회로를 의미합니다.

회로는 증명하려는 연산을 기술합니다. 입력을 받아 출력을 생성하는 일련의 수학 연산입니다. 영지식 증명에서는 연산 입력을 공개하지 않으면서 해당 연산이 올바르게 수행되었음을 나타내는 데 회로를 사용합니다. 일반적인 워크플로는 다음과 같습니다.

  • 회로 작성 및 컴파일 — 회로를 작성하고 컴파일해야 합니다. 소수 p = 7로 정의된 유한체 위에 x * y = z 연산을 수행하는 산술 회로를 만드는 것처럼 간단할 수 있습니다. 핵심은 증명할 연산을 변수 사이의 제약 조건 집합으로 표현하고, 이를 다항식 방정식으로 축약한 다음, 모든 값을 새로운 대수 구조에 일관된 방식으로 매핑하는 코드, 즉 준동형을 작성하는 것입니다. 컴파일 과정에서는 회로가 정의한 제약 조건 집합과 후속 단계에서 사용할 스크립트 또는 바이너리 등 여러 결과물이 생성됩니다
  • 신뢰 설정 세리머니 — 증명 키와 검증 키를 생성하는 데 사용하는 zk-SNARK 유형에 따라 세리머니를 진행해야 할 수 있습니다
  • 회로 실행 — 컴파일 중 생성된 스크립트나 바이너리를 일종의 프로그램처럼 사용해 회로를 실행해야 합니다. 사용자가 공개 및 비공개 입력을 넣으면 모든 중간 변수와 출력 변수의 값이 계산됩니다. 모든 연산 단계의 기록을 witness 또는 trace라고 합니다
  • 증명 생성 — 두 번째 단계의 증명 키와 세 번째 단계의 witness를 사용해, 출력값만 공개하면서 회로에 정의된 모든 제약 조건이 성립한다는 영지식 증명을 생성할 수 있습니다. 이 증명은 검증자에게 전송됩니다
  • 증명 검증 — 검증자는 제출된 증명과 검증 키를 사용해 공개 출력에 대한 증명이 올바른지 확인합니다

Groth16 같은 일부 zk-SNARK 유형은 회로마다 신뢰 설정이 필요합니다. 새로운 프로그램마다 새 세리머니를 진행해야 하므로 제약이 될 수 있습니다. PlonK 같은 다른 zk-SNARK는 범용 신뢰 설정을 한 번만 요구하므로 전체 과정이 단순해집니다. zk-STARK 같은 또 다른 영지식 증명 유형은 신뢰 설정 자체가 필요 없습니다.

zk-STARK

zk-STARK는 Scalable Transparent ARgument of Knowledge의 약자입니다. zk-STARK는 StarkWare가 발명했으며, zk-SNARK의 대안으로 2018년 이 논문에서 처음 제안되었습니다. 본질적으로 블록체인의 연산을 단일 오프체인 STARK 증명자로 옮기고, 온체인 STARK 검증자를 통해 해당 연산의 무결성을 검증할 수 있게 합니다. 

오프체인 증명자가 사용하는 입력은 블록체인에 노출되지 않아 사용자의 프라이버시가 유지되므로 zk-STARK는 영지식으로 간주됩니다. 연산을 오프체인으로 옮겨 L1 검증 비용을 크게 줄이기 때문에 확장성도 갖췄습니다. 증명은 선형적으로 확장되지만 zk-SNARK는 준선형적으로만 확장됩니다. 또한 zk-STARK는 복잡한 신뢰 설정 세리머니에 의존하지 않습니다. 세리머니가 올바르게 진행되지 않으면 검증자가 잘못된 증명을 승인할 수 있는 toxic waste에 취약하다는 이유입니다. 대신 공개적으로 검증 가능한 무작위성을 사용해 증명자와 검증자 간 상호작용을 설정합니다. 그리고 이러한 증명은 필요한 보조 입력과 함께 실제로 연산을 실행한 오프체인 증명자만 생성할 수 있습니다.

zk-STARK는 확장 가능하고 투명한 지식 논증을 통해 zk-SNARK의 한계를 해결합니다. 암호학적 가정도 훨씬 단순하며 타원곡선 같은 요소가 전혀 필요 없습니다. 대신 해시와 정보 이론에만 의존하므로 양자 내성을 갖습니다. 하지만 증명 크기가 수백 킬로바이트에 달해 블록체인처럼 대역폭이나 저장 공간이 제한된 환경에서는 실용성이 떨어질 수 있습니다. 일부 복잡한 증명 설정과 zkVM은 최종 검증 단계에서만 zk-SNARK를 사용하도록 zk-STARK를 재귀적으로 증명하는 방식을 함께 사용합니다.

ZK Compression

상태 증가 문제

Solana가 직면한 가장 시급한 문제 중 하나는 상태 증가 문제입니다. 맥락을 살펴보면 Solana의 상태는 풀 노드 디스크의 Accounts DB에 저장됩니다. 이는 키-값 저장소이며 데이터베이스의 각 항목을 계정이라고 합니다. 각 계정의 주소는 32바이트이며, 저장할 수 있는 데이터 크기는 0~10MB입니다. 현재 10MB의 데이터를 저장하는 비용은 단일 10MB 계정에 저장하든 1,000개의 10KB 계정에 나누어 저장하든 약 70 SOL입니다. Toly의 상태 증가 문제 게시물에 따르면 매일 약 100만 개의 새 계정이 체인에 추가되며, 전체 상태는 5억 개가 넘는 계정에 달합니다. Solana가 계속 성장하면 무제한으로 커지는 스냅샷 크기, PCI 대역폭 제한, 계정 인덱싱, 높은 메모리 및 디스크 관리 비용 등 여러 문제가 발생합니다. 

현재 전체 스냅샷 크기는 약 70GB로, 현행 하드웨어에서 감당할 수 있습니다. 하지만 계속 증가하면 상태 관리의 비효율과 잠재적 병목 현상이 불가피합니다. 스냅샷 크기가 커질수록 하드웨어 장애 후 새 시스템을 콜드 부팅하는 데 걸리는 시간이 크게 늘어나며, 네트워크를 재시작해야 할 때 문제가 될 수 있습니다. 

PCI(Peripheral Component Interconnect) 대역폭은 CPU와 그래픽 카드, 네트워크 카드, 저장 장치 같은 주변 장치 사이의 데이터 전송 속도를 의미합니다. PCI Express(PCIe)는 기존 PCI 표준을 대체하고 더 높은 데이터 전송률을 제공하도록 설계된 고속 인터페이스 표준입니다. 최신 PCI 대역폭은 1TB 또는 128GB/s에 달합니다. 큰 수치처럼 보이지만 Solana의 맥락에서는 그렇지 않습니다. 트랜잭션 하나가 128MB를 읽거나 쓴다면 128GB/s의 PCI 대역폭은 Solana를 초당 1,000트랜잭션(TPS)으로 제한합니다. 하지만 대부분의 트랜잭션은 검증인의 RAM에 이미 로드되고 캐시된 최근 메모리에 접근합니다. 그럼에도 Solana가 확장되는 동안 높은 처리량을 유지하려면 효율적인 상태 메모리가 필수적입니다. 그렇지 않으면 이 대역폭이 빠르게 제한 요소가 될 수 있습니다.

각 검증인은 모든 기존 계정의 인덱스를 유지해야 합니다. 새 계정을 만들려면 해당 계정이 이미 존재하지 않는다는 증명이 필요하기 때문입니다. 전체 상태가 5억 개 이상의 계정으로 구성된 상황에서는 최소한의 인덱스, 즉 항목당 32바이트 키와 32바이트 데이터 해시만 사용해도 약 32GB의 RAM이 필요합니다. 이러한 상태 저장은 비용이 높으며 성능 저하를 막으려면 세심하게 관리해야 합니다. Solana의 상태가 계속 증가할수록 특정 작업에 빠르고 비싼 메모리인 RAM을 사용할지, 느리고 저렴한 메모리인 디스크를 사용할지 구분하는 일이 중요해집니다.

트랜잭션과 상태 증가

모든 Solana 트랜잭션은 읽고 쓰는 계정을 모두 지정해야 합니다. 현재 트랜잭션 크기는 1232바이트로 제한되며 다음을 포함해야 합니다.

  • 헤더(3바이트)
  • 서명(각 64바이트)
  • 계정 주소(각 32바이트)
  • 명령 데이터(임의 크기)
  • 최근 블록해시(32바이트)

트랜잭션을 실행하면 다음 과정이 진행됩니다.

  • 기본 검사 — 최근 트랜잭션만 유효하며 중복 제거, 구조 검증, 수수료 검사, 서명 검사를 수행합니다
  • 프로그램 로딩 — 프로그램 주소를 기반으로 프로그램 바이트코드를 로드하고 Solana Virtual Machine(SVM)을 인스턴스화합니다
  • 계정 로딩 — 트랜잭션이 참조하는 모든 계정을 검사하고 저장소에서 메모리로 불러온 뒤 SVM에 전달합니다
  • 실행 — 프로그램 바이트코드를 실행합니다
  • 동기화 — 수정된 계정을 저장소에 다시 동기화합니다

상태가 계속 증가하면 이 수명 주기는 여러 문제를 일으킵니다. 온체인 상태는 비용이 높고 디스크에 저장되는 계정이 많을수록 스냅샷과 인덱스가 커집니다. 또한 모든 계정에 자주 접근하는 것은 아니므로 지속적인 리소스 비용을 부담하는 방식은 비효율적입니다.

ZK Compression으로 상태 관리 단순화

모든 계정을 디스크에 저장하고 필요할 때 읽는 대신, 트랜잭션 페이로드의 일부로 계정 데이터를 전달할 수 있습니다. Merkle 트리를 사용하면 트랜잭션 제출자가 올바른 상태를 제공했는지 확인할 수 있습니다. Merkle 증명은 특정 데이터를 커밋하는 방법입니다. 커밋을 기준으로 증명을 검증해 올바른 상태가 전달되었고 사용자가 제공한 상태를 속이지 않았는지 확인할 수 있습니다. 

이 증명은 안전하지만 상당히 클 수 있습니다. 예를 들어 트리에 계정 10만 개가 포함되면 증명 크기는 544바이트입니다. 여러 계정의 증명을 제공하면 트랜잭션 크기 제한인 1232바이트를 빠르게 초과할 수 있습니다. 다행히 더 효율적인 증명 시스템으로 이를 우회할 수 있습니다. KZG나 Pedersen 커밋처럼 증명 크기가 일정한 커밋을 사용하면 증명 크기가 줄어들어 트랜잭션 크기 제한 안에 포함하기가 쉬워집니다.

ZK Compression은 Merkle 증명 크기 문제를 해결하는 메커니즘입니다. Solana의 원장을 활용해 온체인 저장 비용 없이 특정 연산이 올바르게 수행되었음을 증명하는 방법입니다.

ZK Compression이란?

ZK Compression은 보안, 성능, 구성 가능성을 유지하면서 온체인 상태를 압축해 상태 비용을 몇 자릿수나 줄일 수 있는 새로운 프리미티브입니다. 예를 들어 현재 토큰 계정 100개를 만드는 데는 ~0.2 SOL이 들지만, ZK Compression을 사용하면 비용이 5,000분의 1인 ~0.00004로 줄어듭니다. 

ZK Compression은 영지식 증명을 활용해 기초 데이터를 노출하지 않고 상태 전환을 검증합니다. 여러 계정을 온체인에 저장되는 하나의 검증 가능한 Merkle 루트로 묶고, 기초 데이터는 원장에 저장하는 방식입니다. 유효성 증명은 m개의 상태 트리에서 n개의 계정이 리프로 존재함을 증명하는 간결한 영지식 증명이며, 증명 크기는 항상 128바이트로 유지됩니다. 증명은 오프체인에서 생성되고 온체인에서 검증되므로 Solana의 전체 연산 부담이 줄어듭니다. ZK Compression은 증명자 시스템에 잘 알려진 페어링 기반 zk-SNARK인 Groth16을 사용합니다.

하지만 이러한 계정은 일반 Solana 계정이 아닙니다. 대신 압축 계정입니다.

압축 계정 모델

ZK 압축 상태는 압축 계정에 저장됩니다. 이 계정은 일반 Solana 계정과 비슷하지만 효율성과 확장성을 높이는 몇 가지 중요한 차이가 있습니다.

  • 해시 식별 — 각 압축 계정은 해시로 식별할 수 있습니다
  • 쓰기 시 해시 변경 — 압축 계정에 쓰기 작업을 수행하면 해시가 변경됩니다
  • 선택적 주소 — 주소를 압축 계정의 영구적인 고유 ID로 선택적으로 설정할 수 있습니다. NFT 같은 특정 사용 사례에 유용합니다. 압축 계정은 해시로 참조할 수 있으므로 연산 오버헤드를 피하기 위해 이 필드는 선택 사항입니다
  • 희소 상태 트리 — 모든 압축 계정은 Merkle 트리에 저장되며 트리의 상태 루트, 즉 Merkle 루트만 온체인 계정 공간에 저장됩니다. 더 구체적으로 상태 트리는 Poseidon 해시 기반 동시성 Merkle 트리입니다

압축된 프로그램 파생 주소(PDA)는 고유하고 영구적인 주소로 식별할 수 있습니다. Data, Lamports, Owner, Address 필드를 사용하는 일반 PDA 계정과 비슷한 구조입니다. 하지만 일반 PDA와 달리 Data 필드에는 Discriminator, Data, DataHash 필드로 구성된 AccountData 구조가 포함됩니다.

노드

여러 유형의 노드가 ZK Compression을 지원하는 데 핵심 역할을 합니다. 누구나 Photon RPC 노드, Prover 노드, Light Forester 노드를 실행해 Devnet과 Mainnet-Beta에 연결할 수 있습니다. 로컬 개발 환경에서는 ZK Compression CLI의 test-validator 명령으로 관련 노드, 즉 Photon RPC와 Prover뿐 아니라 시스템 프로그램, 계정, 런타임 기능까지 갖춘 단일 노드 Solana 클러스터를 시작할 수 있습니다.

Photon RPC 노드는 압축 프로그램을 인덱싱합니다. 이를 통해 클라이언트는 압축 상태와 상호작용하는 트랜잭션을 읽고 구성할 수 있습니다. 표준 압축 인덱서는 Photon이며 Helius가 제공합니다. 이 노드 유형은 최소한의 설정으로 로컬에서 실행할 수 있으며 기존 RPC를 지정해야 합니다. 

Prover 노드는 상태 포함 여부의 유효성 증명을 생성하는 데 사용합니다. ZK Compression RPC API 사양의 getValidityProof 엔드포인트를 사용해 증명을 가져올 수 있습니다. Prover 노드는 독립형 노드로 운영하거나 다른 RPC와 함께 번들로 구성할 수 있습니다. 표준 Photon RPC 구현에는 Prover 노드가 포함됩니다.

Light Forester 노드는 공유 상태 트리와 프로그램 소유 상태 트리의 생성, 롤오버, 업데이트를 관리합니다. 자체 프로그램 소유 상태 트리를 Light Forester 노드 네트워크로 관리하려는 개발자를 위한 기능입니다.

신뢰 가정

누구나 앞서 설명한 노드를 실행하고, 증명 생성과 트랜잭션 제출에 필요한 원시 데이터를 저장할 수 있습니다. 이로 인해 압축 상태의 활성성에 영향을 주는 신뢰 가정이 생깁니다. 데이터가 유실되거나 지연되면 데이터를 직접 저장하지 않은 한 트랜잭션을 제출할 수 없습니다. 데이터를 제공하는 정직한 노드는 하나면 충분하고 증명은 자체 검증이 가능하므로, 문제는 안전성보다 활성성과 잠재적 검열에 있습니다.

또한 압축 계정을 검증하는 프로그램을 현재 업그레이드할 수 있다는 점도 또 다른 신뢰 가정을 만듭니다. 문제를 수정하거나 새로운 요구 사항에 맞게 프로그램을 조정하기 위한 것입니다. 하지만 안정적이고 안전한 상태에 도달하면 향후 변경 불가능하게 만들거나 동결할 수 있습니다.

Forester 노드 사용 역시 활성성에 관한 신뢰 가정입니다. 이 노드는 상태 루트의 전진을 유지하고, 무효화 큐를 비운 뒤 상태 루트를 비동기적으로 전진시키는 방식으로 큐를 관리합니다. 이때 계정 해시는 0으로 대체되어 무효화됩니다. 전진과 무효화를 분리하면 트랜잭션을 Solana의 크기 제한 안에 유지하면서 압축 상태 전환을 즉시 확정할 수 있습니다. 무효화 큐의 크기는 일정하므로 Forester 노드는 프로토콜 활성성에 필수적입니다. 큐가 가득 차면 관련 상태 트리에서 활성성 장애가 발생합니다. 다행히 Forester 노드가 큐를 비워 이를 방지합니다. 하지만 프로토콜의 무결성과 활성성을 유지하려면 누군가 계속 이 노드를 실행해야 합니다. 이 노드가 없다면 ZK Compression은 약 2,000개의 계정 또는 주소만 지원할 수 있습니다.

한계 

무언가를 숨길 필요가 없는 경우에도 영지식 증명은 여러 연산 단계가 필요한 문제를 단일 증명 검증만으로 연산이 올바르게 수행되었는지 확인할 수 있는 문제로 바꿉니다. 이러한 연산은 특정 리프가 주어진 트리에 속하는지 확인하는 데 국한되지 않습니다. 임의의 연산이 될 수 있습니다. 하지만 여기에는 비용이 따릅니다.

ZK Compression을 사용하기 전에 다음 사항을 고려하세요.

  • 더 큰 트랜잭션 크기 — ZK Compression에는 유효성 증명을 위한 128바이트와 온체인에서 읽거나 쓸 데이터 전송 공간이 필요합니다
  • 더 높은 연산 유닛 사용량 — ZK Compression은 유효성 증명 검증에 ~100k CU, 시스템 사용에 ~100k CU, 압축 계정 읽기 또는 쓰기마다 ~6k CU가 필요하므로 연산 유닛(CU) 사용량이 크게 늘어납니다
  • 트랜잭션별 상태 비용 — 각 쓰기 작업은 이전 압축 계정 상태를 무효화하고 새 압축 상태를 상태 트리에 추가해야 하므로 소액의 네트워크 비용이 발생합니다. 따라서 상태 업데이트가 많다면 단일 압축 계정의 전체 수명 비용이 비압축 계정보다 높아질 수 있습니다

다음과 같은 경우에는 일반 계정을 사용하는 편이 나을 수 있습니다.

  • 계정이 자주 업데이트되는 경우
  • 계정의 전체 수명 동안 쓰기 횟수가 많은 경우(예: >1000x)
  • 계정이 온체인 트랜잭션에서 접근해야 하는 대량의 데이터를 저장하는 경우

이점

ZK Compression은 확장 가능하고 안전하며 효율적이고 유연한 프리미티브입니다. Solana의 상태 증가 문제를 직접 해결하며 다양한 애플리케이션과 사용 사례를 지원합니다. 가장 눈에 띄는 장점은 단연 상태 비용 절감입니다. 상태를 더 저렴한 원장 공간에 안전하게 저장하고 상태 지문을 통해 온체인 저장 공간을 최소화하므로 앱을 수백만 사용자까지 쉽게 확장할 수 있습니다. SOL 가격이 미화 130달러라고 가정하고 토큰 계정 10,000개를 민팅하면 약 2,600달러가 듭니다. ZK Compression은 이 비용을 50센트 미만으로 낮춥니다.

ZK Compression은 현재 Solana 사양과도 잘 어우러집니다. 예를 들어 압축 계정의 구조는 일반 Solana 계정과 거의 같습니다. 병렬 처리 같은 Solana 고유의 혁신도 지원합니다. 같은 상태 트리, 즉 커밋 아래에서 서로 다른 압축 계정에 접근하는 두 트랜잭션은 병렬로 실행할 수 있습니다. 또한 ZK Compression은 동기식 원자적 구성 가능성을 강화합니다. 예를 들어 n개의 압축 계정과 m개의 일반 계정을 나열하는 트랜잭션도 완전히 유효한 구성입니다. 압축 계정을 참조하는 명령은 일반 계정을 참조하는 다른 명령이나 프로그램을 호출할 수 있습니다. 계정이 서로 다른 상태 트리에서 압축되었더라도 마찬가지입니다. 한 명령이 실패하면 전체 트랜잭션이 롤백되며, 변경 사항은 한 명령에서 다음 명령으로 전달됩니다. 이는 롤업끼리 잠금을 설정하지 않으면 동기식 또는 원자적으로 서로 호출할 수 없는 ZK 롤업과 다릅니다. 따라서 자연스럽게 ZK Compression과 롤업을 비교하게 됩니다.

ZK Compression은 롤업이 아닙니다

ZK Compression은 롤업이 아닙니다. 두 기술은 동일한 기반 기술을 사용하지만 구현 방식이 다릅니다. 롤업은 두 가지 유형으로 나뉩니다.

  • 옵티미스틱 롤업 — 일정 기간 모든 트랜잭션이 유효하다고 가정하고, 해당 기간 안에 사기 증명을 사용해 잘못된 트랜잭션을 입증합니다
  • 영지식 롤업 — 유효성 증명을 사용해 트랜잭션의 유효 또는 무효 여부를 즉시 증명합니다

영지식 롤업의 전체 상태는 기본 레이어, 즉 Ethereum에서 하나의 루트로 표현됩니다. 이 때문에 ZK Compression이 사실상 롤업이라는 주장이 여러 차례 제기되었습니다. 하지만 둘 사이에는 몇 가지 중요한 차이가 있습니다.

ZK 롤업에서 500개의 트랜잭션을 처리하는 상황을 생각해 보겠습니다. 이 경우 전체 롤업을 하나의 회로로 취급합니다. 500개의 트랜잭션을 함께 검증하고, 상태 루트가 A에서 B로 변경되었음을 확인하는 하나의 증명을 생성합니다. 이 증명을 검증한 뒤 L1과 L2의 상호작용을 관리하는 스마트 계약이 상태 루트를 업데이트합니다. 반면 ZK Compression에서는 500개 트랜잭션 각각이 계정 데이터의 정확성을 확인하는 자체 증명을 생성합니다. 이러한 트랜잭션은 SVM 자체에서 실행되며, 각 증명이 검증되면 계정은 “일반” 계정처럼 취급됩니다.

ZK Compression을 롤업으로 분류한다면 Solana에 저장된 모든 Merkle 루트를 유효성 기반 롤업으로 볼 수 있다는 뜻입니다. 현재 Solana의 모든 압축 cNFT 루트를 살펴보면 민팅이 0인 Merkle 트리를 포함하는지에 따라 약 4,000~5,000개의 유효성 기반 롤업이 존재합니다.

따라서 ZK Compression이 Solana 아키텍처에 맞춰 설계된 고유한 솔루션임이 분명해집니다. ZK 롤업과 달리 롤업의 복잡성과 분리 없이 확장성과 효율성을 높이는 새로운 프리미티브입니다.

Solana에서 ZK와 상호운용성의 미래

Solana ZK의 현황

Helius에서 처음 맡은 집필 과제 중 하나는 Solana v1.16 업데이트를 다루는 일이었습니다. 영지식 증명에 대한 런타임 지원이 개선된다는 소식에 무척 기대했고 글에서도 이를 다뤘습니다. 하지만 이러한 개선 사항은 연기되었습니다. 이후 다시 연기되었는데도 v1.17 업데이트 글에서 더 자세히 다루는 실수를 했습니다. v1.18 업데이트 글에서는 아예 다루지도 않았습니다. 당연히 실망했고 다른 사람들도 불만을 드러냈습니다. 

이러한 분위기에도 Solana에는 작지만 성장 중인 ZK 개발자 커뮤니티가 있습니다. Light Protocol은 ZK Compression에 집중하기 전에는 PSP(Private Solana Programs) 형태의 비공개 프로그램 실행에 주력했습니다. Dark protocol은 Solana에 구축된 퓨타키 기반 프라이버시 프로토콜입니다. 중앙 팀이 없으며 제안을 통해 기여가 이루어집니다. 이전에 Elusiv로 알려졌던 Arcium은 다자간 연산 실행 환경(MXE)을 사용해 자체 병렬 기밀 컴퓨팅 네트워크를 구동합니다. Bonsol은 개발자가 임의의 risc0 image를 실행하고 Solana에서 검증할 수 있게 하는 영지식 "코프로세서"입니다. 즉, 검증 가능한 오프체인 연산을 제공합니다. 튜토리얼과 영지식 증명 관련 링크 모음도 공유되고 있습니다.

가장 주목할 만한 것은 ZK Token Proof Program입니다. 이 프로그램은 curve25519 위에서 Pedersen 커밋 및 Twisted ElGamal 암호화와 함께 작동하도록 설계된 여러 영지식 증명을 검증합니다. 또한 영지식 증명을 사용해 SPL 토큰의 잔액과 트랜잭션 금액을 암호화하는 Confidential Transfers를 지원합니다. 목표는 익명성이 아니라 기밀성입니다. 동형 암호화를 사용하면 암호화된 데이터를 복호화하지 않고도 연산할 수 있습니다. Confidential Transfers는 이를 위해 암호문에 대한 비공개 수학 연산에 Twisted ElGamal 암호화를 사용하고, 민감한 정보를 공개하지 않고 전송을 검증하는 데 Sigma Protocols를 사용합니다. 복호화 키를 가진 계정 소유자만 암호화된 잔액을 볼 수 있습니다. 하지만 Global Auditor System은 별도의 복호화 키를 통해 규정 준수 및 감사를 위한 선택적 읽기 접근을 허용합니다. 

ZK Token Proof Program은 SIMD-0153: ZK ElGamal Proof Program이 통과되어 현재 차단된 기능입니다. 이 새로운 SIMD는 SPL Token 프로그램을 위해 특별히 설계된 기존 ZK Token Proof program을 폐기하고, 특정 애플리케이션에 종속되지 않는 더 범용적인 영지식 증명 프로그램으로 대체하는 것을 목표로 합니다. 이 SIMD는 Anza와 Firedancer 팀의 지원을 받아 병합되었습니다.

하지만 흐름이 바뀌기 시작했습니다. 이러한 개선 사항이 마침내 Devnet과 Mainnet-Beta에 도입되면서 Solana는 ZK 강자로 부상하고 있습니다. 현재 Solana에서는 세 가지 ZK syscall이 가동 중입니다.

Poseidon syscall

Poseidon은 영지식 증명을 위해 특별히 설계된 해시 함수군으로 Zcash, Mina, Light Protocol 같은 프로젝트에서 사용됩니다. Poseidon은 SHA-256처럼 전통적인 범용 해시 함수보다 영지식 증명 연산에 더 효율적입니다. 

Poseidon 해시 함수가 영지식에 적합한 이유는 다음과 같습니다.

  • 산술 연산을 효율적으로 수행합니다
  • 산술 친화적 설계, 최적화된 S-box, 적은 라운드 수 덕분에 증명 생성 단계가 더 적습니다. 즉, 회로 복잡도가 낮습니다
  • 길이에 상관없이 비트 시퀀스를 처리하는 알고리즘을 사용해 활용도가 매우 높습니다

이전에는 단일 트랜잭션에서 Poseidon 해시를 계산하는 비용이 지나치게 높았습니다. 하지만 에포크 644와 Poseidon syscall, 즉 2차원 바이트 슬라이스 입력을 받아 해당 Poseidon 해시를 출력으로 계산하는 시스템 호출이 활성화되면서 상황이 달라졌습니다. ZK Compression이 상태 트리에 Poseidon 해싱을 사용한다는 점에서 매우 기대되는 변화입니다.

Poseidon syscall은 다음 매개변수와 함께 BN254 곡선을 사용해 해시를 계산합니다.

  • S-box — x5 치환 상자
  • 입력 — 1 ≤ n ≤ 12
  • 너비 — 2 ≤ t ≤ 13
  • 라운드 — 8개의 전체 라운드와 t에 따른 부분 라운드: [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65]

출력은 지정된 엔디언 방식에 따라 32바이트로 인코딩된 Posiedon 해시 결과입니다.

여기서 syscall에 사용하는 구체적인 변형은 x5 S-box와 BN254 곡선에 맞춘 매개변수를 사용하는 Poseidon입니다. light-poseidon crate를 사용하면 이 해시를 계산할 수 있습니다. crate 자체는 감사를 받았으며 Circom과 호환됩니다.

alt_bn128 syscall

alt_bn128은 효율적인 zk-SNARK 증명과 연산을 지원하는 페어링 친화적 곡선인 Barreto-Naehrig(BN-128) 타원곡선 구현을 의미합니다. 이 곡선은 Groth16을 비롯한 여러 영지식 증명 시스템에 필수적이며, ZK Compression이 상태 전환을 검증할 때 사용하는 방식이기도 합니다. 이 syscall은 증명당 필요한 공간을 크게 줄여 효율적인 온체인 증명에 중요한 공간 및 시간 최적화를 제공합니다. 

sol_alt_bn128_group_op syscall은 G1의 점 덧셈(G1은 특정 타원곡선 위 점들의 그룹을 의미합니다), G1의 스칼라 곱셈, 페어링을 비롯한 alt_bn128 곡선 연산을 계산합니다.

  • 입력 — 빅 엔디언 형식으로 직렬화된 점과 스칼라
  • 연산 — G1의 점 덧셈, G1의 스칼라 곱셈, 페어링(G1의 점 1개와 G2의 점 1개)
  • 출력 — G1의 점 또는 256비트 정수로 직렬화된 페어링 결과

sol_alt_bn128_compression syscall은 alt_bn128 곡선 위 G1 또는 G2 그룹의 점을 압축하거나 압축 해제하고 표준 빅 엔디언 형식으로 반환합니다.

이 syscall은 현재 testnet에서 가동 중이며, SIMD-0075: Secp256r1 Precompile에 따르면 로드된 프로그램의 재컴파일 단계에 있는 버그가 해결되면 Devnet에서 사용할 수 있을 것으로 보입니다. 이 제안은 alt_bn128 syscall과 Poseidon syscall의 오류 코드를 간소화해 일관성을 보장하고, 검증인이 서로 다른 오류 코드를 반환해 합의 실패가 발생할 위험을 줄이는 것을 목표로 합니다.

alt_bn128 syscall은 KZG 커밋처럼 증명 크기가 일정한 일반 벡터 커밋에 사용할 수 있습니다. 따라서 페어링 친화적인 모든 곡선과 함께 작동하며 ZK 증명자 회로가 필요하지 않습니다. 

상호운용성

Solana는 ZK 체인입니다. 수수료가 낮고 타원곡선 연산을 런타임에서 지원하는 고성능 Layer 1 블록체인입니다. 영지식 증명 관련 syscall을 구현하고 지원하면 혁신을 촉진하며, ZK Compression 같은 새로운 프리미티브와 애플리케이션을 Solana 위에 구축할 수 있습니다.

alt_bn128 syscall의 도입으로 Solana와 EIP-196, EIP-197, EIP-198에 명시된 타원곡선 연산용 사전 컴파일 계약에 의존하는 Solidity 기반 계약 간 구성 가능성 격차가 줄어듭니다. 이러한 연산은 Ethereum의 가스 제한 안에서 zk-SNARK 증명을 검증할 수 있게 합니다. 따라서 해당 타원곡선 연산에 의존하는 Solidity 계약은 이제 Solana로 더 쉽게 이전하거나, Solana와 상호운용할 수도 있습니다.

SIMD-0075는 상호운용성 솔루션에 매우 중요합니다. 이 SIMD가 완전히 구현되면 향후 출시될 blobsream-solana(Celestia에서 Solana로 DA를 스트리밍하는 프로젝트) 같은 프로젝트가 Merkle 커밋을 저장하기 위해 오프체인 증명 생성과 온체인 검증을 사용할 수 있습니다. 이 syscall이 없으면 Solana에서 Groth16 증명을 검증할 수 없습니다. 또한 이 syscall은 신뢰를 최소화한 브리징과 상호운용성을 강화해 다른 블록체인이 Solana와 원활하고 안전하게 상호작용할 수 있게 합니다.  

Toly의 말이 맞습니다. Solana 런타임에 이러한 개선 사항이 모두 적용되면 Solana는 Ethereum L2입니다. 머지않아 Solana의 모든 블록을 Ethereum의 데이터 검증 브리지 계약에 제출하는 일을 막을 요소가 없어집니다. 반대로 Ethereum의 모든 블록을 Solana의 데이터 검증 브리지 프로그램에 제출하는 것도 가능해집니다. 구식 브리지 대신 영지식 증명이 가속하는 양방향 상호운용성은 Solana에 밝고 성장 가능성 높은 미래를 열어 줍니다.

결론

영지식 증명은 의심할 여지 없이 암호학자들이 개발한 가장 강력한 프리미티브 중 하나이며, 어쩌면 가장 강력한 프리미티브일 수 있습니다. 첫 번째 글에서 이 개념의 기반이 되는 이론과 수학, 암호학을 제1원리부터 살펴보면 이는 자명해집니다. 온체인 게임에서 진정한 전장의 안개를 구현하는 것부터 L2의 트랜잭션 집합이 특정 상태 전환을 일으켰음을 증명하는 것까지 잠재적 활용 분야는 무궁무진합니다.

이 2부작 시리즈는 동형 암호화의 복잡한 원리, Circom을 사용한 회로 코딩, 다양한 커밋 방식 분석까지 다루며 50페이지 이상 더 이어질 수도 있었습니다. 하지만 이 글의 목표는 독자에게 영지식 증명의 기초를 설명해 새롭게 얻은 지식을 Solana에 적용할 수 있도록 하는 것입니다. 

Solana는 ZK 강자로 부상하고 있습니다. ZK Compression 출시부터 가까운 미래에 가동될 여러 syscall까지, 그 중요성은 아무리 강조해도 지나치지 않습니다. ZK Compression 같은 프리미티브는 일반 개발자가 영지식 증명의 모든 복잡성을 신경 쓰지 않아도 되도록 추상화하지만, 기본 원리를 이해하는 것은 Solana에서 논의를 발전시키고 개발을 이어가는 데 매우 중요합니다. 

여기까지 읽어 주셔서 감사합니다, 익명의 독자 여러분! 아래에 이메일 주소를 입력해 Solana의 새로운 소식을 빠짐없이 받아보세요. 더 깊이 알아볼 준비가 되셨나요? 지금 Helius 블로그의 최신 글을 살펴보고 Solana 여정을 계속하세요.

추가 자료

Helius 구독하기

최신 Solana 개발 소식을 확인하고 새 게시물 알림을 받아보세요

확대 이미지