def test_find_type4(verbose = 0):
    print("Test function mm_reduce_find_type4")
    for a, v2, v_best  in find_type4_testcases():
        if verbose:
            print("v2 =", hex(v2), ", v_best =", v_best)
            if len(a) <= 10: print("a=", a)
        v0 =  mm_reduce_find_type4(a, len(a), v2)
        val_0 = eval_type4(v0, v2)
        val_a = [eval_type4(x, v2) for x in a]
        if verbose:
            if len(a) <= 10: 
                print("a=", a)
                print("subtypes =", [hex(gen_leech2_subtype(x)) for x in a])
                if v2 & 0xffffff:
                    print("subtypes_2 =", [
                        hex(gen_leech2_subtype(x ^ v2)) for x in a])
            print("best =", hex(v0), ", val_0=", hex(val_0))
            #print("val_a =", [hex(x) for x in val_a])
        assert val_0 <= min(val_a), (hex(val_0), hex(min(val_a)))
        if v_best is None:
            if val_0 >> 24 == 5:
                assert v0 == 0, (hex(v0), gen_leech2_subtype(v0))
            else:
                assert v0 in a, hex(v0)
        else:
            assert v_best == v0, (hex(v_best), hex(v0))
def ref_leech2_start_type4(v):
    """Reference implementation for function gen_leech2_start_type4

    This is equivalent to function ``leech2_start_type4```.
    """
    v &= 0xffffff
    t = gen_leech2_subtype(v)
    if (t & 0xf0) != 0x40:
        return min(-1, -(t >> 4))
    if v == OMEGA:
        return 0
    t2 = gen_leech2_subtype(v ^ BETA)
    return t2 if (t2 & 0xf0) == 0x20 else t
Beispiel #3
0
def xi_reduce_odd_type4(v, verbose=0):
    r"""Compute power of :math:`\xi` that reduces a vector ``v``

    Let ``v`` be a vector in the Leech lattice mod 2 in Leech
    lattice encoding. We assume that ``v`` is of subtype 0x43.

    We compute an exponent ``e`` such that :math:`\xi^e` maps 
    ``v`` to a vector of subtype 0x42 or 0x44.

    The function returns ``e`` if ``v`` is mapped to type 0x42
    and ``0x100 + e`` if ``v`` is mapped to type 0x44.  A negative
    return value indicates that no such exponent ``e`` exists.
    """
    assert v & 0x800  # Error if cocode part ov v is even
    coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
    # Obtain cocode as table of bit fields of 5 bits
    tab = mat24.syndrome_table(coc & 0x7ff)
    # Check if the syndrome bits are in 3 different MOG columns.
    # We first XOR bit field i with bit field (i-1)(mod 3)
    # and then zero the lowest two bits of each bit field.
    tab ^= ((tab >> 5) & 0x3ff) ^ ((tab & 0x1f) << 10)
    tab &= 0x739c
    # Now all three bit fields are nonzero iff the syndrome bits
    # are in three differnt columns. Next add 32 - 4 to each bit
    # field in order to produce a carry if the field is nonzero.
    tab += 0x739c
    # Next we isolate the three carry bits
    tab &= 0x8420
    # Return -1 if all carry bits are set, i.e all syndrome bits
    # are in different columns.
    if (tab == 0x8420):
        return -1
    # Let scalar be the scalar product of the Golay part of v
    # with the standard tetrad \omega
    scalar = (v >> 22) & 1
    # Exponent for element \xi of G_x0 is 2 - scalar
    exp = 2 - scalar
    if verbose:
        w = gen_leech2_op_atom(v, 0x60000000 + exp)
        print(
            "Reducing c = %s, subtype %s, t=%s, e=%d, to v = %s, subtype %s" %
            (hex(mat24.cocode_syndrome(coc, 0)), hex(gen_leech2_subtype(v)),
             hex(tab), exp, hex(
                 mat24.gcode_to_vect(w >> 12)), hex(gen_leech2_subtype(w))))
    # Return exponent for \xi in the lower 4 bits of the retrun value;
    # Return 0 in bit 8 if all syndrome bits of v are in the same
    # MOG column and 1 in bit 8 otherwise.
    return ((tab != 0) << 8) + exp
