You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.5 KiB
84 lines
2.5 KiB
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
|
|
}
|