Baby-step Giant-step and its extension

from wikipedia

In group theory, a branch of mathematics, the baby-step giant-step is a meet-in-the-middle algorithm for computing the discrete logarithm or order of an element in a finite abelian group due to Daniel Shanks. The discrete log problem is of fundamental importance to the area of public key cryptography.

The baby-step giant-step algorithm can solve the problem of finding discrete logorithms in O ( n   ) O(\sqrt{n}\space) O(n  )time, significantly faster than the O ( n ) O(n) O(n) time complexity of the naive trial-and-error approach.

BSGS

The problem we are aiming to solve using BSGS can be properly framed as follow:

Given a cyclic group G \mathbb{G} G of order n \mathbb{n} n, a generator a a a of the group and a group element b b b, we are to find an integer x x x such that a x = b a^x=b ax=b.

In the form of modular arithmetic, this is essentially solving a x ≡ b ( m o d p ) a^x\equiv b\pmod{p} axb(modp), where gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1.

We let x = c ⌈ p ⌉ − d x = c\lceil \sqrt p \rceil - d x=cp d ( 0 ≤ c , d ≤ ⌈ p ⌉ 0\le c,d \le \lceil \sqrt p\rceil 0c,dp ).

Substitute back to the original equation, we have
a c ⌈ p ⌉ − d ≡ b ( m o d p ) a c ⌈ p ⌉ ≡ b a d ( m o d p ) \begin{aligned} a^{c\lceil \sqrt p\rceil -d} &\equiv b \pmod p\\ a^{c\lceil \sqrt p\rceil} &\equiv ba^d \pmod p \end{aligned} acp dacp b(modp)bad(modp)
Next, we compute all possible ⌈ p ⌉ {\lceil \sqrt p\rceil} p values of b a d ba^d bad and store them in a hash table. Then, we compute all possible ⌈ p ⌉ {\lceil \sqrt p\rceil} p values of ( a ⌈ p ⌉ ) c (a^{\lceil \sqrt p\rceil})^c (ap )c and find if there is any b a d ba^d bad with equal value in O ( 1 ) O(1) O(1) time, and corresponding value of x x x can thus be found. The overall time complexity is therefore O ( p ) O(\sqrt p) O(p ).

The idea of BSGS is rather simple, and it is based on a space-time trade-off.

Extension: Finding a discrete root

Next up, we want to find all x x x which satisfies the equation x a ≡ b ( m o d p ) x^a\equiv b\pmod p xab(modp), where p p p is a prime number.

It would require a few steps and some preliminary knowledge about order and primitive root to convert the problem to the typical problem we solve with BSGS.

Primitive Root(Part1)
Primitive Root(Part2)

Suppose prime number p p p has a primitive root g g g, we can solve the equation ( g a ) c ≡ b ( m o d p ) (g^a)^c\equiv b\pmod p (ga)cb(modp) for x ≡ g c ( m o d p ) x\equiv g^c\pmod p xgc(modp) instead in O ( p ) O(\sqrt p) O(p ) time using BSGS. We can always find such c c c since the cyclic group generated by g g g, { g , g 2 , ⋯   , g ϵ p ( g ) − 1 , 1 } \lbrace g,g^2,\cdots,g^{\epsilon_p(g)-1},1 \rbrace {g,g2,,gϵp(g)1,1} has an order of φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p1 and hence should cover every possible remainder of p p p, unless b = 0 b=0 b=0 which would have made the problem trivial to begin with. Now we have one solution determined which is x 0 = g c x_0=g^c x0=gc.

To obtain all the solutions, since we have g p − 1 ≡ 1 ( m o d p ) g^{p-1}\equiv1\pmod p gp11(modp) by Fermat’s Little Theorem, we have g c × ( g p − 1 ) n ≡ b ( m o d p ) g^c\times(g^{p-1})^n\equiv b\pmod p gc×(gp1)nb(modp), and x c + n ( p − 1 ) a = b ( m o d p ) x^{c+\frac{n(p-1)}{a}}=b\pmod p xc+an(p1)=b(modp), where a ∣ n ( p − 1 ) a|n(p-1) an(p1).

