#curve #decryption #jubjub #multi-threaded #algorithm #scalar-field #package

babygiant-alt-bn128

这是一个Rust库,实现了在Baby Jubjub曲线(其基域是alt-bn-128(又称bn254)的标量域)上的多线程版本的baby-step giant-step算法,用于解密u40整数。这是Noir包noir-elgamal的配套库。

2个版本

0.1.1 2023年10月31日
0.1.0 2023年10月24日

#1162 in 算法

MIT许可协议

20KB
136

babygiant-alt-bn128

这是一个Rust库,实现了在Baby Jubjub曲线(其基域是alt-bn-128(又称bn254)的标量域)上的多线程版本的baby-step giant-step算法,用于解密u40整数。这是Noir包noir-elgamal的配套库。

如果您想在前端使用此算法的WASM版本,请参阅配套的npm包

⚠️ 警告:当前的实现容易受到时间攻击,因为运行时间取决于输入。请记住这一点,如果您在生产中使用它,请格外小心。

如何使用

首先,使用来自noir-elgamalexp_elgamal_decrypt函数解密嵌入形式的点。

例如,此电路应输出嵌入在Baby Jubjub曲线上的明文值42

use dep::elgamal::{priv_to_pub_key,exp_elgamal_encrypt,exp_elgamal_decrypt};
use dep::std;

fn main(){
  let plaintext = 42;
  let private_key = 0x04d73359c9166e49aafaf9a4852eaa4dceb2c26878196b10e9048004ff5cc20c;
  let pub_key = priv_to_pub_key(private_key);
  let randomness = 0x03f90f366f9fd55bb1335eac3b11f2190f2ce9ff1769db241edaa7774136099b;
  let encrypted_point = exp_elgamal_encrypt(pub_key, plaintext, randomness);
  let decrypted_point = exp_elgamal_decrypt(private_key, encrypted_point);
  std::println(decrypted_point);
}

确实,运行nargo execute应在终端返回以下点

Point { x: 0x06184da392a17823e9c1d38cb50980b17150ffa411965b03f0b0200d9557daa9, y: 0x244a710118db92636e46e3f97bd80093ba7026ff97ca32d387145337e250549c }

对于解密的最后一步,即从先前的嵌入形式恢复原始明文(作为大小为40位的无符号整数),您可以通过在Cargo.toml中添加以下依赖项在Rust项目中导入此库

[dependencies]
babygiant-alt-bn128 = "0.1.1"

然后在src/main.rs中使用以下代码

use babygiant_alt_bn128::do_compute_dlog;

fn main() {
    let num_threads = 5;
    let dlog = do_compute_dlog("0x06184da392a17823e9c1d38cb50980b17150ffa411965b03f0b0200d9557daa9",
    "0x244a710118db92636e46e3f97bd80093ba7026ff97ca32d387145337e250549c",num_threads);
    assert!(42== dlog);
}

通过运行,您可以验证baby-step giant-step算法确实能够恢复原始明文值42

cargo run --release

Rust程序应在现代计算机上运行少于2秒。

技术描述

此库与Noir包https://github.com/jat9292/noir-elgamal/配套。

do_compute_dlog 是本crate中的主函数,它应该在解密的最后一步被调用,作为输入使用 exp_elgamal_decrypt Noir函数返回的值。

这段代码深受 zkay 的启发,并使用 arkworks crate 作为其主要依赖。

与zkay相比,主要有两个区别

1/ 我们将baby steps循环中的标量乘法替换为点加法,这平均提高了7倍的速度,并通过多线程进一步提高了2.5倍,使得解密 u40 而不是仅仅 u32 的时间缩短到6秒以下(在Mac M1芯片上),这就是为什么我们在 baby_giant 调用中将最大位数参数从 32 替换为 40 的原因。即使在浏览器中(参见配套的 npm包),当使用 num_threads58 之间时,最坏情况下现在也实用地在9秒以内解密 u40(WASM开销)。

2/ 另一个很大的区别是,导入的arkworks库使用的是Edwards形式,而不是Noir中Baby Jubjub曲线使用的Twisted Edwards形式,因此我们进行了坐标变换,将点编码在Twisted Edwards形式而不是Edwards形式,以便使用与Noir实现相同的格式。

以下是函数签名

pub fn do_compute_dlog(x: &str, y: &str, num_threads: u64) -> u64

此函数将计算Baby Jubjub曲线上的点的离散对数,以Twisted Edwards形式表示。嵌入的明文应该是 u40(即小于 1099511627775 的无符号整数),否则程序将找不到有效的离散对数并引发恐慌。

xy 是表示嵌入明文坐标的字符串,应与 noir-elgamal 包中 exp_elgamal_decrypt 返回的值具有相同的格式,即 xy 应该是表示大小最多为 32 的两个字节数组的十六进制字符串。有效输入示例:x="0xbb77a6ad63e739b4eacb2e09d6277c12ab8d8010534e0b62893f3f6bb957051"y="0x25797203f7a0b24925572e1cd16bf9edfce0051fb9e133774b3c257a872d7d8b"。还要记住,如果 (x,y) 不是Twisted Edwards形式的Baby Jubjub曲线上的有效点,程序将引发恐慌。

num_thread 是用于并行化baby-step giant-step算法的线程数。

依赖项

~6.5MB
~128K SLoC