1个不稳定版本

0.1.0 2022年9月14日

#1376密码学

Download history 111/week @ 2024-03-13 354/week @ 2024-03-20 367/week @ 2024-03-27 195/week @ 2024-04-03 213/week @ 2024-04-10 342/week @ 2024-04-17 223/week @ 2024-04-24 472/week @ 2024-05-01 213/week @ 2024-05-08 486/week @ 2024-05-15 199/week @ 2024-05-22 212/week @ 2024-05-29 165/week @ 2024-06-05 449/week @ 2024-06-12 578/week @ 2024-06-19 199/week @ 2024-06-26

1,426 每月下载量
3 crates 中使用

自定义许可

290KB
516

Meow

这个crate是使用KitTen实现的STROBE,采用了减少轮数的Keccak(Keccak轮数减少)。STROBE是对称密码协议框架,类似于Noise在密钥交换中的作用。

因为这个项目结合了类似Noise的框架和KitTen,所以我将其命名为Meow

动机

STROBE使用Keccak的24轮变体。由于加密堆栈过多,我认为24轮是过度的,相反,我认为KitTen的10轮是足够的。

遵循TMC的动机,我也在协议中硬编码了128位的安全性。

还对协议进行了一些细微的修改,例如不允许以流式方式创建或验证MAC,或设置默认的ratcheting长度。但这些并不改变其他操作的行为,内部,这些操作像STROBE一样工作,只是采用了不同的排列。

用例

用例基本上与STROBE相同。您可以使用该框架进行加密、哈希等。

加密

对于基本加密,流程是每一方设置他们的Meow状态,用密钥初始化,然后发送或接收消息。

use ck_meow::Meow;

let key = [0xFF; 32];

let message = b"hello world!";

let mut encrypted = message.to_owned();
let mut meow0 = Meow::new(b"my protocol");
meow0.key(&key, false);
meow0.send_enc(&mut encrypted, false);

let mut plaintext = encrypted.clone();
let mut meow1 = Meow::new(b"my protocol");
meow1.key(&key, false);
meow1.recv_enc(&mut plaintext, false);

assert_eq!(&plaintext, message);

随机加密

也很容易向加密方案中添加nonce。

use ck_meow::Meow;

let key = [0xFF; 32];
let nonce = [0xAA; 32];

let message = b"hello world!";

let mut encrypted = message.to_owned();
let mut meow0 = Meow::new(b"my protocol");
meow0.key(&key, false);
meow0.send_clr(&nonce, false);
meow0.send_enc(&mut encrypted, false);

let mut plaintext = encrypted.clone();
let mut meow1 = Meow::new(b"my protocol");
meow1.key(&key, false);
meow1.recv_clr(&nonce, false);
meow1.recv_enc(&mut plaintext, false);

assert_eq!(&plaintext, message);

只需要添加对send_clrrecv_clr的调用。在真实协议中,这个nonce将被发送给另一方。

AEAD

从这里,可以很容易地将它转变为完整的AEAD方案。我们还可以将附加数据合并到状态中,并生成和检查MAC。

use ck_meow::Meow;

let key = [0xFF; 32];
let nonce = [0xAA; 32];

let message = b"hello world!";

let mut encrypted = message.to_owned();
let mut meow0 = Meow::new(b"my protocol");
meow0.key(&key, false);
meow0.send_clr(&nonce, false);
meow0.ad(b"hello again!", false);
meow0.send_enc(&mut encrypted, false);
let mut mac = [0u8; 32];
meow0.send_mac(&mut mac);


let mut plaintext = encrypted.clone();
let mut meow1 = Meow::new(b"my protocol");
meow1.key(&key, false);
meow1.recv_clr(&nonce, false);
meow1.ad(b"hello again!", false);
meow1.recv_enc(&mut plaintext, false);
assert!(meow1.recv_mac(&mut mac).is_ok());

assert_eq!(&plaintext, message);

这里的基本新功能是send_mac / recv_mac,它允许创建和验证一个MAC,证明迄今为止整个传输的完整性。

哈希

也可以将 Meow 用作一个非常简单的哈希函数

use ck_meow::Meow;

let mut meow = Meow::new(b"my hash function");
meow.ad(b"big data", false);
// Same as hashing to entire string at once.
meow.ad(b"big ", false);
meow.ad(b"data", true);
let mut hash = [0u8; 32];
meow.prf(&mut hash, false);

使用 ad 吸收数据,然后使用 prf 函数将其压缩。此示例还说明了使用 more,它允许我们将操作分成多个调用。对哈希函数的第二次调用是等效的。

菲亚特-沙米尔化

Meow 不仅可以用一次操作进行哈希处理,还可以在吸收和压缩数据之间交替,这对于使交互式公钥协议非交互式很有用。

use ck_meow::Meow;

let mut meow = Meow::new(b"my protocol");
meow.ad(b"some data", false);
meow.ad(b"some more data", false);
let mut challenge = [0u8; 32];
meow.prf(&mut challenge, false);
meow.ad(b"even more data", false);
let mut another_challenge = [0u8; 32];
meow.prf(&mut another_challenge, false);

(注意,添加一些用于框架的 meta_ad 调用以定义输入长度会更好。)

依赖项

~0.4–0.8MB
~19K SLoC