mirror of
https://github.com/saymrwulf/swisspost-evoting-go-poc.git
synced 2026-09-04 20:23:55 +00:00
53 lines
2 KiB
Go
53 lines
2 KiB
Go
|
|
package zkp
|
||
|
|
|
||
|
|
import (
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/user/evote/pkg/elgamal"
|
||
|
|
"github.com/user/evote/pkg/hash"
|
||
|
|
emath "github.com/user/evote/pkg/math"
|
||
|
|
)
|
||
|
|
|
||
|
|
func hashStr(s string) hash.HashableString { return hash.HashableString{Value: s} }
|
||
|
|
|
||
|
|
// TestPlaintextEqualityProofSound confirms the proof primitive is sound when
|
||
|
|
// used correctly: it accepts two single-component ciphertexts that encrypt the
|
||
|
|
// SAME plaintext under different public keys, and rejects when the plaintexts
|
||
|
|
// differ. (Finding F5 was a caller error in the old vote path, not a defect in
|
||
|
|
// this primitive — this test pins the correct contract.)
|
||
|
|
func TestPlaintextEqualityProofSound(t *testing.T) {
|
||
|
|
group := testGroup(t)
|
||
|
|
zq := emath.ZqGroupFromGqGroup(group)
|
||
|
|
g := group.Generator()
|
||
|
|
|
||
|
|
// Two independent public keys h = g^x1, h' = g^x2.
|
||
|
|
h := g.Exponentiate(emath.RandomZqElement(zq))
|
||
|
|
hPrime := g.Exponentiate(emath.RandomZqElement(zq))
|
||
|
|
pk1 := elgamal.PublicKey{Elements: emath.GqVectorOf(h)}
|
||
|
|
pk2 := elgamal.PublicKey{Elements: emath.GqVectorOf(hPrime)}
|
||
|
|
|
||
|
|
m := emath.RandomGqElement(group)
|
||
|
|
r0 := emath.RandomZqElement(zq)
|
||
|
|
r1 := emath.RandomZqElement(zq)
|
||
|
|
c1 := elgamal.Encrypt(elgamal.NewMessage(emath.GqVectorOf(m)), r0, pk1)
|
||
|
|
c2 := elgamal.Encrypt(elgamal.NewMessage(emath.GqVectorOf(m)), r1, pk2)
|
||
|
|
|
||
|
|
proof := GenPlaintextEqualityProof(c1, c2, h, hPrime, r0, r1, group)
|
||
|
|
if !VerifyPlaintextEqualityProof(c1, c2, h, hPrime, proof, group) {
|
||
|
|
t.Fatal("honest same-plaintext proof rejected")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Different plaintext in c2 must fail.
|
||
|
|
m2 := m.Multiply(g)
|
||
|
|
c2bad := elgamal.Encrypt(elgamal.NewMessage(emath.GqVectorOf(m2)), r1, pk2)
|
||
|
|
if VerifyPlaintextEqualityProof(c1, c2bad, h, hPrime, proof, group) {
|
||
|
|
t.Fatal("proof verified against a different plaintext")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Aux-info binding: mismatched aux must fail.
|
||
|
|
p2 := GenPlaintextEqualityProof(c1, c2, h, hPrime, r0, r1, group, hashStr("ctx-A"))
|
||
|
|
if VerifyPlaintextEqualityProof(c1, c2, h, hPrime, p2, group, hashStr("ctx-B")) {
|
||
|
|
t.Fatal("proof verified under mismatched aux info")
|
||
|
|
}
|
||
|
|
}
|