def display_norm_A(axis):
    """Display additional information of a 2A axis

    
    """
    #sample_axes = import_sample_axes()

    norm_A = axis.norm15
    s = "norm(A) = %d (mod 15)" % (norm_A)
    common = [
        a.g_class for a in get_axes().values()
        if a.norm15 == norm_A and a.g_class != axis.g_class
    ]
    if len(common) == 0:
        return s + "\n"
    s += ", same norm for class " + " and ".join(map(str, common))
    d = 2 if norm_A == 4 else 0
    V15 = MMV(15)
    v = axis.v15
    r = mm_op15_eval_A_rank_mod3(v.data, d)
    rank = r >> 48
    v3 = r & 0xffffffffffff
    s_A = "(A - %d * 1)" % d if d else "A"
    s += "\nMatrix U = %s (mod 3) has rank %d" % (s_A, rank)
    if (rank != 23):
        return s + "\n"
    v2 = gen_leech3to2_short(v3)
    if v2:
        f = "Kernel of U is spanned by a short vector v with A(v) ="
        a2 = mm_op15_eval_A(v.data, v2)
        s += "\n%s %d (mod 15)" % (f, a2)
    if gen_leech3to2_type4(v3):
        f = "Kernel of U is spanned by a vector of type 4"
        s += "\n" + f
    return s + "\n"
def v3_to_v2(v3):
    """Map type-4 vector from Leech lattice mod 3 to Leech lattice mod 2

    The operation of this function is equivalent to function
    ``py_gen_leech3to2_type4``. But this function is a wrapper for
    the C function ``gen_leech3to2_type4`` in file ``gen_leech3.c``. 
    """
    result = gen_leech3to2_type4(v3)
    assert result != 0, (str_v3(v3), weight_v3(v3), hex(result))
    return result
Exemple #3
0
def find_in_G_x0(w):
    global err_in_g_x0_py
    g1i = np.zeros(11, dtype = np.uint32)

    if mm_op15_norm_A(w) != ORDER_TAGS[OFS_NORM_A]:
        err_in_g_x0_py = 1
        return None        
    w3 = mm_op15_eval_A_rank_mod3(w, ORDER_TAGS[OFS_DIAG_VA])
    w3 &= 0xffffffffffff
    if w3 == 0: 
        err_in_g_x0_py = 2
        return None
    w_type4 = gen_leech3to2_type4(w3)
    if w_type4 == 0: 
        err_in_g_x0_py = 3
        return None
    wA = np.array(w[:2*24], copy = True)
    len_g1 = gen_leech2_reduce_type4(w_type4, g1i)
    assert 0 <= len_g1 <= 6 
    res = mm_op15_word_tag_A(wA, g1i, len_g1, 1)
    assert res == 0
    perm_num = mm_op15_watermark_A_perm_num(
        ORDER_TAGS[OFS_WATERMARK_PERM:], wA)
    if perm_num < 0: 
        err_in_g_x0_py = 4
        return None
    if perm_num > 0:
        g1i[len_g1] = 0xA0000000 + perm_num 
        res = mm_op15_word_tag_A(wA, g1i[len_g1:], 1, 1)
        assert res  == 0
        len_g1 += 1
    v_y = mm_aux_mmv_extract_sparse_signs(15, wA, 
        ORDER_TAGS[OFS_TAGS_Y:], 11)
    if v_y < 0:
        err_in_g_x0_py = 5
        return None
    y = leech2matrix_solve_eqn(ORDER_TAGS[OFS_SOLVE_Y:], 11, v_y)
    if y > 0:
        g1i[len_g1] = 0xC0000000 + y
        res = mm_op15_word_tag_A(wA, g1i[len_g1:], 1, 1)
        assert res  == 0
        len_g1 += 1
    if (wA != ORDER_VECTOR[:2*24]).all():
        err_in_g_x0_py = 6
        return None
    #print("g1i", g1i[:len_g1])
    return g1i[:len_g1]
