mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-06-04 23:01:38 +00:00
further ipv6 support + addr generation from pubkey
This commit is contained in:
Generated
+49
-1
@@ -66,6 +66,30 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||
dependencies = [
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake2b"
|
||||
version = "0.99.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81ce94c69d161e5588f2ebd67fed9220ede4f7e6a174141a76299a538b2ee90d"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
@@ -147,6 +171,16 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "3.2.1"
|
||||
@@ -154,7 +188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"digest",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
@@ -169,6 +203,17 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.0"
|
||||
@@ -421,8 +466,11 @@ dependencies = [
|
||||
name = "masterproef_v2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"blake2b",
|
||||
"bytes",
|
||||
"clap",
|
||||
"digest 0.10.7",
|
||||
"etherparse",
|
||||
"futures",
|
||||
"getrandom 0.2.9",
|
||||
|
||||
@@ -21,3 +21,6 @@ getrandom = "0.2.9"
|
||||
rand_core = { version = "0.5.1", features = ["getrandom"] }
|
||||
x25519-dalek = "1.2.0"
|
||||
serde_json = "1.0.96"
|
||||
blake2b = "0.99.0"
|
||||
blake2 = "0.10.6"
|
||||
digest = "0.10.7"
|
||||
|
||||
+9
-6
@@ -24,8 +24,6 @@ const LINK_MTU: usize = 1420;
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Cli {
|
||||
#[arg(short = 'a', long = "tun-addr")]
|
||||
tun_addr: Ipv6Addr,
|
||||
#[arg(short = 'p', long = "peers", num_args = 1..)]
|
||||
static_peers: Vec<SocketAddr>,
|
||||
}
|
||||
@@ -34,8 +32,14 @@ struct Cli {
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
// Generate a new keypair for this node, panic if it fails
|
||||
let node_keypair = x25519::get_keypair().unwrap();
|
||||
|
||||
// Generate the node's IPv6 address from its public key
|
||||
let node_addr = x25519::generate_addr_from_pubkey(&node_keypair.1);
|
||||
|
||||
// Create TUN interface and add static route
|
||||
let node_tun = match node_setup::setup_node(cli.tun_addr).await {
|
||||
let node_tun = match node_setup::setup_node(node_addr).await {
|
||||
Ok(tun) => {
|
||||
println!("Node setup complete");
|
||||
tun
|
||||
@@ -45,8 +49,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
};
|
||||
|
||||
// Generate a new keypair for this node, panic if it fails
|
||||
let node_keypair = x25519::get_keypair().unwrap();
|
||||
|
||||
|
||||
println!("Node public key: {:?}", node_keypair.1);
|
||||
@@ -56,7 +58,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Creating a new Router instance
|
||||
let router = match router::Router::new(
|
||||
node_tun.clone(),
|
||||
vec![StaticRoute::new(cli.tun_addr.into())],
|
||||
node_addr,
|
||||
vec![StaticRoute::new(node_addr.into())],
|
||||
node_keypair
|
||||
) {
|
||||
Ok(router) => {
|
||||
|
||||
+72
-26
@@ -1,16 +1,20 @@
|
||||
use futures::stream::TryStreamExt;
|
||||
use futures::TryStreamExt;
|
||||
use rtnetlink::Handle;
|
||||
use std::{error::Error, net::{Ipv4Addr, Ipv6Addr}, sync::Arc};
|
||||
use x25519_dalek::PublicKey;
|
||||
use std::{
|
||||
net::{IpAddr, Ipv6Addr},
|
||||
sync::Arc,
|
||||
};
|
||||
use tokio_tun::{Tun, TunBuilder};
|
||||
|
||||
pub const TUN_NAME: &str = "tun0";
|
||||
pub const TUN_ROUTE_DEST: Ipv6Addr = Ipv6Addr::new(0xfd, 0x00, 0, 0, 0, 0, 0, 0);
|
||||
pub const TUN_ROUTE_PREFIX: u8 = 16;
|
||||
pub const TUN_ROUTE_DEST: Ipv6Addr = Ipv6Addr::new(0x200, 0, 0, 0, 0, 0, 0, 0);
|
||||
pub const TUN_ROUTE_PREFIX: u8 = 7;
|
||||
|
||||
// Create a TUN interface
|
||||
pub fn create_tun_interface() -> Result<Arc<Tun>, Box<dyn Error>> {
|
||||
pub fn create_tun_interface() -> Result<Arc<Tun>, Box<dyn std::error::Error>> {
|
||||
let tun = TunBuilder::new()
|
||||
.name(TUN_NAME)
|
||||
.name("tun0")
|
||||
.tap(false)
|
||||
.mtu(1420)
|
||||
.packet_info(false)
|
||||
@@ -20,43 +24,85 @@ pub fn create_tun_interface() -> Result<Arc<Tun>, Box<dyn Error>> {
|
||||
Ok(Arc::new(tun))
|
||||
}
|
||||
|
||||
// Add a route to the TUN interface
|
||||
pub async fn add_route(handle: Handle) -> Result<(), Box<dyn Error>> {
|
||||
let mut link_request = handle
|
||||
.link()
|
||||
.get()
|
||||
.match_name(String::from(TUN_NAME))
|
||||
.execute();
|
||||
|
||||
let link_idx = if let Some(link) = link_request.try_next().await? {
|
||||
pub async fn retrieve_tun_link_index(handle: Handle) -> Result<u32, Box<dyn std::error::Error>> {
|
||||
let mut link_req = handle.link().get().match_name(TUN_NAME.to_string()).execute();
|
||||
let link_index = if let Some(link) = link_req.try_next().await? {
|
||||
link.header.index
|
||||
} else {
|
||||
eprintln!("link not found");
|
||||
panic!("link not found");
|
||||
};
|
||||
|
||||
let route = handle.route();
|
||||
route
|
||||
.add()
|
||||
.v4()
|
||||
.destination_prefix(TUN_ROUTE_DEST, TUN_ROUTE_PREFIX)
|
||||
.output_interface(link_idx)
|
||||
Ok(link_index)
|
||||
}
|
||||
|
||||
// Add address to TUN interface
|
||||
pub async fn add_address(handle: Handle, addr: Ipv6Addr) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let link_index = retrieve_tun_link_index(handle.clone()).await?;
|
||||
// add address to tun interface
|
||||
handle
|
||||
.address()
|
||||
.add(
|
||||
link_index,
|
||||
IpAddr::V6(addr),
|
||||
7,
|
||||
)
|
||||
.execute()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn setup_node(tun_addr: Ipv6Addr) -> Result<Arc<Tun>, Box<dyn Error>> {
|
||||
let tun = create_tun_interface(tun_addr)?;
|
||||
println!("Interface '{}' ({}) created", TUN_NAME, tun_addr);
|
||||
|
||||
// Adding route to TUN interface
|
||||
pub async fn add_route(handle: Handle) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let link_index = retrieve_tun_link_index(handle.clone()).await?;
|
||||
// add route to tun interface
|
||||
let route = handle.route();
|
||||
route
|
||||
.add()
|
||||
.v6()
|
||||
.destination_prefix(Ipv6Addr::new(0x200, 0, 0, 0, 0, 0, 0, 0), 7)
|
||||
.output_interface(link_index)
|
||||
.execute()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn setup_node(addr: Ipv6Addr) -> Result<Arc<Tun>, Box<dyn std::error::Error>> {
|
||||
|
||||
let tun = match create_tun_interface() {
|
||||
Ok(tun) => {
|
||||
println!("TUN interface created");
|
||||
tun
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("Error creating TUN interface: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
let (conn, handle, _) = rtnetlink::new_connection()?;
|
||||
tokio::spawn(conn);
|
||||
|
||||
add_route(handle.clone()).await?;
|
||||
match add_address(handle.clone(), addr).await {
|
||||
Ok(_) => {
|
||||
println!("Address added to TUN interface");
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("Error adding address to TUN interface: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
println!("Static route created");
|
||||
match add_route(handle.clone()).await {
|
||||
Ok(_) => {
|
||||
println!("Route added to TUN interface");
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("Error adding route to TUN interface: {}", e);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(tun)
|
||||
}
|
||||
|
||||
+67
-47
@@ -69,16 +69,22 @@ impl PeerManager {
|
||||
);
|
||||
|
||||
let mut buf = [0u8; 17];
|
||||
match self.router.node_tun_addr() {
|
||||
IpAddr::V4(tun_addr) => {
|
||||
buf[0] = 0;
|
||||
buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
IpAddr::V6(tun_addr) => {
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
}
|
||||
// old:
|
||||
// match self.router.node_tun_addr() {
|
||||
// IpAddr::V4(tun_addr) => {
|
||||
// buf[0] = 0;
|
||||
// buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// IpAddr::V6(tun_addr) => {
|
||||
// buf[0] = 1;
|
||||
// buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// }
|
||||
// new:
|
||||
// only using IPv6
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&self.router.node_tun_addr().octets()[..]);
|
||||
|
||||
peer_stream.write_all(&buf).await.unwrap();
|
||||
|
||||
let peer_stream_ip = peer_addr.ip();
|
||||
@@ -125,17 +131,21 @@ impl PeerManager {
|
||||
);
|
||||
|
||||
let mut buf = [0u8; 17];
|
||||
|
||||
match self.router.node_tun_addr() {
|
||||
IpAddr::V4(tun_addr) => {
|
||||
buf[0] = 0;
|
||||
buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
IpAddr::V6(tun_addr) => {
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
}
|
||||
// old:
|
||||
// match self.router.node_tun_addr() {
|
||||
// IpAddr::V4(tun_addr) => {
|
||||
// buf[0] = 0;
|
||||
// buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// IpAddr::V6(tun_addr) => {
|
||||
// buf[0] = 1;
|
||||
// buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// }
|
||||
// new:
|
||||
// only using IPv6
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&self.router.node_tun_addr().octets()[..]);
|
||||
|
||||
peer_stream.write_all(&buf).await.unwrap();
|
||||
|
||||
@@ -183,16 +193,22 @@ impl PeerManager {
|
||||
);
|
||||
|
||||
let mut buf = [0u8; 17];
|
||||
match self.router.node_tun_addr() {
|
||||
IpAddr::V4(tun_addr) => {
|
||||
buf[0] = 0;
|
||||
buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
IpAddr::V6(tun_addr) => {
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
}
|
||||
// old:
|
||||
// match self.router.node_tun_addr() {
|
||||
// IpAddr::V4(tun_addr) => {
|
||||
// buf[0] = 0;
|
||||
// buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// IpAddr::V6(tun_addr) => {
|
||||
// buf[0] = 1;
|
||||
// buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// }
|
||||
// new:
|
||||
// only using IPv6
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&self.router.node_tun_addr().octets()[..]);
|
||||
|
||||
peer_stream.write_all(&buf).await.unwrap();
|
||||
|
||||
let peer_stream_ip = peer.ip();
|
||||
@@ -216,7 +232,7 @@ impl PeerManager {
|
||||
Ok(listener) => loop {
|
||||
match listener.accept().await {
|
||||
Ok((stream, _)) => {
|
||||
PeerManager::start_reverse_peer_exchange(stream, self.router.clone()).await;
|
||||
self.start_reverse_peer_exchange(stream).await;
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error accepting connection: {}", e);
|
||||
@@ -229,23 +245,27 @@ impl PeerManager {
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_reverse_peer_exchange(mut stream: TcpStream, router: Router) {
|
||||
async fn start_reverse_peer_exchange(&self, mut stream: TcpStream) {
|
||||
// Steps:
|
||||
// 1. Send own TUN address over the stream
|
||||
// 2. Read other node's TUN address from the stream
|
||||
|
||||
let mut buf = [0u8; 17];
|
||||
|
||||
match router.node_tun_addr() {
|
||||
IpAddr::V4(tun_addr) => {
|
||||
buf[0] = 0;
|
||||
buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
IpAddr::V6(tun_addr) => {
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
}
|
||||
}
|
||||
// old:
|
||||
// match self.router.node_tun_addr() {
|
||||
// IpAddr::V4(tun_addr) => {
|
||||
// buf[0] = 0;
|
||||
// buf[1..5].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// IpAddr::V6(tun_addr) => {
|
||||
// buf[0] = 1;
|
||||
// buf[1..].copy_from_slice(&tun_addr.octets()[..]);
|
||||
// }
|
||||
// }
|
||||
// new:
|
||||
// only using IPv6
|
||||
buf[0] = 1;
|
||||
buf[1..].copy_from_slice(&self.router.node_tun_addr().octets()[..]);
|
||||
|
||||
stream.write_all(&buf).await.unwrap();
|
||||
|
||||
@@ -267,14 +287,14 @@ impl PeerManager {
|
||||
let peer_stream_ip = stream.peer_addr().unwrap().ip();
|
||||
let new_peer = Peer::new(
|
||||
peer_stream_ip,
|
||||
router.router_data_tx(),
|
||||
router.router_control_tx(),
|
||||
self.router.router_data_tx(),
|
||||
self.router.router_control_tx(),
|
||||
stream,
|
||||
received_overlay_ip,
|
||||
);
|
||||
match new_peer {
|
||||
Ok(new_peer) => {
|
||||
router.add_peer_interface(new_peer);
|
||||
self.router.add_peer_interface(new_peer);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error creating peer: {}", e);
|
||||
|
||||
+11
-5
@@ -9,7 +9,7 @@ use x25519_dalek::{StaticSecret, PublicKey};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::Debug,
|
||||
net::IpAddr,
|
||||
net::{IpAddr, Ipv6Addr},
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
||||
@@ -44,6 +44,7 @@ pub struct Router {
|
||||
impl Router {
|
||||
pub fn new(
|
||||
node_tun: Arc<Tun>,
|
||||
node_tun_addr: Ipv6Addr,
|
||||
static_routes: Vec<StaticRoute>,
|
||||
node_keypair: (StaticSecret, PublicKey),
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
@@ -55,6 +56,7 @@ impl Router {
|
||||
let router = Router {
|
||||
inner: Arc::new(RwLock::new(RouterInner::new(
|
||||
node_tun,
|
||||
node_tun_addr,
|
||||
static_routes,
|
||||
router_data_tx,
|
||||
router_control_tx,
|
||||
@@ -91,8 +93,9 @@ impl Router {
|
||||
self.inner.read().unwrap().router_data_tx.clone()
|
||||
}
|
||||
|
||||
pub fn node_tun_addr(&self) -> IpAddr {
|
||||
IpAddr::V6(self.inner.read().unwrap().node_tun.address().unwrap())
|
||||
pub fn node_tun_addr(&self) -> Ipv6Addr {
|
||||
// IpAddr::V6(self.inner.read().unwrap().node_tun.address().unwrap())
|
||||
self.inner.read().unwrap().node_tun_addr
|
||||
}
|
||||
|
||||
pub fn node_tun(&self) -> Arc<Tun> {
|
||||
@@ -485,7 +488,7 @@ impl Router {
|
||||
// If destination IP of packet is same as TUN interface IP, send to TUN interface
|
||||
// If destination IP of packet is not same as TUN interface IP, send to peer with matching overlay IP
|
||||
let node_tun = self.node_tun();
|
||||
let node_tun_addr = node_tun.address().unwrap();
|
||||
let node_tun_addr = self.node_tun_addr();
|
||||
loop {
|
||||
while let Some(data_packet) = router_data_rx.recv().await {
|
||||
match data_packet.dest_ip {
|
||||
@@ -497,7 +500,7 @@ impl Router {
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let best_route = self.select_best_route(IpAddr::V4(data_packet.dest_ip));
|
||||
let best_route = self.select_best_route(IpAddr::V6(data_packet.dest_ip));
|
||||
match best_route {
|
||||
Some (route_entry) => {
|
||||
let peer = self.peer_by_ip(route_entry.next_hop).unwrap();
|
||||
@@ -580,6 +583,7 @@ pub struct RouterInner {
|
||||
router_control_tx: UnboundedSender<ControlStruct>,
|
||||
router_data_tx: UnboundedSender<DataPacket>,
|
||||
node_tun: Arc<Tun>,
|
||||
node_tun_addr: Ipv6Addr,
|
||||
selected_routing_table: RoutingTable,
|
||||
fallback_routing_table: RoutingTable,
|
||||
source_table: SourceTable,
|
||||
@@ -591,6 +595,7 @@ pub struct RouterInner {
|
||||
impl RouterInner {
|
||||
pub fn new(
|
||||
node_tun: Arc<Tun>,
|
||||
node_tun_addr: Ipv6Addr,
|
||||
static_routes: Vec<StaticRoute>,
|
||||
router_data_tx: UnboundedSender<DataPacket>,
|
||||
router_control_tx: UnboundedSender<ControlStruct>,
|
||||
@@ -608,6 +613,7 @@ impl RouterInner {
|
||||
router_seqno: 0,
|
||||
static_routes: static_routes,
|
||||
node_keypair: node_keypair,
|
||||
node_tun_addr,
|
||||
};
|
||||
|
||||
Ok(router_inner)
|
||||
|
||||
+28
-5
@@ -1,13 +1,17 @@
|
||||
use blake2::digest::{Update, VariableOutput};
|
||||
use blake2::Blake2bVar;
|
||||
use rand_core::OsRng;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
use rand_core::OsRng;
|
||||
use std::{
|
||||
net::Ipv6Addr,
|
||||
};
|
||||
use x25519_dalek::{PublicKey, StaticSecret, SharedSecret};
|
||||
|
||||
|
||||
// Read the secret key from a file if it exists, otherwise generate a new one and write it to a file
|
||||
// Returns the secret key and the corresponding public key
|
||||
pub fn get_keypair() -> Result<(StaticSecret, PublicKey), Box<dyn std::error::Error>>{
|
||||
pub fn get_keypair() -> Result<(StaticSecret, PublicKey), Box<dyn std::error::Error>> {
|
||||
let path = Path::new("keys.txt");
|
||||
|
||||
let (secret_key, public_key) = if path.exists() {
|
||||
@@ -29,7 +33,8 @@ pub fn get_keypair() -> Result<(StaticSecret, PublicKey), Box<dyn std::error::Er
|
||||
.open(&path)
|
||||
.expect("Failed to open file");
|
||||
|
||||
file.write_all(secret_key.to_bytes().as_ref()).expect("Failed to write to file");
|
||||
file.write_all(secret_key.to_bytes().as_ref())
|
||||
.expect("Failed to write to file");
|
||||
|
||||
(secret_key, public_key)
|
||||
};
|
||||
@@ -39,4 +44,22 @@ pub fn get_keypair() -> Result<(StaticSecret, PublicKey), Box<dyn std::error::Er
|
||||
|
||||
pub fn shared_secret_from_keypair(secret: StaticSecret, pubkey: PublicKey) -> SharedSecret {
|
||||
secret.diffie_hellman(&pubkey)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_addr_from_pubkey(pubkey: &PublicKey) -> Ipv6Addr {
|
||||
let mut hasher = Blake2bVar::new(16).unwrap(); // output ipv6 is 16 bytes
|
||||
hasher.update(pubkey.as_bytes());
|
||||
let mut buf = [0u8; 16];
|
||||
hasher.finalize_variable(&mut buf).unwrap();
|
||||
|
||||
let ipv6_bytes: [u8; 16] = [
|
||||
0x20, 0x00, // This prefix ensures the address falls into the 200::/7 range
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10],
|
||||
buf[11], buf[12], buf[13],
|
||||
];
|
||||
|
||||
let addr = Ipv6Addr::from(ipv6_bytes);
|
||||
println!("output buf : {:?}", addr);
|
||||
|
||||
addr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user