Esempio n. 1
0
    def gen_xi_short_to_leech(x1):
        """Convert short vector to Leech lattice encoding.

        Both, Leech lattice and short vector encoding of a short vector 
        in Q_x are decribed in the header of this module. The function 
        returns the Leech lattice encoding of element x1 given in short
        vector encoding. 

        The function returns 0 for an illegal input x1. 
        """   
        box, sign, code = x1 >> 16, (x1 >> 15) & 1, x1 & 0x7fff
        octad = 0xffff
        if box == 1:
            if code < 1536:  # this is 2 * 24 * 32 
                gcode = code >= 768
                if gcode:
                    code -= 768
                gcode <<= 11
                i, j = code >> 5, code & 31
                cocode = Mat24.vect_to_cocode((1 << i) ^ (1 << j))
                if cocode == 0 or cocode & 0x800:
                    return 0
            elif code < 2496: # this is 2 * 24 * 32 + 15 * 64 
                octad = code - 1536
            else:
                return 0
        elif box == 2:
            if code >= 23040:  # this is  360 * 64     
                return 0   
            octad = code + 960  # this is 15 * 64
        elif box == 3:
            if code >= 24576:  # this is  384 * 64     
                return 0   
            octad = code + 24000  # this is (15 + 360) * 64
        elif box < 6:
            code += (box - 4) << 15
            cocode = Mat24.vect_to_cocode(1 << (x1 & 31))
            if cocode  == 0:
                return 0
            gcode = (code >> 5) & 0x7ff
            w =  Mat24.gcode_weight(gcode) ^ Mat24.scalar_prod(gcode, cocode) 
            gcode ^= (w & 1) << 11
        else:
            return 0  
        if octad < 48756:  # this is  759 * 64 
            cc = octad & 0x3f
            w = Mat24.bw24(cc) 
            cc = (cc << 1) ^ (w & 1)
            w += w & 1
            gcode = Mat24.octad_to_gcode(octad >> 6)
            gcodev = Mat24.gcode_to_vect(gcode)
            cocode = Mat24.vect_to_cocode(Mat24.spread_b24(cc, gcodev))
            gcode ^=  ((w >> 1) & 1) << 11
        cocode ^= Mat24.ploop_theta(gcode)
        return (sign << 24) | (gcode << 12) | cocode
Esempio n. 2
0
def mat24_make_c_code():
    """Create .c and .h file with the functionality of class Mat24

    The input of this function is the file MAT24_C_FILE.ske that 
    contains a (much faster) C version of the functions in class
    mmgroup.dev.mat24.mat24_ref.Mat24.

    The functions in the .ske file make use of the tables that have 
    been generated for this module and also of some functions for
    generating C code automatically. An example where generating
    code automatically makes sense is the matrix multiplication with
    a constant bit matrix.
     
    The code generating process is described in class TableGenerator
    in module make_c_tables.  
    """
    print("Creating C source from file mat24_functions.ske\n")
    MAT24_C_FILE = "mat24_functions"
    SKE_DIR = os.path.join(DEV_DIR, "mat24")
    # The follwing two tables can't easily be computed earlier
    Mat24.tables["Mat24_doc_basis"] = Mat24.str_basis()
    generator = TableGenerator(Mat24.tables, Mat24.directives)
    f = os.path.join(SKE_DIR, MAT24_C_FILE)
    path_ = os.path.join(C_DIR, MAT24_C_FILE)
    #print("pwd", os.getcwd())
    #print(os.path.realpath(path_ + ".c"))
    generator.generate(f + ".ske", path_ + ".c", path_ + ".h")
    ## generator.export_tables(file_name = "mat24_export.py")

    generator.generate_pxd(os.path.join(PXD_DIR, MAT24_C_FILE + ".pxd"),
                           MAT24_C_FILE + ".h", pxd_declarations)
    print("C files for extension mat24 have been created")
Esempio n. 3
0
def w2_gamma(v):
    """Implement function gamma() in [Seysen20], section 3.3.

    Given a Golay code vector v  in 'gcode' representation, see
    module mat24.py, we return a pair w2, c. Here c is equal to
    the element gamma(v) of the Golay cocode, with gamma() as in 
    [Seysen20], section 3.3. ,c is returned in 'cocode' representation, 
    see module mat24.py. We also return the bit w2 = w2(c), with w2()
    as defined in [Seysen20], section 3.3.   
    """
    x = Mat24.gcode_to_vect(v)
    x1 = sum( (x >> i) & 0x111111 for i in range(1,4) )
    x1 = (x1 >> 1) & 0x111111
    w2 = bw24(x1)
    w2 = ((w2 * (w2 - 1)) >> 1) & 1
    c = Mat24.vect_to_cocode(x1)
    return w2, c
