55个版本 (23个破坏性版本)
0.25.2 | 2024年2月3日 |
---|---|
0.24.0 | 2024年1月14日 |
0.21.0 | 2023年12月29日 |
0.17.0 | 2023年11月19日 |
0.1.0 | 2022年10月28日 |
#133 在 加密学
每月63次下载
52KB
858 行
Lockstitch
Lockstitch是一个用于复杂协议中对称密钥加密操作(例如散列、加密、消息认证码和认证加密)的增量、有状态的加密原语。受TupleHash、STROBE、Noise协议的有状态对象、Merlin转储和Xoodyak的Cyclist模式启发,Lockstitch使用TurboSHAKE128,一个可扩展输出函数(XOF),以及AEGIS-128L,一个认证加密,在128位安全级别上为现代处理器提供100+ Gb/sec的性能。
注意
⚠️ 不建议使用此库。⚠️
此库的设计和实现尚未经过独立评估。设计在design.md
中进行了说明;阅读它并判断其中的论点是否具有说服力。
此外,绝对无法保证向后兼容性。
设计
Lockstitch协议是一个有状态对象,具有五种不同的操作
Init
:使用域分离字符串初始化协议。Mix
:将数据块混合到协议的转储中,使所有未来的输出都依赖于它。Derive
:输出与协议转储相关的伪随机数据。Encrypt>/
Decrypt
:使用协议的转储作为密钥加密和解密数据。Seal>/
Open
:使用协议的转储作为密钥加密和解密数据,并具有认证。
使用这些操作,可以构建各种对称密钥构造。
使用
Lockstitch用于组合加密协议。
例如,我们可以创建消息摘要
fn digest(message: &[u8]) -> [u8; 32] {
let mut md = lockstitch::Protocol::new("com.example.md");
md.mix("message", message);
md.derive_array("digest")
}
assert_eq!(digest(b"this is a message"), digest(b"this is a message"));
assert_ne!(digest(b"this is a message"), digest(b"this is another message"));
我们可以创建消息认证码
fn mac(key: &[u8], message: &[u8]) -> [u8; 16] {
let mut mac = lockstitch::Protocol::new("com.example.mac");
mac.mix("key", key);
mac.mix("message", message);
mac.derive_array("tag")
}
assert_eq!(mac(b"a key", b"a message"), mac(b"a key", b"a message"));
assert_ne!(mac(b"a key", b"a message"), mac(b"another key", b"a message"));
assert_ne!(mac(b"a key", b"a message"), mac(b"a key", b"another message"));
我们甚至可以创建认证加密
fn aead_encrypt(key: &[u8], nonce: &[u8], ad: &[u8], plaintext: &[u8]) -> Vec<u8> {
let mut out = vec![0u8; plaintext.len() + lockstitch::TAG_LEN];
out[..plaintext.len()].copy_from_slice(plaintext);
let mut aead = lockstitch::Protocol::new("com.example.aead");
aead.mix("key", key);
aead.mix("nonce", nonce);
aead.mix("ad", ad);
aead.seal("message", &mut out);
out
}
fn aead_decrypt(key: &[u8], nonce: &[u8], ad: &[u8], ciphertext: &[u8]) -> Option<Vec<u8>> {
let mut ciphertext = ciphertext.to_vec();
let mut aead = lockstitch::Protocol::new("com.example.aead");
aead.mix("key", key);
aead.mix("nonce", nonce);
aead.mix("ad", ad);
aead.open("message", &mut ciphertext).map(|p| p.to_vec())
}
let plaintext = b"a message".to_vec();
let ciphertext = aead_encrypt(b"a key", b"a nonce", b"some data", &plaintext);
assert_eq!(aead_decrypt(b"a key", b"a nonce", b"some data", &ciphertext), Some(plaintext));
assert_eq!(aead_decrypt(b"another key", b"a nonce", b"some data", &ciphertext), None);
assert_eq!(aead_decrypt(b"a key", b"another nonce", b"some data", &ciphertext), None);
assert_eq!(aead_decrypt(b"a key", b"a nonce", b"some other data", &ciphertext), None);
let mut bad_ciphertext = ciphertext.to_vec();
bad_ciphertext[5] ^= 1; // flip one bit
assert_eq!(aead_decrypt(b"a key", b"a nonce", b"some data", &bad_ciphertext), None);
Cargo功能
asm
:启用针对aarch64的TurboSHAKE128的手动编码汇编。默认启用。docs
:启用仅文档的perf和design模块。std
:启用基于Rust标准库的功能。默认启用。zeroize
:启用对零化协议状态的支持。默认启用。
性能
Lockstitch的AEGIS-128L实现从特定CPU指令的使用中受益显著。
x86
/x86_64
在x86
/x86_64
CPU上,Lockstitch在启用aes
和ssse3
目标功能时达到最佳性能。
要编译支持这些功能的二进制文件,创建一个.cargo/config.toml
文件,包含以下内容
[build]
rustflags = ["-C", "target-feature=+aes,+ssse3"]
或者使用以下RUSTFLAGS
环境变量
export RUSTFLAGS="-C target-feature=+aes,+ssse3"
aarch64
在aarch64-darwin-apple
(即macOS)上,默认启用ARMv8-A加密指令和NEON向量指令。在其他目标(例如aarch64-unknown-linux-gnu
)上,应启用sha3
和aes
目标功能。
其他
对于其他平台,portable
crate功能提供了一个非常慢但完全可移植的AES实现。
更多信息
有关Lockstitch设计的更多信息,请参阅design.md
。有关性能的更多信息,请参阅perf.md
。
许可证
版权 © 2023 Coda Hale,Frank Denis
AEGIS-128L实现改编自rust-aegis。
根据MIT许可证分发。
依赖项
~1.5MB
~12K SLoC