# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name :      m_leak_attack
   Description :
   Author :         x3nny
   date :           2021/7/18
-------------------------------------------------
   Change Activity:
                    2021/7/18: Init
-------------------------------------------------
"""


# This file was *autogenerated* from the file xenny/ctf/crypto/modern/asymmetric/rsa/copper_smith/m_leak_attack.sage
from sage.all_cmdline import *   # import sage library

_sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0)
from Crypto.Util.number import *

def high_m_leak(mbar, c, n, e, bits):
    PR = PolynomialRing(Zmod(n), names=('x',)); (x,) = PR._first_ngens(1)
    f = (mbar + x)**e - c
    roots = f.small_roots(X=_sage_const_2 **bits, beta=_sage_const_1 ) # find root < 2^kbits with factor >= n^0.4
    if not roots:
        return None, None
    m = int(roots[_sage_const_0 ]+mbar)
    return m

def low_m_leak(mbar, c, n, e, bits):
    PR = PolynomialRing(Zmod(n), names=('x',)); (x,) = PR._first_ngens(1)
    ZmodN = Zmod(n)
    f = (x*ZmodN(power(_sage_const_2 , mbar.bit_length())) + mbar)**e - c
    f = f.monic()
    roots = f.small_roots(X=_sage_const_2 **bits, beta=_sage_const_1 ) # find root < 2^kbits with factor >= n^0.4
    if not roots:
        return None, None
    m = roots[_sage_const_0 ]+mbar
    return m

def attack(mbar, c, n, e, bits=None):
    if bits is None:
        raise Exception('bits can\'t be None.')
    m = high_m_leak(mbar, c, n, e, bits)
    if m is None:
        return low_m_leak(mbar, c, n, e, bits)
    return m

