initial version
This commit is contained in:
commit
a557a59926
119
zkp.go
Normal file
119
zkp.go
Normal file
@ -0,0 +1,119 @@
|
||||
package zkp
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"qoobing.com/gomod/log"
|
||||
)
|
||||
|
||||
type DLogProof struct {
|
||||
ChallengeResponse *big.Int `json:"cr"`
|
||||
RandomPoint string `json:"pkr"`
|
||||
}
|
||||
|
||||
/*
|
||||
* Prove:
|
||||
* step 1. generate random bignumber: skr, let pkr = skr * G
|
||||
* step 2. caculate challenge: c = SHA256(pkr || G || pk)
|
||||
* step 3. caculate challenge response: cr = skr - c * sk
|
||||
* result:
|
||||
* (pkr, cr)
|
||||
*/
|
||||
func DLogProve(sk *big.Int) (proof *DLogProof, err error) {
|
||||
// Step 0. get pk
|
||||
cv := crypto.S256()
|
||||
Gx := cv.Params().Gx
|
||||
Gy := cv.Params().Gy
|
||||
x, y := cv.ScalarBaseMult(sk.Bytes())
|
||||
var pk = ecdsa.PublicKey{Curve: cv, X: x, Y: y}
|
||||
|
||||
// Step 1. generate random bignumber: skr, let pkr = skr * G
|
||||
randomkey, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
log.Warningf("Gernerate random Q1 failed: '%s'", err.Error())
|
||||
return errors.New("generate random key/number failed")
|
||||
}
|
||||
var skr = randomkey.D
|
||||
var pkr = randomkey.PublicKey
|
||||
//TODO: sk_t_rand_commitment.zeroize();
|
||||
|
||||
// Step 2. caculate challenge: c = SHA256(pkr || G || pk)
|
||||
challenge := fmt.Sprintf(
|
||||
"%x,%x@%x,%x@%x,%x", pkr.X, pkr.Y, Gx, Gy, pk.X, pk.Y)
|
||||
var c = new(big.Int).SetBytes(sha256.Sum256([]byte(challenge))[:])
|
||||
|
||||
// Step 3. caculate challenge response: cr = skr - c * sk
|
||||
tmp := new(big.Int).Mul(c, sk)
|
||||
var cr = new(big.Int).Mul(skr)
|
||||
|
||||
// return
|
||||
proof = &DLogProof{
|
||||
RandomPoint: fmt.Sprintf("%x,%x", pkr.X, pkr.Y),
|
||||
ChallengeResponse: cr,
|
||||
}
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify:
|
||||
* step 1. caculate challenge: c = SHA256(pkr || G || pk)
|
||||
* step 2. caculate proof verify: pkv = cr * G + c * pk
|
||||
* result:
|
||||
* pkr =?= pkv
|
||||
*/
|
||||
func DLogVerify(pkstr string, proof *DLogProof) bool {
|
||||
// Step 0. get pk & pkr
|
||||
var pk, err = HexStringToS256Point(pkstr)
|
||||
if err != nil {
|
||||
//errors.New("input pk is invalid")
|
||||
return false
|
||||
}
|
||||
var pkr, err = HexStringToS256Point(proof.RandomPoint)
|
||||
if err != nil {
|
||||
//errors.New("input pkr is invalid")
|
||||
return false
|
||||
}
|
||||
|
||||
// Step 1. caculate challenge: c = SHA256(pkr || G || pk)
|
||||
cv := crypto.S256()
|
||||
Gx := cv.Params().Gx
|
||||
Gy := cv.Params().Gy
|
||||
challenge := fmt.Sprintf(
|
||||
"%x,%x@%x,%x@%x,%x", pkr.X, pkr.Y, Gx, Gy, pk.X, pk.Y)
|
||||
var c = new(big.Int).SetBytes(sha256.Sum256([]byte(challenge))[:])
|
||||
var cr = proof.ChallengeResponse
|
||||
|
||||
// Step 2. caculate proof verify: pkv = cr * G + c * pk
|
||||
var pkv = ecdsa.PublicKey{Curve: crypto.S256()}
|
||||
pkv.X, pkv.Y = cv.ScalarBaseMult(cr.Bytes())
|
||||
tempX, tempY := cv.ScalarMult(pk.X, pk.Y, c.Bytes())
|
||||
tempX, tempY = cv.Add(pkv.X, pkv.Y, tempX, tempY)
|
||||
|
||||
// return
|
||||
if pkr.X == tempX && pkr.Y == Y {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func HexStringToS256Point(p string) (*ecdsa.PublicKey, error) {
|
||||
var pk = ecdsa.PublicKey{Curve: crypto.S256()}
|
||||
if x2y2 := strings.Split(pkstr, ","); len(x2y2) != 2 {
|
||||
return nil, errors.New("input pk is invalid")
|
||||
} else if x, err := hex.DecodeString(x2y2[0]); err != nil {
|
||||
return nil, errors.New("input pk.x is invalid")
|
||||
} else if y, err := hex.DecodeString(x2y2[1]); err != nil {
|
||||
return nil, errors.New("input pk.y is invalid")
|
||||
} else {
|
||||
pk.X = new(big.Int).SetBytes(x)
|
||||
pk.Y = new(big.Int).SetBytes(y)
|
||||
}
|
||||
return pk, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user