diff --git a/crates/rdsys-backend/Cargo.toml b/crates/rdsys-backend/Cargo.toml index e30c954..782f534 100644 --- a/crates/rdsys-backend/Cargo.toml +++ b/crates/rdsys-backend/Cargo.toml @@ -10,6 +10,9 @@ serde_json = "1" futures-util = { version = "0.3"} serde = { version = "1", features = ["derive"]} bytes = "1" +hex = "0.4.3" +crc64 = "2.0.0" +sha1 = "0.10.5" tokio = { version = "1", features = ["macros"]} reqwest = { version = "0.11", features = ["stream"]} tokio-stream = "0.1.12" diff --git a/crates/rdsys-backend/src/main.rs b/crates/rdsys-backend/src/main.rs new file mode 100644 index 0000000..88c6ad7 --- /dev/null +++ b/crates/rdsys-backend/src/main.rs @@ -0,0 +1,22 @@ +use sha1::{Sha1, Digest}; + +fn get_uid(fingerprint: String, pt_type: String) -> Result { + let hex_fingerprint = match hex::decode(fingerprint) { + Ok(hex_fingerprint) => hex_fingerprint, + Err(e) => return Err(e), + }; + + let mut hasher = Sha1::new(); + hasher.update(hex_fingerprint); + let result_fingerprint = hasher.finalize(); + let uid_string = pt_type+&hex::encode_upper(result_fingerprint); + Ok(crc64::crc64(0, uid_string.as_bytes())) + } + + +fn main() { +let hex_stuff = get_uid("FD8DC7EF92F1F14D00CF9D6F6297A3468B59E707".to_string(), "obfs4".to_string()); +println!("The result is: {:?}", hex_stuff); +let hex_stuff2 = get_uid("FD8DC7EF92F1F14D00CF9D6F6297A3468B59E707".to_string(), "scramblesuit".to_string()); +println!("The result is: {:?}", hex_stuff2); +} \ No newline at end of file diff --git a/crates/rdsys-backend/src/proto.rs b/crates/rdsys-backend/src/proto.rs index f81af42..9ecbaec 100644 --- a/crates/rdsys-backend/src/proto.rs +++ b/crates/rdsys-backend/src/proto.rs @@ -1,6 +1,6 @@ -use std::collections::HashMap; - use serde::{Deserialize, Serialize}; +use sha1::{Digest, Sha1}; +use std::collections::HashMap; /// The body of the request for resources made to the rdsys backend #[derive(Serialize)] @@ -25,6 +25,30 @@ pub struct Resource { pub params: Option>, } +impl Resource { + /// get_uid creates a unique identifier of the resource from a hash of the fingerprint + /// and bridge type. A similar process is used in rdsys + /// https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/blob/main/pkg/usecases/resources/bridges.go#L99 + /// however, the golang and rust implementations of crc64 lead to different hash values. + /// The polynomial used for rust's crc64 package is: https://docs.rs/crc64/2.0.0/src/crc64/lib.rs.html#8 + /// using "Jones" coefficients. Changing go's polynomial to match rust's still doesn't make the hashes the same. + /// We use the get_uid in this case for an identifier in the distributor so as long as it is unique, it doesn't + /// strictly need to match the value in rdsys' backend. + pub fn get_uid(self: &Self) -> Result { + let hex_fingerprint = match hex::decode(self.fingerprint.clone()) { + Ok(hex_fingerprint) => hex_fingerprint, + Err(e) => return Err(e), + }; + + let mut hasher = Sha1::new(); + hasher.update(hex_fingerprint); + let result_fingerprint = hasher.finalize(); + let uid_string = self.r#type.clone() + &hex::encode_upper(result_fingerprint); + + Ok(crc64::crc64(0, uid_string.as_bytes())) + } +} + /// A ResourceDiff holds information about new, changed, or pruned resources #[derive(Deserialize, PartialEq, Eq, Debug)] pub struct ResourceDiff {