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.
71 lines
1.5 KiB
Go
71 lines
1.5 KiB
Go
package mixnet
|
||
|
||
import (
|
||
"math/big"
|
||
|
||
emath "github.com/user/evote/pkg/math"
|
||
)
|
||
|
||
// Permutation represents a random permutation of [0, N).
|
||
type Permutation struct {
|
||
table []int
|
||
}
|
||
|
||
// GenPermutation generates a random permutation of size N using Fisher-Yates.
|
||
func GenPermutation(n int) Permutation {
|
||
table := make([]int, n)
|
||
for i := range table {
|
||
table[i] = i
|
||
}
|
||
for i := 0; i < n; i++ {
|
||
// offset = random integer in [0, n-i)
|
||
max := big.NewInt(int64(n - i))
|
||
offset := emath.RandomBigInt(max).Int64()
|
||
// Swap table[i] with table[i+offset]
|
||
j := i + int(offset)
|
||
table[i], table[j] = table[j], table[i]
|
||
}
|
||
return Permutation{table: table}
|
||
}
|
||
|
||
// Apply returns π[i].
|
||
func (p Permutation) Apply(i int) int {
|
||
return p.table[i]
|
||
}
|
||
|
||
// Size returns N.
|
||
func (p Permutation) Size() int {
|
||
return len(p.table)
|
||
}
|
||
|
||
// Table returns a copy of the permutation table.
|
||
func (p Permutation) Table() []int {
|
||
t := make([]int, len(p.table))
|
||
copy(t, p.table)
|
||
return t
|
||
}
|
||
|
||
// GetMatrixDimensions computes size-optimal m×n dimensions for a vector of size N.
|
||
// Returns (m, n) where m <= n, m*n = N, and m is the largest factor ≤ √N.
|
||
func GetMatrixDimensions(vectorSize int) (int, int) {
|
||
if vectorSize < 2 {
|
||
panic("size must be >= 2")
|
||
}
|
||
m := 1
|
||
n := vectorSize
|
||
sqrtN := isqrt(vectorSize)
|
||
for i := sqrtN; i > 1; i-- {
|
||
if vectorSize%i == 0 {
|
||
m = i
|
||
n = vectorSize / i
|
||
break
|
||
}
|
||
}
|
||
return m, n
|
||
}
|
||
|
||
func isqrt(n int) int {
|
||
x := int64(n)
|
||
s := new(big.Int).Sqrt(big.NewInt(x))
|
||
return int(s.Int64())
|
||
}
|