client.go 17 KB

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