#消息认证 #加密 #aegis-128l #hazmat #turboshake128

无std lockstitch

Lockstitch是一个用于复杂协议中对称密钥加密操作的增量、有状态的加密原语

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加密学

Download history 24/week @ 2024-03-25 40/week @ 2024-04-01 16/week @ 2024-04-08 15/week @ 2024-04-15 9/week @ 2024-04-22 3/week @ 2024-04-29 39/week @ 2024-05-06 33/week @ 2024-05-20 16/week @ 2024-05-27 38/week @ 2024-06-03 33/week @ 2024-06-10 31/week @ 2024-06-17 12/week @ 2024-07-01 13/week @ 2024-07-08

每月63次下载

MIT 许可证

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:启用仅文档的perfdesign模块。
  • std:启用基于Rust标准库的功能。默认启用。
  • zeroize:启用对零化协议状态的支持。默认启用。

性能

Lockstitch的AEGIS-128L实现从特定CPU指令的使用中受益显著。

x86/x86_64

x86/x86_64 CPU上,Lockstitch在启用aesssse3目标功能时达到最佳性能。

要编译支持这些功能的二进制文件,创建一个.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)上,应启用sha3aes目标功能。

其他

对于其他平台,portable crate功能提供了一个非常慢但完全可移植的AES实现。

更多信息

有关Lockstitch设计的更多信息,请参阅design.md。有关性能的更多信息,请参阅perf.md

许可证

版权 © 2023 Coda Hale,Frank Denis

AEGIS-128L实现改编自rust-aegis

根据MIT许可证分发。

依赖项

~1.5MB
~12K SLoC