1个不稳定版本
0.1.0 | 2022年9月14日 |
---|
#1376 在 密码学
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_clr
和recv_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