Esempio n. 4
0
    def gen_xi_leech_to_short(x1):   
        """Convert Leech lattice to short vector encoding.

        Both, Leech lattice and short vector encoding of a short vector 
        in Q_x are decribed in the header of this module. The function 
        returns the short vector encoding of element x1 given in Leech 
        lattice encoding. 

        The function returns 0 if the vector x1 is not short. 
        """   
        sign = (x1 >> 24) & 1
        x1 ^= Mat24.ploop_theta(x1 >> 12)
        gcodev = Mat24.gcode_to_vect(x1 >> 12) 
        cocodev = Mat24.cocode_syndrome(x1, 
            min(23, Mat24.lsbit24(gcodev))
        )
        w = Mat24.gcode_weight(x1 >> 12)
        if x1 & 0x800:
            if (Mat24.bw24(cocodev) > 1 or
                Mat24.scalar_prod(x1 >> 12, x1) !=  (w & 1)):
                return 0
            y = Mat24.lsbit24(cocodev)
            code = (x1 & 0x7ff000) >> 7 | y  
            box = 4 + (code >> 15)
            code &= 0x7fff
        else: 
            if w == 3:
                return 0
            elif w in [2,4]:
                if w == 4:
                    gcodev ^= 0xffffff
                    x1 ^= 0x800000
                w_bad = (Mat24.bw24(cocodev) ^ 2 ^ w) & 3
                if w_bad or (cocodev & gcodev) != cocodev:
                    return 0
                c =  Mat24.extract_b24(cocodev, gcodev)
                if (c & 0x80):
                     c ^=  0xff 
                y1 = Mat24.gcode_to_octad(x1 >> 12)
                code = (y1 << 6) | (c >> 1)
                if code >= 24000: # this is (15 + 360) * 64
                    code -= 24000
                    box = 3
                elif code >= 960: # this is 15 * 64
                    code -= 960
                    box = 2
                else:
                    code += 1536
                    box = 1
            else:
                y1 = Mat24.lsbit24(cocodev) 
                cocodev ^= 1 << y1  
                y2 = Mat24.lsbit24(cocodev) 
                if cocodev != (1 << y2) or y1 >= 24:
                    return 0
                code = 384 * (w & 2) + 32 * y2 + y1
                box = 1
        return  (box << 16) | (sign << 15) | code
def y_table(g, cocodes, sign, code_omega, cocode_x, verbose = 0):
    """Return table for function  ``gen_leech2_reduce_n`` 


    This table is used to map an entry :math:`x_d x_\delta`,
    where :math:`d` is a (signed) octad or dodecad, and 
    where :math:`\delta` is even, to a standard form. The
    table is to be used for a fixed Golay code element 
    :math:`d` up to sign and up to a factor :math:`\Omega`.

    Such a mapping is done via conjugation with an element
    of shape  :math:`y_e x_\epsilon`, with math:`e` a Goly
    code word math:`\epsilon` an even cocode word..

    Here :math:`d` is given by parameter ``g``. Thee we choose
    a Golay code word ``e`` with :math:`g \cap e = \delta`. 
    Using the returned table, ``e`` may be calculated as

    :math:`e = \sum_{i=0}^10 \delta_i \cdot t_i` ,

    where :math:`\delta_i` is the ``i``-th bit of
    :math:`\delta`, and :math:`t_i` is the entry ``table[i+1]`` 
    of the table.
    
    ``table[0]`` is equal to :math:`\theta(d)`. ``table[12]`` 
    is a sign bit ``s``. If the bit 23 of :math:`v \cdot y_e`
    differs from ``s`` then we have to replace :math:`e` by
    :math:`e + e'`, where :math:`e'` is given by ``table[13]``. 
    This operation adds  :math:`x_\Omega` to  :math:`x_d` in
    the cases relevant for function ``gen_leech2_reduce_n``.
    If :math:`v \cdot y_{e + e'}` has a sign bit set then
    we have to multiply that vector with  :math:`x_\epsilon`,
    where the cocode word :math:`epsilon` is given by 
    ``table[13]``. Entries ``table[11,12,13]`` are copied
    from parameters ``sign, code_omega, cocode_x``,
    respectively.

    Parameter ``cocode_x`` is an list of cocode words
    that will be meapped to zero by applying the table.

    On input, all Golay code and cocode word must be given
    as list of integers representing the bit positions set.

    In the returned table, all Golay code or cocode words
    are given as bit vector in **Golay code** or **cocode**
    representation, respectively.
    """
    gv = Mat24.vect_to_gcode(list_to_vect(g))
    b = []
    for i in range(11):
        b.append((Mat24.ploop_cap(gv, 1 << i) << 12) + (1 << i))
    for c in cocodes:
        b.append(Mat24.vect_to_cocode(list_to_vect(c)) << 12)
    if verbose:
        print("Function y_table, g =", hex(list_to_vect(g)))
        print("cocodes =", cocodes)
        print("cocode_x =", cocode_x)
        print("b =", [hex(x) for x in b])
    b, columns = pivot_binary_high(b)
    if verbose:
        print("reduced b =", [hex(x) for x in b])
        print("columns =", columns)
    table = [Mat24.ploop_theta(gv)]
    table1 = []
    for i in range(10, -1, -1):
        if columns[0] == i + 12:
            table1.append(b[0] & 0xfff)
            b, columns = b[1:], columns[1:]
        else:
            table1.append(0)
    table1.reverse()
    table += table1
    table.append(sign)
    table.append(Mat24.vect_to_gcode(list_to_vect(code_omega)))
    table.append(Mat24.vect_to_cocode(list_to_vect(cocode_x)))
    if verbose:
        print("table =", [hex(x) for x in table])
    return table
def vector(gcode, cocode):
    gc = Mat24.vect_to_gcode(sum(1 << x for x in gcode))
    coc = Mat24.vect_to_cocode(sum(1 << x for x in cocode))
    return (gc << 12) ^ coc ^ Mat24.ploop_theta(gc)