// getNotaryPredicate gets the predicate for the proof of correctness of notary ciphertexts: // R_j = r_j*g-hat AND (S_j = -r_j*g_l AND ...) // Since we can't put the minus sign in a predicate, we actually use the following equivalent statement: // R_j = r_j*g-hat AND (S_j = r_j*(-g_l) AND ...) func getNotaryPredicate(amount int) proof.Predicate { preds := make([]proof.Predicate, amount+1) preds[0] = proof.Rep("R_j", "r_j", "g_hat") for l := 0; l < amount; l++ { preds[l+1] = proof.Rep("S_j,"+strconv.Itoa(l), "r_j", "-g_"+strconv.Itoa(l)) } return proof.And(preds...) }
// GetUserPredicate gets the predicate for the proof of correctness of user ciphertexts: // ( R_i = r_i*g-hat AND (C_{i,l} = r_i*g_l AND ...) OR Y = y*g ) // Here R_i = \sum_{j} R_{ij}; same for r_i; C_{i,l} is the l-th ciphertext; // g_l is the l-th base point and Y is the slot owner public key func GetUserPredicate(amount int) proof.Predicate { preds := make([]proof.Predicate, amount+1) preds[0] = proof.Rep("R_i", "r_i", "g_hat") for l := 0; l < amount; l++ { preds[l+1] = proof.Rep("C_i,"+strconv.Itoa(l), "r_i", "g_"+strconv.Itoa(l)) } return proof.Or(proof.And(preds...), proof.Rep("Y", "y", "g")) }
/* Verifies that a blameProof proves a share to be maliciously constructed. * * Arguments * i = the index of the share subject to blame * proof = blameProof that alleges the Dealer to have constructed a bad share. * * Return * an error if the blame is unjustified or nil if the blame is justified. */ func (p *Deal) verifyBlame(i int, bproof *blameProof) error { // Basic sanity checks if i < 0 || i >= p.n { return errors.New("Invalid index. Expected 0 <= i < n") } if err := p.verifySignature(i, &bproof.signature, sigBlameMsg); err != nil { return err } // Verify the Diffie-Hellman shared secret was constructed properly pval := map[string]abstract.Point{"D": bproof.diffieKey, "P": p.pubKey} pred := proof.Rep("D", "x", "P") verifier := pred.Verifier(p.suite, pval) err := proof.HashVerify(p.suite, protocolName, verifier, bproof.proof) if err != nil { return err } // Verify the share is bad. diffieSecret := p.diffieHellmanSecret(bproof.diffieKey) share := p.suite.Secret().Sub(p.secrets[i], diffieSecret) if p.pubPoly.Check(i, share) { return errors.New("Unjustified blame. The share checks out okay.") } return nil }
/* Create a blameProof that the Dealer maliciously constructed a shared secret. * This should be called if verifyShare fails due to the public polynomial * check failing. If it failed for other reasons (such as a bad index) it is not * advised to call this function since the share might actually be valid. * * Arguments * i = the index of the malicious shared secret * gKeyPair = the long term key pair of the insurer of share i * * Return * A blameProof that the Dealer is malicious or nil if an error occurs * An error object denoting the status of the blameProof construction * * TODO: Consider whether it is worthwile to produce some form of blame if * the Dealer gives an invalid index. */ func (p *Deal) blame(i int, gKeyPair *config.KeyPair) (*blameProof, error) { diffieKey := p.suite.Point().Mul(p.pubKey, gKeyPair.Secret) insurerSig := p.sign(i, gKeyPair, sigBlameMsg) choice := make(map[proof.Predicate]int) pred := proof.Rep("D", "x", "P") choice[pred] = 1 rand := p.suite.Cipher(abstract.RandomKey) sval := map[string]abstract.Secret{"x": gKeyPair.Secret} pval := map[string]abstract.Point{"D": diffieKey, "P": p.pubKey} prover := pred.Prover(p.suite, sval, pval, choice) proof, err := proof.HashProve(p.suite, protocolName, rand, prover) if err != nil { return nil, err } return new(blameProof).init(p.suite, diffieKey, proof, insurerSig), nil }
func bifflePred() proof.Predicate { // Branch 0 of either/or proof (for bit=0) rep000 := proof.Rep("Xbar0-X0", "beta0", "G") rep001 := proof.Rep("Ybar0-Y0", "beta0", "H") rep010 := proof.Rep("Xbar1-X1", "beta1", "G") rep011 := proof.Rep("Ybar1-Y1", "beta1", "H") // Branch 1 of either/or proof (for bit=1) rep100 := proof.Rep("Xbar0-X1", "beta1", "G") rep101 := proof.Rep("Ybar0-Y1", "beta1", "H") rep110 := proof.Rep("Xbar1-X0", "beta0", "G") rep111 := proof.Rep("Ybar1-Y0", "beta0", "H") and0 := proof.And(rep000, rep001, rep010, rep011) and1 := proof.And(rep100, rep101, rep110, rep111) or := proof.Or(and0, and1) return or }
// Get the proof predicate for decryption proofs: // PK{ (x) : h = g^x and c2/m = c1^x } func getProofPredicate() proof.Predicate { return proof.And(proof.Rep("h", "x", "g"), proof.Rep("c2/m", "x", "c1")) }