github.com/ahenzinger/simplepir@v0.0.0-20230113230609-e9020b03bf28/pir/pir_test.go (about) 1 package pir 2 3 import ( 4 "encoding/csv" 5 "fmt" 6 "math" 7 "os" 8 "strconv" 9 "testing" 10 "strings" 11 ) 12 13 const LOGQ = uint64(32) 14 const SEC_PARAM = uint64(1 << 10) 15 16 // Test that DB packing methods are correct, when each database entry is ~ 1 Z_p elem. 17 func TestDBMediumEntries(t *testing.T) { 18 N := uint64(4) 19 d := uint64(9) 20 pir := SimplePIR{} 21 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 22 23 vals := []uint64{1, 2, 3, 4} 24 DB := MakeDB(N, d, &p, vals) 25 if DB.Info.Packing != 1 || DB.Info.Ne != 1 { 26 panic("Should not happen.") 27 } 28 29 for i := uint64(0); i < N; i++ { 30 if DB.GetElem(i) != (i + 1) { 31 panic("Failure") 32 } 33 } 34 } 35 36 // Test that DB packing methods are correct, when multiple database entries fit in 1 Z_p elem. 37 func TestDBSmallEntries(t *testing.T) { 38 N := uint64(4) 39 d := uint64(3) 40 pir := SimplePIR{} 41 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 42 43 vals := []uint64{1, 2, 3, 4} 44 DB := MakeDB(N, d, &p, vals) 45 if DB.Info.Packing <= 1 || DB.Info.Ne != 1 { 46 panic("Should not happen.") 47 } 48 49 for i := uint64(0); i < N; i++ { 50 if DB.GetElem(i) != (i + 1) { 51 panic("Failure") 52 } 53 } 54 } 55 56 // Test that DB packing methods are correct, when each database entry requires multiple Z_p elems. 57 func TestDBLargeEntries(t *testing.T) { 58 N := uint64(4) 59 d := uint64(12) 60 pir := SimplePIR{} 61 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 62 63 vals := []uint64{1, 2, 3, 4} 64 DB := MakeDB(N, d, &p, vals) 65 if DB.Info.Packing != 0 || DB.Info.Ne <= 1 { 66 panic("Should not happen.") 67 } 68 69 for i := uint64(0); i < N; i++ { 70 if DB.GetElem(i) != (i + 1) { 71 panic("Failure") 72 } 73 } 74 } 75 76 func TestDBInterleaving(t *testing.T) { 77 N := uint64(16) 78 d := uint64(8) 79 numBytes := uint64(len([]byte("string 16"))) 80 81 DBs := make([]*Database, numBytes) 82 pir := SimplePIR{} 83 p := pir.PickParams(N, d, uint64(1 << 10) /* n */, uint64(32) /* log q */) 84 85 for n:=uint64(0); n<numBytes; n++ { 86 val := make([]uint64, N) 87 for i:=uint64(0); i<N; i++ { 88 arr := []byte("string "+fmt.Sprint(i)) 89 if uint64(len(arr)) > n { 90 val[i] = uint64(arr[n]) 91 } else { 92 val[i] = 0 93 } 94 } 95 DBs[n] = MakeDB(N, d, &p, val) 96 } 97 98 D := pir.ConcatDBs(DBs, &p) 99 100 for i:=uint64(0); i<N; i++ { 101 val := make([]byte, numBytes) 102 for n:=uint64(0); n<numBytes; n++ { 103 val[n] = byte(D.GetElem(i + N*n)) 104 } 105 fmt.Printf("Got '%s' instead of '%s'\n", string(val), "string " + fmt.Sprint(i)) 106 if strings.TrimRight(string(val), "\x00") != "string " + fmt.Sprint(i) { 107 panic("Failure") 108 } 109 } 110 } 111 112 // Print the BW used by SimplePIR 113 func TestSimplePirBW(t *testing.T) { 114 N := uint64(1 << 20) 115 d := uint64(2048) 116 117 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 118 D, _ := strconv.Atoi(os.Getenv("D")) 119 if log_N != 0 { 120 N = uint64(1 << log_N) 121 } 122 if D != 0 { 123 d = uint64(D) 124 } 125 126 pir := SimplePIR{} 127 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 128 DB := SetupDB(N, d, &p) 129 130 fmt.Printf("Executing with entries consisting of %d (>= 1) bits; p is %d; packing factor is %d; number of DB elems per entry is %d.\n", 131 d, p.P, DB.Info.Packing, DB.Info.Ne) 132 133 pir.GetBW(DB.Info, p) 134 } 135 136 // Print the BW used by DoublePIR 137 func TestDoublePirBW(t *testing.T) { 138 N := uint64(1 << 20) 139 d := uint64(2048) 140 141 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 142 D, _ := strconv.Atoi(os.Getenv("D")) 143 if log_N != 0 { 144 N = uint64(1 << log_N) 145 } 146 if D != 0 { 147 d = uint64(D) 148 } 149 150 pir := DoublePIR{} 151 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 152 DB := SetupDB(N, d, &p) 153 154 fmt.Printf("Executing with entries consisting of %d (>= 1) bits; p is %d; packing factor is %d; number of DB elems per entry is %d.\n", 155 d, p.P, DB.Info.Packing, DB.Info.Ne) 156 157 pir.GetBW(DB.Info, p) 158 } 159 160 // Test SimplePIR correctness on DB with short entries. 161 func TestSimplePir(t *testing.T) { 162 N := uint64(1 << 20) 163 d := uint64(8) 164 pir := SimplePIR{} 165 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 166 167 DB := MakeRandomDB(N, d, &p) 168 RunPIR(&pir, DB, p, []uint64{262144}) 169 } 170 171 func TestSimplePirCompressed(t *testing.T) { 172 N := uint64(1 << 20) 173 d := uint64(8) 174 pir := SimplePIR{} 175 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 176 177 DB := MakeRandomDB(N, d, &p) 178 RunPIRCompressed(&pir, DB, p, []uint64{262144}) 179 } 180 181 // Test SimplePIR correctness on DB with long entries 182 func TestSimplePirLongRow(t *testing.T) { 183 N := uint64(1 << 20) 184 d := uint64(32) 185 pir := SimplePIR{} 186 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 187 188 DB := MakeRandomDB(N, d, &p) 189 RunPIR(&pir, DB, p, []uint64{1}) 190 } 191 192 func TestSimplePirLongRowCompressed(t *testing.T) { 193 N := uint64(1 << 20) 194 d := uint64(32) 195 pir := SimplePIR{} 196 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 197 198 DB := MakeRandomDB(N, d, &p) 199 RunPIRCompressed(&pir, DB, p, []uint64{1}) 200 } 201 202 // Test SimplePIR correctness on big DB 203 func TestSimplePirBigDB(t *testing.T) { 204 N := uint64(1 << 25) 205 d := uint64(7) 206 pir := SimplePIR{} 207 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 208 209 DB := MakeRandomDB(N, d, &p) 210 RunPIR(&pir, DB, p, []uint64{0}) 211 } 212 213 func TestSimplePirBigDBCompressed(t *testing.T) { 214 N := uint64(1 << 25) 215 d := uint64(7) 216 pir := SimplePIR{} 217 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 218 219 DB := MakeRandomDB(N, d, &p) 220 RunPIRCompressed(&pir, DB, p, []uint64{0}) 221 } 222 223 // Test SimplePIR correctness on DB with short entries, and batching. 224 func TestSimplePirBatch(t *testing.T) { 225 N := uint64(1 << 20) 226 d := uint64(8) 227 pir := SimplePIR{} 228 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 229 230 DB := MakeRandomDB(N, d, &p) 231 RunPIR(&pir, DB, p, []uint64{0, 0, 0, 0}) 232 } 233 234 func TestSimplePirBatchCompressed(t *testing.T) { 235 N := uint64(1 << 20) 236 d := uint64(8) 237 pir := SimplePIR{} 238 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 239 240 DB := MakeRandomDB(N, d, &p) 241 RunPIRCompressed(&pir, DB, p, []uint64{0, 0, 0, 0}) 242 } 243 244 // Test SimplePIR correctness on DB with long entries, and batching. 245 func TestSimplePirLongRowBatch(t *testing.T) { 246 N := uint64(1 << 20) 247 d := uint64(32) 248 pir := SimplePIR{} 249 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 250 251 DB := MakeRandomDB(N, d, &p) 252 RunPIR(&pir, DB, p, []uint64{0, 0, 0, 0}) 253 } 254 255 func TestSimplePirLongRowBatchCompressed(t *testing.T) { 256 N := uint64(1 << 20) 257 d := uint64(32) 258 pir := SimplePIR{} 259 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 260 261 DB := MakeRandomDB(N, d, &p) 262 RunPIRCompressed(&pir, DB, p, []uint64{0, 0, 0, 0}) 263 } 264 265 // Test DoublePIR correctness on DB with short entries. 266 func TestDoublePir(t *testing.T) { 267 N := uint64(1 << 28) 268 d := uint64(3) 269 pir := DoublePIR{} 270 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 271 272 DB := MakeRandomDB(N, d, &p) 273 RunPIR(&pir, DB, p, []uint64{0}) 274 } 275 276 func TestDoublePirCompressed(t *testing.T) { 277 N := uint64(1 << 22) 278 d := uint64(3) 279 pir := DoublePIR{} 280 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 281 282 DB := MakeRandomDB(N, d, &p) 283 RunPIRCompressed(&pir, DB, p, []uint64{0}) 284 } 285 286 // Test DoublePIR correctness on DB with long entries. 287 func TestDoublePirLongRow(t *testing.T) { 288 N := uint64(1 << 20) 289 d := uint64(32) 290 pir := DoublePIR{} 291 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 292 293 DB := MakeRandomDB(N, d, &p) 294 295 fmt.Printf("Executing with entries consisting of %d (>= 1) bits; p is %d; packing factor is %d; number of DB elems per entry is %d.\n", 296 d, p.P, DB.Info.Packing, DB.Info.Ne) 297 298 RunPIR(&pir, DB, p, []uint64{1 << 19}) 299 } 300 301 func TestDoublePirLongRowCompressed(t *testing.T) { 302 N := uint64(1 << 20) 303 d := uint64(32) 304 pir := DoublePIR{} 305 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 306 307 DB := MakeRandomDB(N, d, &p) 308 309 fmt.Printf("Executing with entries consisting of %d (>= 1) bits; p is %d; packing factor is %d; number of DB elems per entry is %d.\n", 310 d, p.P, DB.Info.Packing, DB.Info.Ne) 311 312 RunPIRCompressed(&pir, DB, p, []uint64{1 << 19}) 313 } 314 315 // Test DoublePIR correctness on big DB 316 func TestDoublePirBigDB(t *testing.T) { 317 N := uint64(1 << 25) 318 d := uint64(7) 319 pir := DoublePIR{} 320 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 321 322 DB := MakeRandomDB(N, d, &p) 323 RunPIR(&pir, DB, p, []uint64{0}) 324 } 325 326 func TestDoublePirBigDBCompressed(t *testing.T) { 327 N := uint64(1 << 23) 328 d := uint64(7) 329 pir := DoublePIR{} 330 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 331 332 DB := MakeRandomDB(N, d, &p) 333 RunPIRCompressed(&pir, DB, p, []uint64{0}) 334 } 335 336 // Test DoublePIR correctness on DB with short entries, and batching. 337 func TestDoublePirBatch(t *testing.T) { 338 N := uint64(1 << 20) 339 d := uint64(8) 340 pir := DoublePIR{} 341 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 342 343 DB := MakeRandomDB(N, d, &p) 344 RunPIR(&pir, DB, p, []uint64{0, 0, 0, 0}) 345 } 346 347 func TestDoublePirBatchCompressed(t *testing.T) { 348 N := uint64(1 << 20) 349 d := uint64(8) 350 pir := DoublePIR{} 351 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 352 353 DB := MakeRandomDB(N, d, &p) 354 RunPIRCompressed(&pir, DB, p, []uint64{0, 0, 0, 0}) 355 } 356 357 // Test DoublePIR correctness on DB with long entries, and batching. 358 func TestDoublePirLongRowBatch(t *testing.T) { 359 N := uint64(1 << 20) 360 d := uint64(32) 361 pir := DoublePIR{} 362 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 363 364 DB := MakeRandomDB(N, d, &p) 365 RunPIR(&pir, DB, p, []uint64{0, 0, 0, 0}) 366 } 367 368 func TestDoublePirLongRowBatchCompressed(t *testing.T) { 369 N := uint64(1 << 20) 370 d := uint64(32) 371 pir := DoublePIR{} 372 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 373 374 DB := MakeRandomDB(N, d, &p) 375 RunPIRCompressed(&pir, DB, p, []uint64{0, 0, 0, 0}) 376 } 377 378 // Benchmark SimplePIR performance. 379 func BenchmarkSimplePirSingle(b *testing.B) { 380 f, err := os.Create("simple-cpu.out") 381 if err != nil { 382 panic("Error creating file") 383 } 384 385 N := uint64(1 << 20) 386 d := uint64(2048) 387 388 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 389 D, _ := strconv.Atoi(os.Getenv("D")) 390 if log_N != 0 { 391 N = uint64(1 << log_N) 392 } 393 if D != 0 { 394 d = uint64(D) 395 } 396 397 pir := SimplePIR{} 398 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 399 400 i := uint64(0) // index to query 401 if i >= p.L*p.M { 402 panic("Index out of dimensions") 403 } 404 405 DB := MakeRandomDB(N, d, &p) 406 var tputs []float64 407 for j := 0; j < 5; j++ { 408 tput, _, _, _ := RunFakePIR(&pir, DB, p, []uint64{i}, f, false) 409 tputs = append(tputs, tput) 410 } 411 fmt.Printf("Avg SimplePIR tput, except for first run: %f MB/s\n", avg(tputs)) 412 fmt.Printf("Std dev of SimplePIR tput, except for first run: %f MB/s\n", stddev(tputs)) 413 } 414 415 // Benchmark DoublePIR performance. 416 func BenchmarkDoublePirSingle(b *testing.B) { 417 f, err := os.Create("double-cpu.out") 418 if err != nil { 419 panic("Error creating file") 420 } 421 422 N := uint64(1 << 20) 423 d := uint64(2048) 424 425 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 426 D, _ := strconv.Atoi(os.Getenv("D")) 427 if log_N != 0 { 428 N = uint64(1 << log_N) 429 } 430 if D != 0 { 431 d = uint64(D) 432 } 433 434 pir := DoublePIR{} 435 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 436 437 i := uint64(0) // index to query 438 if i >= p.L*p.M { 439 panic("Index out of dimensions") 440 } 441 442 DB := MakeRandomDB(N, d, &p) 443 var tputs []float64 444 for j := 0; j < 5; j++ { 445 tput, _, _, _ := RunFakePIR(&pir, DB, p, []uint64{i}, f, false) 446 tputs = append(tputs, tput) 447 } 448 fmt.Printf("Avg DoublePIR tput, except for first run: %f MB/s\n", avg(tputs)) 449 fmt.Printf("Std dev of DoublePIR tput, except for first run: %f MB/s\n", stddev(tputs)) 450 } 451 452 // Benchmark SimplePIR performance, on 1GB databases with increasing row length. 453 func BenchmarkSimplePirVaryingDB(b *testing.B) { 454 flog, err := os.OpenFile("simple-comm.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 455 if err != nil { 456 panic("Error creating log file") 457 } 458 defer flog.Close() 459 460 writer := csv.NewWriter(flog) 461 defer writer.Flush() 462 463 records := []string{"N", "d", "tput", "tput_stddev", "offline_comm", "online_comm"} 464 writer.Write(records) 465 466 pir := SimplePIR{} 467 468 // Set N, D 469 total_sz := 33 470 471 for d := uint64(1); d <= 32768; d *= 2 { 472 N := uint64(1<<total_sz) / d 473 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 474 475 i := uint64(0) // index to query 476 if i >= p.L*p.M { 477 panic("Index out of dimensions") 478 } 479 480 DB := MakeRandomDB(N, d, &p) 481 var tputs []float64 482 var offline_cs []float64 483 var online_cs []float64 484 485 for j := 0; j < 5; j++ { 486 tput, _, offline_c, online_c := RunFakePIR(&pir, DB, p, []uint64{i}, nil, false) 487 tputs = append(tputs, tput) 488 offline_cs = append(offline_cs, offline_c) 489 online_cs = append(online_cs, online_c) 490 } 491 fmt.Printf("Avg SimplePIR tput (%d, %d), except for first run: %f MB/s\n", N, d, avg(tputs)) 492 fmt.Printf("Std dev of SimplePIR tput (%d, %d), except for first run: %f MB/s\n", N, d, stddev(tputs)) 493 if (stddev(offline_cs) != 0) || (stddev(online_cs) != 0) { 494 fmt.Printf("%f %f SHOULD NOT HAPPEN\n", stddev(offline_cs), stddev(online_cs)) 495 //panic("Should not happen!") 496 } 497 writer.Write([]string{strconv.FormatUint(N, 10), 498 strconv.FormatUint(d, 10), 499 strconv.FormatFloat(avg(tputs), 'f', 4, 64), 500 strconv.FormatFloat(stddev(tputs), 'f', 4, 64), 501 strconv.FormatFloat(avg(offline_cs), 'f', 4, 64), 502 strconv.FormatFloat(avg(online_cs), 'f', 4, 64)}) 503 } 504 } 505 506 // Benchmark DoublePIR performance, on 1 GB databases with increasing row length. 507 func BenchmarkDoublePirVaryingDB(b *testing.B) { 508 flog, err := os.OpenFile("double-comm.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 509 if err != nil { 510 panic("Error creating log file") 511 } 512 defer flog.Close() 513 514 writer := csv.NewWriter(flog) 515 defer writer.Flush() 516 517 records := []string{"N", "d", "tput", "tput_stddev", "offline_comm", "online_comm"} 518 writer.Write(records) 519 520 pir := DoublePIR{} 521 522 // Set N, D 523 total_sz := 33 524 for d := uint64(1); d <= 32768; d *= 2 { 525 N := uint64(1<<total_sz) / d 526 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 527 528 i := uint64(0) // index to query 529 if i >= p.L*p.M { 530 panic("Index out of dimensions") 531 } 532 533 DB := MakeRandomDB(N, d, &p) 534 var tputs []float64 535 var offline_cs []float64 536 var online_cs []float64 537 538 for j := 0; j < 5; j++ { 539 tput, _, offline_c, online_c := RunFakePIR(&pir, DB, p, []uint64{i}, nil, false) 540 tputs = append(tputs, tput) 541 offline_cs = append(offline_cs, offline_c) 542 online_cs = append(online_cs, online_c) 543 } 544 fmt.Printf("Avg SimplePIR tput (%d, %d), except for first run: %f MB/s\n", N, d, avg(tputs)) 545 fmt.Printf("Std dev of SimplePIR tput (%d, %d), except for first run: %f MB/s\n", N, d, stddev(tputs)) 546 if (stddev(offline_cs) != 0) || (stddev(online_cs) != 0) { 547 fmt.Printf("%f %f SHOULD NOT HAPPEN\n", stddev(offline_cs), stddev(online_cs)) 548 //panic("Should not happen!") 549 } 550 writer.Write([]string{strconv.FormatUint(N, 10), 551 strconv.FormatUint(d, 10), 552 strconv.FormatFloat(avg(tputs), 'f', 4, 64), 553 strconv.FormatFloat(stddev(tputs), 'f', 4, 64), 554 strconv.FormatFloat(avg(offline_cs), 'f', 4, 64), 555 strconv.FormatFloat(avg(online_cs), 'f', 4, 64)}) 556 } 557 } 558 559 // Benchmark SimplePIR performance with batches of increasing size. 560 func BenchmarkSimplePirBatchLarge(b *testing.B) { 561 f, err := os.Create("simple-cpu-batch.out") 562 if err != nil { 563 panic("Error creating file") 564 } 565 566 flog, err := os.Create("simple-batch.log") 567 if err != nil { 568 panic("Error creating log file") 569 } 570 defer flog.Close() 571 572 N := uint64(1 << 33) 573 d := uint64(1) 574 575 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 576 D, _ := strconv.Atoi(os.Getenv("D")) 577 if log_N != 0 { 578 N = uint64(1 << log_N) 579 } 580 if D != 0 { 581 d = uint64(D) 582 } 583 584 pir := SimplePIR{} 585 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 586 587 i := uint64(0) // index to query 588 if i >= p.L*p.M { 589 panic("Index out of dimensions") 590 } 591 592 DB := MakeRandomDB(N, d, &p) 593 594 writer := csv.NewWriter(flog) 595 defer writer.Flush() 596 597 records := []string{"Batch_sz", "Good_tput", "Good_std_dev", "Num_successful_queries", "Tput"} 598 writer.Write(records) 599 600 for trial := 0; trial <= 10; trial += 1 { 601 batch_sz := (1 << trial) 602 var query []uint64 603 for j := 0; j < batch_sz; j++ { 604 query = append(query, i) 605 } 606 var tputs []float64 607 for iter := 0; iter < 5; iter++ { 608 tput, _, _, _ := RunFakePIR(&pir, DB, p, query, f, false) 609 tputs = append(tputs, tput) 610 } 611 612 expected_num_empty_buckets := math.Pow(float64(batch_sz-1)/float64(batch_sz), float64(batch_sz)) * float64(batch_sz) 613 expected_num_successful_queries := float64(batch_sz) - expected_num_empty_buckets 614 good_tput := avg(tputs) / float64(batch_sz) * expected_num_successful_queries 615 dev := stddev(tputs) / float64(batch_sz) * expected_num_successful_queries 616 617 writer.Write([]string{strconv.Itoa(batch_sz), 618 strconv.FormatFloat(good_tput, 'f', 4, 64), 619 strconv.FormatFloat(dev, 'f', 4, 64), 620 strconv.FormatFloat(expected_num_successful_queries, 'f', 4, 64), 621 strconv.FormatFloat(avg(tputs), 'f', 4, 64)}) 622 } 623 } 624 625 // Benchmark DoublePIR performance with batches of increasing size. 626 func BenchmarkDoublePirBatchLarge(b *testing.B) { 627 f, err := os.Create("double-cpu-batch.out") 628 if err != nil { 629 panic("Error creating file") 630 } 631 632 flog, err := os.Create("double-batch.log") 633 if err != nil { 634 panic("Error creating log file") 635 } 636 defer flog.Close() 637 638 N := uint64(1 << 33) 639 d := uint64(1) 640 641 log_N, _ := strconv.Atoi(os.Getenv("LOG_N")) 642 D, _ := strconv.Atoi(os.Getenv("D")) 643 if log_N != 0 { 644 N = uint64(1 << log_N) 645 } 646 if D != 0 { 647 d = uint64(D) 648 } 649 650 pir := DoublePIR{} 651 p := pir.PickParams(N, d, SEC_PARAM, LOGQ) 652 653 i := uint64(0) // index to query 654 if i >= p.L*p.M { 655 panic("Index out of dimensions") 656 } 657 658 DB := MakeRandomDB(N, d, &p) 659 660 writer := csv.NewWriter(flog) 661 defer writer.Flush() 662 663 records := []string{"Batch_sz", "Good_tput", "Good_std_dev", "Num_successful_queries", "Tput"} 664 writer.Write(records) 665 666 for trial := 0; trial <= 10; trial += 1 { 667 batch_sz := (1 << trial) 668 var query []uint64 669 for j := 0; j < batch_sz; j++ { 670 query = append(query, i) 671 } 672 var tputs []float64 673 for iter := 0; iter < 5; iter++ { 674 tput, _, _, _ := RunFakePIR(&pir, DB, p, query, f, false) 675 tputs = append(tputs, tput) 676 } 677 expected_num_empty_buckets := math.Pow(float64(batch_sz-1)/float64(batch_sz), float64(batch_sz)) * float64(batch_sz) 678 expected_num_successful_queries := float64(batch_sz) - expected_num_empty_buckets 679 good_tput := avg(tputs) / float64(batch_sz) * expected_num_successful_queries 680 dev := stddev(tputs) / float64(batch_sz) * expected_num_successful_queries 681 682 writer.Write([]string{strconv.Itoa(batch_sz), 683 strconv.FormatFloat(good_tput, 'f', 4, 64), 684 strconv.FormatFloat(dev, 'f', 4, 64), 685 strconv.FormatFloat(expected_num_successful_queries, 'f', 4, 64), 686 strconv.FormatFloat(avg(tputs), 'f', 4, 64)}) 687 } 688 }