Zama 发布了 TFHE-rs v1.0 稳定版,该版本稳定了 x86 CPU 后端的高级 API,并确保向后兼容,提升了密码学安全性,优化了分布式协议的性能。此外,还发布了 TFHE-rs 手册,详细介绍了后端的实现,并简化了贡献流程。通过贡献 Zama Bounty Program 还可以获得奖励,此外,GPU 后端也在开发中。
本月,Zama 发布了 TFHE-rs v1.0,这是 TFHE-rs 库的第一个稳定版本。这标志着一个重要的里程碑,稳定了 x86 CPU 后端的高级 API,同时确保了向后兼容性。
换句话说,你现在可以依赖 TFHE-rs API,而无需担心未来更新中的重大更改。
此版本中最重要的改进是密钥参数的改进,这增强了密码安全性,保持了性能,并优化了它们在分布式协议中的使用。此更新还引入了官方手册和简化的贡献流程,这两者都将在本文中详细介绍。
值得注意的是,计算错误的概率已降低到小于 2-128,同时保持了性能。实际上,这意味着发生错误的概率与打破现代密码学标准的可能性一样微不足道。
在发布 TFHE-rs v1.0 的同时,Zama 发布了其 TFHE-rs 手册 的第一版,详细介绍了后端中的所有实现。
TFHE-rs 手册涵盖:
另一点重要的是,与文档不同,该手册侧重于高斯噪声分布,与学术文献中使用的标准定义保持一致。
此版本中的一个核心增强是密码参数的改进,将计算错误的概率从小于 2-64 降低到小于 2-128。
虽然通常对用户隐藏,但密码参数是 TFHE-rs 的基础,可确保计算的安全性、效率和正确性。
直到最近,TFHE-rs 的标准参数集还保证了计算的正确性,错误概率低于 2-64——对于传统的客户端-服务器用例来说,这实际上可以忽略不计。然而,最近的研究表明,在可以访问加密和解密数据的场景中,可能会出现某些理论攻击。虽然使用以前的参数集在计算上仍然不可行——需要平均 263 次计算才能成功——但此更新进一步加强了针对此类可能性的安全性。
Zama 设计 TFHE-rs 旨在为所有应用程序提供最高级别的安全性。使用 TFHE-rs v1.0,密码参数已得到改进,以将计算错误概率降低到 2-128 以下,与标准密码安全级别保持一致,并确保即使在分布式协议中也具有鲁棒性。
通常,将失败概率从 2-64 降低到 2-128 至少会使计算时间增加一倍。但是,TFHE-rs 通过实现一种称为漂移缓解的新技术,将速度降低限制在 10% 左右(有关更多详细信息,请参见相关科学文章)。
由于 TFHE-rs 是 Zama 区块链协议的支柱,使开发人员能够使用 FHE 编写机密智能合约。这个新版本旨在更好地支持分布式协议——其中私钥和公钥的生成可能在多个用户之间共享——TFHE-rs v1.0 现在默认使用 TUniform 噪声分布。这种 Uniform 变体避免了高斯分布施加的约束。
对于喜欢传统方法的用户,基于高斯分布的密码参数仍然可用。
TFHE-rs 文档提供了有关选择密码参数和理解不同分布的全面指南。
为了获得更深入的技术见解,文档中还提供了使用新参数集执行的基准测试,包括整数运算和像 bootstrapping 这样的低级运算的基准测试。
下面是如何在客户端-服务器设置中使用 TFHE-rs 的一个简单演示。
为了使这个示例简单明了,我们有意省略了诸如公钥加密及其相关的零知识证明之类的高级功能——这些功能通常用于分布式环境中,以使用户可以共享一个通用的加密密钥并验证 ciphertext 是否已正确形成。
此示例侧重于核心工作流程,模拟客户端和服务器之间的交互:
use tfhe::prelude::*;
use tfhe::shortint::parameters::{COMP_PARAM_MESSAGE_2_CARRY_2, PARAM_MESSAGE_2_CARRY_2};
use tfhe::{
set_server_key, CompressedCiphertextListBuilder, FheAsciiString, FheBool, FheInt64, FheUint16,
FheUint2, FheUint32,
};
fn main() {
// Use aliases for ease of use, do not use aliases for production (not stable through time)
// 为了方便使用,可以使用别名,但不要在生产环境中使用别名(随时间推移不稳定)
let config = tfhe::ConfigBuilder::with_custom_parameters(PARAM_MESSAGE_2_CARRY_2)
.enable_compression(COMP_PARAM_MESSAGE_2_CARRY_2)
.build();
// On the client side, generate the ClientKey, must remain SECRET
// 在客户端,生成 ClientKey,必须保密
let client_key = tfhe::ClientKey::generate(config);
// Also generate the ServerKey which will allow the server to perform computations, this one is
// sent to the server
// 还要生成 ServerKey,这将允许服务器执行计算,这个密钥被发送到服务器
let server_key = tfhe::ServerKey::new(&client_key);
// Encrypt some values required by service provider
// 加密服务提供商需要的一些值
let ct1 = FheUint32::encrypt(17_u32, &client_key);
let ct2 = FheInt64::encrypt(-1i64, &client_key);
let ct3 = FheBool::encrypt(false, &client_key);
let ct4 = FheUint2::encrypt(3u8, &client_key);
let ct5 = FheAsciiString::encrypt("1.0!", &client_key);
// On the server side, once the server key has been received, set it as the active key
// 在服务器端,一旦收到服务器密钥,就将其设置为活动密钥
set_server_key(server_key);
// The server does some computations without seeing the data
// 服务器在看不到数据的情况下进行一些计算
let ct1_res = ct1 + 25;
let ct2_res = 43 + ct2;
let ct3_res = ct3 & true;
let ct4_res = ct4 - 1;
let ct5_res = ct5.len().into_ciphertext();
// We can compress the data to send or store smaller amounts of data to the client
// 我们可以压缩数据以发送或存储更少的数据量到客户端
let compressed_list = CompressedCiphertextListBuilder::new()
.push(ct1_res)
.push(ct2_res)
.push(ct3_res)
.push(ct4_res)
.push(ct5_res)
.build()
.unwrap();
// On the client side after receiving the compressed data
// 在客户端收到压缩数据后
let a: FheUint32 = compressed_list.get(0).unwrap().unwrap();
let b: FheInt64 = compressed_list.get(1).unwrap().unwrap();
let c: FheBool = compressed_list.get(2).unwrap().unwrap();
let d: FheUint2 = compressed_list.get(3).unwrap().unwrap();
let e: FheUint16 = compressed_list.get(4).unwrap().unwrap();
let a: u32 = a.decrypt(&client_key);
assert_eq!(a, 42);
let b: i64 = b.decrypt(&client_key);
assert_eq!(b, 42);
let c = c.decrypt(&client_key);
assert!(!c);
let d: u8 = d.decrypt(&client_key);
assert_eq!(d, 2);
let e: u16 = e.decrypt(&client_key);
assert_eq!(e, 4);
// The compressed data can be reused by the server if it kept it on disk
// 如果服务器将压缩数据保留在磁盘上,则可以重复使用
let recovered_a: FheUint32 = compressed_list.get(0).unwrap().unwrap();
let new_a = recovered_a << 4u32;
// The result can be sent uncompressed to the Client, which can also decrypt this new result
// 结果可以以未压缩的形式发送到客户端,客户端也可以解密这个新结果
let new_a: u32 = new_a.decrypt(&client_key);
assert_eq!(new_a, a << 4);
}
在 Zama,作为一家开源密码学公司不仅仅是一个要求,更是我们积极拥抱的东西。开放性推动了创新、协作和我们技术的不断改进。
TFHE-rs 的构建考虑到了这种理念,欢迎通过两种主要方式进行贡献:
1. 通过 Zama Bounty Program 为 TFHE-rs 做出贡献:一次一个挑战,推动 FHE 的发展
Zama Bounty Program 奖励开发人员解决推动 TFHE-rs 前进的技术挑战。每个季度都会开放一个新的 TFHE-rs bounty,参与者的解决方案通常会导致库的重大改进。
最近的一个例子是 homomorphic string 功能,它最初是作为 bounty 贡献而开始的,后来被集成到主存储库中。感谢这个添加,用户现在可以运行以下代码来检查一个 substring 是否包含在另一个字符串中:
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ClearString, ConfigBuilder, FheAsciiString};
fn main() {
let config = ConfigBuilder::default().build();
let (cks, sks) = generate_keys(config);
set_server_key(sks);
// Encrypt without padding, does not hide the string length and has better performance
// 使用无填充加密,不隐藏字符串长度,并具有更好的性能
let string = FheAsciiString::try_encrypt("TFHE-rs rocks!", &cks).unwrap();
// Encrypt with padding, hide the true length of the string
// 使用填充加密,隐藏字符串的真实长度
let search_string = FheAsciiString::try_encrypt_with_padding("is meh", 1, &cks).unwrap();
// We can also use clear strings
// 我们也可以使用 clear strings
let clear_search_string = ClearString::new("rocks".to_string());
// Does our initial string contain "is meh"?
// 我们的初始字符串是否包含 "is meh"?
let does_not_contain = string.contains(&search_string);
// Does our initial string contain "rocks"?
// 我们的初始字符串是否包含 "rocks"?
let contains = string.contains(&clear_search_string);
// Decrypt
// 解密
let decrypted_does_not_contain = does_not_contain.decrypt(&cks);
let decrypted_contains = contains.decrypt(&cks);
// Check all worked properly
// 检查是否一切正常
assert!(!decrypted_does_not_contain);
assert!(decrypted_contains);
}
可以在字符串文档中找到此新功能的优点的详细比较。
其他几个 bounty 驱动的贡献也已集成到 TFHE-rs 中,包括 homomorphic SHA-256:
Bounty Program 的下一个季度即将开始!关注官方 Bounty Program 存储库参与。期待你的贡献!
2. 直接为 TFHE-rs 做出贡献:构建、改进和创新
我们引入了一个简化的贡献流程,使开发人员和研究人员可以更轻松地向 TFHE-rs 添加新功能和改进。无论你是构建应用程序还是尝试新的原型,都可以按照以下步骤将你的工作集成到库中:
一旦被接受,你的贡献将像库中的任何其他功能一样,随着时间的推移得到维护。
展望未来,TFHE-rs 正在朝着两个关键目标发展:
- 原文链接: zama.ai/post/tfhe-rs-v1-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!