neocnt

Number theory using FLINT
git clone git://www.tkruger.se/neocnt.git
Log | Files | Refs | README

commit 10a878adc54289a28911c9014bb2aba109f99c59
parent 7cf093214ac397783eb99ad3ef2b332f19884ddb
Author: olikru <olikru@tkruger.se>
Date:   Tue, 19 Sep 2023 13:52:08 +0200

sort of working hnp solver

Diffstat:
A.gitignore | 1+
Aexamples/hnp_instance.txt | 4++++
Mexamples/hnpsolve.c | 136++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mhnp.c | 47+++++++++++++++++++++++++++++++++++++----------
Mhnp.h | 4++--
5 files changed, 120 insertions(+), 72 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/examples/hnp_instance.txt b/examples/hnp_instance.txt @@ -0,0 +1,4 @@ +3 11 131101 +46396 65911 +3185 5049 +30618 56983 diff --git a/examples/hnpsolve.c b/examples/hnpsolve.c @@ -1,87 +1,103 @@ #include <stdlib.h> #include <stdio.h> #include <flint.h> -#include <nmod_mat.h> -#include <nmod_poly.h> -#include <nmod_poly_factor.h> -#include <gr_mat.h> +#include <fmpz_vec.h> #include <hnp.h> -int main(int argc, char* argv[]) -{ - nmod_mat_t m; - nmod_mat_init(m, 4, 4, 13); - - flint_rand_t state; - flint_randinit(state); +#define LINE_SIZE_MAX 4096 - nmod_mat_randtest(m, state); +static int read_next_fmpz(fmpz_t res) +{ + char buffer[LINE_SIZE_MAX]; + size_t i; - flint_randclear(state); + int next_char = getchar(); + while(next_char == '\n' || next_char == ' ') + next_char = getchar(); - nmod_mat_print_pretty(m); + if(next_char == EOF) + return -1; - nmod_mat_t h; - nmod_mat_init(h, 4, 4, 13); + buffer[0] = next_char; + i = 1; + while(i < LINE_SIZE_MAX-1) { + next_char = getchar(); + if(next_char == EOF || next_char == '\n' || next_char == ' ') + break; - gr_ctx_t ctx; - gr_ctx_init_nmod(ctx, 13); + buffer[i] = (char) next_char; - if(gr_mat_hessenberg((gr_mat_struct*) h, (gr_mat_struct*) m, ctx)) { - printf("Failed to compute Hessenberg matrix...\n"); - exit(1); + i++; } + buffer[i] = '\0'; - nmod_mat_print_pretty(h); + return fmpz_set_str(res, buffer, 10); +} - nmod_mat_t j, p; - nmod_mat_init(j, 4, 4, 13); - nmod_mat_init(p, 4, 4, 13); +static int read_stdin_instance(fmpz** a, fmpz** t, slong* m, fmpz_t* B, fmpz_t* n) +{ + flint_scanf("%wd", m); - if(gr_mat_jordan_form((gr_mat_struct*) j, (gr_mat_struct*) p, - (gr_mat_struct*) m, ctx)) { - printf("Failed to compute jordan form\n"); - exit(1); - } + if(read_next_fmpz(*B)) + return -1; - printf("J = \n"); - nmod_mat_print_pretty(j); - printf("P = \n"); - nmod_mat_print_pretty(p); + if(read_next_fmpz(*n)) + return -1; - nmod_poly_t poly; - nmod_poly_init(poly, 13); - nmod_mat_charpoly(poly, m); - - printf("poly = \n"); - nmod_poly_print_pretty(poly, "x"); - printf("\n"); + *a = _fmpz_vec_init(*m); + *t = _fmpz_vec_init(*m); - nmod_poly_factor_t facts; - nmod_poly_factor_init(facts); - nmod_poly_factor(facts, poly); - printf("factors = \n"); - nmod_poly_factor_print_pretty(facts, "z"); + slong i; + int fail = 0; + for(i = 0; i < *m; i++) { + if(read_next_fmpz(&(*t)[i])) { + fail = 1; + break; + } - nmod_mat_clear(m); - nmod_mat_clear(h); - gr_ctx_clear(ctx); + if(read_next_fmpz(&(*a)[i])) { + fail = 1; + break; + } + } - fmpz_t n, B; - fmpz_init_set_ui(n, 123); - fmpz_init_set_ui(B, 12); + if(fail) { + _fmpz_vec_clear(*a, *m); + _fmpz_vec_clear(*t, *m); + return -1; + } - fmpz_t t[3]; - fmpz_t a[3]; - size_t i; - for(i = 0; i < 3; i++) { - fmpz_init_set_ui(t[i], 3*(i+1)); - fmpz_init_set_ui(a[i], 4*(i+1)); + return 0; +} + +int main(int argc, char* argv[]) +{ + slong m; + fmpz* a; + fmpz* t; + fmpz_t B, n; + fmpz_init(B); + fmpz_init(n); + + if(read_stdin_instance(&a, &t, &m, &B, &n) != 0) { + fprintf(stderr, "ERROR! Bad input format?\n"); + exit(1); } - fmpz_t res[4]; - hidden_number_problem(res, 4, t, a, 3, n, B); + fmpz res[m+1]; + slong i; + for(i = 0; i < m+1; i++) fmpz_init(&res[i]); + + int ret = hidden_number_problem(res, m+1, t, a, m, n, B); + if(ret == 0) { + for(i = 0; i < m; i++) { + fmpz_print(&res[i]); + printf(" "); + } + fmpz_print(&res[m]); + printf("\n"); + } return 0; } diff --git a/hnp.c b/hnp.c @@ -16,8 +16,8 @@ * 1 if reduction okay, but solution fails to verify * 0 if solution found */ -int hidden_number_problem(fmpz_t* res, const slong nres, const fmpz_t* t, - const fmpz_t* a, const slong m, const fmpz_t n, const fmpz_t B) +int hidden_number_problem(fmpz* res, const slong nres, const fmpz* t, + const fmpz* a, const slong m, const fmpz_t n, const fmpz_t B) { if(nres < m + 1) return(-1); @@ -47,16 +47,13 @@ int hidden_number_problem(fmpz_t* res, const slong nres, const fmpz_t* t, for(i = 0; i < m; i++) { // t[i]*n fmpz* tmp = fmpz_mat_entry(A, m, i); - fmpz_mul(tmp, t[i], n); + fmpz_mul(tmp, &t[i], n); // a[i]*n tmp = fmpz_mat_entry(A, m+1, i); - fmpz_mul(tmp, a[i], n); + fmpz_mul(tmp, &a[i], n); } - printf("[+] Pre-reduction matrix:\n"); - fmpz_mat_print_pretty(A); printf("\n"); - // use LLL for lattice reduction (delta = 0.99, eta = 0.501) fmpq_t delta, eta; fmpq_init(delta); fmpq_init(eta); @@ -67,14 +64,44 @@ int hidden_number_problem(fmpz_t* res, const slong nres, const fmpz_t* t, fmpq_clear(delta); fmpq_clear(eta); - printf("[+] Post-reduction matrix:\n"); - fmpz_mat_print_pretty(A); printf("\n"); - // extract the potential solution + fmpz_t Bn; + fmpz_init(Bn); + fmpz_mul(Bn, B, n); + for(i = 0; i < m+2; i++) { + if(fmpz_cmpabs(fmpz_mat_entry(A, i, m+1), Bn) == 0) break; + } + if(i >= m+2) return 1; + fmpz_clear(Bn); + + slong r = i; + + for(i = 0; i < m; i++) { + fmpz* tmp = fmpz_mat_entry(A, r, i); + fmpz_tdiv_q(&res[i], tmp, n); + } + fmpz_tdiv_q(&res[m], fmpz_mat_entry(A, r, m), B); fmpz_mat_clear(A); // test that the solution is a solution to original HNP + fmpz_t tmp; + fmpz_init(tmp); + + for(i = 0; i < m; i++) { + // tmp <- t[i]*alpha - a[i] mod n + fmpz_mul(tmp, &t[i], &res[m]); + fmpz_add(tmp, tmp, &a[i]); + fmpz_sub(tmp, tmp, &res[i]); + fmpz_mod(tmp, tmp, n); + + if(fmpz_cmp_ui(tmp, 0) != 0) { + fmpz_clear(tmp); + return 1; + } + } + + fmpz_clear(tmp); return 0; } diff --git a/hnp.h b/hnp.h @@ -7,7 +7,7 @@ #include <fmpq.h> #include <fmpz_mat.h> -int hidden_number_problem(fmpz_t* res, const slong nres, const fmpz_t* t, - const fmpz_t* a, const slong m, const fmpz_t n, const fmpz_t B); +int hidden_number_problem(fmpz* res, const slong nres, const fmpz* t, + const fmpz* a, const slong m, const fmpz_t n, const fmpz_t B); #endif