Beispiel #4
0
def test_reduce_n(ntests=100, verbose=0):
    """Test function ``gen_leech2_reduce_n`` """
    for n, v in enumerate(reduce_n_testdata(ntests)):
        ref_subtype = gen_leech2_subtype(v)
        if verbose:
            print(" \nTest %d, v = %s, subtype  = %s" %
                  (n + 1, hex(v), hex(ref_subtype)))
        subtype, op = ref_gen_leech2_reduce_n(v)
        ok = True
        err = "Unknown error"

        ok1 = ref_subtype == subtype
        if ok and not ok1:
            err = "Function gen_leech2_reduce_n returns wrong subtype"
        ok &= ok1

        v_mapped = gen_leech2_op_word(v, op, len(op))
        ok2 = v_mapped == map_vector(v)
        if ok and not ok2:
            err = "Wrong mapping in function gen_leech2_reduce_n"
        ok &= ok2

        ok3 = len(op) == 3
        tags = [x >> 28 for x in op]
        ok3 &= tags[:2] == [0xa, 0xc] and tags[2] in [9, 0xb]
        if ok and not ok3:
            err = "Error in computed operation on vector"
        ok &= ok3

        if (op[2] & 0xf0000000) == 0xB and v != 0x18000000:
            ok4 = op[2] & 0x800 == 0
        else:
            ok4 = True
        if ok and not ok4:
            err = "Computed operation on vector must be even"
        ok &= ok4

        op_c = np.zeros(3, dtype=np.uint32)
        subtype_c = gen_leech2_reduce_n(v, op_c)
        #op_c[1] &= ~2 # Produce an error for verifying the test
        ok_C_function = subtype_c == subtype
        ok_C_function &= (op_c == op).all()
        if ok and not ok_C_function:
            err = "Error in C function"
        ok &= ok_C_function

        if verbose or not ok:
            if not ok:
                print(" \nTest %d, v = %s, subtype  = %s" %
                      (n + 1, hex(v), hex(ref_subtype)))
            print("transformation", op)
            print("map expected:", hex(map_vector(v)), ", obtained",
                  hex(v_mapped))
            if not ok_C_function:
                print("Subtype from C function is %s, expected %s" %
                      (hex(subtype_c), hex(subtype)))
                print("Operation from C function:", op_c)
                print("Expected:                 ", op)
            if not ok:
                raise ValueError(err)
Beispiel #5
0
def ref_gen_leech2_reduce_n(v, verbose=0):
    vtype = gen_leech2_subtype(v)
    subtype = vtype & 0xf

    out = []

    if subtype & 1:
        coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
        syn = mat24.cocode_syndrome(coc)
        src = mat24.vect_to_list(syn, mat24.bw24(syn))
        assert len(src) in [1, 3]
        lst = [1, 2, 3] if subtype == 3 else [0]
        apply_perm(v, src, lst, len(src), out)
        v = gen_leech2_op_atom(v, out[0])
        out.append(0xC0000000 + ((v >> 12) & 0x7ff))
        v = gen_leech2_op_atom(v, out[1])
        out.append(0xB0000000 + ((v >> 13) & 0x800))
    elif subtype == 6:
        gv = (v >> 12) & 0xfff
        vect = mat24.gcode_to_vect(gv)
        src = mat24.vect_to_list(vect, mat24.bw24(vect))
        assert len(src) == 12
        dest = STD_DODECAD
        if (vtype == 0x36):
            coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
            w = mat24.bw24(mat24.cocode_as_subdodecad(coc, gv))
            if w & 2:
                dest = CPL_DODECAD
        pi = mat24.perm_from_dodecads(dest, src)
        out.append(0xA0000000 + mat24.perm_to_m24num(pi))
        op_y_x(v, TABLE_DODECAD, out)
    elif subtype in [2, 4]:
        if vtype == 0x34:
            find_octad_permutation_odd(v, out)
        else:
            find_octad_permutation(v, out)
        op_y_x(v, TABLE_OCTAD, out)
    elif subtype in [0, 8]:
        if ((v & 0x7ff) == 0):
            out.append(0xA0000000)
            out.append(0xC0000000)
            x = 0x800 if v & 0x1800000 == 0x1800000 else 0
            out.append(0x90000000 + x)
        else:
            syn = mat24.cocode_syndrome(v & 0x7ff, 0)
            src = mat24.vect_to_list(syn, mat24.bw24(syn))
            j = mat24.bw24(syn) & 2
            lst, y0 = ([2, 3], 0x200) if j else ([0, 1, 2, 3], 0x400)
            apply_perm(v, src, lst, len(lst), out)
            v = gen_leech2_op_atom(v, out[0])
            y = y0 if v & 0x800000 else 0
            out.append(0xC0000000 + y)
            v = gen_leech2_op_atom(v, out[1])
            x = y0 if v & 0x1000000 else 0
            out.append(0xB0000000 + x)
    else:
        raise ValueError("Bad subtype " + hex(vtype))
    assert len(out) == 3
    return vtype, np.array(out, dtype=np.uint32)
