# Difference between r2 and drg-attacks and CCS paper
Difference between r2 and drg-attacks (and paper) are two folds:
1. different way to compute the bucket index
2. different way to compute the final value
## Bucket Index of the parent
+ In the paper algorithm (DRSample, Algorithm 1 in CCS [paper](https://acmccs.github.io/papers/p1001-alwenA.pdf), we have:
```rust
g' <-- [1,floor(log2(v))+1]
```
+ In r2, we have the following [code](https://github.com/nicola/r2/blob/master/src/graph.rs#L49):
```rust
let logi = ((node * m) as f32).log2().floor() as usize;
let j = rng.gen::<usize>() % logi;
```
=> r2 uses the floor of the logarithm without doing a +1 when selecting the
value and using modulo (which creates an exclusive upper bound). It gives rises to high differences in bucket index, as show below:
```rust
v = 18, log2(v) = 4.16...
// --- DRSample ---
g' <-- [1, 5] // floor(log2(v)) = 4
// --- R2 ---
g' <-- [1, 4[ <=> [1, 3] // upper bound is 4[ because of the modulo
```
+ In drg-attacks, we have the following [code](https://github.com/nicola/r2/blob/master/src/graph.rs#L49) which follows the paper algorithm:
```rust
let meta_idx = node * m;
// ceil instead of floor() + 1
let max_bucket = (meta_idx as f32).log2().ceil() as usize;
// [1, ceil(log2(v))] <=> [1, floor(log2(v)) + 1]
let i: usize = rng.gen_range(1, max_bucket + 1);
```
**Note**: I believe that is the main issue that causes Valiant's attack to give back different results - ignoring a few buckets change the graph structure.
## Final Index of the parent
+ In the paper [Algorithm 1](https://acmccs.github.io/papers/p1001-alwenA.pdf), we have:
```rust
g <-- min(v, 2^g')
r <-- [max(g/2, 2) , g]
return v - r
```
+ In r2 we have
```rust
// min(v, 2^g')
let jj = cmp::min(node * m + k, 1 << (j + 1));
// r <-- [ max(jj/2, 2), jj ]
let back_dist = rng.gen_range(cmp::max(jj >> 1, 2), jj + 1);
// v - r
let out = (node * m + k - back_dist) / m;
```
+ In drg-attacks we have:
```rust
// g = min(v, 2^g')
let max = std::cmp::min(meta_idx, 1 << i);
// max(2, g / 2)
let min = std::cmp::max(2, max >> 1);
// return v - [ max(2, g/2), g ]
let meta_parent = node * m - rng.gen_range(min, max); // no "+ k" here
let real_parent = meta_parent / degree;
```
The reason for drg-attacks to NOT include the "+k" is because it prevents
falling on the same "real" node when we divide by the degree. Basically,
drg-attacks always choose the minimum index for the "bucket of meta nodes". For
example, with $d = 3$, node 2 gets mapped to $\{6,7,8\}$.
* To find a parent for node 2, drg-attacks's code takes 3 times the meta index 6 as an upper bound so that it always find a number $v - r < 6$.
* In r2, for the third iteration, the "meta index" would be 8 so I may end up selecting the meta-node $8 - 2 = 6$, which corresponds to the same index in the basic graph ($6/d = 2$) !
From what I understand of the paper algorithm, this should not be
possible and is not desirable: for a given child $u$, we always select a parent node $v$ such that $2^(i-1) <= dist(v,u) <= 2^i$ , so $dist(u,v) > 1$. In the code they even go further since the minimum to choose r from is 2, so $v = u - r <= u - 2 \neq v$.