Exemplo n.º 1
0
    def strategy_block_cost(self, L, e):
        """
        Next function computes the expected cost of our approach by assuming we have full torsion points
        """
        elligator_cost = numpy.array([7.0, 3.0, 10.0])  # Elligator cost
        mul_fp_by_cofactor = (numpy.array([4.0, 2.0, 4.0]) *
                              int(ceil(1.64 * bitlength(self.curve.cofactor)))
                              )  # Cost of computing x([self.curve.cofactor]P)

        n = len(L)
        e_prime = [geometric_serie(e[k], L[k]) for k in range(n)]

        tmp_r, tmp_Ls, tmp_Cs = rounds(e_prime, n)

        C_e = numpy.array([0.0, 0.0, 0.0])
        S_out = []
        L_out = []
        R_out = []
        for j in range(len(tmp_r)):

            R_out.append([L[k] for k in tmp_Cs[j]])
            L_out.append([L[k] for k in tmp_Ls[j]])

            bo_C = 1.0 * sum(
                [self.c_xmul[self.formula.L.index(L[k])] for k in tmp_Cs[j]])
            S_tmp, go_C = self.dynamic_programming_algorithm(
                [L[k] for k in tmp_Ls[j]], len(tmp_Ls[j]))

            S_out.append(S_tmp)
            C_e = (C_e +
                   (go_C + bo_C + elligator_cost + 1.0 * mul_fp_by_cofactor) *
                   tmp_r[j])

        return C_e, L_out, R_out, S_out, tmp_r
Exemplo n.º 2
0
def csidh_precompute_strategy(ctx):
    """ Precomputation of optimal strategies """
    algo = ctx.meta['sibc.kwargs']['algo']
    setting = ctx.meta['sibc.kwargs']
    coeff = algo.curve.coeff
    p = algo.params.p
    L = algo.params.L
    m = algo.params.m
    n = algo.params.n
    SQR, ADD = algo.curve.SQR, algo.curve.ADD
    init_runtime = algo.field.init_runtime
    validate = algo.curve.issupersingular
    measure = algo.curve.measure
    GAE_at_0 = algo.gae.GAE_at_0
    GAE_at_A = algo.gae.GAE_at_A
    strategy_block_cost = algo.gae.strategy_block_cost
    random_exponents = algo.gae.random_exponents
    print_exponents = algo.gae.print_exponents

    assert setting.uninitialized, 'option -u (--uninitialized) is required!'

    if algo.formula.name != 'tvelu':
        set_parameters_velu = algo.formula.set_parameters_velu

    temporal_m = list(set(m))
    if len(temporal_m) > 1:
        # Maximum number of degree-(l_i) isogeny constructions is m_i (different for each l_i)
        bounds = '-diffbounds'
    else:
        # Maximum number of degree-(l_i) isogeny constructions is m (the same for each l_i)
        bounds = '-samebounds'

    tuned = {True: '-tuned', False: ''}[setting.tuned]
    multievaluation = {
        True: 'scaled',
        False: 'unscaled'
    }[setting.multievaluation]
    # List of Small Odd Primes, L := [l_0, ..., l_{n-1}]
    m_prime = [geometric_serie(m[k], L[k]) for k in range(n)]
    r_out, L_out, R_out = rounds(m_prime[::-1], n)
    for j in range(0, len(r_out), 1):

        R_out[j] = list([L[::-1][k] for k in R_out[j]])
        L_out[j] = list([L[::-1][k] for k in L_out[j]])

    file_path = ("data/strategies/" + algo.curve.model + '/csidh/' + 'csidh' +
                 '-' + setting.prime + '-' + setting.style + '-e' +
                 setting.exponent + bounds + '-' + setting.formula + '-' +
                 multievaluation + tuned)
    file_path = resource_filename('sibc', file_path)
    print("// Strategies to be computed")
    C_out, L_out, R_out, S_out, r_out = strategy_block_cost(L[::-1], m[::-1])
    f = open(file_path, 'w')
    for i in range(0, len(r_out)):

        f.writelines(' '.join([str(tmp) for tmp in S_out[i]]) + '\n')

    f.close()

    return attrdict(name='csidh-precompute-strategy', **locals())
