feat!: switch from k12 to sha256, use proper multihash /base impl

feat/type-attributes
Tomáš Mládek 2022-09-12 23:30:43 +02:00
parent 327b87a18a
commit ebd11657ac
4 changed files with 214 additions and 91 deletions

184
Cargo.lock generated
View File

@ -498,6 +498,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-buffer"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
dependencies = [
"generic-array",
]
[[package]]
name = "brotli-sys"
version = "0.3.2"
@ -518,12 +527,6 @@ dependencies = [
"libc",
]
[[package]]
name = "bs58"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
[[package]]
name = "bstr"
version = "0.2.17"
@ -695,6 +698,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
[[package]]
name = "core2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
dependencies = [
"memchr",
]
[[package]]
name = "cpufeatures"
version = "0.2.1"
@ -779,10 +791,14 @@ dependencies = [
]
[[package]]
name = "crunchy"
version = "0.2.2"
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "curl"
@ -814,6 +830,32 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "data-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
[[package]]
name = "data-encoding-macro"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca"
dependencies = [
"data-encoding",
"data-encoding-macro-internal",
]
[[package]]
name = "data-encoding-macro-internal"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db"
dependencies = [
"data-encoding",
"syn",
]
[[package]]
name = "deflate"
version = "0.8.6"
@ -881,6 +923,16 @@ dependencies = [
"generic-array",
]
[[package]]
name = "digest"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [
"block-buffer 0.10.3",
"crypto-common",
]
[[package]]
name = "dirs"
version = "3.0.2"
@ -1704,6 +1756,44 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "multibase"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404"
dependencies = [
"base-x",
"data-encoding",
"data-encoding-macro",
]
[[package]]
name = "multihash"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c346cf9999c631f002d8f977c4eaeaa0e6386f16007202308d0b3757522c2cc"
dependencies = [
"core2",
"digest 0.10.3",
"multihash-derive",
"sha2",
"unsigned-varint",
]
[[package]]
name = "multihash-derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd"
dependencies = [
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "mutate_once"
version = "0.1.1"
@ -2060,6 +2150,41 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro-crate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
dependencies = [
"once_cell",
"thiserror",
"toml",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check 0.9.4",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check 0.9.4",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
@ -2442,10 +2567,10 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
dependencies = [
"block-buffer",
"block-buffer 0.9.0",
"cfg-if 1.0.0",
"cpufeatures",
"digest",
"digest 0.9.0",
"opaque-debug",
]
@ -2455,6 +2580,17 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "sha2"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.3",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
@ -2631,6 +2767,18 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "tempfile"
version = "3.2.0"
@ -2781,15 +2929,6 @@ dependencies = [
"syn",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "tinyvec"
version = "1.5.1"
@ -3079,7 +3218,6 @@ dependencies = [
"actix-web",
"actix_derive",
"anyhow",
"bs58",
"built",
"chrono",
"clap",
@ -3099,6 +3237,8 @@ dependencies = [
"log",
"lru",
"mime",
"multibase",
"multihash",
"nonempty",
"once_cell",
"opener",
@ -3109,11 +3249,9 @@ dependencies = [
"serde_json",
"tempfile",
"thiserror",
"tiny-keccak",
"tracing",
"tracing-subscriber",
"tree_magic_mini",
"unsigned-varint",
"uuid",
"walkdir",
"webbrowser",

View File

@ -48,9 +48,8 @@ serde_json = "1.0"
lexpr = "0.2.6"
regex = "1"
bs58 = "^0.4"
tiny-keccak = { version = "2.0", features = ["k12"] }
unsigned-varint = { version = "^0", features = ["std"] }
multibase = "0.9"
multihash = { version = "*", default-features = false, features = ["alloc", "multihash-impl", "sha2", "identity"] }
uuid = { version = "0.8", features = ["v4"] }
filebuffer = "0.4.0"

View File

@ -1,13 +1,11 @@
use crate::util::hash::{b58_decode, b58_encode, Hash, Hashable};
use anyhow::{anyhow, Result};
use multihash::{Code, Multihash, MultihashDigest};
use serde::de::Visitor;
use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::io::prelude::*;
use std::io::Cursor;
use std::str::FromStr;
use thiserror::private::DisplayAsDisplay;
use unsigned_varint::encode;
use uuid::Uuid;
#[derive(Clone, Eq, PartialEq, Hash)]
@ -18,55 +16,46 @@ pub enum Address {
Url(String),
}
// multihash KangarooTwelve
const KANGAROO_TWELVE: u128 = 0x1d01;
// multihash SHA2-256
const SHA2_256: u64 = 0x12;
// multihash identity
const IDENTITY: u128 = 0x00;
const IDENTITY: u64 = 0x00;
impl Address {
pub fn encode(&self) -> Result<Vec<u8>> {
let (hash_func_type, digest) = match self {
Self::Hash(hash) => (KANGAROO_TWELVE, hash.0.clone()),
Self::Uuid(uuid) => (IDENTITY, [vec![b'U'], uuid.as_bytes().to_vec()].concat()),
Self::Attribute(attribute) => (IDENTITY, [&[b'A'], attribute.as_bytes()].concat()),
Self::Url(url) => (IDENTITY, [&[b'X'], url.as_bytes()].concat()),
let hash = match self {
Self::Hash(hash) => Multihash::wrap(SHA2_256, &hash.0).map_err(|err| anyhow!(err))?,
Self::Uuid(uuid) => {
Code::Identity.digest(&[vec![b'U'], uuid.as_bytes().to_vec()].concat())
}
Self::Attribute(attribute) => {
Code::Identity.digest(&[&[b'A'], attribute.as_bytes()].concat())
}
Self::Url(url) => Code::Identity.digest(&[&[b'X'], url.as_bytes()].concat()),
};
let mut result = Cursor::new(vec![0u8; 0]);
result.write_all(encode::u128(hash_func_type, &mut encode::u128_buffer()))?;
result.write_all(encode::usize(digest.len(), &mut encode::usize_buffer()))?;
result.write_all(digest.as_slice())?;
Ok(result.get_ref().clone())
Ok(hash.to_bytes())
}
pub fn decode(buffer: &[u8]) -> Result<Self> {
let (hash_func_type, rest) = unsigned_varint::decode::u128(buffer)?;
let (digest_len, rest) = unsigned_varint::decode::usize(rest)?;
let digest = rest.to_vec();
if digest_len != digest.len() {
Err(anyhow!(format!(
"Actual digest length ({}) does not match declared digest length ({}).",
digest.len(),
digest_len
)))
} else {
match hash_func_type {
KANGAROO_TWELVE => Ok(Self::Hash(Hash(digest))),
IDENTITY => {
let digest_content: Vec<u8> = digest.clone().into_iter().skip(1).collect();
match digest[0] {
b'U' => Ok(Self::Uuid(uuid::Uuid::from_slice(
digest_content.as_slice(),
)?)),
b'A' => Ok(Self::Attribute(String::from_utf8(digest_content)?)),
b'X' => Ok(Self::Url(String::from_utf8(digest_content)?)),
_ => Err(anyhow!("Unknown identity marker.")),
}
let multihash = Multihash::from_bytes(buffer)
.map_err(|err| anyhow!("Error decoding address: {}", err))?;
match multihash.code() {
SHA2_256 => Ok(Self::Hash(Hash(multihash.digest().to_vec()))),
IDENTITY => {
let digest = multihash.digest().to_owned();
let digest_content: Vec<u8> = digest.clone().into_iter().skip(1).collect();
match digest[0] {
b'U' => Ok(Self::Uuid(uuid::Uuid::from_slice(
digest_content.as_slice(),
)?)),
b'A' => Ok(Self::Attribute(String::from_utf8(digest_content)?)),
b'X' => Ok(Self::Url(String::from_utf8(digest_content)?)),
_ => Err(anyhow!("Unknown identity marker.")),
}
_ => Err(anyhow!("Unknown hash function type.")),
}
_ => Err(anyhow!("Unknown hash function type.")),
}
}
}
@ -127,7 +116,17 @@ impl std::fmt::Display for Address {
impl std::fmt::Debug for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_display())
write!(
f,
"Address<{}>: {}",
match self {
Address::Hash(_) => "Hash",
Address::Uuid(_) => "UUID",
Address::Attribute(_) => "Attribute",
Address::Url(_) => "URL",
},
self.as_display()
)
}
}

View File

@ -1,15 +1,15 @@
use crate::addressing::Address;
use actix::prelude::*;
use anyhow::{anyhow, Result};
use anyhow::Result;
use diesel::backend::Backend;
use diesel::deserialize::FromSql;
use diesel::sqlite::Sqlite;
use diesel::{deserialize, sql_types};
use filebuffer::FileBuffer;
use log::trace;
use multihash::Hasher;
use serde::{ser, Serialize, Serializer};
use std::path::{Path, PathBuf};
use tiny_keccak::{Hasher, KangarooTwelve};
#[derive(Debug, Clone, Eq, PartialEq, FromSqlRow, Hash)]
pub struct Hash(pub Vec<u8>);
@ -76,32 +76,19 @@ impl Hashable for Path {
}
pub fn hash<T: AsRef<[u8]>>(input: T) -> Hash {
let mut k12 = KangarooTwelve::new(b"");
k12.update(input.as_ref());
let mut result = [0u8; 256 / 8];
k12.finalize(&mut result);
Hash(Vec::from(result))
let mut hasher = multihash::Sha2_256::default();
hasher.update(input.as_ref());
Hash(Vec::from(hasher.finalize()))
}
pub fn b58_encode<T: AsRef<[u8]>>(vec: T) -> String {
// multibase base58
format!("z{}", bs58::encode(vec).into_string())
multibase::encode(multibase::Base::Base58Btc, vec.as_ref())
}
pub fn b58_decode<T: AsRef<str>>(string: T) -> Result<Vec<u8>> {
let string = string.as_ref();
let (base, data) = string.split_at(1);
// multibase base58
if base != "z" {
Err(anyhow!(format!(
"data not base58 encoded, bailing... ({})",
string
)))
} else {
Ok(bs58::decode(data).into_vec()?)
}
pub fn b58_decode<T: AsRef<str>>(input: T) -> Result<Vec<u8>> {
let input = input.as_ref();
let (_base, data) = multibase::decode(input)?;
Ok(data)
}
#[cfg(test)]