To find all such n n n, we factor out g c d ( a , p − 1 ) gcd(a,p-1) gcd(a,p1),and since gcd ⁡ ( a gcd ⁡ ( a , p − 1 ) , p − 1 gcd ⁡ ( a , p − 1 ) ) = 1 , \gcd(\frac{a}{\gcd(a,p-1)},\frac{p-1}{\gcd(a,p-1)})=1, gcd(gcd(a,p1)a,gcd(a,p1)p1)=1, we are left with a gcd ⁡ ( a , p − 1 ) ∣ n \frac{a}{\gcd(a,p-1)}|n gcd(a,p1)an. We can thus let n = m × a gcd ⁡ ( a , p − 1 ) n=m\times\frac{a}{\gcd(a,p-1)} n=m×gcd(a,p1)a, where m ∈ Z . m\in\mathbb{Z}. mZ. Hence, all solutions x x x to the equations are x = g c + m a gcd ⁡ ( a , p − 1 ) x=g^{c+\frac{ma}{\gcd(a,p-1)}} x=gc+gcd(a,p1)ma, where m ∈ Z . m\in\mathbb{Z}. mZ.

Extension: a more general case

Through a little tweak, we can use BSGS to solve a x ≡ b ( m o d p ) a^x\equiv b\pmod{p} axb(modp) with no restriction on a a a and p p p.

Factor out g c d ( a , p ) = f 1 gcd(a,p)=f_1 gcd(a,p)=f1 from the origianl equation, we have
a f 1 × a x − 1 ≡ b ( m o d b f 1 ) \frac{a}{f_1}\times a^{x-1}\equiv b\pmod{\frac{b}{f1}} f1a×ax1b(modf1b).

We carry out this process for k k k times, after which gcd ⁡ ( a , p ∏ i = 1 k f i ) = 1. \gcd(a,\frac{p}{\prod_{i=1}^k{f_i}})=1. gcd(a,i=1kfip)=1.
Notice that this process will be carried out for at most l o g 2 ( p ) log_2(p) log2(p) times.

Now we have a k ∏ i = 1 k f i × a x − k ≡ b ( m o d p ∏ i = 1 k f i ) \frac{a^k}{\prod_{i=1}^k{f_i}}\times a^{x-k}\equiv b\pmod{\frac{p}{\prod_{i=1}^k{f_i}}} i=1kfiak×axkb(modi=1kfip), and we can find the multiplicative inverse of a k ∏ i = 1 k f i \frac{a^k}{\prod_{i=1}^k{f_i}} i=1kfiak modulo p ∏ i = 1 k f i \frac{p}{\prod_{i=1}^k{f_i}} i=1kfip using the extended euclidean algorithm since gcd ⁡ ( a , p ∏ i = 1 k f i ) = 1. \gcd(a,\frac{p}{\prod_{i=1}^k{f_i}})=1. gcd(a,i=1kfip)=1.

The equation can then be reduced to the simple case
a x − k ≡ b × ( a k ∏ i = 1 k f i ) − 1 ( m o d p ∏ i = 1 k f i ) a^{x-k}\equiv b\times(\frac{a^k}{\prod_{i=1}^k{f_i}})^{-1}\pmod{\frac{p}{\prod_{i=1}^k{f_i}}} axkb×(i=1kfiak)1(modi=1kfip) which we can solve by BSGS. Notice that we might end up with a solution for x − k < k x-k<k xk<k, in this case we only need to add multiple copies of ϵ p ∏ i = 1 k f i ( a ) \epsilon_{\frac{p}{\prod_{i=1}^k{f_i}}}(a) ϵi=1kfip(a) to the answer until it is no longer negative.

Implementation

Below is a short implementation of the extended BSGS algorithm in C++

int exgcd(int a, int b, int& x, int& y)//extended euclidean algorithm to find the multiplicative inverse
{
    if (!b)
    {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

int bsgs(int a, int b, int p)//the basic BSGS algorithm
{
    if (1 % p == b % p) return 0;//special case
    int k = sqrt(p) + 1;//meet in the middle approach
    unordered_map<int, int> hash;//hash map
    for (int i = 0, j = b % p; i < k; i ++ )
    {
        hash[j] = i;
        j = (LL)j * a % p;
    }
    int ak = 1;
    for (int i = 0; i < k; i ++ ) ak = (LL)ak * a % p;
    for (int i = 1, j = ak; i <= k; i ++ )
    {
        if (hash.count(j)) return i * k - hash[j];
        j = (LL)j * ak % p;
    }
    return -inf;//no answer
}

int exbsgs(int a, int b, int p)//extended BSGS
{
    b = (b % p + p) % p;
    if (1 % p == b % p) return 0;
    int x, y;
    int d = exgcd(a, p, x, y);
    if (d > 1)
    {
        if (b % d) return -inf;
        exgcd(a / d, p / d, x, y);
        return exbsgs(a, (LL)b / d * x % (p / d), p / d) + 1;
    }
    return bsgs(a, b, p);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值