Exemplo n.º 3
0
def csidh_header(ctx):
    """ Optimal strategies as C-code headers files """
    algo = ctx.meta['sibc.kwargs']['algo']
    setting = ctx.meta['sibc.kwargs']
    L = algo.params.L
    n = algo.params.n
    m = algo.params.m

    strategy_block_cost = algo.gae.strategy_block_cost
    basis = numpy.eye(n, dtype=int)
    measure = algo.curve.measure

    # ==========================================================================

    if algo.formula.name != 'tvelu':
        set_parameters_velu = algo.formula.set_parameters_velu

    temporal_m = list(set(m))
    if len(temporal_m) > 1:
        # Maximum number of degree-(l_i) isogeny constructions is m_i (different for each l_i)
        bounds = '-diffbounds'
    else:
        # Maximum number of degree-(l_i) isogeny constructions is m (the same for each l_i)
        bounds = '-samebounds'

    # List of Small Odd Primes, L := [l_0, ..., l_{n-1}]
    m_prime = [geometric_serie(m[k], L[k]) for k in range(n)]
    r_out, L_out, R_out = rounds(m_prime[::-1], n)
    for j in range(0, len(r_out), 1):

        R_out[j] = list([L[::-1][k] for k in R_out[j]])
        L_out[j] = list([L[::-1][k] for k in L_out[j]])

    file_path = ("data/strategies/" + algo.curve.model + '/' + 'csidh/csidh' +
                 '-' + setting.prime + '-' + setting.style + '-e' +
                 setting.exponent + bounds + '-' + setting.formula + '-' +
                 algo.formula.multievaluation_name + algo.formula.tuned_name)
    file_path = resource_filename('sibc', file_path)
    f = open(file_path)
    S_out = []
    for i in range(0, len(r_out), 1):

        tmp = f.readline()
        tmp = [int(b) for b in tmp.split()]
        S_out.append(tmp)

    f.close()

    if (len(set(m)) == 1) or ((len(set(m)) == 2) and (0 in set(m))):
        L_out = list([L_out[0]])
        R_out = list([R_out[0]])
        S_out = list([S_out[0]])
        r_out = list([r_out[0]])
    # ---
    k = 3  # Number of rows (format of the list)
    # ---

    print("#ifndef _STRATEGIES_H_")
    print("#define _STRATEGIES_H_\n")
    print("#include <inttypes.h>\n\n")
    print(
        "// This script assumes the C-code implementation has the list of Small Odd Primes (SOPs) stored such that l_0 < l_1 < ... < l_{n-1}"
    )
    print("// Recall, the strategies process from small SOPs to large SOPs.\n")

    for i in range(len(r_out)):
        print(
            "// -----------------------------------------------------------------------------------------------------------------------------------"
        )
        print("// Strategy number %d\n" % (i))
        L_string = "static uint32_t L%d[] " % (i)
        R_string = "static uint32_t W%d[] " % (i)
        S_string = "static uint32_t S%d[] " % (i)

        printl(
            L_string,
            [L.index(l_i) for l_i in L_out[i]],
            len(L_out[i]) // k + 1,
        )
        if R_out[i] != []:
            printl(
                R_string,
                [L.index(r_i) for r_i in R_out[i]],
                len(R_out[i]) // k + 1,
            )
        else:
            print("static uint32_t W%d[1];" % i)
        if S_out[i] != []:
            printl(S_string, S_out[i], len(S_out[i]) // k + 1)
        else:
            print("static uint32_t S%d[1];" % i)

    print("\n")
    print(
        "// -----------------------------------------------------------------------------------------------------------------------------------"
    )
    print(
        "// -----------------------------------------------------------------------------------------------------------------------------------"
    )
    print("#define NUMBER_OF_DIFFERENT_STRATEGIES  %d" % len(L_out))
    print("")
    L_string = (
        "static uint32_t *L_STRATEGY[NUMBER_OF_DIFFERENT_STRATEGIES] = {\n\t")
    R_string = (
        "static uint32_t *W_STRATEGY[NUMBER_OF_DIFFERENT_STRATEGIES] = {\n\t")
    S_string = "static uint32_t *S[NUMBER_OF_DIFFERENT_STRATEGIES] = {\n\t"

    tmp_sizes = "static uint32_t NUMBER_OF_PRIMES[] = {\n\t"
    tmp_round = "static uint8_t ROUNDS[] = {\n\t"

    for i in range(len(L_out) - 1):

        L_string = L_string + "L%d, " % (i)
        R_string = R_string + "W%d, " % (i)
        S_string = S_string + "S%d, " % (i)

        tmp_sizes = tmp_sizes + "%3d," % (len(L_out[i]))
        tmp_round = tmp_round + "%3d," % (r_out[i])

    L_string = L_string + "L%d\n\t};" % (len(L_out) - 1)
    R_string = R_string + "W%d\n\t};" % (len(L_out) - 1)
    S_string = S_string + "S%d\n\t};" % (len(L_out) - 1)

    tmp_sizes = tmp_sizes + "%3d\n\t};" % (len(L_out[len(L_out) - 1]))
    tmp_round = tmp_round + "%3d\n\t};" % (r_out[len(L_out) - 1])

    print(
        "// L_STRATEGY[i] determines the small odd primes l_i per each strategy"
    )
    print(L_string)
    print("\n// W_STRATEGY[i] determines L - L_STRATEGY[i]")
    print(R_string)
    print(
        "\n// S_STRATEGY[i] determines the optimal strategy for L_STRATEGY[i]")
    print(S_string)

    print("\n// Number of primes for each strategy")
    print(tmp_sizes)
    print("")
    print("// Number of rounds per each different strategy")
    print(tmp_round)

    print("")
    print("// Maximum number of degree-(l_i) isogeny constructions")
    printl("static uint8_t M[]", m, n // k + 1)

    STYLE_NAME = {
        'wd2': 'OAYT-style',
        'wd1': 'MCR-style',
        'df': 'dummy-free-style',
    }[setting.style]
    print(
        "\n#endif /* required framework for the strategies to be used in CSIDH-%s using %s */"
        % (setting.prime[1:], STYLE_NAME))
    # Need empty line at EOF for -Wnewline-eof
    print("")
    return attrdict(name='header', **locals())
Exemplo n.º 4
0
def plot_strategy(ctx):
    """
    draw strategy graphs as a subgraph Discrete Right Triangle (DRT)
    """
    algo = ctx.meta['sibc.kwargs']['algo']
    setting = ctx.meta['sibc.kwargs']
    if setting.algorithm == 'csidh':
        L = algo.params.L
        m = algo.params.m
        n = algo.params.n

        temporal_m = list(set(m))
        if len(temporal_m) > 1:
            # Maximum number of degree-(l_i) isogeny constructions is m_i (different for each l_i)
            bounds = '-diffbounds'
        else:
            # Maximum number of degree-(l_i) isogeny constructions is m (the same for each l_i)
            bounds = '-samebounds'

        # List of Small Odd Primes, L := [l_0, ..., l_{n-1}]
        m_prime = [geometric_serie(m[k], L[k]) for k in range(n)]
        r_out, L_out, R_out = rounds(m_prime[::-1], n)
        for j in range(0, len(r_out), 1):

            R_out[j] = list([L[::-1][k] for k in R_out[j]])
            L_out[j] = list([L[::-1][k] for k in L_out[j]])

        file_path = ("data/strategies/" + algo.curve.model + '/' + 'csidh' +
                     '-' + setting.prime + '-' + setting.style + '-e' +
                     setting.exponent + bounds + '-' + setting.formula + '-' +
                     algo.formula.multievaluation_name +
                     algo.formula.tuned_name)
        file_path = resource_filename('sibc', file_path)
        f = open(file_path)
        S_out = []
        for i in range(0, len(r_out), 1):

            tmp = f.readline()
            tmp = [int(b) for b in tmp.split()]
            S_out.append(tmp)

        f.close()

        file_path = ('csidh' + '-' + setting.prime + '-' + setting.style +
                     '-e' + setting.exponent + bounds + '-' + setting.formula +
                     '-' + algo.formula.multievaluation_name +
                     algo.formula.tuned_name + '-' + algo.curve.model)

    elif setting.algorithm == 'bsidh':
        file_path = ("data/strategies/" + algo.curve.model + '/' + 'bsidh' +
                     '-' + setting.prime + '-' + setting.formula + '-' +
                     algo.formula.multievaluation_name +
                     algo.formula.tuned_name)
        file_path = resource_filename('sibc', file_path)
        f = open(file_path)
        S_out = []
        # Corresponding to the list of Small Isogeny Degree, Lp := [l_0, ...,
        # l_{n-1}] [We need to include case l=2 and l=4]
        tmp = f.readline()
        tmp = [int(b) for b in tmp.split()]
        S_out.append(list(tmp))
        # Corresponding to the list of Small Isogeny Degree, Lm := [l_0, ...,
        # l_{n-1}]
        tmp = f.readline()
        tmp = [int(b) for b in tmp.split()]
        S_out.append(list(tmp))
        f.close()

        file_path = ('bsidh' + '-' + setting.prime + '-' + setting.style +
                     '-' + setting.formula + '-' +
                     algo.formula.multievaluation_name +
                     algo.formula.tuned_name + '-' + algo.curve.model)

    else:
        print("only csidh and bsidh are implemented")
        click.Exit(1)

    # ----
    for idx in range(0, len(S_out), 1):
        S = S_out[idx]
        n = len(S) + 1

        # Strategy written as a graph
        vertexes, vertex_colors, edges, edge_colors = strategy_evaluation(S, n)

        # Simba method written as a graph
        # vertexes, vertex_colors, edges, edge_colors = simba(n, 3)

        # All the Discrete Right Triangle
        # vertexes, vertex_colors, edges, edge_colors = DRT(n)
        G = nx.Graph()

        # Adding nodes in specific positions
        G.add_nodes_from(list(range(len(vertexes))))

        nx.set_node_attributes(G, vertexes, 'pos')
        # Adding edges with specific colors
        for i in range(len(edges)):
            G.add_edge(edges[i][0], edges[i][1], color=edge_colors[i])

        # Setting variables for a pretty plot of the graph
        edges = G.edges()
        edge_colors = [G[u][v]['color'] for u, v in edges]
        weights = [6 for u, v in edges]
        vertex_sizes = [24] * len(vertexes)

        # Finally, the graph will be plotted
        plt.figure(1, figsize=(17, 17))
        nx.draw(
            G,
            vertexes,
            node_color=['black'] * len(vertexes),
            node_size=vertex_sizes,
            edge_color=edge_colors,
            width=weights,
            edge_labels=True,
        )

        # Saving the graph as a .PNG figure
        file_name = file_path + '-id' + str(idx) + '.png'
        plt.savefig(file_name)
        print("saving graph: " + file_name)
        # plt.show()
        plt.close()

    print(
        "// The strategies have been plotted and stored in the current directory"
    )

    def DRT(n):

        vertexes = dict()  # list of the position of each node
        vertex_colors = (
            []
        )  # color of each node: red for the leaves, otherwise color is set to white
        acc = 0

        # Different shape of the isogeny graph
        for i in range(n):
            for j in range(n - 1 - i):
                vertex_colors.append('black')
                vertexes[acc] = (i, -j)
                acc += 1

        return vertexes, vertex_colors, [], []

    return attrdict(name='plot-strategy', **locals())