diff --git a/bigint.go b/bigint.go new file mode 100644 index 0000000..0656327 --- /dev/null +++ b/bigint.go @@ -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 +} diff --git a/zkp.go b/zkp.go index 920d56c..a3df908 100644 --- a/zkp.go +++ b/zkp.go @@ -4,6 +4,7 @@ import ( "crypto/ecdsa" "crypto/sha256" "encoding/hex" + "encoding/json" "errors" "fmt" "math/big" @@ -14,8 +15,9 @@ import ( ) type DLogProof struct { - ChallengeResponse *big.Int `json:"cr"` - RandomPoint string `json:"pkr"` + ChallengeResponse *big_Int `json:"cr"` + ChallengeResponseXXXX *big.Int `json:"cr___TODO______debug"` + RandomPoint string `json:"pkr"` } /* @@ -38,7 +40,7 @@ func DLogProve(sk *big.Int) (proof *DLogProof, err error) { randomkey, err := crypto.GenerateKey() if err != nil { 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 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) 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))[:]) + 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 + cvN := cv.Params().N 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 proof = &DLogProof{ - RandomPoint: fmt.Sprintf("%x,%x", pkr.X, pkr.Y), - ChallengeResponse: cr, + RandomPoint: fmt.Sprintf("%x,%x", pkr.X, pkr.Y), + ChallengeResponse: (*big_Int)(cr), + ChallengeResponseXXXX: cr, } return proof, nil } @@ -70,13 +77,13 @@ func DLogProve(sk *big.Int) (proof *DLogProof, err error) { */ func DLogVerify(pkstr string, proof *DLogProof) bool { // Step 0. get pk & pkr - var pk, err = HexStringToS256Point(pkstr) - if err != nil { + var pk, err1 = HexStringToS256Point(pkstr) + if err1 != nil { //errors.New("input pk is invalid") return false } - var pkr, err = HexStringToS256Point(proof.RandomPoint) - if err != nil { + var pkr, err2 = HexStringToS256Point(proof.RandomPoint) + if err2 != nil { //errors.New("input pkr is invalid") return false } @@ -87,25 +94,30 @@ func DLogVerify(pkstr string, proof *DLogProof) bool { 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 + chash256 := sha256.Sum256([]byte(challenge)) + 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 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) + log.Debugf("pkv='%x,%x'", tempX, tempY) // return - if pkr.X == tempX && pkr.Y == Y { - return true + if pkr.X.Cmp(tempX) != 0 || pkr.Y.Cmp(tempY) != 0 { + 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()} - if x2y2 := strings.Split(pkstr, ","); len(x2y2) != 2 { + if x2y2 := strings.Split(pstr, ","); 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") @@ -115,5 +127,18 @@ func HexStringToS256Point(p string) (*ecdsa.PublicKey, error) { pk.X = new(big.Int).SetBytes(x) 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 }