Merge branch 'develop' into feature/provider-from-topology

This commit is contained in:
Dave Hrycyszyn
2019-12-17 13:38:02 +00:00
12 changed files with 440 additions and 113 deletions
+3
View File
@@ -1 +1,4 @@
pub mod bytes;
pub mod poisson;
pub mod sphinx;
pub mod topology;
+6
View File
@@ -0,0 +1,6 @@
use rand_distr::{Distribution, Exp};
pub fn sample(average_delay: f64) -> f64 {
let exp = Exp::new(1.0 / average_delay).unwrap();
exp.sample(&mut rand::thread_rng())
}
+48
View File
@@ -0,0 +1,48 @@
use crate::clients::directory::presence::Topology;
use crate::utils::{bytes, topology};
use curve25519_dalek::montgomery::MontgomeryPoint;
use sphinx::route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier};
use sphinx::SphinxPacket;
const LOOP_COVER_MESSAGE_PAYLOAD: &[u8] = b"The cake is a lie!";
pub fn loop_cover_message(
our_address: DestinationAddressBytes,
surb_id: SURBIdentifier,
topology: &Topology,
) -> (NodeAddressBytes, SphinxPacket) {
let destination = Destination::new(our_address, surb_id);
encapsulate_message(destination, LOOP_COVER_MESSAGE_PAYLOAD.to_vec(), topology)
}
pub fn encapsulate_message(
recipient: Destination,
message: Vec<u8>,
topology: &Topology,
) -> (NodeAddressBytes, SphinxPacket) {
// here we would be getting topology, etc
let mixes_route = topology::route_from(&topology, 1);
let first_provider = topology.mix_provider_nodes.first().unwrap();
let decoded_key_bytes =
base64::decode_config(&first_provider.pub_key, base64::URL_SAFE).unwrap();
let key_bytes = bytes::zero_pad_to_32(decoded_key_bytes);
let key = MontgomeryPoint(key_bytes);
let provider = Node::new(
topology::socket_bytes_from_string(first_provider.host.clone()),
key,
);
let route = [mixes_route, vec![provider]].concat();
let delays = sphinx::header::delays::generate(route.len());
// build the packet
let packet = sphinx::SphinxPacket::new(message, &route[..], &recipient, &delays).unwrap();
let first_node_address = route.first().unwrap().address;
(first_node_address, packet)
}
+61
View File
@@ -0,0 +1,61 @@
use crate::clients::directory;
use crate::clients::directory::presence::Topology;
use crate::clients::directory::requests::presence_topology_get::PresenceTopologyGetRequester;
use crate::clients::directory::DirectoryClient;
use crate::clients::mix::MixClient;
use crate::clients::provider::ProviderClient;
use crate::utils::bytes;
use curve25519_dalek::montgomery::MontgomeryPoint;
use sphinx::route::Node as SphinxNode;
use std::net::SocketAddrV4;
use std::string::ToString;
pub(crate) fn get_topology(is_local: bool) -> Topology {
let url = if is_local {
"http://localhost:8080".to_string()
} else {
"https://directory.nymtech.net".to_string()
};
println!("Using directory server: {:?}", url);
let directory_config = directory::Config { base_url: url };
let directory = directory::Client::new(directory_config);
let topology = directory
.presence_topology
.get()
.expect("Failed to retrieve network topology.");
topology
}
pub(crate) fn route_from(topology: &Topology, route_len: usize) -> Vec<SphinxNode> {
let mut route = vec![];
let nodes = topology.mix_nodes.iter();
for mix in nodes.take(route_len) {
let address_bytes = socket_bytes_from_string(mix.host.clone());
let decoded_key_bytes = base64::decode_config(&mix.pub_key, base64::URL_SAFE).unwrap();
let key_bytes = bytes::zero_pad_to_32(decoded_key_bytes);
let key = MontgomeryPoint(key_bytes);
let sphinx_node = SphinxNode {
address: address_bytes,
pub_key: key,
};
route.push(sphinx_node);
}
route
}
pub(crate) fn socket_bytes_from_string(address: String) -> [u8; 32] {
let socket: SocketAddrV4 = address.parse().unwrap();
let host_bytes = socket.ip().octets();
let port_bytes = socket.port().to_be_bytes();
let mut address_bytes = [0u8; 32];
address_bytes[0] = host_bytes[0];
address_bytes[1] = host_bytes[1];
address_bytes[2] = host_bytes[2];
address_bytes[3] = host_bytes[3];
address_bytes[4] = port_bytes[0];
address_bytes[5] = port_bytes[1];
address_bytes
}