diff --git a/Cargo.lock b/Cargo.lock
index 2044b05..f156c9a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -144,6 +144,30 @@ version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
 
+[[package]]
+name = "async-compression"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c"
+dependencies = [
+ "flate2",
+ "futures-core",
+ "memchr",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.53",
+]
+
 [[package]]
 name = "async-stream"
 version = "0.3.5"
@@ -183,6 +207,15 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "autotools"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "axum"
 version = "0.6.20"
@@ -228,6 +261,20 @@ dependencies = [
  "tower-service",
 ]
 
+[[package]]
+name = "backoff"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
+dependencies = [
+ "futures-core",
+ "getrandom",
+ "instant",
+ "pin-project-lite",
+ "rand",
+ "tokio",
+]
+
 [[package]]
 name = "backtrace"
 version = "0.3.69"
@@ -261,6 +308,16 @@ version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
 
+[[package]]
+name = "base64-serde"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7"
+dependencies = [
+ "base64 0.21.7",
+ "serde",
+]
+
 [[package]]
 name = "base64ct"
 version = "1.6.0"
@@ -404,6 +461,17 @@ dependencies = [
  "alloc-stdlib",
 ]
 
+[[package]]
+name = "bstr"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
+dependencies = [
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
 [[package]]
 name = "bucket-common-types"
 version = "0.1.0"
@@ -443,8 +511,9 @@ dependencies = [
  "bucket-common-types",
  "byte-unit",
  "bytemuck",
- "cookie",
+ "cookie 0.18.0",
  "criterion",
+ "dash-mpd",
  "ed25519-compact",
  "email_address",
  "fuser",
@@ -457,6 +526,7 @@ dependencies = [
  "log",
  "lunchbox",
  "mime",
+ "mnemonic",
  "once_cell",
  "opaque-ke",
  "passkey",
@@ -681,6 +751,16 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
 
+[[package]]
+name = "colored"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
+dependencies = [
+ "lazy_static",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "console_error_panic_hook"
 version = "0.1.7"
@@ -706,6 +786,17 @@ dependencies = [
  "unicode-segmentation",
 ]
 
+[[package]]
+name = "cookie"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
 [[package]]
 name = "cookie"
 version = "0.18.0"
@@ -720,6 +811,33 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "cookie_store"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6"
+dependencies = [
+ "cookie 0.17.0",
+ "idna 0.3.0",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "time",
+ "url",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.6"
@@ -745,6 +863,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "crc32fast"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "criterion"
 version = "0.5.1"
@@ -948,6 +1075,45 @@ dependencies = [
  "syn 2.0.53",
 ]
 
+[[package]]
+name = "dash-mpd"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18c18f28b58beade78e0f61a846a63a122cb92c5f5ed6bad29d7ad13287c7526"
+dependencies = [
+ "async-recursion",
+ "backoff",
+ "base64 0.21.7",
+ "base64-serde",
+ "bstr",
+ "chrono",
+ "colored",
+ "data-url",
+ "ffprobe",
+ "file-format",
+ "fs-err",
+ "governor",
+ "hex-literal",
+ "iso8601",
+ "lazy_static",
+ "num-traits",
+ "pssh-box",
+ "quick-xml",
+ "regex",
+ "reqwest",
+ "sanitise-file-name",
+ "serde",
+ "serde_path_to_error",
+ "serde_with",
+ "tempfile",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "url",
+ "xattr",
+ "xmltree",
+]
+
 [[package]]
 name = "dashmap"
 version = "5.5.3"
@@ -967,6 +1133,12 @@ version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
 
+[[package]]
+name = "data-url"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
+
 [[package]]
 name = "der"
 version = "0.7.8"
@@ -1121,6 +1293,15 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "encoding_rs"
+version = "0.8.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "equivalent"
 version = "1.0.1"
@@ -1163,24 +1344,65 @@ dependencies = [
  "subtle",
 ]
 
+[[package]]
+name = "ffprobe"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5d603974ab029fc75cebf00bfa06c9c6f49a6fb657f4f5f6a9fd6cbd76910a4"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "fiat-crypto"
 version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382"
 
+[[package]]
+name = "file-format"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ba1b81b3c213cf1c071f8bf3b83531f310df99642e58c48247272eef006cae5"
+
 [[package]]
 name = "fixedbitset"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
 
+[[package]]
+name = "flate2"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
 [[package]]
 name = "form_urlencoded"
 version = "1.2.1"
@@ -1190,6 +1412,15 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "fs-err"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "funty"
 version = "2.0.0"
@@ -1282,6 +1513,12 @@ version = "0.3.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
 
+[[package]]
+name = "futures-timer"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
+
 [[package]]
 name = "futures-util"
 version = "0.3.30"
@@ -1697,6 +1934,26 @@ dependencies = [
  "syn 2.0.53",
 ]
 
+[[package]]
+name = "governor"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
+dependencies = [
+ "cfg-if",
+ "dashmap",
+ "futures",
+ "futures-timer",
+ "no-std-compat",
+ "nonzero_ext",
+ "parking_lot",
+ "portable-atomic",
+ "quanta",
+ "rand",
+ "smallvec",
+ "spinning_top",
+]
+
 [[package]]
 name = "group"
 version = "0.13.0"
@@ -1843,6 +2100,12 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
 
+[[package]]
+name = "hxdmp"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a17b27f28a7466846baca75f0a5244e546e44178eb7f1c07a3820f413e91c6b0"
+
 [[package]]
 name = "hyper"
 version = "0.14.28"
@@ -1879,6 +2142,19 @@ dependencies = [
  "tokio-io-timeout",
 ]
 
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
 [[package]]
 name = "iana-time-zone"
 version = "0.1.60"
@@ -1908,6 +2184,16 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
 [[package]]
 name = "idna"
 version = "0.5.0"
@@ -1958,6 +2244,21 @@ dependencies = [
  "generic-array",
 ]
 
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+
 [[package]]
 name = "is-terminal"
 version = "0.4.12"
@@ -1969,6 +2270,15 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "iso8601"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
+dependencies = [
+ "nom",
+]
+
 [[package]]
 name = "itertools"
 version = "0.10.5"
@@ -2134,12 +2444,42 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "mnemonic"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b8f3a258db515d5e91a904ce4ae3f73e091149b90cadbdb93d210bee07f63b"
+
 [[package]]
 name = "multimap"
 version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
 
+[[package]]
+name = "native-tls"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "no-std-compat"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
+
 [[package]]
 name = "nom"
 version = "7.1.3"
@@ -2150,6 +2490,12 @@ dependencies = [
  "minimal-lexical",
 ]
 
+[[package]]
+name = "nonzero_ext"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
+
 [[package]]
 name = "num-bigint"
 version = "0.4.4"
@@ -2195,6 +2541,27 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "num_enum"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b"
+dependencies = [
+ "proc-macro-crate 3.1.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.53",
+]
+
 [[package]]
 name = "object"
 version = "0.32.2"
@@ -2244,6 +2611,50 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "openssl"
+version = "0.10.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
+dependencies = [
+ "bitflags 2.4.2",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.53",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
 [[package]]
 name = "p256"
 version = "0.13.2"
@@ -2323,7 +2734,7 @@ checksum = "f14d42b14749cc7927add34a9932b3b3cc5349a633384850baa67183061439dd"
 dependencies = [
  "ciborium",
  "coset",
- "idna",
+ "idna 0.5.0",
  "passkey-authenticator",
  "passkey-types",
  "public-suffix",
@@ -2556,6 +2967,12 @@ dependencies = [
  "universal-hash",
 ]
 
+[[package]]
+name = "portable-atomic"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
+
 [[package]]
 name = "powerfmt"
 version = "0.2.0"
@@ -2725,6 +3142,50 @@ dependencies = [
  "prost",
 ]
 
+[[package]]
+name = "protobuf-src"
+version = "1.1.0+21.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1"
+dependencies = [
+ "autotools",
+]
+
+[[package]]
+name = "psl-types"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
+
+[[package]]
+name = "pssh-box"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d0f24d6df7a94002c1a3d365d606e2fda2f81d0b569cce73b5cdb2b32457989"
+dependencies = [
+ "anyhow",
+ "base64 0.21.7",
+ "bstr",
+ "byteorder",
+ "bytes",
+ "hex",
+ "hex-literal",
+ "hxdmp",
+ "num_enum",
+ "prost",
+ "prost-build",
+ "prost-types",
+ "protobuf-src",
+ "quick-xml",
+ "serde",
+ "serde-xml-rs",
+ "serde_json",
+ "serde_path_to_error",
+ "serde_with",
+ "tracing",
+ "zerocopy",
+]
+
 [[package]]
 name = "ptr_meta"
 version = "0.1.4"
@@ -2751,12 +3212,47 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ca346b8ff0739660876c8d96a6f9de5cd9b4cd87500bb0ce92485318c674afe"
 
+[[package]]
+name = "publicsuffix"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
+dependencies = [
+ "idna 0.3.0",
+ "psl-types",
+]
+
+[[package]]
+name = "quanta"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c"
+dependencies = [
+ "crossbeam-utils",
+ "libc",
+ "once_cell",
+ "raw-cpuid",
+ "wasi",
+ "web-sys",
+ "winapi",
+]
+
 [[package]]
 name = "quick-error"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
 
+[[package]]
+name = "quick-xml"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
 [[package]]
 name = "quote"
 version = "1.0.35"
@@ -2802,6 +3298,15 @@ dependencies = [
  "getrandom",
 ]
 
+[[package]]
+name = "raw-cpuid"
+version = "11.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1"
+dependencies = [
+ "bitflags 2.4.2",
+]
+
 [[package]]
 name = "rayon"
 version = "1.9.0"
@@ -2875,6 +3380,51 @@ dependencies = [
  "bytecheck",
 ]
 
+[[package]]
+name = "reqwest"
+version = "0.11.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
+dependencies = [
+ "async-compression",
+ "base64 0.21.7",
+ "bytes",
+ "cookie 0.17.0",
+ "cookie_store",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-tls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "system-configuration",
+ "tokio",
+ "tokio-native-tls",
+ "tokio-socks",
+ "tokio-util",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
 [[package]]
 name = "rfc6979"
 version = "0.4.0"
@@ -2979,6 +3529,15 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.7",
+]
+
 [[package]]
 name = "rustversion"
 version = "1.0.14"
@@ -3000,6 +3559,21 @@ dependencies = [
  "winapi-util",
 ]
 
+[[package]]
+name = "sanitise-file-name"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d36299972b96b8ae7e8f04ecbf75fb41a27bf3781af00abcf57609774cb911"
+
+[[package]]
+name = "schannel"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
 [[package]]
 name = "scoped-tls"
 version = "1.0.1"
@@ -3033,6 +3607,29 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "security-framework"
+version = "2.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
 [[package]]
 name = "semver"
 version = "1.0.22"
@@ -3070,6 +3667,18 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "serde-xml-rs"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782"
+dependencies = [
+ "log",
+ "serde",
+ "thiserror",
+ "xml-rs",
+]
+
 [[package]]
 name = "serde_derive"
 version = "1.0.197"
@@ -3093,6 +3702,16 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_path_to_error"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
+dependencies = [
+ "itoa",
+ "serde",
+]
+
 [[package]]
 name = "serde_spanned"
 version = "0.6.5"
@@ -3274,6 +3893,15 @@ version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
 
+[[package]]
+name = "spinning_top"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
+dependencies = [
+ "lock_api",
+]
+
 [[package]]
 name = "spki"
 version = "0.7.3"
@@ -3386,6 +4014,27 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
 
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
 [[package]]
 name = "tap"
 version = "1.0.1"
@@ -3530,6 +4179,28 @@ dependencies = [
  "syn 2.0.53",
 ]
 
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-socks"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
+dependencies = [
+ "either",
+ "futures-util",
+ "thiserror",
+ "tokio",
+]
+
 [[package]]
 name = "tokio-stream"
 version = "0.1.15"
@@ -3837,7 +4508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
 dependencies = [
  "form_urlencoded",
- "idna",
+ "idna 0.5.0",
  "percent-encoding",
 ]
 
@@ -3858,6 +4529,12 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
 [[package]]
 name = "version_check"
 version = "0.9.4"
@@ -4264,6 +4941,16 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "wyz"
 version = "0.5.1"
@@ -4285,6 +4972,32 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "xattr"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
+dependencies = [
+ "libc",
+ "linux-raw-sys",
+ "rustix",
+]
+
+[[package]]
+name = "xml-rs"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
+
+[[package]]
+name = "xmltree"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb"
+dependencies = [
+ "xml-rs",
+]
+
 [[package]]
 name = "yansi"
 version = "0.5.1"
diff --git a/Cargo.toml b/Cargo.toml
index d934289..91bddd9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,12 +5,22 @@ edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 [features]
+default = ["web"]
 s3 = []
 proto = []
 wasm = []
+# Stream API compatibility, mpeg-dash video stream support
+stream = []
+# Listen changes in the Storage, synchronization API support. for listening and parsing webhook events.
+sync = []
+# Compress files before transit. 
+compression = []
+# 
+
 web = ["wasm", "proto"]
 cli = ["proto", "s3", "native"]
 native = [] #"dep:tokio", "dep:tokio-stream"
+
 [dependencies]
 bucket-common-types = { git = "https://github.com/Tim-Leon/bucket-common-types.git", features = [
     "secret_share_link",
@@ -60,6 +70,8 @@ pkg-version = "1.0.0"
 log = "0.4.20"
 prokio = "0.1.0"
 email_address = "0.2.4"
+mnemonic = "1.1.1"
+dash-mpd = {version = "0.15.0", features = ["tokio"],optional = true}
 
 [target.'cfg(unix)'.dependencies]
 fuser = "0.14.0" # https://crates.io/crates/fuser
diff --git a/src/controller/account/authentication.rs b/src/controller/account/authentication.rs
index 9922ef0..ecf5b71 100644
--- a/src/controller/account/authentication.rs
+++ b/src/controller/account/authentication.rs
@@ -2,6 +2,7 @@ use crate::client::query_client::backend_api::{AccountLoginFinishRequest, Accoun
 use crate::client::query_client::QueryClient;
 use crate::controller::account::errors::{LoginError, RegisterError};
 
+use crate::encryption_v1::encryption::create_ed25519_signing_keys;
 use crate::encryption_v1::hash::password_strength;
 use crate::{
     constants::PASSWORD_STRENGTH_SCORE,
@@ -86,7 +87,7 @@ pub async fn register(
     if password_strength(&email, &password, None)? < PASSWORD_STRENGTH_SCORE {
         return Err(RegisterError::PasswordTooWeak);
     }
-    let secrets = encryption_v1::encryption::setup(password, email)?;
+    let master_key = encryption_v1::encryption::setup(password, email)?;
     let mut rng = rand::thread_rng();
     let oprf_start =
         opaque_ke::ClientRegistration::<DefaultCipherSuite>::start(&mut rng, password.as_bytes())
@@ -109,11 +110,13 @@ pub async fn register(
         ClientRegistrationFinishParameters::default(),
     )?;
 
+    let signing_key = create_ed25519_signing_keys(&master_key).unwrap();
+
     let finish_req = CreateAccountFinishRequest {
         oprf: oprf_finish.message.serialize().to_vec(),
         username: username.to_string(),
         session_id: start_resp.session_id,
-        public_signing_key: secrets.get_ed25519_public_signing_key().as_slice().to_vec(),
+        public_signing_key: signing_key.pk.to_vec(),
     };
     let finish_resp = query_client
         .create_account_finish(finish_req)
diff --git a/src/controller/bucket/download_handler.rs b/src/controller/bucket/download_handler.rs
index 272acb8..e739ecc 100644
--- a/src/controller/bucket/download_handler.rs
+++ b/src/controller/bucket/download_handler.rs
@@ -88,12 +88,12 @@ impl BucketFileDownloadHandler for WebBucketFileWriter {
         match decrypted_buffer {
             Either::Left(decrypted_buffer) => {
                 self.write_target_file
-                    .write_chunk(&decrypted_buffer, self.offset);
+                    .write_chunk(&decrypted_buffer, self.offset).unwrap();
                 self.offset += decrypted_buffer.len() as u64;
             }
             Either::Right(decrypted_buffer) => {
                 self.write_target_file
-                    .write_chunk(&decrypted_buffer, self.offset);
+                    .write_chunk(&decrypted_buffer, self.offset).unwrap();
                 self.offset += decrypted_buffer.len() as u64;
             }
         }
@@ -120,7 +120,7 @@ impl BucketFileDownloadHandler for WebBucketFileWriter {
         match self.decryption_module {
             None => {}
             Some(module) => {
-                module.finalize()?; //TODO: Invalid Signature
+                module.finalize(); //TODO: Invalid Signature
             }
         }
 
diff --git a/src/controller/bucket/upload_handler.rs b/src/controller/bucket/upload_handler.rs
index f712a0a..3033f95 100644
--- a/src/controller/bucket/upload_handler.rs
+++ b/src/controller/bucket/upload_handler.rs
@@ -38,7 +38,7 @@ pub trait BucketFileUploadHandler {
     // Called when a chunk is uploaded. returns the chunk to be uploaded. It's up to the implementation to encrypt the chunk if the bucket is encrypted.
     async fn on_upload_chunk(&mut self, chunk_size: u64) -> Result<Vec<u8>, Self::Error>;
     // Called when the last chunk has been uploaded. In this method the user is still able to upload data, if so it will return a Vec.
-    fn on_upload_finish(self) -> Result<Option<Vec<u8>>, Self::Error>;
+    fn on_upload_finish(self) -> Result<(), Self::Error>;
 }
 
 #[async_trait(?Send)]
@@ -56,7 +56,8 @@ impl BucketFileUploadHandler for BucketFileReader {
     ) -> Result<u64, Self::Error> {
         match bucket_encryption {
             Some(_bucket_encryption) => match &self.encryption_module {
-                Some(_encryption_module) => {}
+                Some(_encryption_module) => {
+                }
                 None => {
                     return Err(BucketDownloadHandlerFileErrors::EncryptionModuleNotInitialized);
                 }
@@ -76,18 +77,18 @@ impl BucketFileUploadHandler for BucketFileReader {
 
         match &mut self.encryption_module {
             Some(x) => {
-                let decrypted_bytes = x.update(bytes)?;
-                Ok(decrypted_bytes)
+                let encrypted_bytes = x.update(bytes)?;
+                Ok(encrypted_bytes)
             }
             None => Ok(bytes),
         }
     }
 
-    fn on_upload_finish(self) -> Result<Option<Vec<u8>>, Self::Error> {
-        let signed_hash: Option<Vec<u8>> = match self.encryption_module {
-            Some(x) => Some(x.finalize()?),
+    fn on_upload_finish(self) -> Result<(), Self::Error> {
+        let signed_hash = match self.encryption_module {
+            Some(x) => Some(x.finalize()),
             None => return Err(Self::Error::EncryptionModuleNotInitialized),
         };
-        Ok(signed_hash)
+        Ok(())
     }
 }
diff --git a/src/encryption_v1/constants.rs b/src/encryption_v1/constants.rs
index 2d4a9c3..f6e22c5 100644
--- a/src/encryption_v1/constants.rs
+++ b/src/encryption_v1/constants.rs
@@ -21,3 +21,5 @@ pub const HIGHWAY_HASH_KEY: [u64; 4] = [
 ];
 
 pub const V1_ENCRYPTION_PASSWORD_SALT: &str = "";
+
+pub const V1_X25519_SIGNATURE_HASH_SALT:&str = "";
\ No newline at end of file
diff --git a/src/encryption_v1/decryption_module.rs b/src/encryption_v1/decryption_module.rs
index cff13de..23cff56 100644
--- a/src/encryption_v1/decryption_module.rs
+++ b/src/encryption_v1/decryption_module.rs
@@ -9,30 +9,28 @@ use highway::HighwayHash;
 use crate::encryption_v1::constants::{
     AES_GCM_NONCE, HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE,
 };
-use crate::encryption_v1::encryption::{generate_bucket_encryption_key, ClientSecrets};
+use crate::encryption_v1::encryption::{generate_bucket_encryption_key, MasterKey};
+
+use super::hash_based_signature::Ed25519HighwayHashBasedSignature;
 
 pub trait DecryptionModule {
     type Error;
     /// Returns vector of decrypted data
     fn update(&mut self, ciphertext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error>;
-    /// Finalize decryption by returning Vector which could contain hash/signature, get creative.
-    fn finalize(self) -> Result<(), Self::Error>;
+    fn finalize(self);
 }
 #[derive(Clone)]
 pub struct ZeroKnowledgeDecryptionModuleV1 {
-    secrets: Arc<ClientSecrets>,
+    secrets: Arc<MasterKey>,
     bucket_symmetric_encryption_key: aes_gcm::Aes256Gcm,
-    hasher: highway::HighwayHasher,
     nonce: Nonce<typenum::U12>,
-    ed25519_noise: Noise,
-    signature: Option<Signature>,
+    hash_based_signature: Option<Ed25519HighwayHashBasedSignature>,
 }
 
 impl ZeroKnowledgeDecryptionModuleV1 {
     pub fn new(
-        secrets: Arc<ClientSecrets>,
+        secrets: Arc<MasterKey>,
         bucket_id: &uuid::Uuid,
-        signature: Option<Signature>,
     ) -> Self {
         Self {
             secrets: secrets.clone(),
@@ -41,10 +39,8 @@ impl ZeroKnowledgeDecryptionModuleV1 {
                 bucket_id,
             )
             .unwrap(),
-            hasher: highway::HighwayHasher::new(highway::Key(HIGHWAY_HASH_KEY)),
             nonce: *Nonce::from_slice(&AES_GCM_NONCE), //TODO: NONCE should come from the bucket name?
-            ed25519_noise: Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap(),
-            signature,
+            hash_based_signature: None
         }
     }
 }
@@ -60,26 +56,15 @@ pub enum DecryptionError {
 impl DecryptionModule for ZeroKnowledgeDecryptionModuleV1 {
     type Error = DecryptionError;
     fn update(&mut self, ciphertext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error> {
-        self.hasher.append(ciphertext.as_ref());
         let plaintext = self
             .bucket_symmetric_encryption_key
             .decrypt(&self.nonce, ciphertext.as_ref())
             .map_err(DecryptionError::FailedToDecryptChunk)?;
         Ok(plaintext)
     }
-
-    fn finalize(self) -> Result<(), Self::Error> {
-        let hash_result = self.hasher.finalize256();
-        match self.signature {
-            None => {}
-            Some(signature) => {
-                self.secrets
-                    .ed25519_keypair
-                    .pk
-                    .verify(bytemuck::bytes_of(&hash_result), &signature)
-                    .map_err(DecryptionError::InvalidSignature)?;
-            }
-        }
-        Ok(())
+    
+    fn finalize(self) {
+        
     }
+
 }
diff --git a/src/encryption_v1/encryption.rs b/src/encryption_v1/encryption.rs
index a450af2..a6847c4 100644
--- a/src/encryption_v1/encryption.rs
+++ b/src/encryption_v1/encryption.rs
@@ -3,6 +3,7 @@ use aes_gcm::{
     aead::{generic_array::typenum, Aead},
     KeyInit, Nonce,
 };
+use argon2::password_hash::SaltString;
 
 use std::sync::Arc;
 //use sha2::Sha512;
@@ -13,8 +14,10 @@ use crate::encryption_v1::hash::{
 
 use highway::HighwayHash;
 
-use sha3::{digest::InvalidLength, Digest};
+use sha3::{digest::InvalidLength, Digest, Sha3_256};
 use std::str;
+
+use super::constants::V1_X25519_SIGNATURE_HASH_SALT;
 // struct DefaultCipherSuite;
 // impl CipherSuite for DefaultCipherSuite {
 //     type OprfCs = opaque_ke::Ristretto255;
@@ -76,104 +79,46 @@ pub enum EncryptionSetupError {
 * TODO: Fuzz input
 * MUST BE DETERMINISTIC
 */
-pub fn setup(password: &str, email: &str) -> Result<ClientSecrets, EncryptionSetupError> {
-    let master_key = argon2id_hash_password(password, email, V1_ENCRYPTION_PASSWORD_SALT)?;
-    let seed = ed25519_compact::Seed::from_slice(master_key[0..32].as_bytes()).unwrap();
-    let ed25519_keypair = ed25519_compact::KeyPair::from_seed(seed); //from_slice(master_key.as_bytes().take).unwrap();
-    Ok(ClientSecrets {
-        master_key,
-        ed25519_keypair,
+pub fn setup(password: &str, email: &str) -> Result<MasterKey, EncryptionSetupError> {
+    let salt = SaltString::from_b64(&V1_ENCRYPTION_PASSWORD_SALT).map_err(PasswordHashErrors::PasswordHashError)?;
+    let master_key = argon2id_hash_password(password, email, salt.as_salt())?
+        .hash
+        .unwrap();
+    Ok(MasterKey {
+        0: master_key.to_string(),
     })
 }
 
+
+
+pub fn create_ed25519_signing_keys(master_key: &MasterKey) -> Result<ed25519_compact::KeyPair, ed25519_compact::Error>{
+    let mut hasher = Sha3_256::new(); 
+    hasher.update(master_key.0.as_bytes());
+    hasher.update(V1_X25519_SIGNATURE_HASH_SALT);
+    let slice = hasher.finalize();
+    let seed = ed25519_compact::Seed::from_slice(&slice).unwrap(); //[0..32]
+    let ed25519_key_pair = ed25519_compact::KeyPair::from_seed(seed); 
+    Ok(ed25519_key_pair)
+}
+
 pub fn generate_bucket_encryption_key(
-    secrets: Arc<ClientSecrets>,
+    master_key: Arc<MasterKey>,
     bucket_id: &uuid::Uuid,
 ) -> Result<aes_gcm::Aes256Gcm, InvalidLength> {
-    let bucket_key = bucket_key_hash_sha256(secrets.master_key.clone(), bucket_id);
+    let bucket_key = bucket_key_hash_sha256(&master_key, bucket_id);
     //let aes_gcm_key = aes_gcm::Key::<aes_gcm::Aes256Gcm>::from_slice(bucket_key.as_slice());
     let aes_gcm_key = aes_gcm::Aes256Gcm::new_from_slice(bucket_key.as_slice());
     aes_gcm_key
 }
-
-#[derive(zeroize::Zeroize, Clone)]
-pub struct ClientSecrets {
-    master_key: String,
-    pub ed25519_keypair: ed25519_compact::KeyPair,
-}
-
-impl ClientSecrets {
-    pub fn get_ed25519_public_signing_key(&self) -> ed25519_compact::PublicKey {
-        self.ed25519_keypair.pk
-    }
+#[derive(zeroize::Zeroize)]
+pub struct Secrets {
+    pub master_key: MasterKey,
+    pub signing_key: ed25519_compact::KeyPair,
 }
 
-/*
-Use the aes_gcm symetric key to encrypt the file content.
-Use HighwayHash to hash the encrypted file content.
-Use the ed25519 keypair to sign the hash.
-*/
-pub async fn encrypted_upload_files(
-    aes_gcm_symmetric_key: &aes_gcm::Key<aes_gcm::Aes256Gcm>,
-    ed25519_signing_key: &ed25519_compact::KeyPair,
-    file: gloo::file::File,
-    upload_fn: fn(&[u8]),
-    upload_finish: fn(&[u8]),
-) {
-    let key = highway::Key([1, 2, 3, 4]);
-    let mut highway_hash = highway::HighwayHasher::new(key);
-    let filename = file.name();
-    let aes_gcm_cipher = aes_gcm::Aes256Gcm::new_from_slice(aes_gcm_symmetric_key).unwrap();
-    let nonce = aes_gcm::Nonce::from_slice(filename.as_bytes()); //TODO: Fix
-                                                                 //let mut file_bytes = file.bytes();
-                                                                 //file.read_to_end(&mut file_bytes);
-                                                                 //TODO: Chunk it. Read 1MB at a time.
-                                                                 //let file_reader = gloo::file::futures::read_as_array_bytes(&file, read_fn);
-    let file_size = file.size();
-    // Iterate over the file in 1MB chunks,
-    // encrypt each chunk while also hashing it.
-    // Then upload the encrypted chunk.
-    // After the file is uploaded, sign the hash, upload the hash signature.
-    // Done!
-    for _it in 0..&file_size / 1024 {
-        let chunk_data = gloo::file::futures::read_as_bytes(&file).await.unwrap(); //TODO: What if file is too big for memory?
-        let ciphertext = aes_gcm_cipher
-            .encrypt(nonce, chunk_data.as_slice())
-            .unwrap();
-        highway_hash.append(&ciphertext);
-        upload_fn(&ciphertext);
-    }
-    let hash = highway_hash.finalize256();
-    let signature = ed25519_signing_key.sk.sign(bytemuck::bytes_of(&hash), None);
-    // Upload
-    upload_finish(signature.as_slice());
-}
-
-pub async fn encrypt_chunk(
-    aes_gcm_symmetric_key: &aes_gcm::Key<aes_gcm::Aes256Gcm>,
-    nonce: &Nonce<typenum::U12>,
-    _ed25519_signing_key: &ed25519_compact::KeyPair,
-    highway_hash: &mut highway::HighwayHasher,
-    chunk_data: Vec<u8>,
-) -> Vec<u8> {
-    let aes_gcm_cipher = aes_gcm::Aes256Gcm::new(aes_gcm_symmetric_key);
-    let ciphertext = aes_gcm_cipher
-        .encrypt(nonce, chunk_data.as_slice())
-        .unwrap();
-    highway_hash.append(&ciphertext);
-    ciphertext
-}
-
-// pub async fn encrypt_finalize(
-//     ed25519_signing_key: &ed25519_compact::KeyPair,
-//     highway_hash: &mut highway::HighwayHasher,
-// ) -> Signature {
-//     let hash = highway_hash.finalize256();
-//     let signature = ed25519_signing_key.sk.sign(&bytemuck::bytes_of(&hash), None);
-//     signature
-// }
+#[derive(zeroize::Zeroize, Clone)]
+pub struct MasterKey (pub String);
 
-//pub fn generate_rsa_keypair()
 
 #[cfg(test)]
 mod tests {
diff --git a/src/encryption_v1/encryption_module.rs b/src/encryption_v1/encryption_module.rs
index 940143c..60c0ea9 100644
--- a/src/encryption_v1/encryption_module.rs
+++ b/src/encryption_v1/encryption_module.rs
@@ -3,29 +3,29 @@ use std::sync::Arc;
 use aes_gcm::aead::generic_array::typenum;
 use aes_gcm::aead::Aead;
 use aes_gcm::Nonce;
-use ed25519_compact::Noise;
 use highway::HighwayHash;
 
 use crate::encryption_v1::constants::{
     AES_GCM_NONCE, HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE,
 };
-use crate::encryption_v1::encryption::{generate_bucket_encryption_key, ClientSecrets};
+use crate::encryption_v1::encryption::{generate_bucket_encryption_key, MasterKey};
+
+use super::hash_based_signature::{Ed25519HighwayHashBasedSignature, HashBasedSignature};
 
 pub trait EncryptionModule: Clone + Sized{
     type Error;
     /// Returns vector of encrypted data
     fn update(&mut self, plaintext: impl AsRef<[u8]>) -> Result<Vec<u8>, Self::Error>;
     /// Finalize encryption by returning Vector which could contain hash/signature, get creative.
-    fn finalize(self) -> Result<Vec<u8>, Self::Error>;
+    fn finalize(self);
 }
 
 #[derive(Clone)]
 pub struct ZeroKnowledgeEncryptionModuleV1 {
-    secrets: Arc<ClientSecrets>,
+    secrets: Arc<MasterKey>,
     bucket_symmetric_encryption_key: aes_gcm::Aes256Gcm,
-    hasher: highway::HighwayHasher,
     nonce: Nonce<typenum::U12>,
-    ed25519_noise: Noise,
+    hash_based_signature: Option<Ed25519HighwayHashBasedSignature>,
 }
 
 #[derive(Debug, thiserror::Error)]
@@ -35,7 +35,7 @@ pub enum EncryptionError {
 }
 
 impl ZeroKnowledgeEncryptionModuleV1 {
-    pub fn new(secrets: Arc<ClientSecrets>, bucket_id: &uuid::Uuid) -> Self {
+    pub fn new(secrets: Arc<MasterKey>, bucket_id: &uuid::Uuid) -> Self {
         Self {
             secrets: secrets.clone(),
             bucket_symmetric_encryption_key: generate_bucket_encryption_key(
@@ -43,9 +43,8 @@ impl ZeroKnowledgeEncryptionModuleV1 {
                 bucket_id,
             )
             .unwrap(),
-            hasher: highway::HighwayHasher::new(highway::Key(HIGHWAY_HASH_KEY)),
-            nonce: *Nonce::from_slice(&AES_GCM_NONCE), //TODO: NONCE should come from the bucket name?
-            ed25519_noise: Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap(),
+            nonce: *Nonce::from_slice(&AES_GCM_NONCE),
+            hash_based_signature: None,
         }
     }
 }
@@ -57,17 +56,11 @@ impl EncryptionModule for ZeroKnowledgeEncryptionModuleV1 {
             .bucket_symmetric_encryption_key
             .encrypt(&self.nonce, plaintext.as_ref())
             .map_err(EncryptionError::FailedToEncryptChunk)?;
-        self.hasher.append(&ciphertext);
         Ok(ciphertext)
     }
 
-    fn finalize(self) -> Result<Vec<u8>, Self::Error> {
-        let hash_result = self.hasher.finalize256();
-        let signature = self
-            .secrets
-            .ed25519_keypair
-            .sk
-            .sign(bytemuck::bytes_of(&hash_result), Some(self.ed25519_noise));
-        Ok(signature.to_vec())
+    fn finalize(self) {
+        
     }
+
 }
diff --git a/src/encryption_v1/hash.rs b/src/encryption_v1/hash.rs
index bc6622b..b354611 100644
--- a/src/encryption_v1/hash.rs
+++ b/src/encryption_v1/hash.rs
@@ -1,10 +1,12 @@
 use crate::constants::PASSWORD_STRENGTH_SCORE;
 use aes_gcm::aead::generic_array::{typenum, GenericArray};
-use argon2::password_hash::SaltString;
-use argon2::{Argon2, PasswordHasher};
+use argon2::password_hash::{Salt, SaltString};
+use argon2::{Argon2, PasswordHash, PasswordHasher};
 use base64::engine::Engine;
 use sha3::{Digest, Sha3_256};
 
+use super::encryption::MasterKey;
+
 #[derive(Debug, thiserror::Error)]
 pub enum PasswordHashErrors {
     //#[error("Email with too long username")]
@@ -21,14 +23,17 @@ pub enum PasswordHashErrors {
 * Will be user to create the master key. This key is used to derive encryption keys and signing key for the user.
 * It is essential that the password is kept secret or all the encrypted data can be lost.
 */
-pub fn argon2id_hash_password(
-    password: &str,
-    email: &str,
-    salt_addon: &str,
-) -> Result<String, PasswordHashErrors> {
+pub fn argon2id_hash_password<'a, 'b>(
+    password: &'a str,
+    email: &'a str,
+    salt_addon: Salt<'a>, 
+) -> Result<PasswordHash<'b>, PasswordHashErrors>
+// Specifically the salt must outlive the password hash.
+where 'a:'b
+{
     // Hash the email with sha512 to get a 64 bytes hash. Which is the max size for argon2id salt. Perfect.
     let mut sha256_hasher = Sha3_256::new(); //Sha3_512::new();
-    sha256_hasher.update(salt_addon.as_bytes()); // This is just additional entropy to make the email more unique. Might be useful?
+    sha256_hasher.update(salt_addon.as_str().as_bytes()); // This is just additional entropy to make the email more unique. Might be useful?
     sha256_hasher.update(email.as_bytes());
     let email_hash: GenericArray<_, _> = sha256_hasher.finalize();
     let _password_strength = password_strength(email, password, None)?;
@@ -38,12 +43,13 @@ pub fn argon2id_hash_password(
 
     // Base64 expand size by 1/3
     let encoded = base64::engine::general_purpose::STANDARD_NO_PAD.encode(email_hash.as_slice());
-    let salt = SaltString::from_b64(&encoded).map_err(PasswordHashErrors::PasswordHashError)?;
+    //let salt = SaltString::from_b64(&encoded).map_err(PasswordHashErrors::PasswordHashError)?; .as_salt()
     let argon2id = Argon2::default();
     let password_hash = argon2id
-        .hash_password(password.as_bytes(), salt.as_salt())
+        .hash_password(password.as_bytes(), salt_addon)
         .map_err(PasswordHashErrors::PasswordHashError)?;
-    Ok(password_hash.to_string())
+
+    Ok(password_hash)
 }
 
 #[derive(Debug, thiserror::Error)]
@@ -84,12 +90,12 @@ pub fn password_strength(
 }
 
 pub fn bucket_key_hash_sha256(
-    password_hash: String,
+    password_hash: &MasterKey,
     bucket_id: &uuid::Uuid,
 ) -> GenericArray<u8, typenum::U32> {
     let mut hasher = Sha3_256::new(); //Sha3_512::new();
     hasher.update(bucket_id.as_bytes());
-    hasher.update(password_hash.to_string().as_bytes());
+    hasher.update(password_hash.0.as_bytes());
 
     hasher.finalize()
 }
diff --git a/src/encryption_v1/hash_based_signature.rs b/src/encryption_v1/hash_based_signature.rs
new file mode 100644
index 0000000..5b2d25a
--- /dev/null
+++ b/src/encryption_v1/hash_based_signature.rs
@@ -0,0 +1,70 @@
+use ed25519_compact::{Noise, Signature, VerifyingState};
+use highway::{HighwayHash, HighwayHasher, Key};
+
+use super::{
+    constants::{HIGHWAY_HASH_KEY, SHARE_LINK_SIGNATURE_NOISE},
+    encryption::MasterKey,
+};
+// Used for creating signatures
+pub trait HashBasedSignature: Clone + Sized {
+    type Error;
+
+    fn update(&mut self, ciphertext: impl AsRef<[u8]>);
+    // Creates a signature. 
+    fn finalize(self) -> Result<Signature, Self::Error>;
+}
+
+#[derive(Clone)]
+pub struct Ed25519HighwayHashBasedSignature {
+    highway_hash: highway::HighwayHasher,
+    secret_key: ed25519_compact::SecretKey,
+    ed25519_noise: Noise,
+    //signature: Option<Signature>,
+}
+#[derive(thiserror::Error, Debug)]
+pub enum Ed25519HighwayHashBasedSignatureError {
+    #[error(transparent)]
+    Ed25519Error(#[from] ed25519_compact::Error),
+}
+
+impl Ed25519HighwayHashBasedSignature {
+    // Either we are creating a signature or we provide a signature to verify.
+    fn new(
+        //master_key: &MasterKey,
+        secret_key: ed25519_compact::SecretKey,
+        //signature: Option<Signature>,
+    ) -> Result<Self, Ed25519HighwayHashBasedSignatureError> {
+        //let seed = ed25519_compact::Seed::from_slice(master_key.0.as_bytes()).unwrap(); //[0..32]
+        //let ed25519_signing_key_pair = ed25519_compact::KeyPair::from_seed(seed); //from_slice(master_key.as_bytes().take).unwrap();
+        let key = highway::Key(HIGHWAY_HASH_KEY);
+        let highway_hash = highway::HighwayHasher::new(key);
+        let ed25519_noise =
+            ed25519_compact::Noise::from_slice(&SHARE_LINK_SIGNATURE_NOISE).unwrap();
+
+        Ok(Ed25519HighwayHashBasedSignature {
+            highway_hash,
+            secret_key: secret_key,
+            ed25519_noise,
+            //signature,
+        })
+    }
+}
+
+impl HashBasedSignature for Ed25519HighwayHashBasedSignature {
+    type Error = Ed25519HighwayHashBasedSignatureError;
+
+    fn update(&mut self, ciphertext: impl AsRef<[u8]>) {
+        self.highway_hash.append(ciphertext.as_ref())
+    }
+
+    fn finalize(self) -> Result<Signature, Self::Error> {
+        let hash_result = self.highway_hash.finalize256();
+        let signature = self
+            .secret_key
+            .sign(bytemuck::bytes_of(&hash_result), Some(self.ed25519_noise));
+
+        Ok(signature)
+    }
+}
+
+
diff --git a/src/encryption_v1/hash_based_signature_verifier.rs b/src/encryption_v1/hash_based_signature_verifier.rs
new file mode 100644
index 0000000..f7bc26c
--- /dev/null
+++ b/src/encryption_v1/hash_based_signature_verifier.rs
@@ -0,0 +1,38 @@
+use ed25519_compact::Signature;
+
+
+pub trait HashBasedSignatureVerifier: Clone + Sized {
+    type Error; 
+
+    fn verify_hash(self, hash: impl AsRef<[u8]>) -> Result<(),Self::Error>;
+}
+#[derive(thiserror::Error, Debug)]
+pub enum Ed25519HighwayHashBasedSignatureVerifierError {
+
+}
+
+#[derive(Clone)]
+pub struct Ed25519HighwayHashBasedSignatureVerifier { 
+    pub signature: Signature, 
+    pub public_key: ed25519_compact::PublicKey,
+}
+
+impl HashBasedSignatureVerifier for Ed25519HighwayHashBasedSignatureVerifier {
+    type Error = Ed25519HighwayHashBasedSignatureVerifier;
+    
+    fn verify_hash(self, hash: impl AsRef<[u8]>) -> Result<(),Self::Error> {
+        self.public_key.verify(hash, &self.signature)?
+    }
+}
+
+impl Ed25519HighwayHashBasedSignatureVerifier {
+    fn new(
+        signature: Signature,
+        pk: ed25519_compact::PublicKey,
+    ) -> Result<Self, Ed25519HighwayHashBasedSignatureVerifierError>{
+        Ok(Self {
+            signature,
+            public_key: pk,
+        })
+    }
+}
diff --git a/src/encryption_v1/mod.rs b/src/encryption_v1/mod.rs
index cd24b98..8f064b9 100644
--- a/src/encryption_v1/mod.rs
+++ b/src/encryption_v1/mod.rs
@@ -3,6 +3,8 @@ pub mod decryption_module;
 pub mod encryption;
 pub mod encryption_module;
 pub mod hash;
+pub mod hash_based_signature;
+mod hash_based_signature_verifier;
 
 #[cfg(test)]
 mod tests {
diff --git a/src/lib.rs b/src/lib.rs
index 52df742..bd5714a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,7 +3,9 @@ pub mod constants;
 pub mod controller;
 pub mod dto;
 pub mod encryption_v1;
-mod event;
 mod util;
 pub mod platform;
-pub mod client;
\ No newline at end of file
+pub mod client;
+
+pub mod sync;
+pub mod stream;
diff --git a/src/stream/mod.rs b/src/stream/mod.rs
new file mode 100644
index 0000000..bd458e6
--- /dev/null
+++ b/src/stream/mod.rs
@@ -0,0 +1 @@
+mod mpeg_dash;
\ No newline at end of file
diff --git a/src/stream/mpeg_dash.rs b/src/stream/mpeg_dash.rs
new file mode 100644
index 0000000..0519ecb
--- /dev/null
+++ b/src/stream/mpeg_dash.rs
@@ -0,0 +1 @@
+ 
\ No newline at end of file
diff --git a/src/event/event.rs b/src/sync/event.rs
similarity index 99%
rename from src/event/event.rs
rename to src/sync/event.rs
index 3c547dd..6eee661 100644
--- a/src/event/event.rs
+++ b/src/sync/event.rs
@@ -11,4 +11,7 @@ pub enum BucketEvent {
     BucketUpdated(String),
 }
 
+
+
+
 //pub fn parse_bucket_event()
diff --git a/src/event/mod.rs b/src/sync/mod.rs
similarity index 100%
rename from src/event/mod.rs
rename to src/sync/mod.rs