aboutsummaryrefslogtreecommitdiff
path: root/src/secp256k1/src/gen_ecmult_static_pre_g.c
blob: ba1d1f17d7d96b3ea028b0ef5e5cf2da615f79c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*****************************************************************************************************
 * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
 * Distributed under the MIT software license, see the accompanying                                  *
 * file COPYING or https://www.opensource.org/licenses/mit-license.php.                              *
 *****************************************************************************************************/

#include <inttypes.h>
#include <stdio.h>

/* Autotools creates libsecp256k1-config.h, of which ECMULT_WINDOW_SIZE is needed.
   ifndef guard so downstream users can define their own if they do not use autotools. */
#if !defined(ECMULT_WINDOW_SIZE)
#include "libsecp256k1-config.h"
#endif

#include "../include/secp256k1.h"
#include "assumptions.h"
#include "util.h"
#include "field_impl.h"
#include "group_impl.h"
#include "ecmult.h"

void print_table(FILE *fp, const char *name, int window_g, const secp256k1_gej *gen, int with_conditionals) {
    static secp256k1_gej gj;
    static secp256k1_ge ge, dgen;
    static secp256k1_ge_storage ges;
    int j;
    int i;

    gj = *gen;
    secp256k1_ge_set_gej_var(&ge, &gj);
    secp256k1_ge_to_storage(&ges, &ge);

    fprintf(fp, "static const secp256k1_ge_storage %s[ECMULT_TABLE_SIZE(WINDOW_G)] = {\n", name);
    fprintf(fp, " S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
                  ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
                SECP256K1_GE_STORAGE_CONST_GET(ges));

    secp256k1_gej_double_var(&gj, gen, NULL);
    secp256k1_ge_set_gej_var(&dgen, &gj);

    j = 1;
    for(i = 3; i <= window_g; ++i) {
        if (with_conditionals) {
            fprintf(fp, "#if ECMULT_TABLE_SIZE(WINDOW_G) > %ld\n", ECMULT_TABLE_SIZE(i-1));
        }
        for(;j < ECMULT_TABLE_SIZE(i); ++j) {
            secp256k1_gej_set_ge(&gj, &ge);
            secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL);
            secp256k1_ge_set_gej_var(&ge, &gj);
            secp256k1_ge_to_storage(&ges, &ge);

            fprintf(fp, ",S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
                          ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
                        SECP256K1_GE_STORAGE_CONST_GET(ges));
        }
        if (with_conditionals) {
            fprintf(fp, "#endif\n");
        }
    }
    fprintf(fp, "};\n");
}

void print_two_tables(FILE *fp, int window_g, const secp256k1_ge *g, int with_conditionals) {
    secp256k1_gej gj;
    int i;

    secp256k1_gej_set_ge(&gj, g);
    print_table(fp, "secp256k1_pre_g", window_g, &gj, with_conditionals);
    for (i = 0; i < 128; ++i) {
        secp256k1_gej_double_var(&gj, &gj, NULL);
    }
    print_table(fp, "secp256k1_pre_g_128", window_g, &gj, with_conditionals);
}

int main(void) {
    const secp256k1_ge g = SECP256K1_G;
    const secp256k1_ge g_13 = SECP256K1_G_ORDER_13;
    const secp256k1_ge g_199 = SECP256K1_G_ORDER_199;
    const int window_g_13 = 4;
    const int window_g_199 = 8;
    FILE* fp;

    fp = fopen("src/ecmult_static_pre_g.h","w");
    if (fp == NULL) {
        fprintf(stderr, "Could not open src/ecmult_static_pre_g.h for writing!\n");
        return -1;
    }

    fprintf(fp, "/* This file was automatically generated by gen_ecmult_static_pre_g. */\n");
    fprintf(fp, "/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and\n");
    fprintf(fp, " * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.\n");
    fprintf(fp, " */\n");
    fprintf(fp, "#ifndef SECP256K1_ECMULT_STATIC_PRE_G_H\n");
    fprintf(fp, "#define SECP256K1_ECMULT_STATIC_PRE_G_H\n");
    fprintf(fp, "#include \"group.h\"\n");
    fprintf(fp, "#ifdef S\n");
    fprintf(fp, "   #error macro identifier S already in use.\n");
    fprintf(fp, "#endif\n");
    fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) "
                "SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,"
                "0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n");
    fprintf(fp, "#if ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE) > %ld\n", ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE));
    fprintf(fp, "   #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting ecmult_static_pre_g.h before the build.\n");
    fprintf(fp, "#endif\n");
    fprintf(fp, "#if defined(EXHAUSTIVE_TEST_ORDER)\n");
    fprintf(fp, "#if EXHAUSTIVE_TEST_ORDER == 13\n");
    fprintf(fp, "#define WINDOW_G %d\n", window_g_13);

    print_two_tables(fp, window_g_13, &g_13, 0);

    fprintf(fp, "#elif EXHAUSTIVE_TEST_ORDER == 199\n");
    fprintf(fp, "#define WINDOW_G %d\n", window_g_199);

    print_two_tables(fp, window_g_199, &g_199, 0);

    fprintf(fp, "#else\n");
    fprintf(fp, "   #error No known generator for the specified exhaustive test group order.\n");
    fprintf(fp, "#endif\n");
    fprintf(fp, "#else /* !defined(EXHAUSTIVE_TEST_ORDER) */\n");
    fprintf(fp, "#define WINDOW_G ECMULT_WINDOW_SIZE\n");

    print_two_tables(fp, ECMULT_WINDOW_SIZE, &g, 1);

    fprintf(fp, "#endif\n");
    fprintf(fp, "#undef S\n");
    fprintf(fp, "#endif\n");
    fclose(fp);

    return 0;
}