主页
微信公众号:密码应用技术实战
博客园首页:https://www.cnblogs.com/informatics/
GIT地址:https://github.com/warm3snow
简介
在上一篇文章《密码学承诺之原理和应用 - 概览》中,我们详细介绍了常见的密码学承诺原理,本节我们将重点介绍Pedersen承诺的实现和应用。
在区块链技术中,Pedersen承诺常被用于实现交易的隐私保护,例如在Monero、Grin等隐私币中,Pedersen承诺被用于隐藏交易金额,保护用户隐私。
Pedersen承诺
Pedersen承诺
常见的形式有两种,一种是非零知识的Pedersen承诺,另一种是零知识的Pedersen承诺。
- 非零知识的Pedersen承诺:承诺打开阶段,发送者向接受者发送明文和随机数,接收者重新计算承诺值,并验证发送者的证明。
- 零知识的Pedersen承诺:承诺打开阶段,发送者向接受者发送承诺值和证明,接收者验证证明,但无法获得明文。
非零知识的Pedersen承诺
回顾我们在《密码学承诺之原理和应用 - 概览》中介绍的Pedersen承诺的构造和证明过程,如下:
假设\(G_p\)是阶为\(q\)的乘法群,\(g, h\)是独立生成元,\(m\)是明文(注:流程中所有操作都是\(mod \space p\)的)。Pedersen承诺的构造如下:
- [01] 承诺阶段:发送方选择一个明文\(m\)和一个随机数\(r\),计算承诺值\(C = g^m \cdot h^r\),并发送\(C\)给接收方。
- [02] 打开阶段:发送方揭示明文\(m\)和随机数\(r\)。
- [03] 验证阶段:接收方重新计算承诺值\(C^{'} = g^m \cdot h^r\),并验证\(C^{'}\)和\(C\)是否相等。
Pedersen承诺的隐藏性和绑定性
Pedersen承诺的隐藏性和绑定性是基于离散对数问题的困难性假设,接收方无法从承诺值\(C\)推导出明文\(m\),发送方无法找到两个不同的\((r_1, m_1)\)和\((r_2, m_2)\),使得\(C = g^{m_1} \cdot h^{r_1} = g^{m_2} \cdot h^{r_2}\)。
假设发送方找到两个不同的\((r_1, m_1)\)和\((r_2, m_2)\),使得\(C = g^{m_1} \cdot h^{r_1} = g^{m_2} \cdot h^{r_2}\),则有:
\[g^{m_1} \cdot h^{r_1} = g^{m_2} \cdot h^{r_2} \]\[g^{m_1 - m_2} = h^{r_2 - r_1} mod p \]由于\(g\)和\(h\)是独立生成元, 即它们生成的子群没有重叠,这意味着\(g^{m_1 - m_2} = h^{r_2 - r_1}\)只有在\(_1 - m_2 = 0\)和\(r_2 - r_1 = 0\)时才成立,即:
\[m_1 - m_2 = 0 \Rightarrow m_1 = m_2 \]\[r_2 - r_1 = 0 \Rightarrow r_2 = r_1 \]与假设矛盾,因此Pedersen承诺具有绑定性。
Pedersen承诺也可以基于ECC构造,假设\(G\)和\(H\)是椭圆曲线上的点,\(m\)是明文,\(r\)是随机数。
- 承诺阶段:发送方选择一个明文\(m\)和一个随机数\(r\),计算承诺值\(C = mG + rH\),并发送\(C\)给接收方。
- 打开阶段:发送方揭示明文\(m\)和随机数\(r\)。
- 验证阶段:接收方重新计算承诺值\(C^{'} = mG + rH\),并验证\(C^{'}\)和\(C\)是否相等。
隐藏性和绑定性略,与上述类似。
Pedersen承诺的同态性
Pedersen承诺有一个重要的性质:加法同态性。即两个Pedersen承诺的和等于明文的和的Pedersen承诺。假设\(C_1\)和\(C_2\)是两个Pedersen承诺,\(m_1, m_2\)是明文,\(r_1, r_2\)是随机数。
使用ECC构造的Pedersen承诺同态性证明如下:
- Pedersen承诺和\(C_1+C_2\):
- \(m_1+m_2\)和的Pedersen承诺:
令\(r = r_1 + r_2\),则\(C_1 + C_2 = C_{1,2}\),因此Pedersen承诺具有加法同态性
在门罗币Monero中,机密交易的核心思想就借助了Pedersen承诺来保证金额的保密性,同时利用零知识范围证明保证交易金额的正确性(即金额在一定范围内,本文暂时不做介绍,感兴趣的可以参考Monero官方技术文档)。
零知识的Pedersen承诺
Pedersen承诺
也可以构造为零知识承诺方案。 非交互式版本的Pedersen零知识承诺方案和流程如下:
- [01] 发送承诺:Sender选取随机数\(r\),并生成承诺\(C = m.G + r.H\),发送\(C\)给Receiver。(承诺阶段不变)
- [02] 生成挑战:Sender生成两个随机数\(x\)和\(y\);
- [03] 生成证明:Sender计算\(P = x.G + y.H\),并计算\(h = H(P)\),然后计算\(x^{'} = x + h.m\)和\(y^{'} = y + h.r\);
- [04] 发送证明:Sender发送证明\((P, x^{'}, y^{'})\)给Receiver;
- [05] 验证:Receiver验证证明,计算\(h = H(P)\),并验证\(P + h.C == x^{'}G + y^{'}H\)。
Pedersen零知识承诺的隐藏性、绑定性与Pedersen承诺类似。需要注意的是:Pedersen零知识承诺的安全性与哈希函数的选择有关,需要选择一个安全的哈希函数。
Pedersen零知识承诺的正确性证明
\[P + h.C = (x.G + y.H) + h.(m.G + r.H) \newline = x.G + y.H + h.m.G + h.r.H \newline = (x + h.m).G + (y + h.r).H \newline = x^{'}G + y^{'}H \]因此,\(P + h.C = x^{'}G + y^{'}H\),Pedersen零知识承诺的正确性得到证明。
Pedersen承诺实现
以下测试工具基于 golang
实现,读者可以通过 git clone
下载代码并进行编译,或者通过 go install
进行安装。
gossl命令行工具
- 直接安装
➜ gossl git:(master) go install github.com/warm3snow/gossl@latest
go: downloading github.com/warm3snow/gossl v0.0.0-20240926033959-072365c6c49c
- 下载代码并编译安装
➜ git clone https://github.com/warm3snow/gossl.git
➜ cd gossl && go install
- 查看帮助信息
➜ gossl git:(master) gossl -h
gossl is a crypto command-line tool like openssl.
Usage:
gossl [command]
Available Commands:
asym asymmetric cryptography
commitment cryptographic commitment
completion Generate the autocompletion script for the specified shell
dgst digest or hash cryptography
help Help about any command
kdf key derivation function
req certificate request
sym symmetric cryptography
tls transport layer security(ssl/tls)
x509 x509 certificate
Flags:
-a, --algo string Specify the supported algorithm
--config string config file (default is $HOME/.gossl.yaml)
-h, --help help for gossl
-i, --in string The input file
-o, --out string The output file
-t, --toggle Help message for toggle
-v, --verbose verbose output
Use "gossl [command] --help" for more information about a command.
Pedersen承诺命令
- gossl支持的承诺算法列表
➜ gossl git:(master) gossl commitment list
Supported commitment algorithm list:
hash
elgamal
pedersen
pedersen_ecc
pedersen_ecc_nizk
sigma
说明:
- pedersen: Pedersen承诺(基础实现,基于大整数)
- pedersen_ecc: Pedersen承诺(基于椭圆曲线)
- pedersen_ecc_nizk: Pedersen零知识承诺(基于椭圆曲线)
- gossl中实现的pedersen_ecc_xx承诺,默认基于椭圆曲线P256实现,当前不支持通过命令行参数指定其他椭圆曲线。
下面我们以pedersen_ecc承诺为例,介绍Pedersen承诺的生成和验证过程。
- 生成pedersen承诺
# in-text: 被承诺的明文消息
# -a pedersen_ecc: 使用pedersen_ecc承诺算法
➜ ~ gossl commitment commit -a pedersen_ecc --in-text "hello gossl"
Common Params:
g: 48439561293906451759052585252797914202762949526041747995844080717082404635286||36134250956749795798585127919587881956611106672985015071877198253568414405109
h: 50576502854212466438839749317167527793307683964006364826312081343074441953219||12058943601560843055648971416951613519083652196137588495325292324047710234986
Commitments:
C: 52858049039797670002352603227586253716602554539578338862835685759053587526540||21711818791724266306060874978496030353136730960103405548013991472321077516980
Openings:
m: 68656c6c6f20676f73736c
r: 53777609f68c14befcd5837d186e96c0fa6d9501f0538fea0b04ebf2dc7c9ef9
- 验证pedersen承诺
# -a pedersen_ecc: 使用pedersen_ecc承诺算法
# --g: 群生成元
# --h: 群元素
# --C: 承诺值
# --x: 明文,十六进制(承诺打开参数m)
# --y: 随机数(承诺打开参数r)
➜ ~ gossl commitment verify -a pedersen_ecc \
--g "48439561293906451759052585252797914202762949526041747995844080717082404635286||36134250956749795798585127919587881956611106672985015071877198253568414405109" \
--h "50576502854212466438839749317167527793307683964006364826312081343074441953219||12058943601560843055648971416951613519083652196137588495325292324047710234986" \
--C "52858049039797670002352603227586253716602554539578338862835685759053587526540||21711818791724266306060874978496030353136730960103405548013991472321077516980" \
--x "68656c6c6f20676f73736c" \
--y "53777609f68c14befcd5837d186e96c0fa6d9501f0538fea0b04ebf2dc7c9ef9"
commitment is verified successfully
Pedersen承诺go测试代码
除了使用gossl命令行工具,读者也可以通过以下 go test
代码进行测试。
// 切换到gossl的commitment目录
➜ cd gossl/crypto/commitment
➜ commitment git:(master) ll
total 64
-rw-r--r-- 1 hxy staff 1.1K 9 26 10:36 CommitPoint.go
-rw-r--r-- 1 hxy staff 1.8K 9 26 18:01 commitment_test.go
-rw-r--r-- 1 hxy staff 1.6K 9 26 17:57 elgamal_commit.go
-rw-r--r-- 1 hxy staff 883B 9 24 15:48 hash_commit.go
-rw-r--r-- 1 hxy staff 1.5K 9 26 10:26 Pedersen_commit.go
-rw-r--r-- 1 hxy staff 1.9K 9 26 17:57 Pedersen_ecc_commit.go
-rw-r--r-- 1 hxy staff 3.0K 9 26 17:57 Pedersen_ecc_nizk_commit.go
-rw-r--r-- 1 hxy staff 2.3K 9 26 18:12 sigma_ecc_nizk.go
// 运行测试代码
➜ commitment git:(master) go test -v -test.run=TestNewPedersenEccCommitment
=== RUN TestNewPedersenEccCommitment
Common Params:
G: 48439561293906451759052585252797914202762949526041747995844080717082404635286||36134250956749795798585127919587881956611106672985015071877198253568414405109
H: 55720517404442559634769401373558820863331089079296287221406115337065898291002||37747691253179513919219829090330228887165814968541184613076492361991012192846
C: 13734499214328844940914781327967861406173610952229818629999967975018454890014||111611964019468765819648519106736075510712384884879409701685767024336788829467
m: 68656c6c6f
r: e3fd9734d48d75616df3598e14b3a694fa7a108a87c7442cdba5ad51a50fdb40
Verify: true
--- PASS: TestNewPedersenEccCommitment (0.00s)
PASS
总结
本文详绍了Pedersen承诺的构造和证明过程,以及通过gossl工具实现了Pedersen承诺的生成和验证。Pedersen承诺在区块链和数字货币中已经被广泛应用,例如Monero、Grin等隐私币中。同时,Pedersen承诺扩展,如向量Pedersen承诺在零知识证明(如Bulletproofs)中也重要应用。
通过本文的介绍,希望读者对Pedersen承诺有更深入的了解,为后续的密码学学习和应用打下基础。
参考文献
- 【1】Pedersen Commitment
- 【2】Zero-Knowledge Proofs: An illustrated primer
- 【3】Zero Knowledge Proofs: Example with Pedersen Commitments in Monero
- 【4】gossl