From 06d1065bb91fc2b2ddc20195b58a9e8051a67a6c Mon Sep 17 00:00:00 2001 From: David Florness Date: Mon, 8 Jun 2020 22:51:10 -0600 Subject: [PATCH] Find the constant term of the result polynomial --- linalg.go | 26 ++++++++++++++++---------- voter.go | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/linalg.go b/linalg.go index 6b75606..42c7355 100644 --- a/linalg.go +++ b/linalg.go @@ -6,26 +6,32 @@ import ( type Matrix [][]big.Rat +func (M Matrix) Rows() int { + return len(M) +} + +func (M Matrix) Cols() int { + if len(M) == 0 { + return 0 + } + return len(M[0]) +} + func (M Matrix) RREF() { lead := 0 - rowCount := len(M) - if rowCount == 0 { - return - } - columnCount := len(M[0]) zero := big.NewRat(0, 1) - for r := 0; r < rowCount; r++ { - if lead >= columnCount { + for r := 0; r < M.Rows(); r++ { + if lead >= M.Cols() { return } i := r for M[i][lead].Cmp(zero) == 0 { i++ - if rowCount == i { + if M.Rows() == i { i = r lead++ - if columnCount == lead { + if M.Cols() == lead { return } } @@ -36,7 +42,7 @@ func (M Matrix) RREF() { for j := range M[r] { M[r][j].Mul(&M[r][j], f) } - for i = 0; i < rowCount; i++ { + for i = 0; i < M.Rows(); i++ { if i != r { f.Set(&M[i][lead]) for j, e := range M[r] { diff --git a/voter.go b/voter.go index 6d3d266..67169a6 100644 --- a/voter.go +++ b/voter.go @@ -188,7 +188,7 @@ func findPeers(closeElection <-chan int) { discovery.Advertise(me.ctx, routingDiscovery, string(rendezvousNonce)) logger.Info("successfully announced!") - logger.Info("searching for other voters...") + fmt.Println("finding other voters...") peerChan, err := routingDiscovery.FindPeers(me.ctx, string(rendezvousNonce)) if err != nil { panic(err) @@ -203,7 +203,7 @@ func findPeers(closeElection <-chan int) { if peer.ID == me.ID() { continue } - logger.Info("found voter:", peer) + fmt.Printf("found voter: %s\n", peer) logger.Info("connecting to:", peer) err = me.Connect(me.ctx, peer) @@ -230,7 +230,7 @@ func findPeers(closeElection <-chan int) { func (voter *Voter) fetchNumber(cmd string, args ...string) *big.Int { printErr := func(err error, msg string) { - logger.Errorf("%s: %s fetcing `%s'; retrying in 2 seconds", + logger.Errorf("%s: %s while fetcing `%s'; retrying in 2 seconds", voter.addrInfo.ID, msg, cmd) time.Sleep(time.Second * 2) } @@ -289,11 +289,13 @@ func startVoting() { logger.Infof("our input: %s", me.input) ballot := vote(candidates) + logger.Info("our ballot:", ballot) // no +1 since we want degree k-1 where k is total number of voters me.polyMu.Lock() me.poly = NewRandomPoly(uint(len(election.remoteVoters)), 1024, ballot) me.polyMu.Unlock() + logger.Infof("our constant: %s", me.poly.constant) // get outputs var wg sync.WaitGroup @@ -314,6 +316,7 @@ func startVoting() { me.sum.Add(me.sum, voter.output) } me.sumMu.Unlock() + logger.Infof("our sum: %s", me.sum) // get sums for _, voter := range election.remoteVoters { @@ -327,6 +330,40 @@ func startVoting() { } wg.Wait() + mat := constructPolyMatrix() + mat.RREF() + + result := mat[0][len(mat[0])-1] + // temporary select {} } + +func constructPolyMatrix() Matrix { + mat := make(Matrix, len(election.remoteVoters) + 1) // row for everyone (including ourselves) + + i := 0 + for _, voter := range election.remoteVoters { + mat[i] = make([]big.Rat, len(mat) + 1) // includes column for sum + row := mat[i] + row[0].SetInt64(1) + var j int64 + for j = 1; j <= int64(len(election.remoteVoters)); j++ { + row[j].SetInt(new(big.Int).Exp(voter.input, big.NewInt(j), nil)) + } + row[j].SetInt(voter.sum) + i++ + } + + // row for ourselves + mat[i] = make([]big.Rat, len(mat) + 1) + row := mat[i] + row[0].SetInt64(1) + var j int64 + for j = 1; j <= int64(len(election.remoteVoters)); j++ { + row[j].SetInt(new(big.Int).Exp(me.input, big.NewInt(j), nil)) + } + row[j].SetInt(me.sum) + + return mat +} -- 2.38.4