|
@@ -21,7 +21,9 @@ import (
|
|
"fmt"
|
|
"fmt"
|
|
"math"
|
|
"math"
|
|
"math/big"
|
|
"math/big"
|
|
|
|
+ mr "math/rand"
|
|
"net"
|
|
"net"
|
|
|
|
+ "sort"
|
|
"strconv"
|
|
"strconv"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
@@ -69,7 +71,7 @@ var numThreads = 12
|
|
var dataLength int = 32
|
|
var dataLength int = 32
|
|
|
|
|
|
//this needs to be adjusted peridodically
|
|
//this needs to be adjusted peridodically
|
|
-var dbWriteSize int = 2
|
|
|
|
|
|
+var dbWriteSize int = 20
|
|
|
|
|
|
//counts the number of rounds
|
|
//counts the number of rounds
|
|
var round int = 1
|
|
var round int = 1
|
|
@@ -89,6 +91,7 @@ const publisherRounds int = 3
|
|
var publisherAmount float64
|
|
var publisherAmount float64
|
|
var publisherHistory [publisherRounds]int
|
|
var publisherHistory [publisherRounds]int
|
|
|
|
|
|
|
|
+//todo! handle client dc during phase1/3
|
|
func main() {
|
|
func main() {
|
|
|
|
|
|
generatedPublicKey, generatedPrivateKey, err := box.GenerateKey(rand.Reader)
|
|
generatedPublicKey, generatedPrivateKey, err := box.GenerateKey(rand.Reader)
|
|
@@ -256,6 +259,18 @@ func main() {
|
|
for i := 0; i < dbWriteSize; i++ {
|
|
for i := 0; i < dbWriteSize; i++ {
|
|
C.createDb(C.int(1), C.int(dataLength))
|
|
C.createDb(C.int(1), C.int(dataLength))
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ //creates a new db containing virtual addresses for auditing
|
|
|
|
+ virtualAddresses := createVirtualAddresses()
|
|
|
|
+
|
|
|
|
+ //send all virtualAddresses to follower
|
|
|
|
+ for i := 0; i <= dbWriteSize; i++ {
|
|
|
|
+ _, err = followerConnection.Write(intToByte(virtualAddresses[i]))
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
for id := 0; id < numThreads; id++ {
|
|
for id := 0; id < numThreads; id++ {
|
|
wg.Add(1)
|
|
wg.Add(1)
|
|
|
|
|
|
@@ -265,7 +280,7 @@ func main() {
|
|
}
|
|
}
|
|
followerConnection.SetDeadline(time.Time{})
|
|
followerConnection.SetDeadline(time.Time{})
|
|
|
|
|
|
- go phase1(id, phase, followerConnection, wg, m, startTime)
|
|
|
|
|
|
+ go phase1(id, phase, followerConnection, wg, m, startTime, virtualAddresses)
|
|
}
|
|
}
|
|
|
|
|
|
wg.Wait()
|
|
wg.Wait()
|
|
@@ -314,7 +329,7 @@ func main() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-func phase1(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGroup, m sync.Mutex, startTime time.Time) {
|
|
|
|
|
|
+func phase1(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGroup, m sync.Mutex, startTime time.Time, virtualAddresses []int) {
|
|
|
|
|
|
roundAsBytes := intToByte(round)
|
|
roundAsBytes := intToByte(round)
|
|
gotClient := make([]byte, 1)
|
|
gotClient := make([]byte, 1)
|
|
@@ -375,6 +390,13 @@ func phase1(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
panic(err)
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //auditing starts here
|
|
|
|
+ var clientKeys = clientData[clientConnection.RemoteAddr()]
|
|
|
|
+ clientKeys, pirQuery := handlePirQuery(clientKeys, clientConnection, followerConnection, 0, true)
|
|
|
|
+ getSendVirtualAddress(pirQuery[0], virtualAddresses, clientKeys.SharedSecret, clientConnection, followerConnection)
|
|
|
|
+
|
|
|
|
+ clientData[clientConnection.RemoteAddr()] = clientKeys
|
|
|
|
+
|
|
//accept dpfQuery from client
|
|
//accept dpfQuery from client
|
|
dpfLengthBytes := make([]byte, 4)
|
|
dpfLengthBytes := make([]byte, 4)
|
|
_, err = clientConnection.Read(dpfLengthBytes)
|
|
_, err = clientConnection.Read(dpfLengthBytes)
|
|
@@ -414,15 +436,15 @@ func phase1(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
panic("dpfQueryA decryption not ok")
|
|
panic("dpfQueryA decryption not ok")
|
|
}
|
|
}
|
|
|
|
|
|
- vector := make([]byte, dbSize*16)
|
|
|
|
- //var str string
|
|
|
|
|
|
+ //todo!
|
|
|
|
+ //eval for pos that is not in db then exchange with follower to drop or allow
|
|
|
|
+
|
|
//run dpf, xor into local db
|
|
//run dpf, xor into local db
|
|
for i := 0; i < dbSize; i++ {
|
|
for i := 0; i < dbSize; i++ {
|
|
ds := int(C.db[i].dataSize)
|
|
ds := int(C.db[i].dataSize)
|
|
dataShare := make([]byte, ds)
|
|
dataShare := make([]byte, ds)
|
|
- pos := C.getUint128_t(C.int(i))
|
|
|
|
- v := C.evalDPF(C.ctx[id], (*C.uchar)(&dpfQueryA[0]), pos, C.int(ds), (*C.uchar)(&dataShare[0]))
|
|
|
|
- copy(vector[i*16:(i+1)*16], C.GoBytes(unsafe.Pointer(&v), 16))
|
|
|
|
|
|
+ pos := C.getUint128_t(C.int(virtualAddresses[i]))
|
|
|
|
+ C.evalDPF(C.ctx[id], (*C.uchar)(&dpfQueryA[0]), pos, C.int(ds), (*C.uchar)(&dataShare[0]))
|
|
for j := 0; j < ds; j++ {
|
|
for j := 0; j < ds; j++ {
|
|
db[i][j] = db[i][j] ^ dataShare[j]
|
|
db[i][j] = db[i][j] ^ dataShare[j]
|
|
}
|
|
}
|
|
@@ -726,7 +748,7 @@ func phase3(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
|
|
|
|
if subPhase[0] == 0 {
|
|
if subPhase[0] == 0 {
|
|
sendTopicLists(clientConnection)
|
|
sendTopicLists(clientConnection)
|
|
- clientKeys, _ = handlePirQuery(clientKeys, clientConnection, followerConnection, int(subPhase[0]))
|
|
|
|
|
|
+ clientKeys, _ = handlePirQuery(clientKeys, clientConnection, followerConnection, int(subPhase[0]), false)
|
|
} else if subPhase[0] == 1 {
|
|
} else if subPhase[0] == 1 {
|
|
sendTopicLists(clientConnection)
|
|
sendTopicLists(clientConnection)
|
|
|
|
|
|
@@ -734,7 +756,7 @@ func phase3(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
sharedSecret = sha256.Sum256(sharedSecret[:])
|
|
sharedSecret = sha256.Sum256(sharedSecret[:])
|
|
clientKeys.SharedSecret = sharedSecret
|
|
clientKeys.SharedSecret = sharedSecret
|
|
|
|
|
|
- clientKeys, _ = handlePirQuery(clientKeys, clientConnection, followerConnection, int(subPhase[0]))
|
|
|
|
|
|
+ clientKeys, _ = handlePirQuery(clientKeys, clientConnection, followerConnection, int(subPhase[0]), false)
|
|
}
|
|
}
|
|
|
|
|
|
getSendTweets(clientKeys, nil, clientConnection, followerConnection)
|
|
getSendTweets(clientKeys, nil, clientConnection, followerConnection)
|
|
@@ -751,7 +773,7 @@ func phase3(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
}
|
|
}
|
|
|
|
|
|
if wantsArchive[0] == 1 && archiveTopicAmount > 0 {
|
|
if wantsArchive[0] == 1 && archiveTopicAmount > 0 {
|
|
- _, archiveQuerys := handlePirQuery(clientKeys, clientConnection, followerConnection, -1)
|
|
|
|
|
|
+ _, archiveQuerys := handlePirQuery(clientKeys, clientConnection, followerConnection, -1, false)
|
|
getSendTweets(clientKeys, archiveQuerys, clientConnection, followerConnection)
|
|
getSendTweets(clientKeys, archiveQuerys, clientConnection, followerConnection)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -784,6 +806,58 @@ func phase3(id int, phase []byte, followerConnection net.Conn, wg *sync.WaitGrou
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func createVirtualAddresses() []int {
|
|
|
|
+ //array will be filled with unique random ascending values
|
|
|
|
+ //adapted from: https://stackoverflow.com/questions/20039025/java-array-of-unique-randomly-generated-integers
|
|
|
|
+ //+1 to have a position to evaluate each received message
|
|
|
|
+ arraySize := dbWriteSize + 1
|
|
|
|
+ var maxInt int = int(math.Pow(2, 31))
|
|
|
|
+ virtualAddresses := make([]int, arraySize)
|
|
|
|
+ for i := 0; i < arraySize; i++ {
|
|
|
|
+ virtualAddresses[i] = mr.Intn(maxInt)
|
|
|
|
+
|
|
|
|
+ for j := 0; j < i; j++ {
|
|
|
|
+ if virtualAddresses[i] == virtualAddresses[j] {
|
|
|
|
+ i--
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sort.Ints(virtualAddresses)
|
|
|
|
+ return virtualAddresses
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getSendVirtualAddress(pirQuery []byte, virtualAddresses []int, sharedSecret [32]byte, clientConnection, followerConnection net.Conn) {
|
|
|
|
+ virtualAddress := make([]byte, 4)
|
|
|
|
+ for _, num := range pirQuery {
|
|
|
|
+ if num == 1 {
|
|
|
|
+ currentAddress := intToByte(virtualAddresses[num])
|
|
|
|
+ for i := 0; i < 4; i++ {
|
|
|
|
+ virtualAddress[i] = virtualAddress[i] ^ currentAddress[i]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for i := 0; i < 4; i++ {
|
|
|
|
+ virtualAddress[i] = virtualAddress[i] ^ sharedSecret[i]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ followersAddress := make([]byte, 4)
|
|
|
|
+ _, err := followerConnection.Read(followersAddress)
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for i := 0; i < 4; i++ {
|
|
|
|
+ virtualAddress[i] = virtualAddress[i] ^ followersAddress[i]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _, err = clientConnection.Write(virtualAddress)
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
func getSendTweets(clientKeys clientKeys, archiveQuerys [][]byte, clientConnection, followerConnection net.Conn) {
|
|
func getSendTweets(clientKeys clientKeys, archiveQuerys [][]byte, clientConnection, followerConnection net.Conn) {
|
|
tmpNeededSubscriptions := neededSubscriptions
|
|
tmpNeededSubscriptions := neededSubscriptions
|
|
if archiveQuerys != nil {
|
|
if archiveQuerys != nil {
|
|
@@ -838,7 +912,7 @@ func getSendTweets(clientKeys clientKeys, archiveQuerys [][]byte, clientConnecti
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-func handlePirQuery(clientKeys clientKeys, clientConnection net.Conn, followerConnection net.Conn, subPhase int) (clientKeys, [][]byte) {
|
|
|
|
|
|
+func handlePirQuery(clientKeys clientKeys, clientConnection net.Conn, followerConnection net.Conn, subPhase int, doAuditing bool) (clientKeys, [][]byte) {
|
|
|
|
|
|
clientPublicKey := clientKeys.PublicKey
|
|
clientPublicKey := clientKeys.PublicKey
|
|
|
|
|
|
@@ -880,6 +954,10 @@ func handlePirQuery(clientKeys clientKeys, clientConnection net.Conn, followerCo
|
|
tmpNeededSubscriptions = byteToInt(archiveNeededSubscriptions)
|
|
tmpNeededSubscriptions = byteToInt(archiveNeededSubscriptions)
|
|
tmpTopicAmount = archiveTopicAmount
|
|
tmpTopicAmount = archiveTopicAmount
|
|
}
|
|
}
|
|
|
|
+ if doAuditing {
|
|
|
|
+ tmpNeededSubscriptions = 1
|
|
|
|
+ tmpTopicAmount = dbWriteSize
|
|
|
|
+ }
|
|
|
|
|
|
//send length to follower
|
|
//send length to follower
|
|
_, err = followerConnection.Write(msgLengthBytes)
|
|
_, err = followerConnection.Write(msgLengthBytes)
|
|
@@ -902,7 +980,6 @@ func handlePirQuery(clientKeys clientKeys, clientConnection net.Conn, followerCo
|
|
|
|
|
|
//if sharedSecret is send
|
|
//if sharedSecret is send
|
|
if subPhase == 0 {
|
|
if subPhase == 0 {
|
|
- //bs!
|
|
|
|
var tmpSharedSecret [32]byte
|
|
var tmpSharedSecret [32]byte
|
|
for index := 0; index < 32; index++ {
|
|
for index := 0; index < 32; index++ {
|
|
tmpSharedSecret[index] = decrypted[index]
|
|
tmpSharedSecret[index] = decrypted[index]
|
|
@@ -921,8 +998,8 @@ func handlePirQuery(clientKeys clientKeys, clientConnection net.Conn, followerCo
|
|
pirQuerys[i] = pirQueryFlattened[i*tmpTopicAmount : (i+1)*tmpTopicAmount]
|
|
pirQuerys[i] = pirQueryFlattened[i*tmpTopicAmount : (i+1)*tmpTopicAmount]
|
|
}
|
|
}
|
|
|
|
|
|
- //sets the pirQuery for the client in case whe are not archiving
|
|
|
|
- if subPhase != -1 {
|
|
|
|
|
|
+ //sets the pirQuery for the client in case whe are not archiving, and not Auditing
|
|
|
|
+ if subPhase != -1 && !doAuditing {
|
|
clientKeys.PirQuery = pirQuerys
|
|
clientKeys.PirQuery = pirQuerys
|
|
}
|
|
}
|
|
|
|
|