Skip to content

Instantly share code, notes, and snippets.

@yihuang
Created March 19, 2022 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yihuang/6eb8caa950ca059a711394cab1905035 to your computer and use it in GitHub Desktop.
Save yihuang/6eb8caa950ca059a711394cab1905035 to your computer and use it in GitHub Desktop.
Poker Design Notes.md
# 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