add length support for shake128 and shake256

This commit is contained in:
AldanTanneo
2026-03-13 17:34:52 +01:00
committed by Dorian Péron
parent 0f891cc66f
commit d66817facb
3 changed files with 95 additions and 17 deletions
+22 -14
View File
@@ -250,14 +250,15 @@ pub enum SizedAlgoKind {
Sha3(ShaLength),
// Note: we store Blake2b's length as BYTES.
Blake2b(Option<usize>),
// Shake* length are stored in bits.
Shake128(Option<usize>),
Shake256(Option<usize>),
}
impl SizedAlgoKind {
pub fn from_unsized(kind: AlgoKind, byte_length: Option<usize>) -> UResult<Self> {
pub fn from_unsized(kind: AlgoKind, output_length: Option<usize>) -> UResult<Self> {
use AlgoKind as ak;
match (kind, byte_length) {
match (kind, output_length) {
(
ak::Sysv
| ak::Bsd
@@ -305,19 +306,26 @@ impl SizedAlgoKind {
}
pub fn to_tag(self) -> String {
use SizedAlgoKind::*;
match self {
Md5 => "MD5".into(),
Sm3 => "SM3".into(),
Sha1 => "SHA1".into(),
Blake3 => "BLAKE3".into(),
Sha2(len) => format!("SHA{}", len.as_usize()),
Sha3(len) => format!("SHA3-{}", len.as_usize()),
Blake2b(Some(byte_len)) => format!("BLAKE2b-{}", byte_len * 8),
Blake2b(None) => "BLAKE2b".into(),
Shake128(_) => "SHAKE128".into(),
Shake256(_) => "SHAKE256".into(),
Sysv | Bsd | Crc | Crc32b => panic!("Should not be used for tagging"),
Self::Md5 => "MD5".into(),
Self::Sm3 => "SM3".into(),
Self::Sha1 => "SHA1".into(),
Self::Blake3 => "BLAKE3".into(),
Self::Sha2(len) => format!("SHA{}", len.as_usize()),
Self::Sha3(len) => format!("SHA3-{}", len.as_usize()),
Self::Blake2b(Some(byte_len)) => format!("BLAKE2b-{}", byte_len * 8),
Self::Blake2b(None) => "BLAKE2b".into(),
Self::Shake128(opt_bit_len) => format!(
"SHAKE128-{}",
opt_bit_len.unwrap_or(Shake128::DEFAULT_BIT_SIZE)
),
Self::Shake256(opt_bit_len) => format!(
"SHAKE256-{}",
opt_bit_len.unwrap_or(Shake256::DEFAULT_BIT_SIZE)
),
Self::Sysv | Self::Bsd | Self::Crc | Self::Crc32b => {
panic!("Should not be used for tagging")
}
}
}
@@ -19,7 +19,7 @@ use crate::checksum::{
};
use crate::error::{FromIo, UError, UIoError, UResult, USimpleError};
use crate::quoting_style::{QuotingStyle, locale_aware_escape_name};
use crate::sum::DigestOutput;
use crate::sum::{self, DigestOutput};
use crate::{
os_str_as_bytes, os_str_from_bytes, read_os_string_lines, show, show_warning_caps, translate,
};
@@ -643,6 +643,7 @@ fn identify_algo_name_and_length(
AlgoKind::Sha2 | AlgoKind::Sha3 if [224, 256, 384, 512].contains(&bitlen) => {
Some(bitlen)
}
AlgoKind::Shake128 | AlgoKind::Shake256 => Some(bitlen),
// Either
// the algo based line is provided with a bit length
// with an algorithm that does not support it (only Blake2B does).
@@ -741,6 +742,9 @@ fn process_algo_based_line(
// checksum with it.
let digest_char_length_hint = match (algo_kind, algo_byte_len) {
(AlgoKind::Blake2b, Some(byte_len)) => Some(byte_len),
(AlgoKind::Shake128 | AlgoKind::Shake256, Some(bit_len)) => Some(bit_len.div_ceil(8)),
(AlgoKind::Shake128, None) => Some(sum::Shake128::DEFAULT_BIT_SIZE.div_ceil(8)),
(AlgoKind::Shake256, None) => Some(sum::Shake256::DEFAULT_BIT_SIZE.div_ceil(8)),
_ => None,
};
+68 -2
View File
@@ -3150,13 +3150,19 @@ fn test_check_checkfile_with_io_error() {
"ac"
)]
fn test_shake128(#[case] args: &[&str], #[case] expected: &str) {
let bit_len = if args.is_empty() || args[1] == "0" {
"256"
} else {
args[1]
};
new_ucmd!()
.arg("-a")
.arg("shake128")
.args(args)
.pipe_in("xxx")
.succeeds()
.stdout_only(format!("SHAKE128 (-) = {expected}\n"));
.stdout_only(format!("SHAKE128-{bit_len} (-) = {expected}\n"));
}
#[rstest]
@@ -3213,11 +3219,71 @@ fn test_shake128(#[case] args: &[&str], #[case] expected: &str) {
"2f"
)]
fn test_shake256(#[case] args: &[&str], #[case] expected: &str) {
let bit_len = if args.is_empty() || args[1] == "0" {
"512"
} else {
args[1]
};
new_ucmd!()
.arg("-a")
.arg("shake256")
.args(args)
.pipe_in("xxx")
.succeeds()
.stdout_only(format!("SHAKE256 (-) = {expected}\n"));
.stdout_only(format!("SHAKE256-{bit_len} (-) = {expected}\n"));
}
#[test]
fn test_check_shake128_no_length() {
const INPUT_SHAKE128_CORRECT_LEN: &str =
"SHAKE128 (bar) = ac8549b2861a151896ab721bd29d7a20c1a3d1f75b31266f786f20d963fb0fdf";
const INPUT_SHAKE128_WRONG_LEN: &str = "SHAKE128 (bar) = ac8549b2861a151896ab721bd29d7a20";
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.write("bar", "xxx");
scene
.ucmd()
.arg("-a")
.arg("shake128")
.arg("-c")
.pipe_in(INPUT_SHAKE128_CORRECT_LEN)
.succeeds();
scene
.ucmd()
.arg("-a")
.arg("shake128")
.arg("-c")
.pipe_in(INPUT_SHAKE128_WRONG_LEN)
.fails()
.stderr_only("cksum: 'standard input': no properly formatted checksum lines found\n");
}
#[test]
fn test_check_shake256_no_length() {
const INPUT_SHAKE256_CORRECT_LEN: &str = "SHAKE256 (bar) = 2fa631503c3ea5fe85131dbfa24805185474740e6dcb5f2a64f69d932bcb55f7b24958f3e3c4cc0e71f1fe6f054cd3fb28b9efb62b4f8f3fbe6d50d90f5c6eba";
const INPUT_SHAKE256_WRONG_LEN: &str =
"SHAKE256 (bar) = 2fa631503c3ea5fe85131dbfa24805185474740e6dcb5f2a64f69d932bcb55f7";
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.write("bar", "xxx");
scene
.ucmd()
.arg("-c")
.pipe_in(INPUT_SHAKE256_CORRECT_LEN)
.succeeds();
scene
.ucmd()
.arg("-c")
.pipe_in(INPUT_SHAKE256_WRONG_LEN)
.fails()
.stderr_only("cksum: 'standard input': no properly formatted checksum lines found\n");
}