Vassago/server.go

84 lines
2.5 KiB
Go
Raw Permalink Normal View History

2019-03-20 19:24:59 +00:00
package vassago
import (
"git.openprivacy.ca/lib.surveillance.resistant.tech/trostle-parrish"
"math/big"
"sync"
)
// Server implements the server portion of a Vassago system.
type Server struct {
numberOfBuckets uint
bucketBuffer []byte
currentBucketPointer uint
lengthOfBuckets uint
itemLength uint
}
// NewServer sets up a new server with a given number of buckets.
func NewServer(numberOfBuckets uint, lengthOfBuckets uint, itemLength uint) Server {
var server Server
server.bucketBuffer = make([]byte, numberOfBuckets*lengthOfBuckets*itemLength)
server.numberOfBuckets = numberOfBuckets
server.lengthOfBuckets = lengthOfBuckets
server.itemLength = itemLength
server.currentBucketPointer = 0
return server
}
// Add item to bucket appends an item to the most recent bucket
func (s *Server) AddItem(item []byte) {
copy(s.bucketBuffer[s.currentBucketPointer:], item[:])
s.currentBucketPointer += s.itemLength
if s.currentBucketPointer >= (s.numberOfBuckets*s.lengthOfBuckets*s.itemLength) {
s.currentBucketPointer = 0
}
}
// PrivateLookup takes in a request from a client and calculates the response
// Note this method executes an operation over every item in every bucket.
func (s Server) PrivateLookup(request []trostle_parrish.Ciphertext) (result []trostle_parrish.Ciphertext) {
maxBucketLength := s.lengthOfBuckets*s.itemLength
var wg sync.WaitGroup
result = make([]trostle_parrish.Ciphertext, maxBucketLength)
reduce := make([][]trostle_parrish.Ciphertext, maxBucketLength)
for i := range reduce {
reduce[i] = make([]trostle_parrish.Ciphertext, s.numberOfBuckets)
}
calc := func(bucket int, startIndex int) {
for i:=0; i< int(maxBucketLength); i++{
index := (startIndex + i) % int(s.numberOfBuckets*maxBucketLength)
m := s.bucketBuffer[index]
reduce[i][bucket] = big.NewInt(0).Mul(big.NewInt(int64(m)), request[bucket])
}
wg.Done()
}
// Spin up a go routine for each bucket.
for x := 0; x < int(s.numberOfBuckets); x++ {
wg.Add(1)
startIndexForX := int(s.currentBucketPointer) - (int(maxBucketLength)*(x+1))
if startIndexForX < 0 {
startIndexForX = int(s.numberOfBuckets*s.lengthOfBuckets*s.itemLength) + startIndexForX
}
go calc(x, startIndexForX)
}
// Wait for all the go routines to finish
wg.Wait()
// Add each result together.
for i := range reduce {
total := big.NewInt(0)
for j := 0; j < int(s.numberOfBuckets); j++ {
total = trostle_parrish.Add(total, reduce[i][j])
}
result[i] = total
}
return result
}