def ref_leech2_start_type24(v):
    r"""Reference implementation for function gen_leech2_start_type24

    The function returns the subtype of a vector v of type 2 in
    the Leech lattice modulo, provided that  v + \beta  is of
    type 4. It returns 0 in the special case  v = \beta + \Omega,
    and a negative value if v is not of type 2 or v + \beta
    is not of type 4.
    """
    v &= 0xffffff
    t = gen_leech2_subtype(v)
    if (t & 0xf0) != 0x20:
        return -1
    if (v & 0x7fffff) == 0x200:
        return 0 if v & 0x800000 else -1
    t2 = gen_leech2_subtype(v ^ BETA)
    return t if (t2 & 0xf0) == 0x40 else -1
Beispiel #7
0
def test_reduce_type_4_std(ntests=500, verbose=0):
    """Test function ``reduce_type4_std`` """
    for n, v in enumerate(type4_testdata(ntests)):
        if verbose:
            print(" \nTest %d, v = %s, subtype  =%s" %
                  (n + 1, hex(v), hex(gen_leech2_subtype(v))))
        op = reduce_type4_std(v, verbose)
        w = gen_leech2_op_word(v, op, len(op))
        assert w & 0xffffff == 0x800000, hex(w)
Beispiel #8
0
    def xsubtype(self):
        r"""Return subtype of the element of :math:`Q_{x0}`

        The function returns the integer ``16 * type + subtype``,
        where the pair ``(type, subtype)`` is as in property
        ``subtype``. See section :ref:`computation-leech2` in
        the **guide** for background.
        """
        return gen_leech2_subtype(self.value)
Beispiel #9
0
    def subtype(self):
        r"""Return pair ``(type, subtype)`` of the element of :math:`Q_{x0}`

        Here ``type`` is as in property ``type``, and subtype is
        a one-digit decimal integer describing the subtype of
        a vector in the Leech lattice modulo 2, as explained in
        the **guide** in section :ref:`computation-leech2`.
        """
        t = gen_leech2_subtype(self.value)
        return t >> 4, t & 15
def test_start_type24(ntests=1000, verbose=0):
    """Test function gen_leech2_start_type24()

    The function obtains test vectors from generator function
    type24_testdata(); the number of test vectors given by ``ntests``.

    Each test vector v is a type-2 vector in the Leech lattice mod 2.
    The test function checks that the C function 
    ``gen_leech2_start_type24(v)``  returns the same value as
    function ``ref_leech2_start_type4(v)``.          
    """
    for n, v in enumerate(type24_testdata(ntests)):
        if verbose:
            print("Test %d, v = %s, subtype = %s, subtpe(v2) = %s" %
                  (n, hex(v & 0xffffff), hex(gen_leech2_subtype(v)),
                   hex(gen_leech2_subtype(v ^ BETA))))
        #t_py = leech2_start_type24(v)
        t_ref = ref_leech2_start_type24(v)
        #assert t_py == t_ref, (hex(t_py), hex(t_ref))
        t_c = gen_leech2_start_type24(v)
        assert t_c == t_ref, (hex(t_c), hex(t_ref))
Beispiel #11
0
def test_std_subtypes():
    for subtype, v in [(0, 0)] + list(MAP_VECTOR.items()):
        subtype1 = gen_leech2_subtype(v)
        if subtype1 != subtype:
            print("Subtype obtained: %s, expected: %s" %
                  (hex(subtype1), hex(subtype)))
            print("gcode", gcode)
            print("cocode", cocode)
            err = "Error in transversal of N_x0"
            raise ValueError(err)
    for subtype, v in list(MAP_VECTOR.items()):
        v_c = gen_leech2_reduce_n_rep(subtype)
        assert v == v_c
