Example #1
0
def computeR(P, Q):
    m = P.degree()
    n = Q.degree()
    t = trace_from_minpoly(P, 2 * m * n + 4)
    u = trace_from_minpoly(Q, 2 * m * n + 4)
    v = [t[i] * u[i] for i in range(2 * m * n + 4)]
    from sage.matrix.berlekamp_massey import berlekamp_massey
    BM = berlekamp_massey(v)
    return BM
Example #2
0
def _composed_product(P, Q):
    'composed product of P and Q'
    m = P.degree()
    n = Q.degree()
    t = _trace_from_minpoly(P, 2*m*n+4)
    u = _trace_from_minpoly(Q, 2*m*n+4)
    v = [t[i]*u[i] for i in range(2*m*n+4)]
    BM = berlekamp_massey(v)
    return BM
Example #3
0
def computeR(P, Q):
    m = P.degree()
    n = Q.degree()
    t = trace_from_minpoly(P, 2*m*n+4)
    u = trace_from_minpoly(Q, 2*m*n+4)
    v = [t[i]*u[i] for i in range(2*m*n+4)]
    from sage.matrix.berlekamp_massey import berlekamp_massey
    BM = berlekamp_massey(v)
    return BM
Example #4
0
    def guess(self, sequence, algorithm='sage'):
        """
        Return the minimal CFiniteSequence that generates the sequence.

        Assume the first value has index 0.

        INPUT:

        - ``sequence`` -- list of integers
        - ``algorithm`` -- string
            - 'sage' - the default is to use Sage's matrix kernel function
            - 'pari' - use Pari's implementation of LLL
            - 'bm' - use Sage's Berlekamp-Massey algorithm

        OUTPUT:

        - a CFiniteSequence, or 0 if none could be found

        With the default kernel method, trailing zeroes are chopped
        off before a guessing attempt. This may reduce the data
        below the accepted length of six values.

        EXAMPLES::

            sage: C.<x> = CFiniteSequences(QQ)
            sage: C.guess([1,2,4,8,16,32])
            C-finite sequence, generated by -1/2/(x - 1/2)
            sage: r = C.guess([1,2,3,4,5])
            Traceback (most recent call last):
            ...
            ValueError: Sequence too short for guessing.

        With Berlekamp-Massey, if an odd number of values is given, the last one is dropped.
        So with an odd number of values the result may not generate the last value::

            sage: r = C.guess([1,2,4,8,9], algorithm='bm'); r
            C-finite sequence, generated by -1/2/(x - 1/2)
            sage: r[0:5]
            [1, 2, 4, 8, 16]
        """
        S = self.polynomial_ring()
        if algorithm == 'bm':
            from sage.matrix.berlekamp_massey import berlekamp_massey
            if len(sequence) < 2:
                raise ValueError('Sequence too short for guessing.')
            R = PowerSeriesRing(QQ, 'x')
            if len(sequence) % 2:
                sequence.pop()
            l = len(sequence) - 1
            denominator = S(berlekamp_massey(sequence).reverse())
            numerator = R(S(sequence) * denominator, prec=l).truncate()

            return CFiniteSequence(numerator / denominator)
        elif algorithm == 'pari':
            global _gp
            if len(sequence) < 6:
                raise ValueError('Sequence too short for guessing.')
            if _gp is None:
                _gp = Gp()
                _gp("ggf(v)=local(l,m,p,q,B);l=length(v);B=floor(l/2);\
                if(B<3,return(0));m=matrix(B,B,x,y,v[x-y+B+1]);\
                q=qflll(m,4)[1];if(length(q)==0,return(0));\
                p=sum(k=1,B,x^(k-1)*q[k,1]);\
                q=Pol(Pol(vector(l,n,v[l-n+1]))*p+O(x^(B+1)));\
                if(polcoeff(p,0)<0,q=-q;p=-p);q=q/p;p=Ser(q+O(x^(l+1)));\
                for(m=1,l,if(polcoeff(p,m-1)!=v[m],return(0)));q")
            _gp.set('gf', sequence)
            _gp("gf=ggf(gf)")
            num = S(sage_eval(_gp.eval("Vec(numerator(gf))"))[::-1])
            den = S(sage_eval(_gp.eval("Vec(denominator(gf))"))[::-1])
            if num == 0:
                return 0
            else:
                return CFiniteSequence(num / den)
        else:
            from sage.matrix.constructor import matrix
            from sage.functions.other import ceil
            from numpy import trim_zeros
            seq = sequence[:]
            while seq and sequence[-1] == 0:
                seq.pop()
            l = len(seq)
            if l == 0:
                return 0
            if l < 6:
                raise ValueError('Sequence too short for guessing.')

            hl = ceil(ZZ(l) / 2)
            A = matrix([sequence[k:k + hl] for k in range(hl)])
            K = A.kernel()
            if K.dimension() == 0:
                return 0
            R = PolynomialRing(QQ, 'x')
            den = R(trim_zeros(K.basis()[-1].list()[::-1]))
            if den == 1:
                return 0
            offset = next((i for i, x in enumerate(sequence) if x), None)
            S = PowerSeriesRing(QQ, 'x', default_prec=l - offset)
            num = S(R(sequence) * den).truncate(ZZ(l) // 2 + 1)
            if num == 0 or sequence != S(num / den).list():
                return 0
            else:
                return CFiniteSequence(num / den)
Example #5
0
    def guess(self, sequence, algorithm="sage"):
        """
        Return the minimal CFiniteSequence that generates the sequence.

        Assume the first value has index 0.

        INPUT:

        - ``sequence`` -- list of integers
        - ``algorithm`` -- string
            - 'sage' - the default is to use Sage's matrix kernel function
            - 'pari' - use Pari's implementation of LLL
            - 'bm' - use Sage's Berlekamp-Massey algorithm

        OUTPUT:

        - a CFiniteSequence, or 0 if none could be found

        With the default kernel method, trailing zeroes are chopped
        off before a guessing attempt. This may reduce the data
        below the accepted length of six values.

        EXAMPLES::

            sage: C.<x> = CFiniteSequences(QQ)
            sage: C.guess([1,2,4,8,16,32])
            C-finite sequence, generated by 1/(-2*x + 1)
            sage: r = C.guess([1,2,3,4,5])
            Traceback (most recent call last):
            ...
            ValueError: Sequence too short for guessing.

        With Berlekamp-Massey, if an odd number of values is given, the last one is dropped.
        So with an odd number of values the result may not generate the last value::

            sage: r = C.guess([1,2,4,8,9], algorithm='bm'); r
            C-finite sequence, generated by 1/(-2*x + 1)
            sage: r[0:5]
            [1, 2, 4, 8, 16]
        """
        S = self.polynomial_ring()
        if algorithm == "bm":
            from sage.matrix.berlekamp_massey import berlekamp_massey

            if len(sequence) < 2:
                raise ValueError("Sequence too short for guessing.")
            R = PowerSeriesRing(QQ, "x")
            if len(sequence) % 2 == 1:
                sequence = sequence[:-1]
            l = len(sequence) - 1
            denominator = S(berlekamp_massey(sequence).list()[::-1])
            numerator = R(S(sequence) * denominator, prec=l).truncate()

            return CFiniteSequence(numerator / denominator)
        elif algorithm == "pari":
            global _gp
            if len(sequence) < 6:
                raise ValueError("Sequence too short for guessing.")
            if _gp is None:
                _gp = Gp()
                _gp(
                    "ggf(v)=local(l,m,p,q,B);l=length(v);B=floor(l/2);\
                if(B<3,return(0));m=matrix(B,B,x,y,v[x-y+B+1]);\
                q=qflll(m,4)[1];if(length(q)==0,return(0));\
                p=sum(k=1,B,x^(k-1)*q[k,1]);\
                q=Pol(Pol(vector(l,n,v[l-n+1]))*p+O(x^(B+1)));\
                if(polcoeff(p,0)<0,q=-q;p=-p);q=q/p;p=Ser(q+O(x^(l+1)));\
                for(m=1,l,if(polcoeff(p,m-1)!=v[m],return(0)));q"
                )
            _gp.set("gf", sequence)
            _gp("gf=ggf(gf)")
            num = S(sage_eval(_gp.eval("Vec(numerator(gf))"))[::-1])
            den = S(sage_eval(_gp.eval("Vec(denominator(gf))"))[::-1])
            if num == 0:
                return 0
            else:
                return CFiniteSequence(num / den)
        else:
            from sage.matrix.constructor import matrix
            from sage.functions.other import floor, ceil
            from numpy import trim_zeros

            l = len(sequence)
            while l > 0 and sequence[l - 1] == 0:
                l -= 1
            sequence = sequence[:l]
            if l == 0:
                return 0
            if l < 6:
                raise ValueError("Sequence too short for guessing.")

            hl = ceil(ZZ(l) / 2)
            A = matrix([sequence[k : k + hl] for k in range(hl)])
            K = A.kernel()
            if K.dimension() == 0:
                return 0
            R = PolynomialRing(QQ, "x")
            den = R(trim_zeros(K.basis()[-1].list()[::-1]))
            if den == 1:
                return 0
            offset = next((i for i, x in enumerate(sequence) if x != 0), None)
            S = PowerSeriesRing(QQ, "x", default_prec=l - offset)
            num = S(R(sequence) * den).add_bigoh(floor(ZZ(l) / 2 + 1)).truncate()
            if num == 0 or sequence != S(num / den).list():
                return 0
            else:
                return CFiniteSequence(num / den)
Example #6
0
N = 128
m = 8
F2 = GF(2)

XOR = lambda s1,s2: bytes([x^y for x,y in zip(s1,s2)])
BIT2BYTE = lambda l: bytes(ZZ(l[::-1], base=2).digits(base=256))[::-1]
BYTE2BIT = lambda b: ZZ(list(b[::-1]), base=256).digits(base=2, padto=8*len(b))[::-1]

cipher = open('msg.enc', 'rb').read()
cipherstream = BYTE2BIT(cipher)
BITS_LENGTH = len(cipherstream)

c = [F2(cipherstream[m*i]) for i in range(2*N)]

Pol = berlekamp_massey(c)

per = 2**Pol.degree() - 1
m_inv = inverse_mod(m, per)
T = companion_matrix(Pol, format='right')
TT = T**m_inv

cc = Matrix(F2, c[:N])
bb = []
for _ in range(2*N):
    bb.append( cc[0, 0] )
    cc = cc*TT
fill = bb[:N]

gg = berlekamp_massey(bb)
key = gg.coefficients(sparse=False)[:-1]
Example #7
0
    def guess(sequence, algorithm='pari'):
        """
        Return the minimal CFiniteSequence that generates the sequence. Assume the first
        value has index 0.

        INPUT:

        - ``sequence`` -- list of integers
        
        - ``algorithm`` -- string
            - 'pari' - use Pari's implementation of LLL (fast)
            - 'bm' - use Sage's Berlekamp-Massey algorithm
            
        OUTPUT:
        
        - a CFiniteSequence, or 0 if none could be found
        
        EXAMPLES::

            sage: CFiniteSequence.guess([1,2,4,8,16,32])
            C-finite sequence, generated by 1/(-2*x + 1)
            sage: r = CFiniteSequence.guess([1,2,3,4,5])
            Traceback (most recent call last):
            ...
            ValueError: Sequence too short for guessing.
            sage: CFiniteSequence.guess([1,0,0,0,0,0])
            Finite sequence [1], offset = 0
            
        With Pari LLL, all values are taken into account, and if no o.g.f.
        can be found, `0` is returned::
        
            sage: CFiniteSequence.guess([1,0,0,0,0,1])
            0
            
        With Berlekamp-Massey, if an odd number of values is given, the last one is dropped.
        So with an odd number of values the result may not generate the last value::
        
            sage: r = CFiniteSequence.guess([1,2,4,8,9], algorithm='bm'); r
            C-finite sequence, generated by 1/(-2*x + 1)
            sage: r[0:5]
            [1, 2, 4, 8, 16]
        """
        S = PolynomialRing(QQ, 'x')
        if algorithm == 'bm':
            if len(sequence) < 2:
                raise ValueError('Sequence too short for guessing.')
            R = PowerSeriesRing(QQ, 'x')
            if len(sequence) % 2 == 1: sequence = sequence[:-1]
            l = len(sequence) - 1
            denominator = S(berlekamp_massey(sequence).list()[::-1])
            numerator = R(S(sequence) * denominator, prec=l).truncate()

            return CFiniteSequence(numerator / denominator)
        else:
            global _gp
            if len(sequence) < 6:
                raise ValueError('Sequence too short for guessing.')
            if _gp is None:
                _gp = Gp()
                _gp("ggf(v)=local(l,m,p,q,B);l=length(v);B=floor(l/2);\
                if(B<3,return(0));m=matrix(B,B,x,y,v[x-y+B+1]);\
                q=qflll(m,4)[1];if(length(q)==0,return(0));\
                p=sum(k=1,B,x^(k-1)*q[k,1]);\
                q=Pol(Pol(vector(l,n,v[l-n+1]))*p+O(x^(B+1)));\
                if(polcoeff(p,0)<0,q=-q;p=-p);q=q/p;p=Ser(q+O(x^(l+1)));\
                for(m=1,l,if(polcoeff(p,m-1)!=v[m],return(0)));q")
            _gp.set('gf', sequence)
            _gp("gf=ggf(gf)")
            num = S(sage_eval(_gp.eval("Vec(numerator(gf))"))[::-1])
            den = S(sage_eval(_gp.eval("Vec(denominator(gf))"))[::-1])
            if num == 0:
                return 0
            else:
                return CFiniteSequence(num / den)
        
        """