diff options
Diffstat (limited to 'moon-abe/pbc-0.5.14/ecc/param.c')
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/param.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/moon-abe/pbc-0.5.14/ecc/param.c b/moon-abe/pbc-0.5.14/ecc/param.c new file mode 100644 index 00000000..4fa25eef --- /dev/null +++ b/moon-abe/pbc-0.5.14/ecc/param.c @@ -0,0 +1,220 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> // for intptr_t +#include <string.h> +#include <gmp.h> +#include "pbc_utils.h" +#include "pbc_memory.h" +#include "pbc_param.h" +#include "pbc_a_param.h" +#include "pbc_mnt.h" +#include "pbc_d_param.h" +#include "pbc_e_param.h" +#include "pbc_f_param.h" +#include "pbc_a1_param.h" +#include "pbc_g_param.h" +#include "pbc_i_param.h" + +#include "misc/symtab.h" +#include "ecc/param.h" + +// Parser that reads a bunch of strings and places them in a symbol table. +// TODO: Replace with Flex/Bison? + +enum { + token_none = 0, + token_langle, + token_langleslash, + token_rangle, + token_word, + token_eof, +}; + +struct token_s { + int type; + char *s; +}; +typedef struct token_s token_t[1]; +typedef struct token_s *token_ptr; + +// Reads next token from `input`. +// Returns 1 on reaching `end` (if not NULL) or '\0' is read, 0 otherwise. +static const char *token_get(token_t tok, const char *input, const char *end) { + char *buf; + int n = 32; + int i; + char c; + #define get() (((!end || input < end) && *input) ? (c = *input++, 0) : 1) + // Skip whitespace and comments. + for(;;) { + do { + if (get()) { + tok->type = token_eof; + return input; + } + } while (strchr(" \t\r\n", c)); + if (c == '#') { + do { + if (get()) { + tok->type = token_eof; + return input; + } + } while (c != '\n'); + } else break; + } + + tok->type = token_word; + pbc_free(tok->s); + buf = (char *) pbc_malloc(n); + i = 0; + for (;;) { + buf[i] = c; + i++; + if (i == n) { + n += 32; + buf = (char *) pbc_realloc(buf, n); + } + if (get() || strchr(" \t\r\n</>", c)) break; + } + buf[i] = 0; + tok->s = buf; + return input; + #undef get +} + +static void token_init(token_t tok) { + tok->type = token_none; + tok->s = NULL; +} + +static void token_clear(token_t tok) { + pbc_free(tok->s); +} + +static void read_symtab(symtab_t tab, const char *input, size_t limit) { + token_t tok; + const char *inputend = limit ? input + limit : NULL; + token_init(tok); + for (;;) { + input = token_get(tok, input, inputend); + if (tok->type != token_word) break; + char *key = pbc_strdup(tok->s); + input = token_get(tok, input, inputend); + if (tok->type != token_word) { + pbc_free(key); + break; + } + symtab_put(tab, pbc_strdup(tok->s), key); + pbc_free(key); + } + token_clear(tok); +} + +// These functions have hidden visibility (see header). + +void param_out_type(FILE *stream, char *s) { + fprintf(stream, "type %s\n", s); +} + +void param_out_mpz(FILE *stream, char *s, mpz_t z) { + fprintf(stream, "%s ", s); + mpz_out_str(stream, 0, z); + fprintf(stream, "\n"); +} + +void param_out_int(FILE *stream, char *s, int i) { + mpz_t z; + mpz_init(z); + + mpz_set_si(z, i); + param_out_mpz(stream, s, z); + mpz_clear(z); +} + +static const char *lookup(symtab_t tab, const char *key) { + if (!symtab_has(tab, key)) { + pbc_error("missing param: `%s'", key); + return NULL; + } + return symtab_at(tab, key); +} + +int lookup_mpz(mpz_t z, symtab_t tab, const char *key) { + const char *data = lookup(tab, key); + if (!data) { + pbc_error("missing param: `%s'", key); + return 1; + } + mpz_set_str(z, data, 0); + return 0; +} + +int lookup_int(int *n, symtab_t tab, const char *key) { + mpz_t z; + const char *data = lookup(tab, key); + if (!data) { + pbc_error("missing param: `%s'", key); + return 1; + } + mpz_init(z); + + mpz_set_str(z, data, 0); + *n = mpz_get_si(z); + mpz_clear(z); + + return 0; +} + +static int param_set_tab(pbc_param_t par, symtab_t tab) { + const char *s = lookup(tab, "type"); + + static struct { + char *s; + int (*fun)(pbc_param_ptr, symtab_t tab); + } funtab[] = { + { "a", pbc_param_init_a }, + { "d", pbc_param_init_d }, + { "e", pbc_param_init_e }, + { "f", pbc_param_init_f }, + { "g", pbc_param_init_g }, + { "a1", pbc_param_init_a1 }, + { "i", pbc_param_init_i }, + }; + + int res = 1; + if (s) { + unsigned int i; + for(i = 0; i < sizeof(funtab)/sizeof(*funtab); i++) { + if (!strcmp(s, funtab[i].s)) { + res = funtab[i].fun(par, tab); + if (res) pbc_error("bad pairing parameters"); + return res; + } + } + } + + pbc_error("unknown pairing type"); + return res; +} + +// Public functions: + +int pbc_param_init_set_str(pbc_param_t par, const char *input) { + symtab_t tab; + symtab_init(tab); + read_symtab(tab, input, 0); + int res = param_set_tab(par, tab); + symtab_forall_data(tab, pbc_free); + symtab_clear(tab); + return res; +} + +int pbc_param_init_set_buf(pbc_param_t par, const char *input, size_t len) { + symtab_t tab; + symtab_init(tab); + read_symtab(tab, input, len); + int res = param_set_tab(par, tab); + symtab_forall_data(tab, pbc_free); + symtab_clear(tab); + return res; +} |