diff options
Diffstat (limited to 'src/exhaustive')
| -rw-r--r-- | src/exhaustive/exhaustive.c | 17 | ||||
| -rw-r--r-- | src/exhaustive/nums.c | 111 | ||||
| -rw-r--r-- | src/exhaustive/nums.h | 60 |
3 files changed, 188 insertions, 0 deletions
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c index a8d0f22..4eba6bd 100644 --- a/src/exhaustive/exhaustive.c +++ b/src/exhaustive/exhaustive.c @@ -7,6 +7,7 @@ #include "arg.h" #include "brainpool.h" #include "brainpool_rfc.h" +#include "nums.h" #include "check.h" #include "gen/curve.h" #include "gen/equation.h" @@ -114,6 +115,14 @@ static void exhaustive_ginit(gen_f *generators) { generators[OFFSET_ORDER] = &order_gen_prime; generators[OFFSET_GENERATORS] = &brainpool_gen_gens; } break; + case SEED_NUMS: { + generators[OFFSET_SEED] = &gen_skip; + generators[OFFSET_FIELD] = &nums_gen_field; + generators[OFFSET_A] = &nums_gen_a; + generators[OFFSET_B] = &nums_gen_b; // TODO: Missing transformation from b -> -b. + generators[OFFSET_ORDER] = &nums_gen_order; + generators[OFFSET_GENERATORS] = &nums_gen_gens; + } break; case SEED_FIPS: break; default: @@ -227,12 +236,19 @@ static void exhaustive_cinit(check_t **validators) { break; case SEED_BRAINPOOL: case SEED_BRAINPOOL_RFC: { + // TODO: Missing Brainpool CM disc check. check_t *order_check = check_new(brainpool_check_order, NULL); validators[OFFSET_ORDER] = order_check; check_t *gens_check = check_new(gens_check_anomalous, brainpool_check_gens, NULL); validators[OFFSET_GENERATORS] = gens_check; } break; + case SEED_NUMS: { + // TODO: Missing CM disc check. + check_t *gens_check = + check_new(gens_check_anomalous, brainpool_check_gens, NULL); + validators[OFFSET_GENERATORS] = gens_check; + } break; case SEED_FIPS: break; default: @@ -407,6 +423,7 @@ static void exhaustive_init(exhaustive_t *setup) { static void exhaustive_quit(exhaustive_t *setup) { field_quit(); equation_quit(); + nums_quit(); exhaustive_clear(setup); } diff --git a/src/exhaustive/nums.c b/src/exhaustive/nums.c new file mode 100644 index 0000000..7e41938 --- /dev/null +++ b/src/exhaustive/nums.c @@ -0,0 +1,111 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2023 J08nY + */ + +#include "nums.h" +#include "math/subgroup.h" +#include "obj/point.h" +#include "obj/subgroup.h" + +GENERATOR(nums_gen_field) { + pari_sp ltop = avma; + GEN base = int2u(cfg->bits); + GEN c = stoi(1); + GEN p = subii(base, c); + while (!isprime(p)) { + c = addiu(c, 4); + p = subii(base, c); + } + curve->field = gerepilecopy(ltop, p); + return 1; +} + +GENERATOR(nums_gen_a) { + curve-> a = gmodulo(stoi(-3), curve->field); + return 1; +} + +static GEN b = NULL; +static curve_t *curve_b = NULL; + +GENERATOR(nums_gen_b) { + pari_sp ltop = avma; + if (!b) { + b = gclone(gen_1); + curve->b = gmodulo(gen_1, curve->field); + curve_b = curve; + return 1; + } else { + if (curve_b == curve) { + // use b, add 1 to it, store it back modified, + GEN bn; + if (equaliu(b, 1)) { + bn = addiu(b, 2); + } else { + bn = addiu(b, 1); + } + gunclone(b); + b = gclone(bn); + curve->b = gerepilecopy(ltop, gmodulo(bn, curve->field)); + return 1; + } else { + // dont use b, regenerate it, + gunclone(b); + b = gclone(gen_1); + curve->b = gerepilecopy(ltop, gmodulo(gen_1, curve->field)); + curve_b = curve; + return 1; + } + } +} + +GENERATOR(nums_gen_order) { + pari_sp ltop = avma; + GEN order = ellsea(curve->curve, 1); + GEN frobenius = subii(addis(curve->field, 1), order); + GEN twist_order = addii(order, muliu(frobenius, 2)); + if (gequal0(order) || !(isprime(order)) || !(isprime(twist_order))) { + avma = ltop; + return -2; // Just go one step back and regenerate the b. + } else { + curve->order = gerepilecopy(ltop, order); + obj_insert_shallow(curve->curve, 1, curve->order); + return 1; + } +} + +GENERATOR(nums_gen_gens) { + pari_sp ltop = avma; + GEN x = stoi(1); + GEN Qy = ellordinate(curve->curve, x, 0); + while (glength(Qy) == 0) { + x = addiu(x, 1); + Qy = ellordinate(curve->curve, x, 0); + } + GEN P = NULL; + if (cmpii(lift(gel(Qy, 1)), lift(gel(Qy, 2))) < 0) { + P = mkvec2(gmodulo(x, curve->field), gel(Qy, 1)); + } else { + P = mkvec2(gmodulo(x, curve->field), gel(Qy, 2)); + } + + curve->generators = subgroups_new(1); + curve->ngens = 1; + subgroup_t *sub = subgroup_new(); + curve->generators[0] = sub; + point_t *G = point_new(); + sub->generator = G; + G->point = P; + G->order = ellorder(curve->curve, G->point, NULL); + G->cofactor = divii(curve->order, G->order); + gerepileall(ltop, 3, &G->point, &G->order, &G->cofactor); + return 1; +} + + +void nums_quit(void) { + if (b && isclone(b)) { + gunclone(b); + } +}
\ No newline at end of file diff --git a/src/exhaustive/nums.h b/src/exhaustive/nums.h new file mode 100644 index 0000000..40cb1b4 --- /dev/null +++ b/src/exhaustive/nums.h @@ -0,0 +1,60 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2023 J08nY + */ +/* + * @file nums.h + */ +#ifndef ECGEN_EXHAUSTIVE_NUMS_H +#define ECGEN_EXHAUSTIVE_NUMS_H + +#include "misc/types.h" + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(nums_gen_field); + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(nums_gen_a); + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(nums_gen_b); + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(nums_gen_order); + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(nums_gen_gens); + +void nums_quit(); + +#endif // ECGEN_EXHAUSTIVE_NUMS_H |
