提问人:PrinceZee 提问时间:9/30/2023 最后编辑:Jared SmithPrinceZee 更新时间:9/30/2023 访问量:67
在 rust 上移植 BSGS (ECDSA)
Porting BSGS (ECDSA) on rust
问:
嗨,大家好,我正在将此处显示的示例中的 Baby step Giant Step 算法移植到 Rust 编程语言。https://github.com/ashutosh1206/Crypton 普通版本移植成功,没有问题,这里是一个示例。
use serde::{Deserialize, Serialize};
use num_bigint::BigUint;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BSGS(String);
pub struct Parallel(String);
use rayon::prelude::*;
use num_traits::{One, Zero};
use std::collections::HashMap;
use std::sync::{Mutex, Arc};
// https://github.com/ashutosh1206/Crypton/blob/master/Discrete-Logarithm-Problem/Algo-Baby-Step-Giant-Step/bsgs.py
impl BSGS {
// """
// Reference:
// To solve DLP: h = g^x % p and get the value of x.
// We use the property that x = i*m + j, where m = ceil(sqrt(n))
// :parameters:
// g : int/long
// Generator of the group
// h : int/long
// Result of g**x % p
// p : int/long
// Group over which DLP is generated. Commonly p is a prime number
// :variables:
// m : int/long
// Upper limit of baby steps / giant steps
// x_poss : int/long
// Values calculated in each giant step
// c : int/long
// Giant Step pre-computation: c = g^(-m) % p
// i, j : int/long
// Giant Step, Baby Step variables
// lookup_table: dictionary
// Dictionary storing all the values computed in the baby step
// """
pub fn new(bsgs: String) -> Self {
Self(bsgs)
}
pub fn run(g: &BigUint, h: &BigUint, p: &BigUint) -> Option<BigUint> {
let mod_size = p.bits();
println!("[+] Using BSGS algorithm to solve DLP");
println!("[+] Modulus size: {}. Warning! BSGS not space efficient\n", mod_size);
let m = (*&p - BigUint::one()).sqrt() + BigUint::one();
let mut lookup_table: HashMap<BigUint, BigUint> = HashMap::new();
// Baby Step
let mut j = BigUint::zero();
while &j < &m {
let key = g.modpow(&j, &p);
lookup_table.insert(key.clone(), j.clone());
j += BigUint::one();
}
// Giant Step pre-computation
let c = g.modpow(&(&m * (*&p - BigUint::from(2u32))), &p);
// Giant Steps
let mut i = BigUint::zero();
while &i < &m {
let temp = &(h * &c.modpow(&i, &p)) % p;
if let Some(j) = lookup_table.get(&temp) {
// x found
return Some(i * &m + j);
}
i += BigUint::one();
}
None
}
}
但我很难移植定义为:
from sage.all import *
def bsgs_ecdlp(P, Q, E):
if Q == E((0, 1, 0)):
return P.order()
if Q == P:
return 1
m = ceil(sqrt(P.order()))
lookup_table = {j*P: j for j in range(m)}
for i in range(m):
temp = Q - (i*m)*P
if temp in lookup_table:
return (i*m + lookup_table[temp]) % P.order()
return None
if __name__ == "__main__":
import random
E = EllipticCurve(GF(17), [2, 2])
try:
for i in range(100):
x = random.randint(2, 19)
assert bsgs_ecdlp(E((5, 1)), x*E((5, 1)), E) == x
except Exception as e:
print e
print "[-] Something's wrong!"
这里的这部分让我头疼,因为它正在使用 Sage 来做键减法。 由于 Rust 中的模块 SECP256K1 遵循不同的模式,因此最佳方法是什么。
temp = Q - (i*m)*P
我的直觉告诉我,这部分只是(i*m)*P
let secp = Secp256k1::new();
let pub_key = PublicKey::from_secret_key(&secp, &secret);
其中 secret 是操作。
但是如何在 Rust 中做 Q - New_Pub_Key_points ?(i*m)
答: 暂无答案
评论
temp = Q - (i*m)*P
这意味着这个;(加密格式)乘法,这只是整数乘法,让.然后进行标量乘法,这是将点P本身相加t次(可惜有人称之为点乘法)。那么你需要否定 R(将坐标更改为 ),然后添加 .如您所见,您需要使用加倍算法的点加法和标量乘法才能在最佳速度下获得良好效果。Q-[i*m]P
i
m
t = i*m
[t]P
R = [t]P
y
-y
S = -R
Q+S