#ifndef LLL_CC #define LLL_CC #include "LLL.h" // subroutines for the LLL-algorithms void REDI_KB(const short& k, const short& l, BigInt** b, const short& number_of_vectors, const short& vector_dimension, BigInt** H, BigInt* d, BigInt** lambda) // the REDI procedure for relations(...) (to compute the Kernel Basis, // algorithm 2.7.2 in Cohen's book) { #ifdef GMP if(abs(BigInt(2)*lambda[k][l])<=d[l+1]) #else // GMP if(labs(2*lambda[k][l])<=d[l+1]) // labs is the abs-function for long ints #endif // GMP return; #ifdef GMP BigInt q=(BigInt(2)*lambda[k][l]+d[l+1])/(BigInt(2)*d[l+1]); #else // GMP long q=(long int) floor(((float)(2*lambda[k][l]+d[l+1]))/(2*d[l+1])); #endif // GMP // q is the integer quotient of the division // (2*lambda[k][l]+d[l+1])/(2*d[l+1]). // Because of the rounding mode (always towards zero) of GNU C++, // we cannot use the built-in integer division // here; it causes errors when dealing with negative numbers. Therefore // the complicated casts: The divident is first casted to a float which // causes the division result to be a float. This result is explicitly // rounded downwards. As the floor-function returns a double (for range // reasons), this has to be casted to an integer again. for(short n=0;n1) for(short j=0;j<=k-2;j++) { // exchange lambda[k][j] and lambda[k-1][j] BigInt swap=lambda[k][j]; lambda[k][j]=lambda[k-1][j]; lambda[k-1][j]=swap; } BigInt _lambda=lambda[k][k-1]; BigInt B=(d[k-1]*d[k+1] + _lambda*_lambda)/d[k]; // It might be better to choose another evaluation order for this formula, // see below. for(short i=k+1;i<=k_max;i++) { BigInt t=lambda[i][k]; lambda[i][k]=(d[k+1]*lambda[i][k-1] - _lambda*t)/d[k]; lambda[i][k-1]=(B*t + _lambda*lambda[i][k])/d[k+1]; } d[k]=B; } void SWAPK(const short& k, const short& k_max, BigInt** b, BigInt** H, char *f, BigInt* d, BigInt** lambda) // the SWAPK procedure of algorithm 2.7.2 { // exchange H[k] and H[k-1] // This can be done efficiently by swapping pointers (not entries). BigInt *swap=H[k]; H[k]=H[k-1]; H[k-1]=swap; // exchange b[k] and b[k-1] by the same method swap=b[k]; b[k]=b[k-1]; b[k-1]=swap; if(k>1) for(short j=0;j<=k-2;j++) { // exchange lambda[k][j] and lambda[k-1][j] BigInt swap=lambda[k][j]; lambda[k][j]=lambda[k-1][j]; lambda[k-1][j]=swap; } BigInt _lambda=lambda[k][k-1]; if(_lambda==BigInt(0)) { d[k]=d[k-1]; f[k-1]=0; f[k]=1; lambda[k][k-1]=0; for(short i=k+1;i<=k_max;i++) { lambda[i][k]=lambda[i][k-1]; lambda[i][k-1]=0; } } else // lambda!=0 { for(short i=k+1;i<=k_max;i++) lambda[i][k-1]=(_lambda*lambda[i][k-1])/d[k]; // Multiplie lambda[i][k-1] by _lambda/d[k]. // One could also write // lambda[i][k-1]*=(lambda/d[k]); (*) // Without a BigInt class, this can prevent overflows when computing // _lambda*lambda[i][k-1]. // But examples show that lambda/d[k] is in general not an integer. // So (*) could lead to problems due to the inexact floating point // arithmetic... // Therefore, we chose the secure evaluation order in all such cases. BigInt t=d[k+1]; d[k]=(_lambda*_lambda)/d[k]; d[k+1]=d[k]; for(short j=k+1;j<=k_max-1;j++) for(short i=j+1;i<=k_max;i++) lambda[i][j]=(lambda[i][j]*d[k])/t; for(short j=k+1;j<=k_max;j++) d[j+1]=(d[j+1]*d[k])/t; } } typedef BigInt* BigIntP; short relations(BigInt **b, const short& number_of_vectors, const short& vector_dimension, BigInt**& H) { // first check arguments if(number_of_vectors<0) { cerr<<"\nWARNING: short relations(BigInt**, const short&, const short&, " "BigInt**):\nargument number_of_vectors out of range"<k. // Step 1: Initialization short k=1; short k_max=0; // for iteration d[0]=1; BigInt t=0; for(short m=0;m=number_of_vectors. do { // Step 2: Incremental Gram-Schmidt if(k>k_max) // else we can immediately go to step 3. { k_max=k; for(short j=0;j<=k;j++) if((f[j]==0) && (j1) k--; else k=1; // k=max(1,k-1) } else break; } while(1); // Now the conditions above are no longer satisfied. for(short l=k-2;l>=0;l--) if(f[l]!=0) REDI_KB(k,l,b,number_of_vectors,vector_dimension,H,d,lambda); k++; // Step 4: Finished? } while(k0) H=new BigIntP[r]; for(short i=0;ik. // Step 1: Initialization short k=1; short k_max=0; // for iteration d[0]=1; d[1]=0; for(short n=0;nr. do { // Step 2: Incremental Gram-Schmidt if(k>k_max) // else we can immediately go to step 3. { k_max=k; for(short j=0;j<=k;j++) { BigInt u=0; // compute scalar product of b[k] and b[j] for(short n=0;n1) k--; // k=max(1,k-1) } else break; } while(1); // Now the condition above is no longer satisfied. for(short l=k-2;l>=0;l--) REDI_IL(k,l,b,vector_dimension,d,lambda); k++; // Step 4: Finished? } while(k