Threshold Signatures, MPC, and Distributed Key Generation (DKG) TODO
Concept
A (t,n) threshold signature splits a private key into n shares such that any t or more must combine to produce a valid signature — the complete key never exists in one place at any point in time. The underlying idea is Shamir's secret sharing: distributing points on a degree-(t-1) polynomial lets any t points reconstruct the constant term (the secret), while t-1 points reveal nothing at all. DKG is a protocol where participants jointly generate a shared public key and their individual shares purely through interaction, with no trusted dealer, using verifiable secret sharing to filter out cheating participants. BLS signatures thresholdize naturally because keys and signatures simply add together, whereas ECDSA's multiplicative structure demands a far more complex MPC protocol. General MPC is the broader category — computing a joint function's result while each party's input stays hidden — and threshold signing is a special case of it.
The security of a bridge, custody, or oracle signer set ultimately comes down to how the key is split, and a large share of real incidents start from a single leaked key.
Code & Formula
# 임계 서명·MPC·DKG — Shamir 비밀 분산으로 (t, n) 임계 스킴의 핵심(다항식 보간)을 구현한다.
# t개 지분이 모이면 비밀(상수항)을 복원하고, t-1개로는 아무 정보도 얻지 못함을 보인다. (교육용)
import secrets
PRIME = 2**127 - 1 # 큰 소수 체 (토이 규모)
def make_shares(secret_value, t, n):
"""t-1차 다항식을 무작위 계수로 만들고, n개 지분 (x, f(x))을 반환한다."""
coeffs = [secret_value] + [secrets.randbelow(PRIME) for _ in range(t - 1)]
def f(x):
return sum(c * pow(x, i, PRIME) for i, c in enumerate(coeffs)) % PRIME
return [(x, f(x)) for x in range(1, n + 1)]
def lagrange_interpolate_at_zero(shares):
"""t개 지분 (x_i, y_i) 으로부터 f(0) = 비밀을 라그랑주 보간으로 복원한다."""
secret = 0
for i, (xi, yi) in enumerate(shares):
num, den = 1, 1
for j, (xj, _) in enumerate(shares):
if i == j:
continue
num = (num * -xj) % PRIME
den = (den * (xi - xj)) % PRIME
secret = (secret + yi * num * pow(den, -1, PRIME)) % PRIME
return secret
SECRET_KEY = 424242424242424242
t, n = 3, 5 # (t,n) 임계: 5명 중 3명이 모여야 서명(복원) 가능
shares = make_shares(SECRET_KEY, t, n)
print(f"generated {n} shares for a ({t},{n}) threshold scheme")
print("shares:", shares)
recovered_with_t = lagrange_interpolate_at_zero(shares[:t])
print(f"recovered with exactly t={t} shares:", recovered_with_t)
print("matches original secret:", recovered_with_t == SECRET_KEY)
# t-1개(부족한 지분)로 복원을 시도하면 완전히 다른(무의미한) 값이 나온다
recovered_with_t_minus_1 = lagrange_interpolate_at_zero(shares[:t - 1] + [(999, 12345)])
print(f"attempting recovery with only t-1 shares gives garbage:", recovered_with_t_minus_1)
print("=> below threshold, the polynomial is underdetermined: any value is equally consistent")
docs/code/algorithms/algorithms-86.py
Exercise
Implement Shamir's secret sharing over a small prime finite field, and confirm experimentally that t shares reconstruct the secret while t-1 shares leave every possible value equally plausible.
Practical Connection
If Verex puts oracle submission or settlement authority behind a threshold signature or multisig instead of a single EOA, one compromised key no longer translates directly into a manipulated market outcome.
Where it lands in Jayverse
- Bridge: put the lock-and-mint relayer's minting authority behind a (t,n) threshold signature instead of one EOA. One compromised relayer key currently means unbacked minting; threshold signing removes that single point.
- Wallet: use BLS's additive threshold structure for session-key/mandate revocation authority once Wallet handles real value. BLS thresholdizes naturally; retrofitting the same onto ECDSA is a much harder MPC protocol, so the signature scheme choice matters before the design is set.
- Devnet: prototype Shamir/DKG on devnet first, using the exercise's small-prime-field implementation, before deciding which of Verex, Bridge or Wallet gets threshold signing first.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| split X into shares | X를 조각(share)들로 나누다 · 개인키를 n개의 조각으로 분할하는 방식. "splits a private key into n shares" |
| reconstruct | (조각을 모아) 복원하다 · t개 이상의 점을 모아 원래 비밀을 되살리는 과정. "any t points reconstruct the constant term" |
| filter out | (걸러서) 배제하다, 솎아내다 · 검증 가능한 비밀 분산으로 부정행위자를 걸러내는 것. "using verifiable secret sharing to filter out cheating participants" |
| thresholdize | 문턱값(threshold) 방식으로 만들다 · 서명 방식을 threshold 구조로 바꾸는 것. "BLS signatures thresholdize naturally" |
| come down to | 결국 ~로 귀결되다 · 보안이 결국 키를 어떻게 나눴는지에 달려있다는 뜻. "ultimately comes down to how the key is split" |
| translate directly into | 곧바로 ~로 이어지다 · 키 하나가 뚫려도 바로 시장 조작으로 이어지지 않게 하는 것. "no longer translates directly into a manipulated market outcome" |
| DKG | 분산 키 생성(Distributed Key Generation) · 신뢰된 딜러 없이 참여자들이 함께 키를 만드는 프로토콜. "DKG is a protocol where participants jointly generate a shared" |
| MPC | 다자간 계산(Multi-Party Computation) · 각자의 입력을 숨긴 채 공동 함수를 계산하는 상위 범주 기법. "General MPC is the broader category" |
| BLS | BLS 서명 방식(Boneh-Lynn-Shacham) · 키와 서명이 단순히 더해지는 구조라 threshold화가 자연스러운 서명 스킴. "BLS signatures thresholdize naturally because keys and signatures simply add" |
| ECDSA | 타원곡선 전자서명 알고리즘(Elliptic Curve Digital Signature Algorithm) · 곱셈적 구조 때문에 threshold화가 훨씬 복잡한 서명 스킴. "ECDSA's multiplicative structure demands a far more complex MPC protocol" |
| EOA | 외부 소유 계정(Externally Owned Account) · 단일 개인키로 제어되는 이더리움 계정, threshold 서명과 대비됨. "instead of a single EOA" |
If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.