def make_v71_sample(g71):
    r"""Compute a vector stabilized by a group element of order 71
    
    Let ``g71`` be an element of the monster group of order 71. The
    function generates  a random vector ``v71`` in the representatoon
    of the monster modulo 3 and computes the vector
    ``w = sum(v71 * g71**i for i in range(71))``. ``w`` is
    stabilized by ``g71``. 
    
    The function returns triple containing ``v71`` if ``w`` is 
    non-trivial and ``w`` satisfies an additional property
    described below. Ohterwise the function returns ``None``. The 
    function succeeds with probability about 1/700; so it must be 
    repeated several times.
    
    The part of the vector ``w`` labelled with the tag ``A`` 
    corresponds to a symmetric bilinear form over the Leech lattice
    modulo 3. The function succeeds if that bilinear form correponding
    to ``w`` has a one-dimesional eigenspace with the eigenvalue 
    ``diag`` containing a type-4 eigenvector in the Leech lattice. 
    
    In case of success we return the triple ``(v71, gA, diag)``. Here 
    ``gA`` is an element  of the subgroup :math:`G_{x0}` of the 
    monster group such that the bilinear form on the Leech lattice 
    corresponding  to `w * gA`` has a type-4 eigenvector in the 
    standard frame math:`\Omega`. 

    The values ``v71`` and ``gA`` are returned as strings. ``diag``
    is returned as an integer.        
    """
    r1 = [("s", x, "r") for x in "XTXTX"]
    g71 = MM0(g71)
    v71 = MMV3(r1)
    w71 = stabilizer_vector(v71, g71, 71)
    if not w71:
        return None
    for diag in range(3):
        v3 = mm_op3_eval_A_rank_mod3(w71.data, diag) & 0xffffffffffff
        if v3:
            v_type4 = gen_leech3to2_type4(v3)
            if v_type4:
                return str(v71), gA_from_type4(v_type4), diag
    return None
def make_order_vector(s_g71, s_v71, s_gA, diag, s_g94, s_v94):
    v71 = vector_from_data(10, s_v71)
    g71 = mm_element_from_data(s_g71)
    w71 = stabilizer_vector(v71, g71, 71)
    assert w71 is not None
    w71 *= mm_element_from_data(s_gA)
    v94 = vector_from_data(6, s_v94)
    g94 = mm_element_from_data(s_g94)
    w94 = stabilizer_vector(v94 - v94 * g94, g94**2, 47)
    assert w94 is not None
    if not isinstance(diag, int): diag = diag[0]
    w = w71 + w94 + identity_vector(5 * diag % 15)
    diag = 0
    v3 = mm_op15_eval_A_rank_mod3(w.data, diag) & 0xffffffffffff
    assert v3 != 0
    v_type4 = gen_leech3to2_type4(v3)
    assert v_type4 == 0x800000
    w.reduce()
    return w
def rand_v3_dict(n):
    """Create n random vectors and group the according to their weight

    We create n random vectors in GF(3)^{24}. We return a dictionary
    ``d`` with the following entries:

    d[0] counts the vectors not of type 4 in the Leech lattice mod 3.
    d[w] counts the vectors v of type 4 such that  DICT_P[weight(v)]
    is equal to w.

    Then the value d[i] should be about P[i] / n.    
    """
    d = defaultdict(int)
    for i in range(n):
        v3 = rand_v3()
        v2 = gen_leech3to2_type4(v3)
        if (v2 == 0):
            d[0] += 1
        else:
            w = mat24_bw24((v3 | (v3 >> 24)) & 0xffffff)
            d[DICT_P[w]] += 1
    return d
Exemple #7
0
def display_norm_A(i):
    """Display additional information of a 2A axis

    
    """
    sample_axes = import_sample_axes()

    if isinstance(i, str): i = axis_index(i)
    norm_A = norm_A_mod15(i)
    s = "norm(A) = %d (mod 15)" % (norm_A)
    common = [
        s for j, s in enumerate(sample_axes.g_classes)
        if norm_A_mod15(j) == norm_A and j != i
    ]
    if len(common) == 0:
        return s + "\n"
    s += ", same norm for class " + " and ".join(map(str, common))
    d = 2 if norm_A == 4 else 0
    V15 = MMV(15)
    v = V15(sample_axes.v_start) * MM0(sample_axes.g_strings[i])
    r = mm_op15_eval_A_rank_mod3(v.data, d)
    rank = r >> 48
    v3 = r & 0xffffffffffff
    s_A = "(A - %d * 1)" % d if d else "A"
    s += "\nMatrix U = %s (mod 3) has rank %d" % (s_A, rank)
    if (rank != 23):
        return s + "\n"
    v2 = gen_leech3to2_short(v3)
    if v2:
        f = "Kernel of U is spanned by a short vector v with A(v) ="
        a2 = mm_op15_eval_A(v.data, v2)
        s += "\n%s %d (mod 15)" % (f, a2)
    if gen_leech3to2_type4(v3):
        f = "Kernel of U is spanned by a vector of type 4"
        s += "\n" + f
    return s + "\n"