/ src / secp256k1 / src / precompute_ecmult_gen.c
precompute_ecmult_gen.c
  1  /*********************************************************************************
  2   * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille *
  3   * Distributed under the MIT software license, see the accompanying              *
  4   * file COPYING or https://www.opensource.org/licenses/mit-license.php.          *
  5   *********************************************************************************/
  6  
  7  #include <inttypes.h>
  8  #include <stdio.h>
  9  #include <stdlib.h>
 10  
 11  #include "../include/secp256k1.h"
 12  
 13  #include "assumptions.h"
 14  #include "util.h"
 15  
 16  #include "group.h"
 17  #include "int128_impl.h"
 18  #include "ecmult_gen.h"
 19  #include "ecmult_gen_compute_table_impl.h"
 20  
 21  static const int CONFIGS[][2] = {
 22      {2, 5},
 23      {11, 6},
 24      {43, 6}
 25  };
 26  
 27  static void print_table(FILE* fp, int blocks, int teeth) {
 28      int spacing = CEIL_DIV(256, blocks * teeth);
 29      size_t points = ((size_t)1) << (teeth - 1);
 30      int outer;
 31      size_t inner;
 32  
 33      secp256k1_ge_storage* table = checked_malloc(&default_error_callback, blocks * points * sizeof(secp256k1_ge_storage));
 34      secp256k1_ecmult_gen_compute_table(table, &secp256k1_ge_const_g, blocks, teeth, spacing);
 35  
 36      fprintf(fp, "#elif (COMB_BLOCKS == %d) && (COMB_TEETH == %d) && (COMB_SPACING == %d)\n", blocks, teeth, spacing);
 37      for (outer = 0; outer != blocks; outer++) {
 38          fprintf(fp,"{");
 39          for (inner = 0; inner != points; inner++) {
 40              fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
 41                          ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")",
 42                      SECP256K1_GE_STORAGE_CONST_GET(table[outer * points + inner]));
 43              if (inner != points - 1) {
 44                  fprintf(fp,",\n");
 45              }
 46          }
 47          if (outer != blocks - 1) {
 48              fprintf(fp,"},\n");
 49          } else {
 50              fprintf(fp,"}\n");
 51          }
 52      }
 53      free(table);
 54  }
 55  
 56  int main(int argc, char **argv) {
 57      const char outfile[] = "src/precomputed_ecmult_gen.c";
 58      FILE* fp;
 59      size_t config;
 60      int did_current_config = 0;
 61  
 62      (void)argc;
 63      (void)argv;
 64  
 65      fp = fopen(outfile, "w");
 66      if (fp == NULL) {
 67          fprintf(stderr, "Could not open %s for writing!\n", outfile);
 68          return EXIT_FAILURE;
 69      }
 70  
 71      fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n");
 72      fprintf(fp, "/* See ecmult_gen_impl.h for details about the contents of this file. */\n");
 73      fprintf(fp, "#include \"group.h\"\n");
 74      fprintf(fp, "#include \"ecmult_gen.h\"\n");
 75      fprintf(fp, "#include \"precomputed_ecmult_gen.h\"\n");
 76      fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n");
 77      fprintf(fp, "#    error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode\n");
 78      fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n");
 79      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");
 80  
 81      fprintf(fp, "const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = {\n");
 82      fprintf(fp, "#if 0\n");
 83      for (config = 0; config < ARRAY_SIZE(CONFIGS); ++config) {
 84          print_table(fp, CONFIGS[config][0], CONFIGS[config][1]);
 85          if (CONFIGS[config][0] == COMB_BLOCKS && CONFIGS[config][1] == COMB_TEETH) {
 86              did_current_config = 1;
 87          }
 88      }
 89      if (!did_current_config) {
 90          print_table(fp, COMB_BLOCKS, COMB_TEETH);
 91      }
 92      fprintf(fp, "#else\n");
 93      fprintf(fp, "#    error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build.\n");
 94      fprintf(fp, "#endif\n");
 95  
 96      fprintf(fp, "};\n");
 97      fprintf(fp, "#undef S\n");
 98      fclose(fp);
 99  
100      return EXIT_SUCCESS;
101  }