Beispiel #12
0
def reduce_type4(v, verbose=0):
    r"""Map type-4 vector in Leech lattice to standard vector

    This is  a python implementation of the C function
    ``gen_leech2_reduce_type4`` in file ``gen_leech.c``.
   
    Let ``v \in \Lambda / 2 \Lambda`` of type 4 be given by 
    parameter ``v`` in Leech lattice encoding. 

    Let ``Omega`` be the type- vector in the Leech  lattice 
    corresponding to the standard coordinate frame in the Leech
    lattice. Let ``beta`` be the short vector in the Leech  
    lattice propotional  to  ``e_2 - e_3``, where ``e_i`` is  
    the ``i``-th basis vector  of ``\{0,1\}^{24}``.
   
    Then the function constructs a ``g \in G_{x0}`` 
    that maps ``v`` to ``Omega``. If ``v + beta`` is of type 2
    and orthogonal to ``beta`` in the real Leech lattice then the 
    returned element ``g`` also fixes ``beta``.
 
    The element ``g`` is returned as a word in the generators
    of ``G_{x0}`` of length ``n \leq 6``. Each atom of the 
    word ``g`` is encoded as  defined in the header 
    file ``mmgroup_generators.h``. 

    The function stores ``g`` as a word of generators in the
    array ``pg_out`` and returns the length  ``n``  of that
    word. It returns a negative number in case of failure, 
    e.g. if ``v`` is not of type 4.
    """
    vtype = gen_leech2_subtype(v)
    if (vtype >> 4) != 4:
        err = "Leech lattice vector must be of type 4"
        raise ValueError(err)
    vtype_beta = gen_leech2_subtype(v ^ BETA)
    if (vtype_beta >> 4) == 2:
        return reduce_type2_ortho(v ^ BETA, verbose)
    return reduce_type4_std(v, verbose)
Beispiel #13
0
def test_reduce_type_2(ntests=500, verbose=0):
    """Test function ``reduce_type2`` """
    for n, v in enumerate(type2_ortho_testdata(ntests)):
        if verbose:
            print(" \nTest %d, v = %s, subtype  =%s" %
                  (n + 1, hex(v), hex(gen_leech2_subtype(v))))
        op = reduce_type2(v, verbose)
        w = gen_leech2_op_word(v, op, len(op))
        assert w & 0xffffff == BETA, hex(w)
        a = np.zeros(6, dtype=np.uint32)
        l = gen_leech2_reduce_type2(v, a)
        if l < 0:
            err = "Error %s in function gen_leech2_reduce_type2"
            raise ValueError(err % hex(l & 0xffffffff))
        a = a[:l]
        assert list(a) == list(op), ((a), (op))
Beispiel #14
0
def test_type3(verbose=0):
    r"""Test conversion of type-2 vectors 

    The function converts random sshort vectors in the Leech
    lattice mod2 2 to vectors in the Leech lattice mod 3, and
    vice versa, and check that these conversions are consistent. 

    It also checks functions in module ``checks  
    """
    weights = defaultdict(int)
    for ntest, (v2, vtype) in enumerate(type2_testvectors()):
        if verbose:
            print("\nTEST %s" % (ntest + 1))
            print("v2 = ", hex(v2))
        assert gen_leech2_subtype(v2) == vtype
        assert gen_leech2_type2(v2) == vtype

        v3 = v2_to_v3(v2)
        assert v3_to_v2(v3) == v2
        v3n = gen_leech3_neg(v3)
        assert v3_to_v2(v3n) == v2
Beispiel #15
0
def check_leech2_subtype(x, t_expected):
    """Test computation of subtype of vector in Leech lattice mod 2

    Given a vector ``x`` in the Leech lattice mod 2 in **Leech 
    lattice encoding**, the function checkse if the subtype of ``x``
    is correctly computed as the value ``t_expected``.

    Therefore it computes the subtype with function ``gen_leech2_subtype``
    in file ``gen_leech.c`` and checks it against ``subtype``. This 
    function also checks function ``gen_leech2_type2``.   
    """
    t = gen_leech2_subtype(x)
    ok = t == t_expected
    if not ok:
        print("Error: expected Leech type: %s, obtained: %s" %
              (hex(t_expected), hex(t)))
        display_leech_vector(x)
        err = "Error in computing Leech type"
        raise ValueError(err)
    expected_type2 = t_expected if (t_expected >> 4) == 2 else 0
    found_type2 = gen_leech2_type2(x)
    ok = expected_type2 == found_type2
    if not ok:
        print("Error:  x = %s, Leech type: %s" % (hex(x), hex(t_expected)),
              expected_type2, hex(found_type2))
        err = "Function gen_leech2_subtype2 failed"
        raise ValueError(err)
    alt_found_type2 = alternative_type2(x)
    is_type2 = (t_expected >> 4) == 2
    ok = is_type2 == alt_found_type2
    if not ok:
        print("Error:  x = %s, Leech type: %s" % (hex(x), hex(t_expected)),
              is_type2, alt_found_type2)
        err = "Function xsp2co1_leech2_count_type2 failed"
        #raise ValueError(err)
    if not is_type2:
        assert not found_type2
    assert gen_leech2_type(x) == t >> 4
Beispiel #16
0
def reduce_type2(v, verbose=1):
    r"""Map (orthgonal) short vector in Leech lattice to standard vector

    This is a python implementation of the C function
    ``gen_leech2_reduce_type2`` in file ``gen_leech.c``.
   
    Let ``v \in \Lambda / 2 \Lambda`` of type 2 be given by 
    parameter ``v`` in Leech lattice encoding. 

    Let ``beta`` be the short vector in the Leech  lattice propotional
    to  ``e_2 - e_3``, where ``e_i`` is  the ``i``-th basis vector
    of ``\{0,1\}^{24}``.
   
    Then the function constructs a ``g \in G_{x0}`` 
    that maps ``v`` to ``beta``.
 
    The element ``g`` is returned as a word in the generators
    of ``G_{x0}`` of length ``n \leq 6``. Each atom of the 
    word ``g`` is encoded as  defined in the header 
    file ``mmgroup_generators.h``. 

    The function stores ``g`` as a word of generators in the
    array ``pg_out`` and returns the length  ``n``  of that
    word. It returns a negative number in case of failure, 
    e.g. if ``v`` is not of type 2.
    """
    vtype = gen_leech2_subtype(v)
    if (vtype >> 4) != 2:
        raise ValueError("Vector is not short")
    result = []
    for _i in range(4):
        if verbose:
            coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
            vt = gen_leech2_subtype(v)
            coc_anchor = 0
            if vt in [0x22]:
                w = mat24.gcode_weight(v >> 12)
                vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12)
                coc_anchor = mat24.lsbit24(vect)
            coc_syn = Cocode(coc).syndrome_list(coc_anchor)
            gcode = mat24.gcode_to_vect(v >> 12)
            print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" %
                  (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn))
        assert vtype == gen_leech2_subtype(v)
        if vtype == 0x21:
            exp = xi_reduce_odd_type2(v)
            vtype = 0x22
        elif vtype == 0x22:
            exp = xi_reduce_octad(v)
            if exp < 0:
                w = mat24.gcode_weight(v >> 12)
                vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12)
                src = mat24.vect_to_list(vect, 4)
                dest = [0, 1, 2, 3]
                v = apply_perm(v, src, dest, 4, result, verbose)
                exp = xi_reduce_octad(v)
                assert exp >= 0
            vtype = 0x20
        elif vtype == 0x20:
            exp = 0
            # map v to stadard cocode word [2,3]
            if v & 0x7fffff != 0x200:
                syn = (mat24.cocode_syndrome(v, 0))
                src = mat24.vect_to_list(syn, 2)
                v = apply_perm(v, src, [2, 3], 2, result, verbose)
            # correct v2 if v2 is the cocode word [2,3] + Omega
            if v & 0x800000:
                atom = 0xC0000200
                # operation y_d such that d has odd scalar
                # product with cocode word [2,3]
                v = gen_leech2_op_atom(v, atom)
                result.append(atom)
            assert v & 0xffffff == 0x200
            return np.array(result, dtype=np.uint32)
        else:
            raise ValueError("WTF")
        if exp:
            exp = 0xE0000003 - exp
            v = gen_leech2_op_atom(v, exp)
            result.append(exp)
    raise ValueError("WTF1")
Beispiel #17
0
def map_vector(v):
    return MAP_VECTOR[gen_leech2_subtype(v)] if v else 0
Beispiel #18
0
def reduce_type4_std(v, verbose=0):
    r"""Map type-4 vector in Leech lattice to standard vector

    This is (almost) a python implementation of the C function
    ``gen_leech2_reduce_type4`` in file ``gen_leech.c``.
   
    Let ``v \in \Lambda / 2 \Lambda`` of type 4 be given by 
    parameter ``v`` in Leech lattice encoding. 

    Let ``Omega`` be the type- vector in the Leech  lattice 
    corresponding to the standard coordinate frame in the Leech
    lattice.
   
    Then the function constructs a ``g \in G_{x0}`` 
    that maps ``v`` to ``Omega``.
 
    The element ``g`` is returned as a word in the generators
    of ``G_{x0}`` of length ``n \leq 6``. Each atom of the 
    word ``g`` is encoded as  defined in the header 
    file ``mmgroup_generators.h``. 

    The function stores ``g`` as a word of generators in the
    array ``pg_out`` and returns the length  ``n``  of that
    word. It returns a negative number in case of failure, 
    e.g. if ``v`` is not of type 4.

    We remark that the C function ``gen_leech2_reduce_type4`` 
    treats certain type-4  vectors ``v`` in a special way
    as indicated in function ``reduce_type4``.
    """
    if verbose:
        print("Transforming  type-4 vector %s to Omega" % hex(v & 0x1ffffff))
    vtype = gen_leech2_subtype(v)
    result = []
    for _i in range(5):
        coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
        if verbose:
            vt = gen_leech2_subtype(v)
            coc_anchor = 0
            if vt in [0x42, 0x44]:
                w = mat24.gcode_weight(v >> 12)
                vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12)
                coc_anchor = mat24.lsbit24(vect)
            coc_syn = Cocode(coc).syndrome_list(coc_anchor)
            gcode = mat24.gcode_to_vect(v >> 12)
            print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" %
                  (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn))
        assert vtype == gen_leech2_subtype(v)
        if vtype == 0x48:
            if verbose:
                res = list(map(hex, result))
                print("Transformation is\n", res)
            return np.array(result, dtype=np.uint32)
        elif vtype == 0x40:
            if v & 0x7ffbff:
                syn = mat24.cocode_syndrome(coc, 0)
                src = mat24.vect_to_list(syn, 4)
                v = apply_perm(v, src, LSTD, 4, result, verbose)
                #print("after type 40", hex(v),  Cocode(v).syndrome(0))
            exp = 2 - ((v >> 23) & 1)
            vtype = 0x48
        elif vtype in [0x42, 0x44]:
            exp = xi_reduce_octad(v)
            if exp < 0:
                v = find_octad_permutation(v, result, verbose)
                exp = xi_reduce_octad(v)
                assert exp >= 0
            vtype = 0x40
        elif vtype == 0x46:
            exp = xi_reduce_dodecad(v, verbose)
            if exp < 0:
                vect = mat24.gcode_to_vect(v >> 12)
                src = mat24.vect_to_list(vect, 4)
                v = apply_perm(v, src, LSTD, len(src), result, verbose)
                exp = xi_reduce_dodecad(v, verbose)
                assert exp >= 0
            vtype = 0x44
        elif vtype == 0x43:
            exp = xi_reduce_odd_type4(v, verbose)
            if exp < 0:
                vect = mat24.gcode_to_vect(v >> 12)
                syn = mat24.cocode_syndrome(coc, 24)
                src = mat24.vect_to_list(syn, 3)
                #print("coc list", src)
                v = apply_perm(v, src, LSTD[1:], len(src), result, verbose)
                exp = xi_reduce_odd_type4(v, verbose)
                assert exp > 0
            vtype = 0x42 + ((exp & 0x100) >> 7)
            exp &= 3
        else:
            raise ValueError("WTF")
        if exp:
            exp = 0xE0000003 - exp
            v_old = v
            v = gen_leech2_op_atom(v, exp)
            assert v & 0xfe000000 == 0, (hex(v_old), hex(exp), hex(v))
            result.append(exp)
    raise ValueError("WTF1")
Beispiel #19
0
def reduce_type2_ortho(v, verbose=0):
    r"""Map (orthgonal) short vector in Leech lattice to standard vector

    This is a python implementation of the C function
    ``gen_leech2_reduce_type2_ortho`` in file ``gen_leech.c``.
   
    Let ``v \in \Lambda / 2 \Lambda`` of type 2 be given by 
    parameter ``v`` in Leech lattice encoding. 

    In the real Leech lattice, (the origin of) the vector ``v`` must
    be orthogonal to the standard short vector ``beta``. Here ``beta``
    is the short vector in the Leech  lattice  propotional
    to  ``e_2 - e_3``, where ``e_i`` is  the ``i``-th basis vector
    of ``\{0,1\}^{24}``.
   
    Let ``beta'`` be the short vector in the Leech lattice propotional
    to  ``e_2 + e_3``.  Then the function constructs a ``g \in G_{x0}`` 
    that maps ``v`` to ``beta'`` and fixes ``beta``.
 
    The element ``g`` is returned as a word in the generators
    of ``G_{x0}`` of length ``n \leq 6``. Each atom of the 
    word ``g`` is encoded as  defined in the header 
    file ``mmgroup_generators.h``. 

    The function stores ``g`` as a word of generators in the
    array ``pg_out`` and returns the length  ``n``  of that
    word. It returns a negative number in case of failure, 
    e.g. if ``v`` is not of type 2,  or not orthogonal 
    to ``beta'`` in the real Leech lattice.
    """
    vtype = gen_leech2_subtype(v)
    if (vtype >> 4) != 2:
        raise ValueError("Vector is not short")
    if gen_leech2_type(v ^ 0x200) != 4:
        raise ValueError("Vector not orthogonal to standard vector")
    result = []
    for _i in range(4):
        if verbose:
            coc = (v ^ mat24.ploop_theta(v >> 12)) & 0xfff
            vt = gen_leech2_subtype(v)
            coc_anchor = 0
            if vt in [0x22]:
                w = mat24.gcode_weight(v >> 12)
                vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12)
                coc_anchor = mat24.lsbit24(vect)
            coc_syn = Cocode(coc).syndrome_list(coc_anchor)
            gcode = mat24.gcode_to_vect(v >> 12)
            print("Round %d, v = %s, subtype %s, gcode %s, cocode %s" %
                  (_i, hex(v & 0xffffff), hex(vt), hex(gcode), coc_syn))
        assert vtype == gen_leech2_subtype(v)
        if vtype == 0x21:
            exp = xi_reduce_odd_type2(v)
            vtype = 0x22
        elif vtype == 0x22:
            exp = xi_reduce_octad(v)
            if exp < 0:
                w = mat24.gcode_weight(v >> 12)
                vect = mat24.gcode_to_vect((v ^ ((w & 4) << 21)) >> 12)
                if vect & 0x0c:
                    vect &= ~0x0c
                    src = mat24.vect_to_list(vect, 2) + [2, 3]
                    dest = [0, 1, 2, 3]
                else:
                    src = [2, 3] + mat24.vect_to_list(vect, 3)
                    v5 = (1 << src[2]) | (1 << src[3]) | (1 << src[4])
                    v5 |= 0x0c
                    special = mat24.syndrome(v5, 24)
                    src.append(mat24.lsbit24(special & vect))
                    dest = [2, 3, 4, 5, 6, 7]
                v = apply_perm(v, src, dest, len(src), result, verbose)
                exp = xi_reduce_octad(v)
                assert exp >= 0
            vtype = 0x20
        elif vtype == 0x20:
            if ((v & 0xffffff) == 0x800200):
                return np.array(result, dtype=np.uint32)
            syn = (mat24.cocode_syndrome(v, 0)) & ~0xc
            if syn and syn != 3:
                src = mat24.vect_to_list(syn, 2) + [2, 3]
                v = apply_perm(v, src, [0, 1, 2, 3], 4, result, verbose)
            exp = 2 - ((v >> 23) & 1)
        else:
            raise ValueError("WTF")
        if exp:
            exp = 0xE0000003 - exp
            v = gen_leech2_op_atom(v, exp)
            result.append(exp)
    raise ValueError("WTF1")
def eval_type4(v, v2 = 0):
    value = VALUE_T4[gen_leech2_subtype(v)]
    if v2 & 0xffffff and gen_leech2_type(v ^ v2) != 2:
        value = 5
    return min(0x5000000, (v & 0xffffff) + (value << 24))