용어집 / 프로토콜과 업그레이드
키 경로 지출
- 키 경로 지출이란 무엇입니까?
- 키 경로 지출은 조정된 출력 키에 대한 서명 1개로 Taproot 출력을 정산하며, 정확히 1개 요소로 이루어진 위트니스를 공개하고 대체 스크립트에 대해서는 아무것도 드러내지 않습니다.
BIP-341에 명시되어 있습니다.
Taproot 출력은 그 키로 서명하거나 커밋된 스크립트를 공개하여 비울 수 있으며, 키 경로가 조용한 쪽입니다. BIP-341은 그 위트니스를 정확히 하나의 요소로 고정하는데, 기본 sighash 아래의 64바이트 Schnorr 서명이며, 이로써 입력 전체가 230 가중치 단위, 즉 57.5 vbytes가 됩니다. 보유자 입장에서는 공유 금고와 단독 결제가 온체인에서 동일하게 보입니다.
작동 방식
키 경로 지출은 출력 키로 서명하는데, 그 키는 누구도 고른 키가 아닙니다. BIP-341은 이를 Q = P + int(t)G로 구성하며, 여기서 P는 내부 공개 키이고 t는 P와 스크립트 트리의 머클 루트를 함께 태그 해시한 값입니다.
따라서 서명이란 같은 이동을 비밀 쪽에 적용하는 것을 뜻합니다. 참조 루틴은 내부 점의 y 좌표가 홀수일 때 비밀 키의 부호를 먼저 뒤집는데, taproot 조정이 32바이트 x-only 키에 적용되기 때문이며, 그다음 곡선의 위수로 나눈 나머지 연산으로 t를 더합니다. 그 결과는 BIP-340에 따라 서명되어 위트니스 스택에 단독으로 올라갑니다.
검증은 암호학적 검사이기 전에 개수를 세는 검사입니다. 노드는 위트니스 프로그램의 32바이트를 읽고, 위트니스 스택이 비어 있으면 즉시 실패시키며, 요소가 둘 이상이고 마지막 요소가 0x50으로 시작하면 그 요소를 annex로 제거합니다. 정확히 하나의 요소가 남으면 그 지출은 키 경로 지출이고, 그 요소는 출력 키에 대해 BIP-340 서명으로 검증되어야 합니다. 그 절차 어디에도 스크립트 트리가 커밋된 적이 있는지 노드에 알려 주는 부분은 없습니다.
서명은 SIGHASH_DEFAULT, 값 0x00이 암시될 때 64바이트이며, 이는 트랜잭션 전체를 포함합니다. 다른 sighash 바이트가 덧붙여지면 65바이트가 되며, 마지막 위치에 0x00을 담은 65바이트 서명은 의도적으로 거부됩니다. 이를 허용하면 채굴업자나 릴레이하는 임의의 노드가 64바이트 서명을 65바이트로 늘려 wtxid와 발신자가 의도한 수수료율을 바꿀 수 있기 때문입니다.
서명이 포함하는 것은 최대 206바이트의 메시지입니다. 트랜잭션 버전과 locktime, 모든 입력의 outpoint, 금액, 이전 scriptPubKey, 시퀀스 번호의 해시, 그리고 출력들에 커밋합니다.
크기 산술은 여기서 따라 나옵니다. BIP-141에 따르면 트랜잭션 가중치는 기본 크기에 3을 곱하고 전체 크기를 더한 값이며, 가상 크기는 그 가중치를 4로 나눈 값을 트랜잭션 전체에 대해 올림한 값입니다. Taproot 입력은 41 기본 바이트(36바이트 outpoint, 빈 scriptSig를 위한 길이 바이트 1개, 4바이트 시퀀스)와 66 위트니스 바이트(스택 개수, 길이 접두사, 서명)를 차지하여 41 곱하기 3 더하기 107, 즉 230 가중치 단위가 되고 따라서 57.5 vbytes가 됩니다.
BIP-341의 한 가지 권고는 지갑 개발자들이 자주 놓치는 부분입니다. 스크립트가 전혀 없는 출력도 내부 키 자체에 대한 태그 해시로 계산된 조정에 여전히 커밋해야 하며, 내부 키를 그대로 공개해서는 안 됩니다. 명세서는 그 이유를 명시합니다. 두 당사자가 각자의 키를 더해 공유 출력 키를 만들 때, 한쪽이 자신만 지출할 수 있는 스크립트 경로를 숨기는 조정을 조용히 끼워 넣을 수 있고, 다른 쪽은 그것을 알아챌 방법이 없습니다.
비트코인을 구매할 때 이것이 중요한 이유
Taproot의 서명 메시지는 하드웨어 지갑이 연결된 컴퓨터를 신뢰하지 않고도 수수료를 계산할 수 있는 이유입니다.
BIP-143, SegWit 버전 0 규칙 아래에서 메시지는 서명된 입력이 지출하는 금액에만 커밋했으며, 그 밖의 금액에는 커밋하지 않았습니다. 3개 입력 트랜잭션의 입력 하나에 서명하는 기기는 나머지 두 금액을 전달받아야 했고 이를 검증할 수 없었는데, 이것이 침해된 호스트가 화면에 표시된 것보다 훨씬 많은 수수료를 서명하게 만드는 통로입니다. BIP-341은 트랜잭션이 지출하는 모든 입력의 금액과 그 모든 이전 scriptPubKey에 커밋하므로, 서명자는 이를 스스로 합산할 수 있습니다. 이 업그레이드는 스크립트 경로 지출도 포함하지만, 이 사이트의 41개 지갑 리뷰에 나오는 기기 소유자 대부분은 키 경로에서 이를 만나게 됩니다.
지갑이 키를 도출할 수 있어야 이 모든 것이 적용되며, 그 리뷰들에서 상황은 고르지 않습니다. KeepKey는 2025년 2월에 펌웨어 7.10.0에서 Taproot 출력 지원을 추가했습니다. MetaMask의 자체 발표는 여전히 Taproot를 추후 제공 항목으로 나열하므로, 나머지 비트코인 지원이 어떻든 수신에 쓸 bc1p 주소를 제공할 수 없습니다.
수수료는 입력당 작은 차이로 키 경로 쪽으로 기울며, 이는 대부분의 독자가 구매하는 방향으로 누적됩니다. BIP-143의 자체 테스트 벡터에서 서명된 P2WPKH 입력은 71바이트 서명과 33바이트 키를 담고, 스택 개수와 길이 접두사를 세면 107 위트니스 바이트이며, 이는 271 가중치 단위, 즉 67.75 vbytes가 됩니다. 키 경로 입력은 그에 비해 10.25 vbytes를 절약하므로, 30번의 개별 소액 구매를 모아 두었다가 나중에 통합하는 저축자는 그 한 트랜잭션에서 약 307 vbytes를 줄입니다.
프라이버시가 실제로 무엇을 사는지 분명히 해야 합니다. 지출 정책을 숨기는 것은 이력을 숨기는 것이 아닙니다. 코인이 이 사이트가 리뷰하는 63개 거래소 중 하나에서 왔다면, 그 플랫폼은 이미 신분 서류와 출금 주소를 보유하고 있으며 어떤 서명 형식도 그것을 건드리지 않습니다. 숨겨지는 것은 그 코인이 키 하나로 보호되었는지, 변호사의 복구 분기를 둔 정족수로 보호되었는지이며, 주소를 표적이 될 만하게 만드는 것은 바로 그 두 번째 사실입니다.
taproot_sign_key 살펴보기
taproot_sign_key는 BIP-341이 바로 이 위트니스를 생성하기 위해 공개한 참조 루틴이며, 전체가 9줄의 Python입니다.
스크립트 트리, 내부 비밀 키, sighash 유형, 그리고 BIP-340이 요구하는 보조 무작위성을 인자로 받습니다. 스크립트 트리가 비어 있으면 조정 입력을 빈 바이트 문자열로 설정하고, 그렇지 않으면 그 입력은 트리 도우미가 반환한 머클 루트입니다. 그 값으로 내부 비밀 키를 조정하고, sighash에 서명하고, 유형이 0이 아닐 때만 해시 유형 바이트를 덧붙이고, 항목 하나를 담은 목록을 반환합니다. 그 항목이 위트니스 전체입니다.
두 가지 세부 사항을 눈여겨볼 만합니다. 빈 분기는 겉보기와 달리 조정 없는 경우가 아닙니다. 빈 바이트 문자열을 넣으면 조정이 내부 키 자체의 태그 해시로 남는데, 이는 정확히 명세서가 스크립트가 없는 출력에 권장하는 지출 불가능한 커밋입니다. 그리고 무작위성 인자는 Taproot가 아니라 BIP-340에 속합니다. 키가 조정되고 나면 결과는 평범한 Schnorr 서명이며, 그래서 키 경로 지출은 일괄 검증을 위해 특별한 처리가 필요하지 않습니다.
키 경로 지출 vs P2TR
P2TR은 출력 유형이고, 키 경로 지출은 그러한 출력을 비우는 두 가지 방법 중 하나입니다. 코인은 나중에 어느 경로로 소비되든 P2TR 코인으로 남습니다. 누군가 Taproot 주소가 프라이버시를 제공한다고 말할 때 이 구분이 중요합니다. 그러한 주소로 수신하면 어느 경우든 32바이트 키만 공개되고 그 외에는 아무것도 공개되지 않으며, 사람들이 말하는 프라이버시는 지출하는 순간에, 그것도 키 경로를 택했을 때만 생깁니다.
키 경로 지출 vs MuSig2
MuSig2는 키 경로 지출이 필요로 하는 서명을 생성하는 한 가지 방법이며, 키 경로 지출의 요건은 아닙니다. 단일 소유자가 단일 키로 서명하면 결제할 때마다 집계 프로토콜 없이 키 경로 지출을 합니다. 둘이 혼동되는 것은 집계가 흥미로운 사례이기 때문입니다. MuSig2는 여러 당사자가 하나의 키와 하나의 서명에 도달하게 하므로, 그들의 정산은 점심값을 내는 사람과 같은 경로와 같은 57.5 vbytes를 씁니다. 반대 방향도 성립하는데, 집계 키가 스크립트 리프 안에 있을 수 있고, 그 경우 이를 지출하는 것은 MuSig2를 쓰는 스크립트 경로 지출입니다.