Wednesday, August 18, 2010

[Geopriv] geopriv-policy randomization visualization

The following processing script shows the proposed algorithm for location randomization/obscuring. Credit to Robert for the script that this is based on.

This can be run in Processing (http://processing.org/).

Info:
The location (shown with a black "+") moves randomly.
The red circle shows what is sent to a recipient.
The cyan circle is the trigger circle - when the location moves outside this circle, a new location is created
The yellow "+" shows where the location was at the time that the location was last updated

Controls:
Click mouse to pause/unpause
Drag mouse to move the location directly
Left and right arrow to adjust the amount of obscuring
Up and down arrow to adjust the uncertainty of the location

--- fuzz.pde ---

Fuzzer fuzz;
float uncertaintyStep = 2.5; // uncertainty starts at this
float obscureDistance = 50; // uncertainty is increased to this

void setup() {
size(600,600);
smooth();
background(255);
ellipseMode(RADIUS);
textFont(loadFont("CenturyGothic-12.vlw"));
textMode(SCREEN);
textAlign(LEFT);
fuzz = new Fuzzer();
}

void draw() {
fuzz.update();
}

void mouseReleased() {
fuzz.togglePause();
}
void mouseDragged() {
fuzz.drag();
}

void keyPressed() {
if (key == CODED) {
if (keyCode == UP) {
fuzz.incrementUncertainty(uncertaintyStep);
}
else if (keyCode == DOWN) {
fuzz.incrementUncertainty(-uncertaintyStep);
}
else if (keyCode == LEFT) {
obscureDistance = max(0, obscureDistance - uncertaintyStep);
}
else if (keyCode == RIGHT) {
obscureDistance = obscureDistance + uncertaintyStep;
}
}
}

class Fuzzer {
int throttle = 0;
int step;
boolean paused = false;
boolean dragging = false;

PVector location;
float uncertainty = uncertaintyStep;

// the centre of the circle that is reportedLocation
PVector reportedLocation;
// the location that we use to determine whether to provide a new location
PVector triggerLocation;
// the distance from the trigger location at which we generate a new location
float threshold;
// the location at the time that we last provided a new location
PVector oldLocation;

// for randomly moving a point around
Mover mover;

Fuzzer() {
location = new PVector(width / 2, height / 2);
mover = new Mover();
incrementUncertainty(0);
this.newLocation();
}

void togglePause() {
if (!dragging) {
paused = !paused;
}
dragging = false;
}

void incrementUncertainty(float incr) {
uncertainty = max(uncertaintyStep, uncertainty + incr);
// fudge factors
mover.setTopSpeed(2*sqrt(uncertainty));
step = 2 + round(2*sqrt(uncertainty));
}

void drag() {
PVector m = new PVector(mouseX, mouseY);
if (PVector.sub(m, this.location).mag() > 0) {
dragging = true;
location = m;
this.update();
}
}

void update() {
if ((paused && !dragging) || (throttle++ % step) != 0) {
return;
}

if (location.dist(triggerLocation) > threshold) {
this.newLocation();
}

if (!dragging) {
location = mover.movePoint(location);
}

this.display();
}

// we need to report a new location because the current real location has moved too far
void newLocation() {
oldLocation = location.get();

// the location that is reported encloses the location of the target
// this includes the uncertainty, but it is otherwise random
reportedLocation = location.get();
reportedLocation.add(this.randomVector(max(0, obscureDistance - uncertainty)));

triggerLocation = location.get();
// only move the trigger location by half the obscuring distance
// this ensures that new locations are generated when the straight line
// movement is from 0.5 to 1.5 times the obscuring distance
triggerLocation.add(this.randomVector(obscureDistance/2));
// moving the trigger location is sufficient randomization for triggering
threshold = obscureDistance;
}

PVector randomVector(float maxSize) {
float theta = random(0, TWO_PI);
PVector r = new PVector(sin(theta), cos(theta));
r.mult(maxSize*sqrt(random(1)));
return r;
}

void display() {
noStroke();
fill(255,10);
rect(0,0,width,height);
fill(255);
rect(0,0,110,36);
fill(0);
text("Obscure: " + obscureDistance, 0, 13);
text("Uncertainty: " + uncertainty, 0, 27);

stroke(0);
fill(220,0,0,20);
float repRadius = max(obscureDistance, uncertainty);
ellipse(reportedLocation.x, reportedLocation.y, repRadius, repRadius);
fill(0,220,110,20);
ellipse(triggerLocation.x, triggerLocation. y,threshold, threshold);
stroke(0);
showLocation(location, uncertainty);
stroke(220, 220, 0);
showLocation(oldLocation, uncertainty);
}
void showLocation(PVector pt, float unc) {
// ellipse(pt.x,pt.y,unc,unc);
line(pt.x - unc, pt.y, pt.x + unc, pt.y);
line(pt.x, pt.y - unc, pt.x, pt.y + unc);
}
}

class Mover {
PVector velocity;
float topspeed = 4;
float maxChange = 0.5; // maximum change in velocity for less erratic movement

Mover() {
velocity = new PVector(0,0);
}

void setTopSpeed(float top) {
topspeed = top;
}

PVector movePoint(PVector location) {
float rx = random(-topspeed*maxChange, topspeed*maxChange);
float ry = random(-topspeed*maxChange, topspeed*maxChange);
PVector delta = new PVector(rx, ry);
velocity.add(delta);
velocity.limit(topspeed);
location.add(velocity);
location.x = (location.x + width) % width;
location.y = (location.y + height) % height;
return location;
}
}


_______________________________________________
Geopriv mailing list
Geopriv@ietf.org
https://www.ietf.org/mailman/listinfo/geopriv