#encryption #random #no-std #enocoro #enocoro128

no-std enocoro128v2

安全、适用于嵌入式设备的Enocoro-128(第2版)流密码。已使用日立的官方测试向量进行验证。

7个版本

0.1.6 2021年11月12日
0.1.5 2020年6月21日
0.1.4 2020年4月21日
0.1.2 2020年1月2日

密码学中排名第616

每月下载量30

MIT协议

260KB
475

enocoro128v2

crates.io GitHub Actions Unsafe-Zero-Percent

#![forbid(unsafe_code)]#![no_std]实现了Enocoro-128v2 [1],这是轻量级、CRYPTREC候选 [3] 流密码的更新版本 [2]。尚未报告针对Enocoro-128v2的实际攻击 [4]。

功能

  • 对称密钥加密
  • 伪随机数生成器(PRNG)

实现

  • 在裸机环境中运行:无标准库依赖项,无动态内存分配
  • 在释放时从内存安全擦除状态 [5]
  • 与日立的C参考实现 [6] 紧密映射,以方便审计代码
  • 使用日立的官方测试向量 [7] 进行验证

注意事项

  • 仅加密不能保证完整性和真实性:根据您的使用情况,此库可能需要与基于哈希的消息认证码(HMAC)结合使用
  • PRNG函数必须从平台特定的熵源中初始化

使用方法

当明文或密文的全部内容同时驻留在内存中时,可以使用简化的API(相关函数)

use enocoro128v2::Enocoro128;

let key: [u8; 16] = [
   0x4b, 0x8e, 0x29, 0x87, 0x80, 0x95, 0x96, 0xa3,
   0xbb, 0x23, 0x82, 0x49, 0x9f, 0x1c, 0xe7, 0xc2,
];

let iv: [u8; 8] = [0x3c, 0x1d, 0xbb, 0x05, 0xe3, 0xca, 0x60, 0xd9];

let plaintext = [
   0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
]; // "Hello world!"

let mut msg: [u8; 12] = plaintext.clone();

// Encrypt in-place
Enocoro128::apply_keystream_static(&key, &iv, &mut msg);
assert_ne!(msg, plaintext);

// Decrypt in-place
Enocoro128::apply_keystream_static(&key, &iv, &mut msg);
assert_eq!(msg, plaintext);

如果明文或密文的全部内容永远不会同时驻留在内存中(例如,以数据块的形式接收/传输,大小可能不同),则可以使用实例API

use enocoro128v2::Enocoro128;

let key: [u8; 16] = [
   0x4b, 0x8e, 0x29, 0x87, 0x80, 0x95, 0x96, 0xa3,
   0xbb, 0x23, 0x82, 0x49, 0x9f, 0x1c, 0xe7, 0xc2,
];

let iv: [u8; 8] = [0x3c, 0x1d, 0xbb, 0x05, 0xe3, 0xca, 0x60, 0xd9];

let plaintext_1 = [0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello"
let plaintext_2 = [0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21]; // " world!"

let mut msg_1 = plaintext_1.clone();
let mut msg_2 = plaintext_2.clone();

// Create an instance of the cipher
let mut e128 = Enocoro128::new(&key, &iv);

// Encrypt in-place
e128.apply_keystream(&mut msg_1);
e128.apply_keystream(&mut msg_2);
assert_ne!(msg_1, plaintext_1);
assert_ne!(msg_2, plaintext_2);

// Reset keystream prior to decryption
e128.init_keystream();

// Decrypt in-place
e128.apply_keystream(&mut msg_1);
e128.apply_keystream(&mut msg_2);
assert_eq!(msg_1, plaintext_1);
assert_eq!(msg_2, plaintext_2);

从密钥流生成随机缓冲区或数字(请注意,调用者负责使用特定平台的熵源创建密钥和IV,这些值初始化PRNG!)

use enocoro128v2::Enocoro128;

// Assuming bytes gathered from a reliable, platform-specific entropy source
let key: [u8; 16] = [
   0x4b, 0x8e, 0x29, 0x87, 0x80, 0x95, 0x96, 0xa3,
   0xbb, 0x23, 0x82, 0x49, 0x9f, 0x1c, 0xe7, 0xc2,
];

// Assuming bytes gathered from a reliable, platform-specific entropy source
let iv: [u8; 8] = [0x3c, 0x1d, 0xbb, 0x05, 0xe3, 0xca, 0x60, 0xd9];

let mut my_rand_buf = [0; 3];
let mut my_rand_u16: u16 = 0;
let mut my_rand_u64: u64 = 0;

let mut e128 = Enocoro128::new(&key, &iv);

e128.rand_buf(&mut my_rand_buf);
assert!(my_rand_buf.iter().all(|&x| x != 0));

my_rand_u16 = e128.rand_u16();
assert_ne!(my_rand_u16, 0);

my_rand_u64 = e128.rand_u64();
assert_ne!(my_rand_u64, 0);

参考资料


依赖关系

~320–770KB
~17K SLoC