3个版本 (破坏性更新)
0.4.0 | 2021年12月20日 |
---|---|
0.3.0 | 2021年12月20日 |
0.2.0 | 2021年5月11日 |
#2525 in 加密学
14KB
159 行
hash2field
这个crate旨在用于无需std的环境。
实现了类似于IETF草案第5节描述的安全哈希映射到有限域。
这个crate旨在由哈希到曲线的实现者调用,无需编写哈希到域的章节,因为这是曲线无关的。
它提供了两个结构体、两个特性和函数hash_to_field
。
FromRO
应该由hash_to_field
的调用者实现,并用于将输出摘要转换为域元素。
ExpandMsg
由ExpandMsgXof
和ExpandMsgXmd
实现,因此不需要直接实现。
ExpandMsgXmd
是实现第5.4.1节的实现,并允许调用者选择固定的输出摘要。
ExpandMsgXof
是实现第5.4.2节的实现,并允许调用者选择任何XOF。
hash_to_field
使用了在Rust 1.51中实现的const generics。
以下是一个使用它的k256
crate的示例
use hash2field::*;
use digest::generic_array::{GenericArray, typenum::U32};
use k256::FieldElement;
use num_bigint::BigUint;
use num_integer::Integer;
use sha2::Sha256;
const L: usize = 48;
const COUNT: usize = 2;
const OUT: usize = L * COUNT;
const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_";
impl FromOkm<L> for FieldElement {
fn from_okm(data: &[u8; L]) -> Self {
let p = BigUint::from_bytes_be(&hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F").unwrap());
let mut x = BigUint::from_bytes_be(&data[..]);
x = x.mod_floor(&p);
let mut t = x.to_bytes_be();
while t.len() < 32 {
t.insert(0, 0u8);
}
let t = GenericArray::<u8, U32>::clone_from_slice(&t);
FieldElement::from_bytes(&t).unwrap()
}
}
let output = hash_to_field::<ExpandMsgXmd<Sha256>, FieldElement, L, COUNT, OUT>(b"this is a test", DST);
}
使用ExpandMsgXof
非常相似
use hash2field::*;
use digest::generic_array::{GenericArray, typenum::U32};
use k256::FieldElement;
use num_bigint::BigUint;
use num_integer::Integer;
use sha3::Shake256;
const L: usize = 48;
const COUNT: usize = 2;
const OUT: usize = L * COUNT;
const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XOF:SHAKE-256_SSWU_RO_";
impl FromOkm<L> for FieldElement {
fn from_okm(data: &[u8; L]) -> Self {
let p = BigUint::from_bytes_be(&hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F").unwrap());
let mut x = BigUint::from_bytes_be(&data[..]);
x = x.mod_floor(&p);
let mut t = x.to_bytes_be();
while t.len() < 32 {
t.insert(0, 0u8);
}
let t = GenericArray::<u8, U32>::clone_from_slice(&t);
FieldElement::from_bytes(&t).unwrap()
}
}
let output = hash_to_field::<ExpandMsgXof<Shake256>, FieldElement, L, COUNT, OUT>(b"this is a test", DST);
依赖关系
~2MB
~42K SLoC