FROST, MuSig2, Threshold ECDSA 차이와 라이브러리 선택
FROST는 t-of-n threshold Schnorr, MuSig2는 n-of-n Schnorr multisig, threshold ECDSA/TSS는 Bitcoin/EVM custody에서 쓰는 t-of-n ECDSA에 가깝습니다. 목적이 다르기 때문에 라이브러리도 따로 봐야 합니다.
FROST, MuSig2, threshold ECDSA/TSS는 모두 여러 참여자가 서명에 관여하는 기술이다.
하지만 같은 문제를 푸는 기술은 아니다.
먼저 이렇게 나누는 것이 좋다.
| 구분 | 의미 | 주로 맞는 곳 |
|---|---|---|
| FROST | t-of-n threshold Schnorr | Schnorr 기반 threshold signature |
| MuSig2 | n-of-n Schnorr multisig | Bitcoin Taproot, BIP340 Schnorr |
| Threshold ECDSA / TSS | t-of-n ECDSA | Bitcoin/Ethereum 등 ECDSA 주소 체계 |
핵심 차이는 t-of-n인지, n-of-n인지, 최종 서명이 Schnorr인지 ECDSA인지다.
MuSig2는 threshold signature가 아니다. BIP327에도 MuSig2는 n-of-n multi-signature scheme이고 t-of-n threshold-signature scheme이 아니라고 설명되어 있다.
용어 정리
FROST
FROST는 Flexible Round-Optimized Schnorr Threshold Signatures다.
여기서 중요한 단어는 threshold와 Schnorr다. 하나의 그룹 공개키가 있고, 개인키는 여러 share로 나뉜다. 전체 n명 중 threshold를 만족하는 t명이 참여하면 하나의 Schnorr signature를 만들 수 있다.
FROST에서 중요한 구현 포인트는 다음이다.
| 항목 | 설명 |
|---|---|
| Key share 생성 | trusted dealer 방식 또는 DKG 방식이 있다. |
| DKG | dealer 없이 참여자들이 key share를 만든다. |
| Broadcast | DKG에서는 public commitment에 대해 참여자들이 같은 view를 가져야 한다. |
| Signing round | FROST는 two-round threshold Schnorr signing을 목표로 한다. |
| Nonce 관리 | multi-party Schnorr에서 nonce 재사용은 치명적이다. |
FROST는 Schnorr 계열이다. ECDSA 주소 체계를 그대로 유지해야 하는 EVM custody 문제에 바로 끼워 넣는 기술은 아니다. Schnorr 검증을 쓰는 시스템이나, 컨트랙트가 별도 검증 로직을 둘 수 있는 구조에서 더 자연스럽다.
MuSig2
MuSig2는 여러 공개키를 하나의 aggregate public key로 묶고, 여러 참여자가 협력해 하나의 BIP340 Schnorr signature를 만드는 방식이다.
하지만 threshold는 아니다.
MuSig2는 n-of-n이다. 3명이 aggregate key를 만들었다면, 기본적으로 그 3명이 모두 signing에 참여해야 한다.
그래서 MuSig2는 다음 문제에 맞다.
| 맞는 경우 | 이유 |
|---|---|
| Bitcoin Taproot key path | 최종 on-chain footprint가 일반 Taproot key spend처럼 보일 수 있다. |
| 모든 참여자 동의가 필요한 지갑 | n-of-n 구조가 요구사항과 맞다. |
| BIP340 Schnorr 호환성 | Bitcoin Schnorr 생태계와 맞다. |
반대로 "5명 중 3명만 동의하면 된다" 같은 요구사항이면 MuSig2만으로는 맞지 않는다. 그 경우는 FROST 같은 threshold Schnorr나 threshold ECDSA/TSS를 봐야 한다.
Threshold ECDSA / TSS
Threshold ECDSA/TSS는 여러 참여자가 ECDSA private key를 share로 나누고, threshold 참여자가 협력해 하나의 ECDSA signature를 만드는 방식이다.
최종 결과가 일반 ECDSA signature라서 기존 Bitcoin, Ethereum, EVM 주소 체계와 잘 맞는다.
이쪽은 FROST보다 프로토콜이 무겁다. ECDSA는 Schnorr보다 multi-party protocol이 복잡하고, Paillier, safe prime, zero-knowledge proof, auxiliary information 같은 구성요소가 같이 나온다.
그래도 기존 ECDSA 주소를 유지해야 하는 custody 시스템에서는 threshold ECDSA가 현실적인 선택지가 된다.
선택 기준
먼저 체인과 검증식을 봐야 한다.
질문 순서는 다음이 좋다.
| 질문 | 선택 |
|---|---|
| 최종 signature가 ECDSA여야 하는가? | 그렇다면 threshold ECDSA/TSS를 먼저 본다. |
| Bitcoin Taproot에서 n-of-n을 만들고 싶은가? | MuSig2가 자연스럽다. |
| t-of-n Schnorr가 필요한가? | FROST를 본다. |
| 컨트랙트 계정에서 자체 검증할 수 있는가? | ECDSA에 묶이지 않아도 된다. |
| 운영자가 signer를 식별하고 제외해야 하는가? | identifiable abort, key refresh, resharing 지원을 확인한다. |
| 프로덕션에 넣을 것인가? | audit, maintenance, release, 보안 문서를 확인한다. |
Rust 라이브러리
FROST
Rust에서는 ZcashFoundation/frost를 먼저 본다.
이 저장소는 RFC 9591 기반 FROST 구현이다. frost-core, frost-ristretto255, frost-ed25519, frost-p256, frost-secp256k1, frost-secp256k1-tr 같은 ciphersuite별 crate가 있다.
README 기준으로 crates는 stable, feature complete로 설명되어 있고, 일부 crate는 NCC audit 대상에 포함되어 있다.
FROST DKG는 frost_core::keys::dkg를 본다. 이 모듈은 trusted dealer 없이 FROST key share를 만들기 위한 DKG 구조를 제공한다. 단, secure broadcast requirement가 있다. DKG에서는 모든 참여자가 public commitment에 대해 같은 view를 가져야 한다.
정리하면 다음과 같다.
| 목적 | 후보 |
|---|---|
| Rust FROST | ZcashFoundation/frost |
| Rust FROST DKG | frost_core::keys::dkg |
| secp256k1 FROST | frost-secp256k1 |
| Taproot 계열 FROST | frost-secp256k1-tr |
| P-256 FROST | frost-p256 |
Threshold ECDSA
Rust threshold ECDSA는 LFDT-Lockness/cggmp21을 먼저 볼 수 있다.
현재 저장소는 CGGMP24 기반 threshold ECDSA 구현을 제공한다. README 기준으로 다음 기능을 제공한다.
| 기능 | 상태 |
|---|---|
| t-of-n key generation | 지원 |
| n-of-n key generation | 지원 |
| threshold signing | 지원 |
| auxiliary info generation | 지원 |
| HD wallet support | feature 기반 지원 |
| key refresh | 현재 미지원 |
| identifiable abort | 현재 미지원 |
| audit | Kudelski audit 언급 |
threshold ECDSA는 단순 signing 라이브러리처럼 보면 안 된다. 네트워크 레이어, party index, execution id, aux info, presignature 재사용 방지, key share 보관 정책까지 같이 설계해야 한다.
MuSig2
Bitcoin 계열 Rust MuSig2는 rust-bitcoin/rust-secp256k1을 먼저 확인한다.
rust-secp256k1 changelog 기준으로 0.32.0에서 MuSig2 support가 추가되었다. Bitcoin/Taproot/BIP340 흐름에 맞추는 경우 이 라인을 먼저 보는 것이 자연스럽다.
고수준 API가 필요하면 conduition/musig2 같은 후보도 볼 수 있지만, 프로덕션 선택에서는 maintenance와 release 상태를 따로 확인해야 한다.
Go 라이브러리
FROST
Go에서는 bytemare/frost를 먼저 볼 수 있다.
README 기준으로 RFC9591 FROST 구현이고, Ristretto255, Edwards25519, Secp256k1, NIST curve 계열을 지원한다.
FROST DKG는 bytemare/dkg를 같이 본다. 이 라이브러리는 FROST-compatible DKG를 제공하고, 2-round Pedersen DKG에 rogue-key attack 방지를 위한 zero-knowledge proof를 붙인다.
Generic DKG / Pedersen, Rabin
Go에서 범용 crypto/DKG toolbox가 필요하면 drand/kyber를 볼 수 있다.
Kyber는 DEDIS 계열 advanced crypto library이고, drand에서 fork해 쓰는 라인이다. FROST만 구현하려는 경우에는 전용 FROST/DKG 라이브러리를 먼저 보는 것이 단순하다. 하지만 Pedersen, Rabin DKG 같은 범용 DKG 구성요소를 살펴볼 때는 Go 쪽 기준점으로 볼 수 있다.
Threshold ECDSA
Go threshold ECDSA는 bnb-chain/tss-lib이 대표적인 후보 중 하나다.
README 기준으로 Gennaro-Goldfeder 계열 multi-party {t,n} threshold ECDSA와 EdDSA를 구현한다. keygen, signing, resharing 프로토콜을 포함한다.
| 목적 | 후보 |
|---|---|
| Go threshold ECDSA | bnb-chain/tss-lib |
| Go threshold EdDSA | bnb-chain/tss-lib |
| Keygen | 지원 |
| Signing | 지원 |
| Resharing | 지원 |
TSS 라이브러리는 API만 보고 고르면 안 된다. 운영에서는 party discovery, message transport, timeout, blame, key share backup, resharing, 장애 복구가 더 큰 문제가 된다.
MuSig2
Go Bitcoin stack에서는 btcsuite/btcd/btcec/v2/schnorr/musig2를 먼저 확인한다.
btcd release note에도 btcec/schnorr/musig2 구현과 업데이트 이력이 나온다. Bitcoin/Taproot n-of-n multisig라면 이 라인이 자연스럽다.
한 번에 비교
| 영역 | Rust | Go | 판단 |
|---|---|---|---|
| FROST | ZcashFoundation/frost | bytemare/frost | Rust는 ZF FROST가 가장 무난하다. Go는 bytemare 쪽을 먼저 본다. |
| FROST DKG | frost_core::keys::dkg | bytemare/dkg | 둘 다 FROST key share 생성 흐름에 맞다. |
| Generic DKG | FROST면 ZF FROST DKG, ECDSA TSS면 CGGMP 계열 | drand/kyber | Rust는 목적별 라이브러리를 고르는 편이 현실적이다. Go는 Kyber가 기준점이다. |
| Threshold ECDSA / TSS | LFDT-Lockness/cggmp21 | bnb-chain/tss-lib | ECDSA 주소 체계를 유지해야 할 때 본다. |
| MuSig2 | rust-bitcoin/rust-secp256k1 | btcsuite/btcec/schnorr/musig2 | Bitcoin Taproot n-of-n이면 이 라인을 본다. |
내가 고른다면
Rust는 다음 조합을 먼저 본다.
| 목적 | 선택 |
|---|---|
| FROST | ZcashFoundation/frost |
| FROST DKG | frost-core::keys::dkg |
| Threshold ECDSA | LFDT-Lockness/cggmp21 / cggmp24 |
| Bitcoin MuSig2 | rust-bitcoin/rust-secp256k1 |
Go는 다음 조합을 먼저 본다.
| 목적 | 선택 |
|---|---|
| FROST | bytemare/frost |
| FROST DKG | bytemare/dkg |
| Generic DKG | drand/kyber |
| Threshold ECDSA | bnb-chain/tss-lib |
| Bitcoin MuSig2 | btcsuite/btcec/schnorr/musig2 |
피하거나 조심할 것
coinbase/kryptology는 예전에는 자주 언급되던 라이브러리지만, 현재 README에서 archived, no longer supported, should not be used라고 명시되어 있다. 새 프로젝트의 1순위 후보로 두면 안 된다.
taurushq-io/multi-party-sig는 CGGMP, FROST, Taproot 계열까지 넓게 다루지만, README에 production-ready를 위해 추가 testing과 audit가 필요하다는 disclaimer가 있다. 연구나 PoC 검토 대상으로는 볼 수 있지만, 프로덕션 1순위로 두기에는 확인할 것이 많다.
정리
FROST, MuSig2, threshold ECDSA/TSS는 이름이 비슷하게 묶이지만 선택 기준이 다르다.
짧게 말하면 다음과 같다.
| 상황 | 먼저 볼 것 |
|---|---|
| t-of-n Schnorr가 필요하다 | FROST |
| Bitcoin Taproot n-of-n이 필요하다 | MuSig2 |
| EVM/Bitcoin ECDSA 주소를 유지해야 한다 | Threshold ECDSA/TSS |
| 컨트랙트 계정에서 자체 검증 가능하다 | ECDSA 고정 요구사항부터 다시 확인 |
가장 흔한 실수는 MuSig2를 threshold signature로 착각하는 것이다. MuSig2는 n-of-n이다. threshold가 필요하면 FROST나 threshold ECDSA/TSS를 봐야 한다.
참고
다음 읽기
이 생각이 이어지는 방향
읽은 뒤의 대화
읽은 뒤의 생각을 이어갑니다
질문, 반론, 조용한 후속 메모를 이 글 아래에 남길 수 있습니다.