1个不稳定版本
0.9.0 | 2021年10月7日 |
---|
#1995在 密码学
每月32次下载
在xcbc-rsa-fdh中使用
235KB
508 行
全域哈希
这是一个用于开发目的的分支。它不再维护。请使用原始库。
全域哈希(FDH)是一种有用的密码学构造,它限制了哈希函数摘要的域(例如确保摘要小于RSA的模数n
)。其次,它还可以用于将哈希摘要的长度扩展到任意长度,将常规哈希函数转换为XOF哈希函数。
我们通过计算一系列周期来构造FDH
周期=(目标长度)/(摘要长度) + 1
然后我们计算
FDH(M) = 哈希(M||0) || 哈希(M||1) || ... || 哈希(M||周期−1)
其中HASH
是任何哈希函数,M
是消息,||
表示连接,数值是单字节u8
。
FDH通常与RSA签名方案一起使用,其中目标长度是密钥的大小,域小于模数n
。参见https://en.wikipedia.org/wiki/Full_Domain_Hash
这个crate广泛使用了
crate的密码学哈希特征,所以大多数有用的方法都作为digest
digest
特征的组成部分实现。这些特征为了方便起见被重新导出。参见https://github.com/RustCrypto/hashes以获取兼容哈希的列表。
需要注意的是,FDH与消息不是恒定时间的。虽然FDH的变量时间特性不能用于恢复消息(除了在病理情况下),但它可以用于从消息的所有可能值集合中消除某些值。
示例
use sha2::Sha256;
use fdh::{FullDomainHash, VariableOutput, Input};
// Expand SHA256 from 256 bits to 1024 bits.
let output_bits = 1024;
let output_bytes = 1024 / 8;
let mut hasher = FullDomainHash::<Sha256>::new(output_bytes)?;
hasher.input(b"ATTACK AT DAWN");
let result = hasher.vec_result();
no_std
这个crate也支持no_std
,因此它可以用于无分配的嵌入式或其他环境中。
#![no_std]
use sha2::Sha256;
use fdh::{FullDomainHash, Input, ExtendableOutput, XofReader};
// Expand SHA256 from 256 bits to 512 bits (and beyond!), reading it in 16 byte chunks.
let mut hasher = FullDomainHash::<Sha256>::default();
hasher.input(b"ATTACK AT DAWN");
let mut reader = hasher.xof_result();
let mut read_buf = <[u8; 16]>::default();
// Read the first 16 bytes into read_buf
reader.read(&mut read_buf);
// Read the second 16 bytes into read_buf
reader.read(&mut read_buf);
// If we want, we can just keep going, reading as many bits as we want indefinitely.
reader.read(&mut read_buf);
reader.read(&mut read_buf);
受限域
这个crate还支持获取特定域内的摘要。它遵循以下算法
fn digest_in_domain(message, iv):
digest = fdh(message, iv)
while not in_domain(digest):
iv++
digest = fdh(message, iv)
return digest, iv
提供了方法 results_in_domain()
来实现这一功能。辅助方法 results_between()
、results_lt()
、results_gt()
适用于需要散列值位于特定范围的常见情况。
生成奇数散列值的示例
use sha2::Sha512;
use fdh::{FullDomainHash, Input, VariableOutput};
use num_bigint::BigUint;
use num_integer::Integer;
// Get a full domain hash that is odd
let mut hasher = FullDomainHash::<Sha512>::new(64).unwrap();
hasher.input(b"ATTACKATDAWN");
fn digest_is_odd(digest: &[u8]) -> bool {
BigUint::from_bytes_be(digest).is_odd()
}
let iv = 0;
let (digest, iv) = hasher.results_in_domain(iv, digest_is_odd).unwrap();
贡献者
依赖
~330–760KB
~17K SLoC