Browse Source

Verification

Ian Goldberg 2 years ago
parent
commit
7e2b0506e7
2 changed files with 94 additions and 5 deletions
  1. 92 4
      gk15.go
  2. 2 1
      main.go

+ 92 - 4
gk15.go

@@ -137,7 +137,6 @@ func ProofStep1(params GroupParams, c []kyber.Point, ell uint32, privkey kyber.S
 				p_i[t] = group.Scalar().Zero()
 			}
 
-			// TODO: finish computation of p_i
 			j = 1
 			// jmask = 2^(j-1)
 			jmask := uint32(1)
@@ -207,7 +206,7 @@ func ProofStep2(params GroupParams, priv PrivState, x kyber.Scalar) Proof {
 	// mask = 2^(j-1)
 	j = 1
 	mask = 1
-	for  ; j <= n ; {
+	for ; j <= n ; {
 		if (priv.ell & mask) != 0 {
 			proof.f[j] = group.Scalar().Add(x, priv.a[j])
 		} else {
@@ -241,6 +240,95 @@ func ProofStep2(params GroupParams, priv PrivState, x kyber.Scalar) Proof {
 	return proof
 }
 
-func Verify(params GroupParams, pub PubState, x kyber.Scalar, proof Proof) bool {
-	return false
+// We assume that the checks that the Points are in fact in the right
+// group and the Scalars are in the right range were done at the time
+// the PubState and Proof structures were populated from data received
+// over the network.  This function checks the relations between the
+// elements.
+func Verify(params GroupParams, c []kyber.Point, pub PubState, x kyber.Scalar, proof Proof) bool {
+	N := uint32(len(c))
+	group := params.group
+
+	// Find n := ceil(log_2(N))
+	n := uint32(1)
+	two_n := uint32(2) // 2^n
+	for ; two_n < N ; {
+		n += 1
+		two_n *= 2
+	}
+
+	// Check that the lengths of the arrays are correct
+	if len(pub.cl) != int(n+1) || len(pub.ca) != int(n+1) ||
+			len(pub.cb) != int(n+1) ||
+			len(pub.cd) != int(n) ||
+			len(proof.f) != int(n+1) ||
+			len(proof.za) != int(n+1) ||
+			len(proof.zb) != int(n+1) {
+		fmt.Printf("Inputs not of the correct length\n")
+		return false
+	}
+
+	for j := uint32(1) ; j <= n ; j++ {
+		lhs1 := group.Point().Add(group.Point().Mul(x, pub.cl[j]),
+			pub.ca[j])
+		rhs1 := group.Point().Add(
+			group.Point().Mul(proof.f[j], params.A),
+			group.Point().Mul(proof.za[j], params.B))
+		if !lhs1.Equal(rhs1) {
+			fmt.Printf("Failed equality check 1\n")
+			return false
+		}
+		lhs2 := group.Point().Add(
+			group.Point().Mul(
+				group.Scalar().Sub(x, proof.f[j]),
+				pub.cl[j]),
+			pub.cb[j])
+		rhs2 := group.Point().Mul(proof.zb[j], params.B)
+		if !lhs2.Equal(rhs2) {
+			fmt.Printf("Failed equality check 2\n")
+			return false
+		}
+
+	}
+
+	lhs := group.Point().Null()
+	for i := uint32(0) ; i < two_n ; i++ {
+		fprod := group.Scalar().One()
+		j := uint32(1)
+		mask := uint32(1) // mask = 2^(j-1)
+		for ; j <= n ; {
+			if (i & mask) != 0 {
+				fprod = group.Scalar().Mul(fprod,
+					proof.f[j])
+			} else {
+				fprod = group.Scalar().Mul(fprod,
+					group.Scalar().Sub(x,
+						proof.f[j]))
+			}
+			j++
+			mask *= 2
+		}
+		if i < N {
+			lhs = group.Point().Add(lhs,
+				group.Point().Mul(fprod, c[i]))
+		} else {
+			lhs = group.Point().Add(lhs,
+				group.Point().Mul(fprod, params.Y))
+		}
+	}
+	rhs := group.Point().Mul(proof.zd, params.B)
+	k := uint32(0)
+	xk := group.Scalar().One() // xk = x^k
+	for ; k < n ; {
+		rhs = group.Point().Add(rhs,
+			group.Point().Mul(xk, pub.cd[k]))
+		k++
+		xk = group.Scalar().Mul(xk, x)
+	}
+	if !lhs.Equal(rhs) {
+		fmt.Printf("Failed equality check\n")
+		return false
+	}
+
+	return true
 }

+ 2 - 1
main.go

@@ -42,6 +42,7 @@ func main() {
 	// Which one do we know?  Pick a random 0 <= ell < N
 	Nbig := big.NewInt(int64(N))
 	ell := uint32(random.Int(Nbig, rand).Int64())
+	fmt.Printf("ell = %d\n", ell)
 	var privkey kyber.Scalar
 	var i uint32
 	for i = 0; i < N32; i++ {
@@ -56,7 +57,7 @@ func main() {
 	pub, priv := ProofStep1(params, Cs, ell, privkey)
 	x := GenChallenge(params, pub)
 	proof := ProofStep2(params, priv, x)
-	if Verify(params, pub, x, proof) {
+	if Verify(params, Cs, pub, x, proof) {
 		fmt.Printf("SUCCESS\n")
 	} else {
 		fmt.Printf("VERIFICATION FAILED\n")