MuSig2는 여러 사람이 하나의 Schnorr 서명을 함께 만들도록 한다. 특정 메시지에 대한 승인을 증명하면서 각자의 개인 키는 드러내지 않는다. BIP327의 절차는 두 차례 통신으로 공개 키를 집계하고 각자의 기여를 BIP340 호환 서명으로 합친다. 기본 모델은 n-of-n으로, 참여하는 서명자 모두의 기여가 필요하다.
앨리스와 밥이 모두 승인해야 돈을 쓸 수 있는 공동 금고를 생각해 보자. 디지털 서명은 비밀 숫자 값인 개인 키로 결제 승인을 증명하며, 키 자체는 공개하지 않는다. 기존 스크립트 기반 Multisig는 거래에서 여러 키와 서명을 공개할 수 있다. MuSig2에서는 각자가 개인키를 보관하면서 공동 서명에 기여한다. 네트워크는 결과 하나를 검증한다. 절약되는 것은 블록체인 기록 공간과 검증 비용이며, 참여자 사이의 조율은 여전히 필요하다. Jonas Nick, Tim Ruffing, Yannick Seurin은 2020년 10월 공개한 논문에서 이 프로토콜을 제안했다. [3] [2] [10]
MuSig2 자체는 아무 두 사람이 부재한 세 번째 서명자를 대신할 수 있는 2-of-3 방식이 아니다. n-of-n 그룹의 모든 구성원이 기여해야 한다. 연락이 안 되거나 거절하는 참여자는 협력을 중단시킬 수 있다. 지갑은 비트코인을 받고 보내는 앱이나 기기다. 그런 상황에서도 지갑을 사용하려면 별도의 지출 경로나 서명 방식을 미리 설계해야 한다. MuSig2라는 이름이 이를 자동으로 제공하지는 않는다. [1] [8]
서명 전에 참여자들은 집계 공개 키를 만든다. 공개 키는 서명을 검증하는 데 사용하며 비밀로 유지할 필요가 없다. 첫 번째 통신에서는 서명 준비에 쓰는 일회용 기여인 공개 nonce를 교환한다. 두 번째에서는 같은 메시지와 맥락에 대한 부분 서명을 만들어 보내고 최종 서명으로 합친다. 프로토콜 조건에 따르면 결제 내용이 정해지기 전에 첫 번째 통신을 준비할 수 있다. 하지만 각 참여자는 자신의 부분 서명을 만들기 전에 구체적인 거래, 특히 수신자, 금액, 수수료를 확인해야 한다. 준비는 알 수 없는 결제에 대한 승인이 아니며, 서명한 뒤 확인하는 것은 너무 늦다. [1] [3]
단순한 덧셈에서는 공격자가 다른 사람들의 키를 악용하도록 자신의 공개키를 선택할 수 있다. 따라서 MuSig2는 키 목록에서 계산한 수치 가중치인 계수를 사용한다. KeyAgg는 키 순서도 고려하며, 애플리케이션은 KeySort로 순서를 통일할 수 있다. 모두 같은 목록과 규칙을 사용해야 같은 집계키를 계산한다. [1] [5]
여기서 nonce는 채굴용 카운터가 아니라 일회용 서명 재료다. pubnonce는 다른 사람에게 전달하지만 secnonce는 서명자가 보관한다. 비밀 nonce를 다른 Sign 호출에 재사용해서는 안 된다. 재사용으로 만들어진 두 부분 서명은 개인키를 노출할 수 있다. 메시지를 바꾸거나 겉보기에 같은 결제를 반복하는 것도 안전한 예외가 아니다. [1] [7]
암호 계산이 정확해도 재시작 뒤 백업에서 사용한 secnonce를 되살리거나 두 병렬 작업에 같은 값을 넘기면 충분히 안전하지 않다. Libsecp256k1은 서명 중 비밀 nonce를 덮어써 무효화하지만 통제 밖에 있는 복사본은 이 보호를 우회할 수 있다. 오류, 복구, 동시 실행에서도 재사용을 막는 상태 관리가 필요하다. 개인 서명키 자체는 반복해서 쓸 수 있고, 일회용인 것은 nonce다. [7]
조정자는 공개 nonce와 부분 서명을 모아 교환을 중개할 수 있다. 프로토콜을 올바르게 사용하면 정직한 참여자 대신 서명할 권한이 생기지는 않지만, 절차를 방해할 수는 있다. 모든 서명자는 무엇에 서명하는지 확인해야 한다. 부분 서명 검증은 문제를 찾는 데 도움이 되지만 원래의 공개 기여와 올바른 맥락이 필요하다. 집계 nonce만으로는 문제를 일으킨 사람을 식별할 수 없다. [1] [7]
결과는 64바이트 BIP340 서명이다. Taproot key path는 네트워크가 출력에 기록된 키에 대한 서명을 검증하고 예비 스크립트를 공개하지 않는 지출 방식이다. 기본 모드를 사용하지 않으면 서명 뒤에 sighash 유형을 나타내는 바이트가 붙는다. 이는 서명이 거래의 어느 부분에 연결되는지 정하며, 그 부분을 바꾸면 서명이 무효가 된다. 서명 자체만으로 참여자 수나 개별 키는 알 수 없다. 그러나 MuSig2가 금액, 결제의 모든 관련 정보나 당사자 사이의 통신을 숨기지는 않는다. 서로 다른 입력의 서명도 자동으로 합치지 않는다. 입력은 이번 거래가 쓰려는, 이전에 받은 출력을 가리킨다. [5] [6]
Taproot에는 공동 key path 외에 다른 키 조합이나 시간 잠금 같은 스크립트 조건을 포함할 수 있다. 시간 잠금은 정해진 시간이나 블록 높이 이후에 특정 경로를 사용할 수 있게 하며, 필요한 서명을 대신하지 않는다. 블록은 공동 기록에 추가하는 거래 묶음이다. 블록 높이는 체인에서 블록의 위치를 나타낸다. 조건은 지출 규칙이 붙은 구체적인 금액인 출력을 만들 때 암호학적으로 확정해야 한다. 서명자를 잃은 뒤에 추가할 수는 없다. Script path는 이 스크립트를 통한 지출이며, 해당 조건을 공개하고 비용이 더 들 수 있다. 따라서 복구에는 개별 비밀 키뿐 아니라 선택한 구성에 대한 정보도 필요하다. [6] [1] [9]
BIP327은 프로토콜을 설명하고, 라이브러리와 지갑은 실제 인터페이스, 백업, 지원 절차를 결정한다. 버전, 테스트 벡터, nonce 처리, 서명할 거래의 검토 방식을 확인해야 한다. Schnorr 서명을 지원한다고 모든 지갑이 MuSig2를 완전히 지원하는 것은 아니다. 공동 서명은 기존 BIP340과 Taproot 규칙을 사용하므로 MuSig2 자체를 쓰기 위해 새로운 합의 opcode가 필요한 것은 아니다. [4] [7] [2]
더 정확히 이해하려면 이 항목과 함께 다음도 읽어 보세요 Schnorr Signature, Taproot, Multisig, PSBT. 다음 항목에서도 이 글을 참조합니다 Schnorr Signature, Submarine Swap, FROST, PTLC.