client.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. package main
  2. /*
  3. #cgo CFLAGS: -O2
  4. #cgo LDFLAGS: -lcrypto -lm
  5. #include "../c/dpf.h"
  6. #include "../c/okvClient.h"
  7. #include "../c/dpf.c"
  8. #include "../c/okvClient.c"
  9. */
  10. import "C"
  11. //sssssssssss
  12. import (
  13. lib "2PPS/lib"
  14. "bytes"
  15. "crypto/rand"
  16. "crypto/sha256"
  17. "crypto/tls"
  18. "encoding/json"
  19. "fmt"
  20. "math/big"
  21. mr "math/rand"
  22. "net"
  23. "sort"
  24. "strings"
  25. "sync"
  26. "time"
  27. "unsafe"
  28. "golang.org/x/crypto/nacl/box"
  29. )
  30. type tweet struct {
  31. Topics []string
  32. Text string
  33. }
  34. const leader string = "127.0.0.1:4441"
  35. //needs to be changed at leader/follower/client at the same time
  36. const neededSubscriptions = 1
  37. const numClients = 1
  38. var topicList []string
  39. var archiveTopicList []string
  40. //todo! expand this for multiple clients
  41. var archiveInterests = make([]int, 1)
  42. var sharedSecret [numClients][2][32]byte = createSharedSecret()
  43. var wantsArchive = make([]byte, 1)
  44. var dataLen int = 64
  45. var numThreads int = 12
  46. var dbWriteSize int = 4
  47. var leaderPublicKey *[32]byte
  48. var followerPublicKey *[32]byte
  49. var clientPrivateKey *[32]byte
  50. var clientPublicKey *[32]byte
  51. func main() {
  52. //creates test tweets
  53. tweets := make([][]byte, numClients)
  54. for i := range tweets {
  55. tweets[i] = make([]byte, dataLen)
  56. }
  57. for i := 0; i < numClients; i++ {
  58. var tweet []byte
  59. if i == 0 {
  60. topics := []byte("house, mouse;")
  61. text := []byte("I am a house in a mouse;")
  62. tweet = append(tweet, topics...)
  63. tweet = append(tweet, text...)
  64. }
  65. tweet = append(tweet, []byte(";")[0])
  66. //adds padding
  67. length := dataLen - len(tweet)
  68. padding := make([]byte, length)
  69. rand.Read(padding)
  70. tweet = append(tweet, padding...)
  71. tweets[i] = tweet
  72. }
  73. wg := &sync.WaitGroup{}
  74. for i := 0; i < numClients; i++ {
  75. wg.Add(1)
  76. go client(tweets[i], i)
  77. }
  78. wg.Wait()
  79. }
  80. func client(tweet []byte, clientNumber int) {
  81. /*
  82. if len(os.Args) != 4 {
  83. fmt.Println("try again with: numThreads, dataLength, numRows")
  84. return
  85. }
  86. //input when executing is follower amount
  87. serverAmount, _ = strconv.Atoi(os.Args[1])
  88. serverAmount++
  89. dataLen, _ = strconv.Atoi(os.Args[2])
  90. numThreads, _ = strconv.Atoi(os.Args[3])
  91. dbSize, _ = strconv.Atoi(os.Args[4])
  92. */
  93. generatedPublicKey, generatedPrivateKey, err := box.GenerateKey(rand.Reader)
  94. if err != nil {
  95. panic(err)
  96. }
  97. clientPrivateKey = generatedPrivateKey
  98. clientPublicKey = generatedPublicKey
  99. C.initializeCipher()
  100. //initializes the connection to the leader
  101. conf := &tls.Config{
  102. InsecureSkipVerify: true,
  103. }
  104. leaderConn, err := tls.Dial("tcp", leader, conf)
  105. if err != nil {
  106. panic(err)
  107. }
  108. leaderConn.SetDeadline(time.Time{})
  109. //receives topics first so client can participate asap
  110. receiveTopicLists(leaderConn)
  111. //gets the public keys of both servers
  112. var tmpLeaderPubKey [32]byte
  113. _, err = leaderConn.Read(tmpLeaderPubKey[:])
  114. if err != nil {
  115. panic(err)
  116. }
  117. leaderPublicKey = &tmpLeaderPubKey
  118. var tmpFollowerPubKey [32]byte
  119. _, err = leaderConn.Read(tmpFollowerPubKey[:])
  120. if err != nil {
  121. panic(err)
  122. }
  123. followerPublicKey = &tmpFollowerPubKey
  124. //sends own public key
  125. _, err = leaderConn.Write(clientPublicKey[:])
  126. if err != nil {
  127. panic(err)
  128. }
  129. //setup ends above
  130. //while client is active he is always connected and has to participate
  131. for {
  132. //gets current phase
  133. phase := make([]byte, 1)
  134. _, err = leaderConn.Read(phase)
  135. if err != nil {
  136. panic(err)
  137. }
  138. fmt.Println("Phase: ", phase[0])
  139. if phase[0] == 1 {
  140. //gets current dbWriteSize from leader
  141. dbWriteSizeBytes := make([]byte, 4)
  142. _, err = leaderConn.Read(dbWriteSizeBytes)
  143. if err != nil {
  144. panic(err)
  145. }
  146. dbWriteSize = byteToInt(dbWriteSizeBytes)
  147. //todo! put into tweet creation
  148. roundAsBytes := make([]byte, 4)
  149. _, err = leaderConn.Read(roundAsBytes)
  150. if err != nil {
  151. panic(err)
  152. }
  153. //request virtualAddress from leader via pirQuery
  154. encryptedQueryLeader, encryptedQueryFollower := createAuditPIRQuery(clientNumber)
  155. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  156. pos := receiveVirtualAddress(sharedSecret[clientNumber], leaderConn)
  157. //prep the query
  158. dataSize := len(tweet)
  159. querySize := make([]byte, 4)
  160. cQuerySize := C.int(byteToInt(querySize))
  161. var dpfQueryA *C.uchar
  162. var dpfQueryB *C.uchar
  163. C.prepQuery(C.int(pos), C.int(dbWriteSize), (*C.uchar)(&tweet[0]), C.int(dataSize), &cQuerySize, &dpfQueryA, &dpfQueryB)
  164. intQuerySize := int(cQuerySize) //byteToInt(querySize)
  165. //write the query
  166. queryAPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryA), C.int(intQuerySize))
  167. //encrypts queryA and appends it to message
  168. var nonce [24]byte
  169. //fill nonce with randomness
  170. _, err = rand.Read(nonce[:])
  171. if err != nil {
  172. panic("couldn't get randomness for nonce!")
  173. }
  174. dpfQueryAEncrypted := box.Seal(nonce[:], queryAPlaintext, &nonce, leaderPublicKey, clientPrivateKey)
  175. //encrypts queryB and appends it to message
  176. queryBPlaintext := C.GoBytes(unsafe.Pointer(dpfQueryB), C.int(intQuerySize))
  177. //fill nonce with randomness
  178. _, err = rand.Read(nonce[:])
  179. if err != nil {
  180. panic("couldn't get randomness for nonce!")
  181. }
  182. dpfQueryBEncrypted := box.Seal(nonce[:], queryBPlaintext, &nonce, followerPublicKey, clientPrivateKey)
  183. //writes the dpfQuery to the leader
  184. dpfLengthBytes := intToByte(len(dpfQueryAEncrypted))
  185. _, err = leaderConn.Write(dpfLengthBytes)
  186. if err != nil {
  187. panic(err)
  188. }
  189. _, err = leaderConn.Write(dpfQueryAEncrypted)
  190. if err != nil {
  191. panic(err)
  192. }
  193. _, err = leaderConn.Write(dpfQueryBEncrypted)
  194. if err != nil {
  195. panic(err)
  196. }
  197. C.free(unsafe.Pointer(dpfQueryA))
  198. C.free(unsafe.Pointer(dpfQueryB))
  199. } else if phase[0] == 3 {
  200. /*
  201. possible Values
  202. 0 : new client
  203. leader expects sharedSecrets, expects pirQuery
  204. 1 : update needed
  205. leader sends topicList, performs local update of sharedSecret, expects pirQuery
  206. 2 : no update needed
  207. nothing
  208. */
  209. subPhase := make([]byte, 1)
  210. _, err := leaderConn.Read(subPhase)
  211. if err != nil {
  212. panic(err)
  213. }
  214. var encryptedQueryLeader, encryptedQueryFollower []byte
  215. //first time participating
  216. if subPhase[0] == 0 {
  217. receiveTopicLists(leaderConn)
  218. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  219. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  220. }
  221. //updates the topic list and what client is interested in
  222. if subPhase[0] == 1 {
  223. receiveTopicLists(leaderConn)
  224. //updates local secret
  225. for index := 0; index < 2; index++ {
  226. sharedSecret[clientNumber][index] = sha256.Sum256(sharedSecret[clientNumber][index][:])
  227. }
  228. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(int(subPhase[0]), clientNumber)
  229. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, false)
  230. }
  231. receiveTweets(sharedSecret[clientNumber], leaderConn, false)
  232. if len(archiveTopicList) > 0 {
  233. wantsArchive[0] = 0 //archive test
  234. } else {
  235. wantsArchive[0] = 0
  236. }
  237. _, err = leaderConn.Write(wantsArchive)
  238. if err != nil {
  239. panic(err)
  240. }
  241. if wantsArchive[0] == 1 && len(archiveTopicList) > 0 {
  242. encryptedQueryLeader, encryptedQueryFollower = createPIRQuery(-1, clientNumber)
  243. sendQuerys(encryptedQueryLeader, encryptedQueryFollower, leaderConn, true)
  244. receiveTweets(sharedSecret[clientNumber], leaderConn, true)
  245. }
  246. } else {
  247. panic("somethin went wrong")
  248. }
  249. }
  250. }
  251. //creates and sends the pirQuerys for each server
  252. func createPIRQuery(subPhase int, clientNumber int) ([]byte, []byte) {
  253. //later this will be taken from gui, this is only for testing
  254. topicsOfInterest := make([]int, 1)
  255. topicsOfInterest[0] = 1
  256. archiveInterests[0] = 1
  257. tmptopicsOfInterest := make([]int, len(topicsOfInterest))
  258. copy(tmptopicsOfInterest, topicsOfInterest)
  259. tmpNeededSubscriptions := neededSubscriptions
  260. tmpTopicList := make([]string, len(topicList))
  261. copy(tmpTopicList, topicList)
  262. if wantsArchive[0] == 1 && subPhase == -1 {
  263. tmpNeededSubscriptions = len(archiveInterests)
  264. copy(tmptopicsOfInterest, archiveInterests) //archiveInterests from gui
  265. copy(tmpTopicList, archiveTopicList)
  266. }
  267. topicsOfInterestAsBytes := make([][]byte, tmpNeededSubscriptions)
  268. for i := range topicsOfInterestAsBytes {
  269. topicsOfInterestAsBytes[i] = make([]byte, len(tmpTopicList))
  270. }
  271. //creates fake topicsOfInterest if client is boooring
  272. if len(tmptopicsOfInterest) < tmpNeededSubscriptions && subPhase != -1 {
  273. tmptopicsOfInterest = addFakeInterests(neededSubscriptions, len(tmpTopicList), tmptopicsOfInterest, false)
  274. }
  275. for topic, position := range tmptopicsOfInterest {
  276. //change used to be positon-1
  277. topicsOfInterestAsBytes[topic][position-1] = 1
  278. }
  279. //pirQuery [serverAmount][topicsofinterest][topicAmount]byte
  280. pirQuerys := make([][][]byte, 2)
  281. for i := range pirQuerys {
  282. pirQuerys[i] = make([][]byte, len(tmptopicsOfInterest))
  283. for j := range pirQuerys[i] {
  284. pirQuerys[i][j] = make([]byte, len(tmpTopicList))
  285. }
  286. }
  287. //for leader
  288. //pirQuery will be filled with random bits
  289. for topic := range tmptopicsOfInterest {
  290. for index := range tmpTopicList {
  291. bit, err := rand.Int(rand.Reader, big.NewInt(2))
  292. if err != nil {
  293. panic(err)
  294. }
  295. pirQuerys[0][topic][index] = byte(bit.Int64())
  296. }
  297. }
  298. //creating last manually with result and wanted
  299. //if position random result correct -> 0, not correct -> 1
  300. for topic := range tmptopicsOfInterest {
  301. for index := range tmpTopicList {
  302. if pirQuerys[0][topic][index] == topicsOfInterestAsBytes[topic][index] {
  303. pirQuerys[1][topic][index] = 0
  304. } else {
  305. pirQuerys[1][topic][index] = 1
  306. }
  307. }
  308. }
  309. //flattens the querys to be able to send them more efficently
  310. messagesFlattened := make([][]byte, 2)
  311. //adds the sharedSecret to the first pirQuery when first time participating
  312. if subPhase == 0 {
  313. for server := 0; server < 2; server++ {
  314. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  315. }
  316. }
  317. for server := 0; server < 2; server++ {
  318. for topic := range pirQuerys[server] {
  319. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[server][topic][:]...)
  320. }
  321. }
  322. var nonce [24]byte
  323. _, err := rand.Read(nonce[:])
  324. if err != nil {
  325. panic("couldn't get randomness for nonce!")
  326. }
  327. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey)
  328. _, err = rand.Read(nonce[:])
  329. if err != nil {
  330. panic("couldn't get randomness for nonce!")
  331. }
  332. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey)
  333. return encryptedQueryLeader, encryptedQueryFollower
  334. }
  335. func sendQuerys(encryptedQueryLeader, encryptedQueryFollower []byte, leaderConn net.Conn, getArchive bool) {
  336. encryptedLength := len(encryptedQueryLeader)
  337. //sends the pirQuerysLength to the leader
  338. _, err := leaderConn.Write(intToByte(encryptedLength))
  339. if err != nil {
  340. panic(err)
  341. }
  342. //sends the pirQuerys to the leader
  343. _, err = leaderConn.Write(encryptedQueryLeader)
  344. if err != nil {
  345. panic(err)
  346. }
  347. _, err = leaderConn.Write(encryptedQueryFollower)
  348. if err != nil {
  349. panic(err)
  350. }
  351. if getArchive {
  352. leaderConn.Write(intToByte(len(archiveInterests)))
  353. if err != nil {
  354. panic(err)
  355. }
  356. }
  357. }
  358. func receiveVirtualAddress(sharedSecret [2][32]byte, leaderConn net.Conn) int {
  359. virtualAddressByte := make([]byte, 4)
  360. _, err := leaderConn.Read(virtualAddressByte)
  361. if err != nil {
  362. panic(err)
  363. }
  364. //xores the sharedSecret
  365. for h := 0; h < 2; h++ {
  366. for i := 0; i < 4; i++ {
  367. virtualAddressByte[i] = virtualAddressByte[i] ^ sharedSecret[h][i]
  368. }
  369. }
  370. return byteToInt(virtualAddressByte)
  371. }
  372. func receiveTweets(sharedSecret [2][32]byte, leaderConn net.Conn, getArchive bool) int {
  373. tmpNeededSubscriptions := neededSubscriptions
  374. if getArchive {
  375. tmpNeededSubscriptions = len(archiveInterests)
  376. }
  377. for i := 0; i < tmpNeededSubscriptions; i++ {
  378. //client receives tweets
  379. tweetsLengthBytes := make([]byte, 4)
  380. _, err := leaderConn.Read(tweetsLengthBytes)
  381. if err != nil {
  382. panic(err)
  383. }
  384. tweetsLength := byteToInt(tweetsLengthBytes)
  385. tweets := make([]byte, tweetsLength)
  386. _, err = leaderConn.Read(tweets)
  387. if err != nil {
  388. panic(err)
  389. }
  390. //expand sharedSecret so it is of right length
  391. expandBy := len(tweets) / 32
  392. expandedSharedSecrets := make([][]byte, 2)
  393. for i := 0; i < 2; i++ {
  394. for j := 0; j < expandBy; j++ {
  395. expandedSharedSecrets[i] = append(expandedSharedSecrets[i], sharedSecret[i][:]...)
  396. }
  397. }
  398. //xors the received messge into the message to display
  399. for i := 0; i < 2; i++ {
  400. lib.Xor(expandedSharedSecrets[i][:], tweets)
  401. }
  402. //tweets can be displayed
  403. split := strings.Split(string(tweets), ";")
  404. topic := split[0]
  405. text := split[1]
  406. fmt.Println("Topics: ", topic)
  407. fmt.Println("Text: ", text)
  408. }
  409. return 0
  410. }
  411. //creates a shared secret for each server
  412. func createSharedSecret() [numClients][2][32]byte {
  413. var tmpSharedSecret [numClients][2][32]byte
  414. for i := 0; i < numClients; i++ {
  415. for j := 0; j < 2; j++ {
  416. _, err := rand.Read(tmpSharedSecret[i][j][:])
  417. if err != nil {
  418. panic("couldn't get randomness for sharedSecret!")
  419. }
  420. }
  421. }
  422. return tmpSharedSecret
  423. }
  424. func createAuditPIRQuery(clientNumber int) ([]byte, []byte) {
  425. //pirQuery [serverAmount][dbWriteSize]byte
  426. pirQuerys := make([][]byte, 2)
  427. for i := range pirQuerys {
  428. pirQuerys[i] = make([]byte, dbWriteSize)
  429. }
  430. //for leader
  431. //pirQuery will be filled with random bits
  432. for index := range pirQuerys[0] {
  433. bit := mr.Intn(2)
  434. pirQuerys[0][index] = byte(bit)
  435. }
  436. copy(pirQuerys[1], pirQuerys[0])
  437. //the positon the virtual address will be taken from
  438. pos := mr.Intn(dbWriteSize)
  439. pirQuerys[0][pos] = 1
  440. pirQuerys[1][pos] = 0
  441. //flattens the querys to be able to send them more efficently
  442. messagesFlattened := make([][]byte, 2)
  443. //adds the sharedSecret to the pirQuery
  444. for server := 0; server < 2; server++ {
  445. messagesFlattened[server] = append(messagesFlattened[server], sharedSecret[clientNumber][server][:]...)
  446. }
  447. for server := 0; server < 2; server++ {
  448. messagesFlattened[server] = append(messagesFlattened[server], pirQuerys[server][:]...)
  449. }
  450. var nonce [24]byte
  451. _, err := rand.Read(nonce[:])
  452. if err != nil {
  453. panic("couldn't get randomness for nonce!")
  454. }
  455. encryptedQueryLeader := box.Seal(nonce[:], messagesFlattened[0], &nonce, leaderPublicKey, clientPrivateKey)
  456. _, err = rand.Read(nonce[:])
  457. if err != nil {
  458. panic("couldn't get randomness for nonce!")
  459. }
  460. encryptedQueryFollower := box.Seal(nonce[:], messagesFlattened[1], &nonce, followerPublicKey, clientPrivateKey)
  461. return encryptedQueryLeader, encryptedQueryFollower
  462. }
  463. //generates a topicOfInterest array with random values
  464. func addFakeInterests(length, max int, topicsOfInterest []int, doAuditing bool) []int {
  465. fakeTopicsOfInterest := make([]int, length)
  466. maxInt := max
  467. //fills the array with unique random ascending values ranging from 0 to max
  468. for i := 0; i < length; i++ {
  469. fakeTopicsOfInterest[i] = mr.Intn(maxInt)
  470. for j := 0; j < i; j++ {
  471. if fakeTopicsOfInterest[i] == fakeTopicsOfInterest[j] {
  472. i--
  473. break
  474. }
  475. }
  476. }
  477. if doAuditing {
  478. sort.Ints(fakeTopicsOfInterest)
  479. return fakeTopicsOfInterest
  480. }
  481. //adds unique and new random numbers to topicOfInterests until length is satisfied
  482. for _, number := range fakeTopicsOfInterest {
  483. if !inList(number, topicsOfInterest) {
  484. topicsOfInterest = append(topicsOfInterest, number)
  485. }
  486. if len(topicsOfInterest) == neededSubscriptions {
  487. break
  488. }
  489. }
  490. sort.Ints(topicsOfInterest)
  491. return topicsOfInterest
  492. }
  493. func inList(number int, list []int) bool {
  494. for _, element := range list {
  495. if element == number {
  496. return true
  497. }
  498. }
  499. return false
  500. }
  501. func receiveTopicLists(leaderConn net.Conn) {
  502. for i := 0; i < 2; i++ {
  503. topicListLength := make([]byte, 4)
  504. _, err := leaderConn.Read(topicListLength)
  505. if err != nil {
  506. panic(err)
  507. }
  508. recTopicList := make([]byte, byteToInt(topicListLength))
  509. _, err = leaderConn.Read(recTopicList[:])
  510. if err != nil {
  511. panic(err)
  512. }
  513. var tmpTopicList []string
  514. arrayReader := bytes.NewReader(recTopicList[:])
  515. json.NewDecoder(arrayReader).Decode(&tmpTopicList)
  516. if i == 0 {
  517. topicList = tmpTopicList
  518. } else {
  519. archiveTopicList = tmpTopicList
  520. }
  521. }
  522. }
  523. func intToByte(myInt int) (retBytes []byte) {
  524. retBytes = make([]byte, 4)
  525. retBytes[3] = byte((myInt >> 24) & 0xff)
  526. retBytes[2] = byte((myInt >> 16) & 0xff)
  527. retBytes[1] = byte((myInt >> 8) & 0xff)
  528. retBytes[0] = byte(myInt & 0xff)
  529. return
  530. }
  531. func byteToInt(myBytes []byte) (x int) {
  532. x = int(myBytes[3])<<24 + int(myBytes[2])<<16 + int(myBytes[1])<<8 + int(myBytes[0])
  533. return
  534. }