import math


def giantstep_babyStep(m, c, n, phi, group) :
    """
    With c = m^e % n 
    given m, c, n, 𝜙(𝑛), and the target group 
    This function will find out e % group in time O(√N).
    
    Give : 
        @m : plaintxt data
        @c : cipher data
        @n : module
        @phi : 𝜙(𝑛)
        @group : A factor in phi

    Return :
        @e : what exponent this m is taken in group field.
    """
    # Raising to subgroup 
    assert phi % group == 0, f"This phi didn't make {group} group"
    e = phi // group
    sqf = math.ceil(math.sqrt(group)) 
    gf = pow(m, e, n) 
    gsqf = pow(gf, sqf, n) 
    table = {}
    # Giant step 
    ygna = pow(c, e, n) 
    for a in range(sqf):
        table[ygna] = a 
        ygna = (ygna * gsqf) % n
    # Baby step
    gb = 1
    for b in range(sqf): 
        if gb in table :
            a = table[gb]
            ki = (b-a*sqf) % group
            return ki
        gb = (gb*gf)%n