Created
March 19, 2022 09:43
-
-
Save yihuang/6eb8caa950ca059a711394cab1905035 to your computer and use it in GitHub Desktop.
Poker Design Notes.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Poker Design Notes | |
## 合约框架 | |
### CheckIn | |
- 创建牌桌,初始化参数 | |
- 玩家加入,锁定资产 | |
- 玩家提交公钥和DLOG证明,客户端合并玩家公钥可得全局公钥 | |
### CheckOut | |
- 提交所有玩家签名的终局状态 | |
- 结算资产 | |
- 销毁牌桌 | |
### Recovery | |
- 提交一个所有玩家都签名的 CheckPoint | |
- 提交玩家下一步的操作,合约判定是否合法 | |
- 如果有玩家没有提交操作,等待超时时间,超时后判定未提交的用户作弊 | |
- 如果有玩家作弊,对玩家资产进行惩罚,结算资产,结束游戏 | |
- 否则游戏继续 | |
## 链下框架 | |
### 消息广播 | |
游戏逻辑在链下执行,所有玩家加入p2p网络或者消息转发服务器,消息通讯模式为广播(所有消息一律在房间内广播)。 | |
### Checkpoint | |
游戏进程分为多轮,每一轮玩家按顺序广播自己的操作,所有玩家操作后,每个人按照游戏规则计算本地游戏状态,签名并广播游戏状态,如果所有人状态一致,合并签名和状态成为一个Checkpoint。 | |
如果某一轮发现玩家作弊(1. 操作不符合游戏规则,2. 不能提供有效的证明,3. 超时不执行操作),任何一个玩家可以到合约上进行Recovery,提交最近的Checkpoint和已广播的玩家操作,由合约逻辑进行判定。 | |
## 游戏操作类型 | |
### 洗牌 | |
先用全局共钥对牌进行加密,然后每个玩家按顺序进行洗牌操作 (Permutation + Re-randomization),并公开洗牌结果和NIZK。 | |
### 开公共牌 | |
所有玩家执行 `decrypt_share`, 并公开结果和`DLEQ`证明,合并结果可解密得到公共牌。 | |
### 开私有牌 | |
特定玩家以外所有玩家执行 `decrypt_share`,公开结果和`DLEQ`证明,该玩家结合本地私钥可解密得到私有牌。 | |
### 下注 | |
普通签名的操作 | |
## 攻击方式 | |
### DoS | |
在链下游戏过程中不执行操作,但是在合约Recovery时提交有效操作,可以成功拖慢游戏进程。同时没有人得到惩罚。 | |
## (n-n)-Threshold ElGamal Cryptosystem | |
```python | |
x: secret key | |
H: public key | |
G: base point | |
M: plain text message | |
r: random number | |
CT: cipher text | |
# 生成本地私钥, NIZK: DLOG | |
H = xG | |
# public key encryption | |
def encrypt(H, M, r): | |
return (rG, M + rH) | |
# decryption with secret key | |
def decrypt(x, CT): | |
(C1, C2) = CT | |
return C2 - xC1 # = (M + rH) - xrG = (M + rxG) - xrG = M | |
# re-randomization. | |
def rerand(H, CT, r): | |
(C1, C2) = CT | |
return (C1 + rG, C2 + rH) # = (r'G + rG, M + r'H + rH) = ((r'+r)G, M + (r'+r)H) | |
# combine keys | |
def combine_pk(Hs): | |
return sum(Hs) # = sum([xG]) = sum([x]) G | |
def combine_sk(xs): | |
return sum(xs) | |
# decrypt share, NIZK: DLEQ | |
def decrypt_share(x, CT): | |
(C1, _) = CT | |
return xC1 | |
def decrypt_with_shares(CT, shares): | |
(_, C2) = CT | |
return C2 - sum(shares) | |
# invariant: decrypt_with_shares(H, CT, [decrypt_share(x, CT) for x in xs]) | |
# == decrypt(combine_sk(xs), CT) | |
``` | |
## 零知识证明 | |
### DLOG | |
证明我有对应的公钥的私钥: `H = xG` | |
```python | |
def generate(G, x, r): | |
H = xG | |
A = rG | |
c = Hash(G, H, A) | |
z = r + cx | |
return (c, z) | |
def verify(G, H, proof): | |
c, z = proof | |
A = zG - cH # A = zG - cxG = (z - cx)G | |
return C == Hash(G, H, A) | |
``` | |
### DLEQ | |
``` | |
D = xC1 # decrypt_share(x, CT) | |
H = xG | |
``` | |
证明两组公式里的`x`是同一个私钥。 | |
```python | |
def generate(G, x, C1, r): | |
A1 = rG | |
A2 = rC1 | |
H = xG | |
D = xC1 # decrypt_share(x, CT) | |
c = Hash(H1, H2, A1, A2) | |
z = r + cx | |
return (c, z) | |
def verify(G, H, C1, D, proof): | |
(c, z) = proof | |
R1 = zG | |
R2 = zC1 | |
A1 = R1 - cH # = zG - cxG = (z - cx)G = rG | |
A2 = R2 - cD | |
return c == Hash(H, D, A1, A2) | |
``` | |
### 洗牌 | |
Permutation + Re-randomization. | |
论文:http://www0.cs.ucl.ac.uk/staff/J.Groth/MinimalShuffle.pdf | |
中文笔记:https://blog.csdn.net/mutourend/article/details/105554913 | |
Presentation: https://www.youtube.com/watch?v=KGs3A3GMcuw | |
Prototype Implementation: https://github.com/input-output-hk/casino |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment