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
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
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)
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
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)
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)
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))
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
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)
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))
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
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
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")
def map_vector(v): return MAP_VECTOR[gen_leech2_subtype(v)] if v else 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")
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))