initial version

This commit is contained in:
bryanqiu 2022-11-14 17:46:23 +08:00
parent a557a59926
commit a1ade9e06f
2 changed files with 70 additions and 19 deletions

26
bigint.go Normal file
View File

@ -0,0 +1,26 @@
package zkp
import (
"fmt"
"math/big"
)
type big_Int big.Int
func (b big_Int) MarshalJSON() ([]byte, error) {
i := big.Int(b)
v := fmt.Sprintf("\"%x\"", i.Bytes())
return []byte(v), nil
}
func (b *big_Int) UnmarshalJSON(p []byte) error {
if string(p) == "null" {
return nil
}
var v = []byte{}
if _, err := fmt.Sscanf(string(p), "\"%x\"", &v); err != nil {
return fmt.Errorf("not a valid big integer: %s", p)
}
*b = big_Int(*new(big.Int).SetBytes(v))
return nil
}

59
zkp.go
View File

@ -4,6 +4,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
@ -14,7 +15,8 @@ import (
) )
type DLogProof struct { type DLogProof struct {
ChallengeResponse *big.Int `json:"cr"` ChallengeResponse *big_Int `json:"cr"`
ChallengeResponseXXXX *big.Int `json:"cr___TODO______debug"`
RandomPoint string `json:"pkr"` RandomPoint string `json:"pkr"`
} }
@ -38,7 +40,7 @@ func DLogProve(sk *big.Int) (proof *DLogProof, err error) {
randomkey, err := crypto.GenerateKey() randomkey, err := crypto.GenerateKey()
if err != nil { if err != nil {
log.Warningf("Gernerate random Q1 failed: '%s'", err.Error()) log.Warningf("Gernerate random Q1 failed: '%s'", err.Error())
return errors.New("generate random key/number failed") return nil, errors.New("generate random key/number failed")
} }
var skr = randomkey.D var skr = randomkey.D
var pkr = randomkey.PublicKey var pkr = randomkey.PublicKey
@ -47,16 +49,21 @@ func DLogProve(sk *big.Int) (proof *DLogProof, err error) {
// Step 2. caculate challenge: c = SHA256(pkr || G || pk) // Step 2. caculate challenge: c = SHA256(pkr || G || pk)
challenge := fmt.Sprintf( challenge := fmt.Sprintf(
"%x,%x@%x,%x@%x,%x", pkr.X, pkr.Y, Gx, Gy, pk.X, pk.Y) "%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))[:]) chash256 := sha256.Sum256([]byte(challenge))
var c = new(big.Int).SetBytes(chash256[:])
log.Debugf("challenge='%s',c='%x'", challenge, c)
// Step 3. caculate challenge response: cr = skr - c * sk // Step 3. caculate challenge response: cr = skr - c * sk
cvN := cv.Params().N
tmp := new(big.Int).Mul(c, sk) tmp := new(big.Int).Mul(c, sk)
var cr = new(big.Int).Mul(skr) var cr = new(big.Int).Sub(skr, tmp)
cr = new(big.Int).Mod(cr, cvN)
// return // return
proof = &DLogProof{ proof = &DLogProof{
RandomPoint: fmt.Sprintf("%x,%x", pkr.X, pkr.Y), RandomPoint: fmt.Sprintf("%x,%x", pkr.X, pkr.Y),
ChallengeResponse: cr, ChallengeResponse: (*big_Int)(cr),
ChallengeResponseXXXX: cr,
} }
return proof, nil return proof, nil
} }
@ -70,13 +77,13 @@ func DLogProve(sk *big.Int) (proof *DLogProof, err error) {
*/ */
func DLogVerify(pkstr string, proof *DLogProof) bool { func DLogVerify(pkstr string, proof *DLogProof) bool {
// Step 0. get pk & pkr // Step 0. get pk & pkr
var pk, err = HexStringToS256Point(pkstr) var pk, err1 = HexStringToS256Point(pkstr)
if err != nil { if err1 != nil {
//errors.New("input pk is invalid") //errors.New("input pk is invalid")
return false return false
} }
var pkr, err = HexStringToS256Point(proof.RandomPoint) var pkr, err2 = HexStringToS256Point(proof.RandomPoint)
if err != nil { if err2 != nil {
//errors.New("input pkr is invalid") //errors.New("input pkr is invalid")
return false return false
} }
@ -87,25 +94,30 @@ func DLogVerify(pkstr string, proof *DLogProof) bool {
Gy := cv.Params().Gy Gy := cv.Params().Gy
challenge := fmt.Sprintf( challenge := fmt.Sprintf(
"%x,%x@%x,%x@%x,%x", pkr.X, pkr.Y, Gx, Gy, pk.X, pk.Y) "%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))[:]) chash256 := sha256.Sum256([]byte(challenge))
var cr = proof.ChallengeResponse var c = new(big.Int).SetBytes(chash256[:])
var cr = (*big.Int)(proof.ChallengeResponse)
log.Debugf("challenge='%s',c='%x',cr='%x'", challenge, c, cr)
// Step 2. caculate proof verify: pkv = cr * G + c * pk // Step 2. caculate proof verify: pkv = cr * G + c * pk
var pkv = ecdsa.PublicKey{Curve: crypto.S256()} var pkv = ecdsa.PublicKey{Curve: crypto.S256()}
pkv.X, pkv.Y = cv.ScalarBaseMult(cr.Bytes()) pkv.X, pkv.Y = cv.ScalarBaseMult(cr.Bytes())
tempX, tempY := cv.ScalarMult(pk.X, pk.Y, c.Bytes()) tempX, tempY := cv.ScalarMult(pk.X, pk.Y, c.Bytes())
tempX, tempY = cv.Add(pkv.X, pkv.Y, tempX, tempY) tempX, tempY = cv.Add(pkv.X, pkv.Y, tempX, tempY)
log.Debugf("pkv='%x,%x'", tempX, tempY)
// return // return
if pkr.X == tempX && pkr.Y == Y { if pkr.X.Cmp(tempX) != 0 || pkr.Y.Cmp(tempY) != 0 {
return true log.Debugf("pkr='%x,%x'", pkr.X, pkr.Y)
} log.Debugf("pkv='%x,%x'", tempX, tempY)
return false return false
}
return true
} }
func HexStringToS256Point(p string) (*ecdsa.PublicKey, error) { func HexStringToS256Point(pstr string) (*ecdsa.PublicKey, error) {
var pk = ecdsa.PublicKey{Curve: crypto.S256()} var pk = ecdsa.PublicKey{Curve: crypto.S256()}
if x2y2 := strings.Split(pkstr, ","); len(x2y2) != 2 { if x2y2 := strings.Split(pstr, ","); len(x2y2) != 2 {
return nil, errors.New("input pk is invalid") return nil, errors.New("input pk is invalid")
} else if x, err := hex.DecodeString(x2y2[0]); err != nil { } else if x, err := hex.DecodeString(x2y2[0]); err != nil {
return nil, errors.New("input pk.x is invalid") return nil, errors.New("input pk.x is invalid")
@ -115,5 +127,18 @@ func HexStringToS256Point(p string) (*ecdsa.PublicKey, error) {
pk.X = new(big.Int).SetBytes(x) pk.X = new(big.Int).SetBytes(x)
pk.Y = new(big.Int).SetBytes(y) pk.Y = new(big.Int).SetBytes(y)
} }
return pk, nil return &pk, nil
}
func (dlogproof *DLogProof) ToString() string {
var b, _ = json.Marshal(dlogproof)
return string(b)
}
func DLogProofFromString(jsonstr string) (*DLogProof, error) {
var proof = DLogProof{}
if err := json.Unmarshal([]byte(jsonstr), &proof); err != nil {
return nil, err
}
return &proof, nil
} }