-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy path1bitext_xor.cc
111 lines (89 loc) · 3.54 KB
/
1bitext_xor.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* This file is part of libtrevisan, a modular implementation of
Trevisan's randomness extraction construction.
Copyright (C) 2011-2012, Wolfgang Mauerer <[email protected]>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libtrevisan. If not, see <http://www.gnu.org/licenses/>. */
// A 1-bit extractor based on XOR
// Algorithmic description and parameter calculations by Ch. Portmann
#include<iostream>
#include<fstream>
#include<cstddef>
#include<stdlib.h>
#include<RInside.h>
#include "timing.h"
#include "utils.hpp"
#include "1bitext_xor.h"
using namespace std;
vertex_t bitext_xor::num_random_bits() {
if (l == std::numeric_limits<vertex_t>::max()) {
cerr << "(XOR extractor) Internal error: num_random_bits() called for "
<< "without valid value for parameter l" << endl;
exit(-1);
}
// The number of random bits per run is l*log(n) (see the comment in
// extract why we compute with nb(n-1))
return l*numbits<vertex_t>(pp.n-1);
}
void bitext_xor::compute_l() {
SEXP ans;
stringstream call;
call << "do.opt.xor(" << pp.alpha << ", " << mu << ", " << r << ", "
<< pp.n << ", " << pp.eps << ")";
r_interp->parse_eval(call.str(), ans);
l = Rcpp::as<vertex_t>(ans);
}
uint64_t bitext_xor::compute_k() {
SEXP ans;
stringstream call;
call << "gamma.func(" << pp.alpha << ", " << mu << ", " << r << ", "
<< pp.n << ", " << pp.eps << ")" << endl;
r_interp->parse_eval(call.str(), ans);
long double gamma = Rcpp::as<long double>(ans);
long double eps_prime = sqrt(pp.eps)/(1+sqrt(2));
vertex_t k = ceil(gamma*pp.n + r*pp.m + 6*log2((1+sqrt(2))/eps_prime) +
log2(4.0/3.0));
return(k);
}
bool bitext_xor::extract(void *initial_rand) {
unsigned short bits_per_val = numbits<uint64_t>(pp.n-1);
unsigned short bits_per_datum = BITS_PER_TYPE(datum_t);
datum_t idx;
bool res = 0;
local_bf.set_raw_data(initial_rand, num_random_bits());
#ifdef EXPENSIVE_SANITY_CHECKS
if (l == std::numeric_limits<vertex_t>::max()) {
cerr << "(XOR extractor) Internal error: extract() called for "
<< "without valid value for parameter l" << endl;
exit(-1);
}
#endif
// NOTE: Since the number of bits representable in a machine with
// word length w is 8*2^w= 2^(w+3), we can simplify the bit selection
// if sizeof(elem_t) \geq w+3: It is guaranteed that all bits fit
// into one instance of the type in principle.
// Technically, this amounts to the fact that elem_t must provide
// enough bits to hold a complete index, that is, n bits.
if (bits_per_datum < bits_per_val) {
fprintf(stderr, "Internal error: Assumption "
"bits_per_datum < bits_per_val failed!\n");
exit(-1);
}
// Iterate along the given initial randomness, take nb(n-1)=bits_per_val bits in
// each step, and select the bit in n with this index. Compute the
// cumulative XOR value over all bits.
for (uint64_t i = 0; i < l; i++) {
local_bf.get_bit_range(i*bits_per_val, (i+1)*bits_per_val-1, &idx);
// Take the bit indexed by idx of the global randomness
// and xor it to the result
res ^= b.get_bit(idx);
}
return res;
}