fix docker ids, implement reading from stdin

This commit is contained in:
Bryson Steck 2025-08-06 20:12:54 -06:00
parent 8f2f40f566
commit 6ab9b03ed7
Signed by: bryson
SSH key fingerprint: SHA256:XpKABw/nP4z8UVaH+weLaBnEOD86+cVwif+QjuYLGT4
6 changed files with 441 additions and 188 deletions

9
Cargo.lock generated
View file

@ -277,6 +277,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hex-literal"
version = "0.4.1"
@ -361,7 +367,7 @@ checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "picca"
version = "0.4.0"
version = "0.5.0"
dependencies = [
"ascon-hash",
"belt-hash",
@ -372,6 +378,7 @@ dependencies = [
"fsb",
"gost94",
"groestl",
"hex",
"jh",
"k12",
"md-5",

View file

@ -1,7 +1,7 @@
[package]
name = "picca"
version = "0.4.0"
edition = "2021"
version = "0.5.0"
edition = "2024"
[dependencies]
sha2 = "0.10.9"
@ -29,3 +29,4 @@ tiger = "0.2.1"
whirlpool = "0.10.4"
blake3 = "1.8.2"
quit = "2.0.0"
hex = "0.4.3"

View file

@ -21,7 +21,6 @@ LABEL org.opencontainers.image.source="https://forge.steck.dev/bryson/picca"
LABEL org.opencontainers.image.created="${DATE}"
RUN apk upgrade --no-cache
RUN mkdir /etc/picca
COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY --from=build /usr/src/picca /usr/src

View file

@ -2,13 +2,13 @@
# Entrypoint file for picca Docker containers
if [ -z "$UID" ]; then
echo "UID not set! Setting to id $(id -u)"
export UID=$(id -u)
echo "UID not set! Setting to default 1000" >> /dev/stderr
export UID=1000
fi
if [ -z "$GID" ]; then
echo "GID not set! Setting to id $(id -g)"
export GID=$(id -g)
echo "GID not set! Setting to default 1000" >> /dev/stderr
export GID=1000
fi
addgroup -g $GID dockeruser

View file

@ -15,87 +15,131 @@ use sha1::Sha1;
use sha2::{Digest as _, Sha224, Sha256, Sha384, Sha512};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
use shabal::{Shabal192, Shabal224, Shabal256, Shabal384, Shabal512};
use skein::{consts::U32, Skein1024, Skein256, Skein512};
use skein::{Skein256, Skein512, Skein1024, consts::U32};
use sm3::Sm3;
use std::io;
use std::io::{self, Write};
use std::{fs::File, io::Read};
use streebog::{Streebog256, Streebog512};
use tiger::Tiger;
use whirlpool::Whirlpool;
pub fn hash_streebog256(mut file: File) -> String {
pub fn hash_streebog256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Streebog256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_streebog512(mut file: File) -> String {
pub fn hash_streebog512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Streebog512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_tiger(mut file: File) -> String {
pub fn hash_tiger(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Tiger::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_whirlpool(mut file: File) -> String {
pub fn hash_whirlpool(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Whirlpool::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha224(mut file: File) -> String {
pub fn hash_sha224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sm3(mut file: File) -> String {
pub fn hash_sm3(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sm3::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha3_224(mut file: File) -> String {
pub fn hash_sha3_224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha3_224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha3_256(mut file: File) -> String {
pub fn hash_sha3_256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha3_256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha3_384(mut file: File) -> String {
pub fn hash_sha3_384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha3_384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha3_512(mut file: File) -> String {
pub fn hash_sha3_512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha3_512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_shake128(mut file: File) -> String {
pub fn hash_shake128(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shake128::default();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
_ = hasher.write_fmt(format_args!("{}", stdin.unwrap()));
}
let mut result = String::new();
let mut finalized = hasher.finalize_xof();
@ -104,9 +148,13 @@ pub fn hash_shake128(mut file: File) -> String {
return format!("{}", result);
}
pub fn hash_shake256(mut file: File) -> String {
pub fn hash_shake256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shake256::default();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
_ = hasher.write_fmt(format_args!("{}", stdin.unwrap()));
}
let mut result = String::new();
let mut finalized = hasher.finalize_xof();
@ -115,128 +163,200 @@ pub fn hash_shake256(mut file: File) -> String {
return format!("{}", result);
}
pub fn hash_shabal192(mut file: File) -> String {
pub fn hash_shabal192(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shabal192::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_shabal224(mut file: File) -> String {
pub fn hash_shabal224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shabal224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_shabal256(mut file: File) -> String {
pub fn hash_shabal256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shabal256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_shabal384(mut file: File) -> String {
pub fn hash_shabal384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shabal384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_shabal512(mut file: File) -> String {
pub fn hash_shabal512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Shabal512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_skein256(mut file: File) -> String {
pub fn hash_skein256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Skein256::<U32>::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_skein512(mut file: File) -> String {
pub fn hash_skein512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Skein512::<U32>::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_skein1024(mut file: File) -> String {
pub fn hash_skein1024(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Skein1024::<U32>::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_gost94(mut file: File) -> String {
pub fn hash_gost94(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Gost94CryptoPro::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_groestl224(mut file: File) -> String {
pub fn hash_groestl224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Groestl224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_groestl256(mut file: File) -> String {
pub fn hash_groestl256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Groestl256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_groestl384(mut file: File) -> String {
pub fn hash_groestl384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Groestl384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_groestl512(mut file: File) -> String {
pub fn hash_groestl512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Groestl512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_jh224(mut file: File) -> String {
pub fn hash_jh224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Jh224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_jh256(mut file: File) -> String {
pub fn hash_jh256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Jh256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_jh384(mut file: File) -> String {
pub fn hash_jh384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Jh384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_jh512(mut file: File) -> String {
pub fn hash_jh512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Jh512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_k12(mut file: File) -> String {
pub fn hash_k12(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = KangarooTwelve::default();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
_ = hasher.write_fmt(format_args!("{}", stdin.unwrap()));
}
let mut result = String::new();
let mut finalized = hasher.finalize_xof();
@ -245,149 +365,233 @@ pub fn hash_k12(mut file: File) -> String {
return format!("{}", result);
}
pub fn hash_md2(mut file: File) -> String {
pub fn hash_md2(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Md2::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_md4(mut file: File) -> String {
pub fn hash_md4(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Md4::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_ripemd128(mut file: File) -> String {
pub fn hash_ripemd128(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Ripemd128::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_ripemd160(mut file: File) -> String {
pub fn hash_ripemd160(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Ripemd160::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_ripemd256(mut file: File) -> String {
pub fn hash_ripemd256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Ripemd256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_ripemd320(mut file: File) -> String {
pub fn hash_ripemd320(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Ripemd320::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_ascon(mut file: File) -> String {
pub fn hash_ascon(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = AsconHash256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_belt(mut file: File) -> String {
pub fn hash_belt(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = BeltHash::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_blake3(mut file: File) -> String {
pub fn hash_blake3(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Blake3::default();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
_ = hasher.write_fmt(format_args!("{}", stdin.unwrap()));
}
return format!("{}", hasher.finalize().to_hex());
}
pub fn hash_blake2b512(mut file: File) -> String {
pub fn hash_blake2b512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Blake2b512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_blake2s256(mut file: File) -> String {
pub fn hash_blake2s256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Blake2s256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_fsb160(mut file: File) -> String {
pub fn hash_fsb160(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Fsb160::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_fsb224(mut file: File) -> String {
pub fn hash_fsb224(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Fsb224::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_fsb256(mut file: File) -> String {
pub fn hash_fsb256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Fsb256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_fsb384(mut file: File) -> String {
pub fn hash_fsb384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Fsb384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_fsb512(mut file: File) -> String {
pub fn hash_fsb512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Fsb512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_md5(mut file: File) -> String {
pub fn hash_md5(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Md5::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha1(mut file: File) -> String {
pub fn hash_sha1(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha1::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha256(mut file: File) -> String {
pub fn hash_sha256(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha256::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha384(mut file: File) -> String {
pub fn hash_sha384(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha384::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}
pub fn hash_sha512(mut file: File) -> String {
pub fn hash_sha512(file: Option<File>, stdin: Option<String>) -> String {
let mut hasher = Sha512::new();
_ = io::copy(&mut file, &mut hasher);
if file.is_some() {
_ = io::copy(&mut file.unwrap(), &mut hasher);
} else if stdin.is_some() {
hasher.update(stdin.unwrap());
}
return format!("{:x}", hasher.finalize());
}

View file

@ -1,10 +1,11 @@
use clap::Parser;
use std::collections::{HashMap, VecDeque};
use std::fs::{self, read_to_string, File};
use std::fs::{self, File, read_to_string};
use std::io::{self, Read};
use std::path::PathBuf;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::{Arc, Mutex};
use std::thread::{self, available_parallelism, JoinHandle};
use std::thread::{self, JoinHandle, available_parallelism};
mod common;
mod hashers;
@ -128,7 +129,7 @@ struct Args {
)]
quiet: bool,
#[arg(trailing_var_arg = true, required_unless_present("check"))]
#[arg(trailing_var_arg = true)]
files: Vec<PathBuf>,
}
@ -145,6 +146,8 @@ struct ThreadInfo {
fn hash(info: ThreadInfo) -> Result<(), String> {
loop {
let mut stdin = None;
let mut file = None;
let filename = match info.filenames.lock().unwrap().pop_front() {
Some(f) => f,
None => break,
@ -158,73 +161,81 @@ fn hash(info: ThreadInfo) -> Result<(), String> {
));
}
if filename.is_dir() {
if filename.display().to_string() == "-" {
let mut buffer = String::new();
match io::stdin().lock().read_to_string(&mut buffer) {
Ok(_) => (),
Err(e) => common::error(format!("stdin: {}", e)),
}
stdin = Some(buffer)
} else if filename.is_dir() {
common::error(format!("{}: Is a directory", filename.as_path().display()));
info.file_errors.fetch_add(1, Ordering::SeqCst);
continue;
} else {
file = Some(match File::open(&filename) {
Err(e) => {
println!("{}: FAILED ({})", filename.as_path().display(), e);
info.file_errors.fetch_add(1, Ordering::SeqCst);
continue;
},
Ok(f) => f,
});
}
let file = match File::open(&filename) {
Err(e) => {
println!("{}: FAILED ({})", filename.as_path().display(), e);
info.file_errors.fetch_add(1, Ordering::SeqCst);
continue;
},
Ok(f) => f,
};
let res = match &*info.algorithm.as_str() {
"ascon" => hashers::hash_ascon(file),
"belt" => hashers::hash_belt(file),
"blake2b512" => hashers::hash_blake2b512(file),
"blake2s256" => hashers::hash_blake2s256(file),
"blake3" => hashers::hash_blake3(file),
"fsb160" => hashers::hash_fsb160(file),
"fsb224" => hashers::hash_fsb224(file),
"fsb256" => hashers::hash_fsb256(file),
"fsb384" => hashers::hash_fsb384(file),
"fsb512" => hashers::hash_fsb512(file),
"gost94" => hashers::hash_gost94(file),
"groestl224" => hashers::hash_groestl224(file),
"groestl256" => hashers::hash_groestl256(file),
"groestl384" => hashers::hash_groestl384(file),
"groestl512" => hashers::hash_groestl512(file),
"jh224" => hashers::hash_jh224(file),
"jh256" => hashers::hash_jh256(file),
"jh384" => hashers::hash_jh384(file),
"jh512" => hashers::hash_jh512(file),
"k12" => hashers::hash_k12(file),
"md2" => hashers::hash_md2(file),
"md4" => hashers::hash_md4(file),
"md5" => hashers::hash_md5(file),
"ripemd128" => hashers::hash_ripemd128(file),
"ripemd160" => hashers::hash_ripemd160(file),
"ripemd256" => hashers::hash_ripemd256(file),
"ripemd320" => hashers::hash_ripemd320(file),
"sha1" => hashers::hash_sha1(file),
"sha224" => hashers::hash_sha224(file),
"sha256" => hashers::hash_sha256(file),
"sha384" => hashers::hash_sha384(file),
"sha512" => hashers::hash_sha512(file),
"sha3_224" => hashers::hash_sha3_224(file),
"sha3_256" => hashers::hash_sha3_256(file),
"sha3_384" => hashers::hash_sha3_384(file),
"sha3_512" => hashers::hash_sha3_512(file),
"shabal192" => hashers::hash_shabal192(file),
"shabal224" => hashers::hash_shabal224(file),
"shabal256" => hashers::hash_shabal256(file),
"shabal384" => hashers::hash_shabal384(file),
"shabal512" => hashers::hash_shabal512(file),
"shake128" => hashers::hash_shake128(file),
"shake256" => hashers::hash_shake256(file),
"skein256" => hashers::hash_skein256(file),
"skein512" => hashers::hash_skein512(file),
"skein1024" => hashers::hash_skein1024(file),
"sm3" => hashers::hash_sm3(file),
"streebog256" => hashers::hash_streebog256(file),
"streebog512" => hashers::hash_streebog512(file),
"tiger" => hashers::hash_tiger(file),
"whirlpool" => hashers::hash_whirlpool(file),
"ascon" => hashers::hash_ascon(file, stdin),
"belt" => hashers::hash_belt(file, stdin),
"blake2b512" => hashers::hash_blake2b512(file, stdin),
"blake2s256" => hashers::hash_blake2s256(file, stdin),
"blake3" => hashers::hash_blake3(file, stdin),
"fsb160" => hashers::hash_fsb160(file, stdin),
"fsb224" => hashers::hash_fsb224(file, stdin),
"fsb256" => hashers::hash_fsb256(file, stdin),
"fsb384" => hashers::hash_fsb384(file, stdin),
"fsb512" => hashers::hash_fsb512(file, stdin),
"gost94" => hashers::hash_gost94(file, stdin),
"groestl224" => hashers::hash_groestl224(file, stdin),
"groestl256" => hashers::hash_groestl256(file, stdin),
"groestl384" => hashers::hash_groestl384(file, stdin),
"groestl512" => hashers::hash_groestl512(file, stdin),
"jh224" => hashers::hash_jh224(file, stdin),
"jh256" => hashers::hash_jh256(file, stdin),
"jh384" => hashers::hash_jh384(file, stdin),
"jh512" => hashers::hash_jh512(file, stdin),
"k12" => hashers::hash_k12(file, stdin),
"md2" => hashers::hash_md2(file, stdin),
"md4" => hashers::hash_md4(file, stdin),
"md5" => hashers::hash_md5(file, stdin),
"ripemd128" => hashers::hash_ripemd128(file, stdin),
"ripemd160" => hashers::hash_ripemd160(file, stdin),
"ripemd256" => hashers::hash_ripemd256(file, stdin),
"ripemd320" => hashers::hash_ripemd320(file, stdin),
"sha1" => hashers::hash_sha1(file, stdin),
"sha224" => hashers::hash_sha224(file, stdin),
"sha256" => hashers::hash_sha256(file, stdin),
"sha384" => hashers::hash_sha384(file, stdin),
"sha512" => hashers::hash_sha512(file, stdin),
"sha3_224" => hashers::hash_sha3_224(file, stdin),
"sha3_256" => hashers::hash_sha3_256(file, stdin),
"sha3_384" => hashers::hash_sha3_384(file, stdin),
"sha3_512" => hashers::hash_sha3_512(file, stdin),
"shabal192" => hashers::hash_shabal192(file, stdin),
"shabal224" => hashers::hash_shabal224(file, stdin),
"shabal256" => hashers::hash_shabal256(file, stdin),
"shabal384" => hashers::hash_shabal384(file, stdin),
"shabal512" => hashers::hash_shabal512(file, stdin),
"shake128" => hashers::hash_shake128(file, stdin),
"shake256" => hashers::hash_shake256(file, stdin),
"skein256" => hashers::hash_skein256(file, stdin),
"skein512" => hashers::hash_skein512(file, stdin),
"skein1024" => hashers::hash_skein1024(file, stdin),
"sm3" => hashers::hash_sm3(file, stdin),
"streebog256" => hashers::hash_streebog256(file, stdin),
"streebog512" => hashers::hash_streebog512(file, stdin),
"tiger" => hashers::hash_tiger(file, stdin),
"whirlpool" => hashers::hash_whirlpool(file, stdin),
_ => panic!("Somehow did not pass a supported algorithm"),
};
@ -290,11 +301,18 @@ fn verify(
};
}
let threads;
if buffer.len() >= cpus {
threads = cpus
} else {
threads = buffer.len()
}
let arc_fe = Arc::new(AtomicI32::new(0));
let arc_he = Arc::new(AtomicI32::new(0));
let arc_buf = Arc::new(Mutex::new(buffer));
let arc_hash = Arc::new(Mutex::new(hash_map));
for i in 0..cpus {
for i in 0..threads {
let safe_fe = Arc::clone(&arc_fe);
let safe_he = Arc::clone(&arc_he);
let safe_buf = Arc::clone(&arc_buf);
@ -328,11 +346,18 @@ fn generate(
Arc<AtomicI32>,
Arc<AtomicI32>,
) {
let threads;
if buffer.len() >= cpus {
threads = cpus
} else {
threads = buffer.len()
}
let mut handles = vec![];
let arc_fe = Arc::new(AtomicI32::new(0));
let arc_he = Arc::new(AtomicI32::new(0));
let arc_buf = Arc::new(Mutex::new(buffer));
for i in 0..cpus {
for i in 0..threads {
let safe_fe = Arc::clone(&arc_fe);
let safe_he = Arc::clone(&arc_he);
let safe_buf = Arc::clone(&arc_buf);
@ -357,6 +382,14 @@ fn generate(
#[quit::main]
fn main() {
let args = Args::parse();
let docker = match option_env!("PICCA_DOCKER") {
Some(v) => match v {
"true" => true,
_ => false,
},
None => false,
};
let cpus = match args.threads {
0 => available_parallelism().unwrap().get(),
_ => args.threads,
@ -364,9 +397,13 @@ fn main() {
if args.debug {
common::debug(format!(
"Starting psha using algorithm {} with {} threads",
"Starting picca using algorithm {} with a max of {} threads",
args.algorithm, cpus
));
if docker {
common::debug(format!("Docker is detected"));
}
}
if UNSECURE_ALGORITHMS.contains(&args.algorithm.as_str()) {
@ -379,20 +416,25 @@ fn main() {
let handles;
let arc_fe;
let arc_he;
let check_mode = ! args.check.is_empty();
let check_mode = !args.check.is_empty();
if &args.check.len() >= &1 {
(handles, arc_fe, arc_he) = verify(cpus, args.algorithm, args.debug, args.quiet, args.check);
} else {
let mut buffer = VecDeque::new();
for file in args.files {
if args.canonicalize {
match fs::canonicalize(file.as_path()) {
Ok(p) => buffer.push_back(p),
Err(e) => panic!("unable to canonicalize {}: {}", file.as_path().display(), e),
};
} else {
buffer.push_back(file);
if &args.files.len() >= &1 {
for file in args.files {
if args.canonicalize {
match fs::canonicalize(file.as_path()) {
Ok(p) => buffer.push_back(p),
Err(e) => panic!("unable to canonicalize {}: {}", file.as_path().display(), e),
};
} else {
buffer.push_back(file);
}
}
} else {
// read from stdin instead
buffer.push_back(PathBuf::from("-"));
}
(handles, arc_fe, arc_he) = generate(cpus, buffer, args.algorithm, args.debug, args.quiet);