init: v1.0.0
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
package sm2m
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/grand"
|
||||
"xdx.jelly/xgcl/he/paillier"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
"xdx.jelly/xgcl/sm/sm2/ec256"
|
||||
)
|
||||
|
||||
// clientBlindSignContext 只能使用NewClientBlindSignContext来生成.
|
||||
type clientBlindSignContext struct {
|
||||
k1 *big.Int
|
||||
rand io.Reader
|
||||
paillierPrivateKey *paillier.PrivateKey
|
||||
}
|
||||
|
||||
// NewClientSignContext 生成客户端协同签名上下文
|
||||
// pk没有用,可以传nil, rnd是随机数发生器. paillierPrivateKey可以临时产生密钥,也可以产生长期的保存在客户端.
|
||||
// 注: pk实际是用来验证完成后的签名. 这里由调用者自己验证即可.
|
||||
func NewClientBlindSignContext(pk *sm2.PublicKey, paillierPrivateKey *paillier.PrivateKey, r io.Reader) *clientBlindSignContext {
|
||||
c := &clientBlindSignContext{
|
||||
k1: new(big.Int),
|
||||
rand: r,
|
||||
paillierPrivateKey: paillierPrivateKey,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Initial 客户端第一步, 返回e的同态密文和临时点P, 将他们同同态公钥一起发送给服务端.
|
||||
//
|
||||
// 客户端生成选择随机数k1 in [1, n - 1],计算e = SM3(Z || M), P = [k1]G,
|
||||
// 其中Z为32字节杂凑值,G为基点,向服务端发送签名请求并将 Enc_paillier(e), P, 发送给服务端。
|
||||
// 注: 同态公钥可以使用客户端的部分私钥对应的公钥签名,服务端验证.
|
||||
func (c *clientBlindSignContext) Initial(e []byte) (ecipher *paillier.Cipher, p *sm2.PublicKey, err error) {
|
||||
if c.rand == nil {
|
||||
c.rand = grand.Reader
|
||||
}
|
||||
if c.k1 == nil {
|
||||
c.k1 = new(big.Int)
|
||||
}
|
||||
buf := make([]byte, sm2.ByteSize())
|
||||
if n, err := c.rand.Read(buf); n != len(buf) || err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
c.k1.SetBytes(buf)
|
||||
c.k1.Mod(c.k1, sm2.OrderN())
|
||||
|
||||
x, y := sm2.Curve256.ScalarMult(sm2.BaseX(), sm2.BaseY(), c.k1.Bytes())
|
||||
p = &sm2.PublicKey{Curve: sm2.Curve(), X: x, Y: y}
|
||||
paillierPublicKey := c.paillierPrivateKey.Public()
|
||||
ecipher, err = paillierPublicKey.Encrypt(new(big.Int).SetBytes(e), c.rand)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return ecipher, p, nil
|
||||
}
|
||||
|
||||
// ServerSign 服务端计算. serverKey是服务端的部分密钥, pcipher,p和ppublickey是客户端发送过来的数据.
|
||||
//
|
||||
// 服务端生成随机数k2, k3, k4 in [1,n-1],(k = k1 * k2 + k3)
|
||||
// 计算(x1,y1)=[k2]P+[k3]G,
|
||||
// rcipher = Enc(r) = Enc(e)*Enc(x1)
|
||||
// s1 = k2*d2 mod n
|
||||
// s2cipher = Enc(s2) = (Enc(r)*E(k_3))^ds * Enc(k4*n) = Enc(ds*(r+k3)+k4*n).
|
||||
// 返回rcipher, s1, s2cipher, 并发送给客户端
|
||||
func ServerBlindSign(serverKey *sm2.PrivateKey, ecipher *paillier.Cipher,
|
||||
p *sm2.PublicKey, ppublickey *paillier.PublicKey, rnd io.Reader) (rcipher *paillier.Cipher, s1 *big.Int, s2cipher *paillier.Cipher, err error) {
|
||||
var k2, k3, k4 *big.Int
|
||||
for {
|
||||
k2, err = rand.Int(rnd, sm2.OrderN())
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if k2.Sign() == 0 {
|
||||
continue
|
||||
}
|
||||
k3, err = rand.Int(rnd, sm2.OrderN())
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if k3.Sign() == 0 {
|
||||
continue
|
||||
}
|
||||
k4, err = rand.Int(rnd, sm2.OrderN())
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if k4.Sign() == 0 {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
x1, _ := ec256.CombinedMult(p.X, p.Y, k3.Bytes(), k2.Bytes())
|
||||
x1cipher, err := ppublickey.Encrypt(x1, rnd)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
rcipher = x1cipher.HomomorphicAdd(x1cipher, ecipher, ppublickey)
|
||||
|
||||
s1 = new(big.Int)
|
||||
s1.Mul(k2, serverKey.D)
|
||||
s1.Mod(s1, sm2.OrderN())
|
||||
|
||||
s2cipher, err = ppublickey.Encrypt(k3, rnd)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
s2cipher.HomomorphicAdd(s2cipher, rcipher, ppublickey)
|
||||
s2cipher.HomomorphicScalarMul(s2cipher, serverKey.D, ppublickey)
|
||||
|
||||
k4.Mul(k4, sm2.OrderN())
|
||||
k4Cipher, err := ppublickey.Encrypt(k4, rnd)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
s2cipher.HomomorphicAdd(s2cipher, k4Cipher, ppublickey)
|
||||
|
||||
return rcipher, s1, s2cipher, nil
|
||||
}
|
||||
|
||||
// Final 客户端计算签名
|
||||
//
|
||||
// 客户端解密rcipher, s2cipher得到r, s2,
|
||||
// 计算s = d1*(k1*s1+s2)-r mod n,并检查s,r+s是否为0 mod q。
|
||||
// 对消息M的签名为(r,s),客户端可验证签名是否正确.
|
||||
func (c *clientBlindSignContext) Final(clientKey *sm2.PrivateKey,
|
||||
rcipher *paillier.Cipher, s1 *big.Int, s2cipher *paillier.Cipher) (*sm2.Signature, error) {
|
||||
r, err := c.paillierPrivateKey.Decrypt(rcipher)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.Mod(r, sm2.OrderN())
|
||||
if r.Sign() == 0 {
|
||||
return nil, errors.New("Blind sign failed, r = 0")
|
||||
}
|
||||
|
||||
s2, err := c.paillierPrivateKey.Decrypt(s2cipher)
|
||||
s2.Mod(s2, sm2.OrderN())
|
||||
|
||||
s := c.k1.Mul(c.k1, s1)
|
||||
s.Add(s, s2).Mod(s, sm2.OrderN()).Mul(s, clientKey.D).Sub(s, r).Mod(s, sm2.OrderN())
|
||||
if s.Sign() == 0 {
|
||||
return nil, errors.New("Blind sign failed, s = 0")
|
||||
}
|
||||
c.k1 = nil
|
||||
return &sm2.Signature{R: r, S: s}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user