libsm icon indicating copy to clipboard operation
libsm copied to clipboard

ecc.rs中初始化table的方法可以使用读文件的方式进行加速

Open HaoXuan40404 opened this issue 2 years ago • 5 comments

我发现ecc.rs的创建点乘表table1和table2时,采用了lazy_static方法,这种方法在被第一次调用时会展开,这步大概需要3~5秒的时间,这里可以直接把两个表512个点(大概2M)写入到文件中,可以显著提高第一次调用该方法的效率 image

HaoXuan40404 avatar Apr 06 '22 08:04 HaoXuan40404

收到了你的建议。我本人建议是可以将计算结果也写成rust文件,进一步加快读取速度,也更加容易维护。你可以帮libsm提出issue和pr。ty

Pencil-Yao avatar Apr 06 '22 08:04 Pencil-Yao

收到了你的建议。我本人建议是可以将计算结果也写成rust文件,进一步加快读取速度,也更加容易维护。你可以帮libsm提出issue和pr。ty

好的,我尝试一下将结果写入二进制文件中,对这里进行一下加速

HaoXuan40404 avatar Apr 07 '22 04:04 HaoXuan40404

我写了一段程序,来尝试把这些数据写入到文件中并恢复他,我发现这些数据在debug显示下看上去是一样的,但是真正比较时又并不一样,我的测试程序是这样的

#[test]
    fn test_generate_table1() {
        let curve = EccCtx::new();

        let mut table = File::create("./table1.data").unwrap();
        // let mut table: Vec<Point> = Vec::new();
        for i in 1..256 {
            let p1 = curve.mul_raw(&pre_vec_gen(i as u32), &curve.generator());
            println!("p1:{}", p1);
            let p_bytes = curve.point_to_bytes(&p1, false);
            table.write(&p_bytes).unwrap();
        }
    }

    #[test]
    fn test_recover_table1() {
        let curve = EccCtx::new();
        let mut buffer = [0u8; 65*255];
        let mut file = File::open("./table1.data").unwrap();
        file.read(&mut buffer).unwrap();

        for i in 0..255 {
            let idx: usize = i * 65;
            let idx_end: usize = idx + 65;
            let new_g = curve.bytes_to_point(&buffer[idx..idx_end]).unwrap();
            let p1 = curve.mul_raw(&pre_vec_gen((i + 1) as u32), &curve.generator());
            println!("new_g:{}", new_g);
            println!("p1:{}", p1);
            assert_eq!(new_g, p1)
        }
    }

错误提示为

new_g:(x = 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7, y = 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0)
p1:(x = 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7, y = 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0)
new_g:(x = 0x3d251b54e10d581f71e834cf86896c1051e46707fd55865668a88405ae53c1e9, y = 0x87891d33fb98b4d85931f6831a8d8c11eeaf729853e526fe1884d5b0eeb19032)
p1:(x = 0x3d251b54e10d581f71e834cf86896c1051e46707fd55865668a88405ae53c1e9, y = 0x87891d33fb98b4d85931f6831a8d8c11eeaf729853e526fe1884d5b0eeb19032)
thread 'sm2::ecc::tests::test_recover_table1' panicked at 'assertion failed: `(left == right)`
  left: `Point { x: FieldElem { value: [1025842004, 3775748127, 1911043279, 2257153040, 1373923079, 4250240598, 1755874309, 2924724713] }, y: FieldElem { value: [2273910067, 4221088984, 1496446595, 445484049, 4004475544, 1407526654, 411358640, 4004614194] }, z: FieldElem { value: [0, 0, 0, 0, 0, 0, 0, 1] } }`,
 right: `Point { x: FieldElem { value: [3530100962, 1503658241, 2644576579, 1194393339, 2027275901, 4238351532, 2458124336, 4150437411] }, y: FieldElem { value: [2290422836, 3079446265, 2521014915, 2038845571, 863739665, 2709782356, 3050917920, 3274615524] }, z: FieldElem { value: [4229885632, 457521614, 939797413, 1252819368, 3706385922, 3252672339, 1921353704, 2107211753] } }`', src/sm2/ecc.rs:883:13

这种情况可能的原因是什么呢

HaoXuan40404 avatar Apr 07 '22 10:04 HaoXuan40404

这种问题可以从以下几点去考虑:

  1. 公式的代码实现是否有误
  2. 数据处理是否有误,eg. 大小端问题
  3. 坐标系问题 仿射 映射 是否有误,有点类似问题1

Pencil-Yao avatar May 30 '22 08:05 Pencil-Yao

建议使用curve.eq()方法判断两个点是否相等, 其原因似乎与问题3有关

这种问题可以从以下几点去考虑:

  1. 公式的代码实现是否有误
  2. 数据处理是否有误,eg. 大小端问题
  3. 坐标系问题 仿射 映射 是否有误,有点类似问题1

FullyRobert avatar Jun 04 '22 07:06 FullyRobert

https://github.com/citahub/libsm/pull/49 我在其中做了阐述,这种情况从实际上来说收效并不大。从优化来讲并不指向真正的性能瓶颈,而是一个针对初始化的过程,这个过程只会经历一次,所以在此 close这个issuse,如果有更好想法可以再次开启

Pencil-Yao avatar Mar 02 '23 03:03 Pencil-Yao