mirror of
https://github.com/saymrwulf/swisspost-evoting-go-poc.git
synced 2026-05-14 20:58:03 +00:00
Proof-of-concept reimplementation of the Swiss Post e-voting cryptographic protocol in Go. Single binary, 52 source files, 2 dependencies. Covers ElGamal encryption, Bayer-Groth verifiable shuffles, zero-knowledge proofs, return codes, and a full election ceremony demo.
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package math
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
)
|
|
|
|
// ZqGroup represents the group of integers modulo q.
|
|
type ZqGroup struct {
|
|
q *big.Int
|
|
identity ZqElement
|
|
}
|
|
|
|
// NewZqGroup creates a new ZqGroup with the given order q.
|
|
func NewZqGroup(q *big.Int) (*ZqGroup, error) {
|
|
if q == nil {
|
|
return nil, fmt.Errorf("q must not be nil")
|
|
}
|
|
if q.Cmp(big.NewInt(2)) < 0 {
|
|
return nil, fmt.Errorf("q must be >= 2")
|
|
}
|
|
group := &ZqGroup{
|
|
q: new(big.Int).Set(q),
|
|
}
|
|
group.identity = ZqElement{value: big.NewInt(0), group: group}
|
|
return group, nil
|
|
}
|
|
|
|
// ZqGroupFromGqGroup creates a ZqGroup with the same order as the given GqGroup.
|
|
func ZqGroupFromGqGroup(gqGroup *GqGroup) *ZqGroup {
|
|
group := &ZqGroup{
|
|
q: new(big.Int).Set(gqGroup.q),
|
|
}
|
|
group.identity = ZqElement{value: big.NewInt(0), group: group}
|
|
return group
|
|
}
|
|
|
|
// Q returns the group order q.
|
|
func (g *ZqGroup) Q() *big.Int {
|
|
return new(big.Int).Set(g.q)
|
|
}
|
|
|
|
// Identity returns the identity element (0).
|
|
func (g *ZqGroup) Identity() ZqElement {
|
|
return g.identity
|
|
}
|
|
|
|
// IsGroupMember checks if value is in Z_q: value >= 0 AND value < q.
|
|
func (g *ZqGroup) IsGroupMember(value *big.Int) bool {
|
|
if value == nil {
|
|
return false
|
|
}
|
|
return value.Sign() >= 0 && value.Cmp(g.q) < 0
|
|
}
|
|
|
|
// Equals checks if two groups have the same order.
|
|
func (g *ZqGroup) Equals(other *ZqGroup) bool {
|
|
if other == nil {
|
|
return false
|
|
}
|
|
return g.q.Cmp(other.q) == 0
|
|
}
|
|
|
|
// String returns a string representation.
|
|
func (g *ZqGroup) String() string {
|
|
return fmt.Sprintf("ZqGroup(q=%v)", g.q)
|
|
}
|