├── cpucycles.h ├── crypto_int16.h ├── crypto_int32.h ├── crypto_uint32.h ├── sign.h ├── gauss ├── rnd │ ├── random.h │ └── random.c └── samplers │ └── rejection_ber_independent │ ├── rej_ber_independent_table.data │ ├── rej_ber_independent.c │ └── gen_ber_table.py ├── oracle.h ├── cpucycles.c ├── randombytes.h ├── sample.h ├── fastrandombytes.h ├── api.h ├── crypto_hash_sha512.h ├── crypto_hash_sha256.h ├── crypto_stream.h ├── crypto_stream_salsa20.h ├── params.h ├── ntt.h ├── randombytes.c ├── crypto_sign.h ├── oracle.c ├── Makefile ├── fastrandombytes.c ├── sample.c ├── README.md ├── ntt.c ├── test ├── test_sign.c └── speed.c ├── crypto_stream.c ├── crypto_hash_sha256.c ├── sign.c ├── crypto_hash_sha512.c ├── bitrev.code ├── ntt_transform.c └── consts.c /cpucycles.h: -------------------------------------------------------------------------------- 1 | #ifndef CPUCYCLES_H 2 | #define CPUCYCLES_H 3 | 4 | long long cpucycles(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /crypto_int16.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_INT16_H 2 | #define CRYPTO_INT16_H 3 | 4 | typedef short crypto_int16; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /crypto_int32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_int32_h 2 | #define crypto_int32_h 3 | 4 | typedef int crypto_int32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /crypto_uint32.h: -------------------------------------------------------------------------------- 1 | #ifndef crypto_uint32_h 2 | #define crypto_uint32_h 3 | 4 | typedef unsigned int crypto_uint32; 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /sign.h: -------------------------------------------------------------------------------- 1 | int get_sig_rejections_wi(void); 2 | void delete_sig_rejections_wi(void); 3 | int get_sig_rejections_final(void); 4 | void delete_sig_rejections_final(void); 5 | -------------------------------------------------------------------------------- /gauss/rnd/random.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOM_H 2 | #define RANDOM_H 3 | 4 | #include 5 | void get_random_256(uint32_t *buf); 6 | uint8_t get_random_8(void); 7 | void clear_buffer(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /oracle.h: -------------------------------------------------------------------------------- 1 | #ifndef ORACLE_H 2 | #define ORACLE_H 3 | 4 | #include "params.h" 5 | #include "ntt.h" 6 | 7 | void random_oracle(unsigned char *c_bin, poly v1, poly v2, const unsigned char *m, unsigned long long mlen); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /cpucycles.c: -------------------------------------------------------------------------------- 1 | #include "cpucycles.h" 2 | 3 | long long cpucycles(void) 4 | { 5 | unsigned long long result; 6 | asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax" 7 | : "=a" (result) :: "%rdx"); 8 | return result; 9 | } 10 | -------------------------------------------------------------------------------- /randombytes.h: -------------------------------------------------------------------------------- 1 | /* 2 | randombytes/devurandom.h version 20080713 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #ifndef RANDOMBYTES_H 8 | #define RANDOMBYTES_H 9 | 10 | void randombytes(unsigned char *,unsigned long long); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /sample.h: -------------------------------------------------------------------------------- 1 | #ifndef SAMPLE_H 2 | #define SAMPLE_H 3 | 4 | #include 5 | #include "params.h" 6 | #include "ntt.h" 7 | 8 | void sample_y(poly y); 9 | 10 | void sample_gauss_poly(poly x); 11 | 12 | void generate_c(uint32_t *pos_list, unsigned char *c_bin); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /fastrandombytes.h: -------------------------------------------------------------------------------- 1 | #ifndef FASTRANDOMBYTES_H 2 | #define FASTRANDOMBYTES_H 3 | 4 | void fastrandombytes(unsigned char *r, unsigned long long rlen); 5 | void get_random_key(); 6 | void set_key(const unsigned char *data, unsigned long long datalen); 7 | void set_zero_key(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /api.h: -------------------------------------------------------------------------------- 1 | #include "params.h" 2 | #include 3 | 4 | //Contains S and E 5 | #define CRYPTO_SECRETKEYBYTES (sizeof(double)*PARAM_N+sizeof(double)*PARAM_N*2) 6 | 7 | //Contains T 8 | #define CRYPTO_PUBLICKEYBYTES (sizeof(double)*2*PARAM_N) 9 | 10 | //Contains z (bounded by B) and a hash 11 | #define CRYPTO_BYTES (3*PARAM_N+32) 12 | -------------------------------------------------------------------------------- /crypto_hash_sha512.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_H 2 | #define HASH_H 3 | 4 | int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen); 5 | 6 | int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen); 7 | 8 | #define crypto_hash_sha512_BYTES 64 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /crypto_hash_sha256.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_HASH_SHA256_H 2 | #define CRYPTO_HASH_SHA256_H 3 | 4 | int crypto_hashblocks_sha256(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen); 5 | 6 | int crypto_hash_sha256(unsigned char *out,const unsigned char *in,unsigned long long inlen); 7 | 8 | #define crypto_hash_sha256_BYTES 32 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /crypto_stream.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_STREAM_H 2 | #define CRYPTO_STREAM_H 3 | 4 | #define crypto_stream_KEYBYTES 32 5 | #define crypto_stream_NONCEBYTES 8 6 | 7 | #define crypto_stream crypto_stream_salsa20_amd64_xmm6 8 | 9 | int crypto_stream( 10 | unsigned char *c,unsigned long long clen, 11 | const unsigned char *n, 12 | const unsigned char *k 13 | ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /crypto_stream_salsa20.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_STREAM_H 2 | #define CRYPTO_STREAM_H 3 | 4 | #define crypto_stream_salsa20_KEYBYTES 32 5 | #define crypto_stream_salsa20_NONCEBYTES 8 6 | 7 | int crypto_stream_salsa20_amd64_xmm6( 8 | unsigned char *c,unsigned long long clen, 9 | const unsigned char *n, 10 | const unsigned char *k 11 | ); 12 | 13 | #define crypto_stream_salsa20 crypto_stream_salsa20_amd64_xmm6 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /params.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMS_H 2 | #define PARAMS_H 3 | 4 | #define PARAM_N 512 5 | #define PARAM_N_LOG 9 6 | #define PARAM_M 1024 7 | #define PARAM_SIGMA 48 8 | #define PARAM_Q 33550337 9 | #define PARAM_Q_LOG 25 10 | #define PARAM_QINV .00000002980595992225 11 | #define PARAM_B 4194303 12 | #define PARAM_BINV .00000011920928955078 13 | #define PARAM_B_BITS 22 14 | 15 | #define PARAM_K PARAM_N 16 | #define PARAM_SIGMA_E PARAM_SIGMA 17 | 18 | #define PARAM_W 19 19 | #define PARAM_D 23 20 | 21 | #define PARAM_KEYGEN_BOUND 1882 22 | #define PARAM_REJECTION PARAM_KEYGEN_BOUND 23 | #define PARAM_U 2848 24 | #endif 25 | -------------------------------------------------------------------------------- /ntt.h: -------------------------------------------------------------------------------- 1 | #ifndef NTT_H 2 | #define NTT_H 3 | #include "params.h" 4 | #include 5 | 6 | typedef double __attribute__ ((aligned (32))) poly[PARAM_N]; 7 | 8 | extern double omegas[]; 9 | extern double omegas_inv[]; 10 | 11 | extern double psis[]; 12 | extern double psis_inv[]; 13 | 14 | /* Interface function prototypes */ 15 | void poly_mul(poly result, const poly x, const poly y); 16 | void poly_transform(poly result, const poly x); 17 | void poly_mul_fixed(poly result, const poly x, const poly a); 18 | void poly_add(poly result, const poly x, const poly y); 19 | void poly_sub(poly result, const poly x, const poly y); 20 | 21 | #endif /* NTT_H */ 22 | -------------------------------------------------------------------------------- /randombytes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "randombytes.h" 6 | 7 | /* it's really stupid that there isn't a syscall for this */ 8 | 9 | static int fd = -1; 10 | 11 | void randombytes(unsigned char *x,unsigned long long xlen) 12 | { 13 | int i; 14 | 15 | if (fd == -1) { 16 | for (;;) { 17 | fd = open("/dev/urandom",O_RDONLY); 18 | if (fd != -1) break; 19 | sleep(1); 20 | } 21 | } 22 | 23 | while (xlen > 0) { 24 | if (xlen < 1048576) i = xlen; else i = 1048576; 25 | 26 | i = read(fd,x,i); 27 | if (i < 1) { 28 | sleep(1); 29 | continue; 30 | } 31 | 32 | x += i; 33 | xlen -= i; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /crypto_sign.h: -------------------------------------------------------------------------------- 1 | #include "api.h" 2 | 3 | extern int crypto_sign_keypair( 4 | unsigned char *, 5 | unsigned char * 6 | ); 7 | 8 | extern int crypto_sign( 9 | unsigned char *,unsigned long long *, 10 | const unsigned char *,unsigned long long, 11 | const unsigned char * 12 | ); 13 | 14 | extern int crypto_sign_open( 15 | unsigned char *,unsigned long long *, 16 | const unsigned char *,unsigned long long, 17 | const unsigned char * 18 | ); 19 | 20 | int crypto_sign_open_batch( 21 | unsigned char* const m[],unsigned long long mlen[], 22 | unsigned char* const sm[],const unsigned long long smlen[], 23 | unsigned char* const pk[], 24 | unsigned long long batchsize 25 | ); 26 | 27 | #define crypto_sign_SECRETKEYBYTES CRYPTO_SECRETKEYBYTES 28 | #define crypto_sign_PUBLICKEYBYTES CRYPTO_PUBLICKEYBYTES 29 | #define crypto_sign_BYTES CRYPTO_BYTES 30 | -------------------------------------------------------------------------------- /oracle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "params.h" 4 | #include "crypto_hash_sha512.h" 5 | #include "ntt.h" 6 | 7 | static void compress_v(int32_t t[PARAM_N], double v[PARAM_N]) 8 | { 9 | int i; 10 | for(i=0;i>PARAM_D; 14 | } 15 | } 16 | 17 | 18 | 19 | void random_oracle(unsigned char *c_bin, poly v1, poly v2, const unsigned char *m, unsigned long long mlen) 20 | { 21 | int32_t t1[PARAM_N],t2[PARAM_N]; 22 | unsigned long long i; 23 | unsigned char buf[2*PARAM_N+mlen]; 24 | compress_v(t1, v1); 25 | compress_v(t2, v2); 26 | for(i=0; i gauss/samplers/rejection_ber_independent/rej_ber_independent_table.data 24 | $(CC) $(CFLAGS) $(SOURCE) test/test_sign.c -lm -o $@ randombytes.c 25 | 26 | test/speed: $(SOURCE) $(HEADER) test/speed.c randombytes.c 27 | $(CC) $(CFLAGS) $(SOURCE) test/speed.c -lm -o $@ randombytes.c 28 | 29 | .PHONY: clean 30 | 31 | clean: 32 | -rm test/test_sign 33 | -rm test/speed 34 | -------------------------------------------------------------------------------- /fastrandombytes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "crypto_stream.h" 3 | #include "randombytes.h" 4 | #include "gauss/rnd/random.h" 5 | 6 | static int init = 0; 7 | static unsigned char key[crypto_stream_KEYBYTES]; 8 | static unsigned char nonce[crypto_stream_NONCEBYTES] = {0}; 9 | 10 | 11 | void set_key(const unsigned char *data, unsigned long long datalen){ 12 | //Set key to zero 13 | unsigned long long i; 14 | if (datalen > crypto_stream_KEYBYTES){ 15 | printf("Seed too large"); 16 | } 17 | 18 | clear_buffer(); 19 | 20 | for(i=0; i> 8*i) & 0xff; 78 | } 79 | -------------------------------------------------------------------------------- /gauss/rnd/random.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../../fastrandombytes.h" 4 | 5 | void get_random_256(uint32_t * buf){ 6 | //Write 256 bits/32 bytes of randomness into the buffer 7 | 8 | //use c rand() function as placeholder for testing on PC 9 | //int i; 10 | //2Dfor(i=0; i<8; i++){ 11 | //buf[i] = (uint32_t) rand(); 12 | //} 13 | 14 | fastrandombytes( (unsigned char*) buf, 8*4); 15 | 16 | } 17 | 18 | 19 | #define BUF_VARS 128 20 | static int32_t buf_cnt = -1; 21 | static uint8_t buf[BUF_VARS]; 22 | 23 | void clear_buffer(){ 24 | buf_cnt = -1; 25 | } 26 | 27 | uint8_t get_random_8(void){ 28 | //Write 256 bits/32 bytes of randomness into the buffer 29 | //use c rand() function as placeholder for testing on PC 30 | 31 | //Maintain an internal buffer which contains random numbers. User can request bytes from this buffer. 32 | //In case the internal buffer is deepleted, we have to resample uniform bits again. 33 | //TODO 34 | //return (uint8_t) (rand() & 0xFF); 35 | //printf("%x",val); 36 | 37 | if (buf_cnt < 0){ 38 | fastrandombytes(buf, BUF_VARS); 39 | buf_cnt = BUF_VARS-1; 40 | } 41 | 42 | return buf[buf_cnt--]; 43 | } 44 | 45 | 46 | 47 | /* 48 | uint32_t getRandom(void) 49 | { 50 | uint32_t r; 51 | 52 | // while(!(RNG->SR & RNG_FLAG_DRDY)); 53 | //return RNG->DR; 54 | 55 | // XXX: TODO 56 | randombytes((unsigned char *)&r, 4); 57 | return r; 58 | } 59 | 60 | 61 | 62 | 63 | 64 | void getRandomPoly(int32_t * poly) 65 | { 66 | int i; 67 | for(i = 0; i= paramQ); 72 | } 73 | } 74 | */ 75 | -------------------------------------------------------------------------------- /sample.c: -------------------------------------------------------------------------------- 1 | #include "sample.h" 2 | #include "crypto_stream.h" 3 | #include "fastrandombytes.h" 4 | 5 | //Interface of Gauss sampler 6 | extern int32_t sample_gauss(void); 7 | static double fmodq(double x) 8 | { 9 | double c = x * PARAM_QINV; 10 | c = round(c); 11 | c *= PARAM_Q; 12 | return x-c; 13 | } 14 | 15 | void sample_y(double mat_y[PARAM_N]) 16 | { 17 | int32_t val; 18 | unsigned char buf[3*PARAM_N+68]; 19 | int pos=0, i=0; 20 | 21 | fastrandombytes(buf,3*PARAM_N+68); 22 | do 23 | { 24 | if(pos == 3*PARAM_N+66) 25 | { 26 | fastrandombytes(buf,3*PARAM_N+68); 27 | pos = 0; 28 | } 29 | val = (*(int32_t *)(buf+pos)) & 0x7fffff; 30 | 31 | if(val < 0x7fffff) 32 | mat_y[i++] = val-PARAM_B; 33 | 34 | pos+=3; 35 | } 36 | while(i< PARAM_N); 37 | } 38 | 39 | 40 | 41 | 42 | void sample_gauss_poly(poly x) 43 | { 44 | unsigned int j; 45 | double gauss; 46 | 47 | for(j=0; j 2 | #include 3 | 4 | #include "../crypto_sign.h" 5 | #include "../params.h" 6 | #include "../api.h" 7 | #include "../ntt.h" 8 | #define MLEN 100 9 | 10 | #define NTESTS 1000 11 | 12 | unsigned char sk[CRYPTO_SECRETKEYBYTES]; 13 | unsigned char pk[CRYPTO_PUBLICKEYBYTES]; 14 | unsigned char sksav[CRYPTO_SECRETKEYBYTES]; 15 | unsigned char pksav[CRYPTO_PUBLICKEYBYTES]; 16 | 17 | unsigned char sk2[CRYPTO_SECRETKEYBYTES]; 18 | unsigned char pk2[CRYPTO_PUBLICKEYBYTES]; 19 | 20 | unsigned char mi[MLEN]; 21 | unsigned char mo[MLEN+CRYPTO_BYTES]; 22 | unsigned char sm[MLEN+CRYPTO_BYTES]; 23 | unsigned long long smlen; 24 | unsigned long long mlen; 25 | 26 | extern poly poly_a1; 27 | extern poly poly_a2; 28 | unsigned char Atsav[PARAM_N*PARAM_M]; 29 | 30 | extern unsigned long long rejwctr; 31 | extern unsigned long long rejyzctr; 32 | /*extern unsigned long long ctr;*/ 33 | 34 | int main() 35 | { 36 | double rejw=.0,rejyz=.0; 37 | int r; 38 | unsigned long long i,j; 39 | FILE *urandom = fopen("/dev/urandom", "r"); 40 | 41 | crypto_sign_keypair(pk, sk); 42 | /*printf("%.2f,",1.0/((double)ctr));fflush(stdout);*/ 43 | memcpy(sksav,sk,CRYPTO_SECRETKEYBYTES); 44 | memcpy(pksav,pk,CRYPTO_PUBLICKEYBYTES); 45 | 46 | /*memcpy(Atsav,matrix_At,PARAM_N*PARAM_M);*/ 47 | 48 | for(i=0; i 2 | #include 3 | #include "../fastrandombytes.h" 4 | #include "../cpucycles.h" 5 | #include "../crypto_sign.h" 6 | #include "../sign.h" 7 | #include "../ntt.h" 8 | 9 | 10 | #define MLEN 59 11 | #define NRUNS 50 12 | #define NRUNS_GEN 2 13 | #define NRUNS_SIGN 100 14 | #define NRUNS_VERIF 100 15 | 16 | //int get_sig_rejections(void); 17 | 18 | static int cmp_llu(const void *a, const void*b) 19 | { 20 | if(*(unsigned long long *)a < *(unsigned long long *)b) return -1; 21 | if(*(unsigned long long *)a > *(unsigned long long *)b) return 1; 22 | return 0; 23 | } 24 | 25 | 26 | static unsigned long long median(unsigned long long *l, size_t llen) 27 | { 28 | qsort(l,llen,sizeof(unsigned long long),cmp_llu); 29 | 30 | if(llen%2) return l[llen/2]; 31 | else return (l[llen/2-1]+l[llen/2])/2; 32 | } 33 | 34 | static unsigned long long average(unsigned long long *t, size_t tlen) 35 | { 36 | unsigned long long acc=0; 37 | size_t i; 38 | for(i=0;i 2 | #include "../../rnd/random.h" 3 | 4 | //The table for the Bernoulli sampler 5 | #include "rej_ber_independent_table.data" 6 | 7 | //Used for testing 8 | 9 | static int32_t sample_rejection_independent_time(); 10 | static uint32_t reject_counter =0; 11 | 12 | int32_t gauss_max_val(){ 13 | return MAX_GAUSS_VAL; 14 | } 15 | 16 | int32_t gauss_sigma(){ 17 | return SIGMA; 18 | } 19 | 20 | 21 | int32_t sample_gauss(){ 22 | //returns a sample 23 | 24 | int32_t val; 25 | uint8_t rnd; 26 | 27 | while(1){ 28 | //obtain a sample from positive half of Gaussian 29 | val = sample_rejection_independent_time(); 30 | rnd = get_random_8(); 31 | 32 | //Check for a zero value and reject half of them 33 | if (val == 0){ 34 | if (((rnd>>1) &1) == 0){ 35 | //restart sampling procedure 36 | continue; 37 | }else{ 38 | return val; 39 | } 40 | } 41 | 42 | //Sample a sign 43 | if (((rnd &1)==1)){ 44 | return -val; 45 | } 46 | else{ 47 | return val; 48 | } 49 | } 50 | 51 | } 52 | 53 | 54 | 55 | static int32_t sample_rejection_independent_time() { 56 | //Bernoulli rejection sampling which can be made independent time- 57 | //Reads out the whole table in case of a sucessfull sampling 58 | //Rejections if stuff does not work 59 | uint32_t val =0,x; 60 | uint32_t j, accept_mask; 61 | int32_t i; 62 | uint8_t r,reject; 63 | uint16_t smaller; 64 | uint16_t larger; 65 | 66 | 67 | //Use break an continue to escape from this loop 68 | while(1){ 69 | 70 | val=0; 71 | i=0; 72 | //sample a candidate 73 | while (val < MAX_GAUSS_VAL){ 74 | val |= ((uint32_t)get_random_8())<<(8*i); 75 | i++; 76 | } 77 | //mask the candidate and reject when necessary 78 | val = val & ((1<= MAX_GAUSS_VAL){ 80 | continue; 81 | } 82 | 83 | //Check the table if we can accept this value 84 | //In case of a rejection we just abort 85 | //Otherwise the whole table has to be checked 86 | accept_mask = 0; 87 | reject = 0; 88 | x = val * val; //Have to evaluate exp(x^2/f). Keep val for later use (in case of success). 89 | for(j=0; j=0; i--){ 93 | //Sample a uniform byte 94 | 95 | r = get_random_8(); 96 | 97 | //We check wether the random value is smaller than the one in the table 98 | smaller = 0; 99 | larger = 0; 100 | if (r < ber_table[i][j]){ 101 | smaller = 1; 102 | } 103 | if (r > ber_table[i][j]){ 104 | larger = 1; 105 | } 106 | 107 | //If the random value r is (a) smaller and (b) we havent accepted it so far, 108 | //then we mark the index as accepted 109 | if ((smaller == 1) && (((accept_mask >> i)&1) == 0)){ 110 | accept_mask |= (1<> i)&1)==1) && ((accept_mask >> i)&1) == 0 ){ 118 | //Break from the loop and restart again 119 | reject = 1; 120 | reject_counter++; 121 | break; 122 | } 123 | } 124 | if (reject == 1){ 125 | break; 126 | } 127 | } 128 | 129 | if (reject == 0){ 130 | //loop is finished - no reject 131 | //break the loop and output the value 132 | break; 133 | } 134 | } 135 | 136 | return val; 137 | } 138 | 139 | 140 | 141 | 142 | int32_t get_rejections(){ 143 | return reject_counter; 144 | } 145 | 146 | void clear_rejections(){ 147 | reject_counter = 0; 148 | } 149 | -------------------------------------------------------------------------------- /crypto_stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | version 20080912 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #define ROUNDS 20 8 | 9 | typedef unsigned int uint32; 10 | 11 | static uint32 rotate(uint32 u,int c) 12 | { 13 | return (u << c) | (u >> (32 - c)); 14 | } 15 | 16 | static uint32 load_littleendian(const unsigned char *x) 17 | { 18 | return 19 | (uint32) (x[0]) \ 20 | | (((uint32) (x[1])) << 8) \ 21 | | (((uint32) (x[2])) << 16) \ 22 | | (((uint32) (x[3])) << 24) 23 | ; 24 | } 25 | 26 | static void store_littleendian(unsigned char *x,uint32 u) 27 | { 28 | x[0] = u; u >>= 8; 29 | x[1] = u; u >>= 8; 30 | x[2] = u; u >>= 8; 31 | x[3] = u; 32 | } 33 | 34 | static int crypto_core_salsa20( 35 | unsigned char *out, 36 | const unsigned char *in, 37 | const unsigned char *k, 38 | const unsigned char *c 39 | ) 40 | { 41 | uint32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; 42 | uint32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; 43 | int i; 44 | 45 | j0 = x0 = load_littleendian(c + 0); 46 | j1 = x1 = load_littleendian(k + 0); 47 | j2 = x2 = load_littleendian(k + 4); 48 | j3 = x3 = load_littleendian(k + 8); 49 | j4 = x4 = load_littleendian(k + 12); 50 | j5 = x5 = load_littleendian(c + 4); 51 | j6 = x6 = load_littleendian(in + 0); 52 | j7 = x7 = load_littleendian(in + 4); 53 | j8 = x8 = load_littleendian(in + 8); 54 | j9 = x9 = load_littleendian(in + 12); 55 | j10 = x10 = load_littleendian(c + 8); 56 | j11 = x11 = load_littleendian(k + 16); 57 | j12 = x12 = load_littleendian(k + 20); 58 | j13 = x13 = load_littleendian(k + 24); 59 | j14 = x14 = load_littleendian(k + 28); 60 | j15 = x15 = load_littleendian(c + 12); 61 | 62 | for (i = ROUNDS;i > 0;i -= 2) { 63 | x4 ^= rotate( x0+x12, 7); 64 | x8 ^= rotate( x4+ x0, 9); 65 | x12 ^= rotate( x8+ x4,13); 66 | x0 ^= rotate(x12+ x8,18); 67 | x9 ^= rotate( x5+ x1, 7); 68 | x13 ^= rotate( x9+ x5, 9); 69 | x1 ^= rotate(x13+ x9,13); 70 | x5 ^= rotate( x1+x13,18); 71 | x14 ^= rotate(x10+ x6, 7); 72 | x2 ^= rotate(x14+x10, 9); 73 | x6 ^= rotate( x2+x14,13); 74 | x10 ^= rotate( x6+ x2,18); 75 | x3 ^= rotate(x15+x11, 7); 76 | x7 ^= rotate( x3+x15, 9); 77 | x11 ^= rotate( x7+ x3,13); 78 | x15 ^= rotate(x11+ x7,18); 79 | x1 ^= rotate( x0+ x3, 7); 80 | x2 ^= rotate( x1+ x0, 9); 81 | x3 ^= rotate( x2+ x1,13); 82 | x0 ^= rotate( x3+ x2,18); 83 | x6 ^= rotate( x5+ x4, 7); 84 | x7 ^= rotate( x6+ x5, 9); 85 | x4 ^= rotate( x7+ x6,13); 86 | x5 ^= rotate( x4+ x7,18); 87 | x11 ^= rotate(x10+ x9, 7); 88 | x8 ^= rotate(x11+x10, 9); 89 | x9 ^= rotate( x8+x11,13); 90 | x10 ^= rotate( x9+ x8,18); 91 | x12 ^= rotate(x15+x14, 7); 92 | x13 ^= rotate(x12+x15, 9); 93 | x14 ^= rotate(x13+x12,13); 94 | x15 ^= rotate(x14+x13,18); 95 | } 96 | 97 | x0 += j0; 98 | x1 += j1; 99 | x2 += j2; 100 | x3 += j3; 101 | x4 += j4; 102 | x5 += j5; 103 | x6 += j6; 104 | x7 += j7; 105 | x8 += j8; 106 | x9 += j9; 107 | x10 += j10; 108 | x11 += j11; 109 | x12 += j12; 110 | x13 += j13; 111 | x14 += j14; 112 | x15 += j15; 113 | 114 | store_littleendian(out + 0,x0); 115 | store_littleendian(out + 4,x1); 116 | store_littleendian(out + 8,x2); 117 | store_littleendian(out + 12,x3); 118 | store_littleendian(out + 16,x4); 119 | store_littleendian(out + 20,x5); 120 | store_littleendian(out + 24,x6); 121 | store_littleendian(out + 28,x7); 122 | store_littleendian(out + 32,x8); 123 | store_littleendian(out + 36,x9); 124 | store_littleendian(out + 40,x10); 125 | store_littleendian(out + 44,x11); 126 | store_littleendian(out + 48,x12); 127 | store_littleendian(out + 52,x13); 128 | store_littleendian(out + 56,x14); 129 | store_littleendian(out + 60,x15); 130 | 131 | return 0; 132 | } 133 | 134 | static const unsigned char sigma[16] = "expand 32-byte k"; 135 | 136 | int crypto_stream( 137 | unsigned char *c,unsigned long long clen, 138 | const unsigned char *n, 139 | const unsigned char *k 140 | ) 141 | { 142 | unsigned char in[16]; 143 | unsigned char block[64]; 144 | unsigned long long i; 145 | unsigned int u; 146 | 147 | if (!clen) return 0; 148 | 149 | for (i = 0;i < 8;++i) in[i] = n[i]; 150 | for (i = 8;i < 16;++i) in[i] = 0; 151 | 152 | while (clen >= 64) { 153 | crypto_core_salsa20(c,in,k,sigma); 154 | 155 | u = 1; 156 | for (i = 8;i < 16;++i) { 157 | u += (unsigned int) in[i]; 158 | in[i] = u; 159 | u >>= 8; 160 | } 161 | 162 | clen -= 64; 163 | c += 64; 164 | } 165 | 166 | if (clen) { 167 | crypto_core_salsa20(block,in,k,sigma); 168 | for (i = 0;i < clen;++i) c[i] = block[i]; 169 | } 170 | return 0; 171 | } 172 | -------------------------------------------------------------------------------- /gauss/samplers/rejection_ber_independent/gen_ber_table.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on 12.03.2014 3 | 4 | @author: thomas 5 | ''' 6 | 7 | import math 8 | from decimal import * 9 | import pprint 10 | import sys 11 | 12 | def get_binary_expansion_fraction(x): 13 | val = 0 14 | res =[] 15 | for i in range(1, getcontext().prec): 16 | tmp = Decimal(2**(-i)) 17 | if (val+tmp) < x: 18 | val = val + tmp 19 | res.append(1) 20 | else: 21 | res.append(0) 22 | return res 23 | 24 | def generate_table(max_val,sigma): 25 | '''generate the table for the exp functions''' 26 | val = [] 27 | 28 | #print(max_val, "dadasdas") 29 | for i in range(0, max_val): 30 | #val.append( list(bin(int(str(((Decimal(2) ** ((Decimal((-i)/(2*sigma*sigma)))))/S_sigma).quantize(Decimal(10)**(Decimal(-max_round))))[2:]))[2:])) 31 | #val.append( float(((Decimal(2) ** ((Decimal((-i)/(2*sigma*sigma)))))/S_sigma.quantize(Decimal(10)**(Decimal(-max_round))) ) ) ) 32 | #val.append( str(((((Decimal((-Decimal(2)**(i))/(Decimal(2*sigma*sigma)))))).exp()).quantize(Decimal(10)**(Decimal(-50))))) 33 | 34 | tmp = (Decimal(((-Decimal(2)**(i))/(Decimal(2*sigma*sigma))).exp())) 35 | #print(tmp) 36 | val.append(get_binary_expansion_fraction(tmp)) 37 | # 38 | return val 39 | 40 | def chunks(l, n): 41 | return [l[i:i+n] for i in range(0, len(l), n)] 42 | 43 | def conv(bin_list): 44 | val = 0; 45 | for i in range(0,len(bin_list)): 46 | if bin_list[i] == 1: 47 | val |= (1<<(len(bin_list)-i-1)) 48 | return val 49 | 50 | def print_table_bytes(table): 51 | #print the table as byte array 52 | val_table = [] 53 | 54 | for i in range(0,len(table)): 55 | val_table.append(chunks(table[i], 8)) 56 | 57 | byte_table = [] 58 | for i in range(0,len(val_table)): 59 | byte_table.append([]) 60 | for j in range(len(val_table[0])): 61 | byte_table[i].append(conv(val_table[i][j])) 62 | #byte_table[i].append(val_table[i][j]) 63 | 64 | #pprint.pprint(byte_table) 65 | 66 | 67 | print("#define MAX_BER_ENTRIES "+str(len(byte_table))) 68 | print("#define MAX_BER_BYTES "+str(len(byte_table[0]))) 69 | print("") 70 | print("static uint8_t ber_table[MAX_BER_ENTRIES][MAX_BER_BYTES]={") 71 | for i in range(0,len(byte_table)): 72 | print("{", end="") 73 | for j in range(len(byte_table[0])-1): 74 | print(byte_table[i][j], end="") 75 | print(",", end="") 76 | print(byte_table[i][len(byte_table[0])-1], end="") 77 | print("},") 78 | 79 | print("};") 80 | 81 | 82 | def print_table_int64(table): 83 | #Print the table as int64 in columns 84 | #print the table as byte array 85 | val_table = [] 86 | 87 | for i in range(0,len(table)): 88 | val_table.append(chunks(table[i], 8)) 89 | 90 | byte_table = [] 91 | for i in range(0,len(val_table)): 92 | byte_table.append([]) 93 | for j in range(len(val_table[0])): 94 | byte_table[i].append(conv(val_table[i][j])) 95 | #byte_table[i].append(val_table[i][j]) 96 | 97 | #pprint.pprint(byte_table) 98 | 99 | print("#define MAX_BER64_ENTRIES "+str(len(byte_table))) 100 | print("#define MAX_BER64_BYTES "+str(len(byte_table[0]))) 101 | print("#define MAX_BER64_TABLE "+str(len(len(byte_table)*byte_table[0]))) 102 | print("") 103 | print("static uint64_t ber64_table[]={") 104 | 105 | 106 | val = 0 107 | cnt = 0 108 | for j in range(0, len(byte_table[0])-1): 109 | for i in range(0, len(byte_table)): 110 | val = (val * 256) + (int(byte_table[i][j])) 111 | cnt = cnt +1 112 | 113 | if cnt == 8: 114 | print(val, end="ull, ") 115 | val = 0; 116 | cnt = 0 117 | print("};") 118 | 119 | 120 | def list_to_int(list): 121 | val = 0 122 | for i in range(0,len(list)): 123 | val = val*2 + list[i] 124 | return val 125 | 126 | 127 | 128 | if __name__ == '__main__': 129 | #Parameter 1: sigma 130 | #Parameter 2: tailcut 131 | #parameter 3: precision 132 | 133 | 134 | 135 | sigma = int(sys.argv[1]) 136 | tail = int(sys.argv[2]) 137 | precision = int(sys.argv[3]) 138 | 139 | print("//Usage: Sigma, tailcut, precision. Eg., 215 13 8") 140 | 141 | print("//Sigma: ",sigma ,"Tailcut: ",tail,"Precision: ",precision) 142 | print("#define MAX_GAUSS_VAL "+str(int(math.ceil(tail*sigma)))) 143 | print("#define MAX_GAUSS_LOG "+str(int(math.log(int(math.ceil(tail*sigma)),2)))) 144 | print("#define SIGMA "+str(sigma)) 145 | 146 | #Computation 147 | max_val = math.ceil(math.log(tail*tail*sigma*sigma,2)) 148 | getcontext().prec = math.ceil(precision/8.0)*8 +1 #For byte packing increase precision 149 | table = generate_table(max_val,sigma) 150 | #print(table) 151 | #print_table_int64(table) 152 | print_table_bytes(table) 153 | -------------------------------------------------------------------------------- /crypto_hash_sha256.c: -------------------------------------------------------------------------------- 1 | /* 2 | 20080913 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #define blocks crypto_hashblocks_sha256 8 | 9 | typedef unsigned int uint32; 10 | 11 | static uint32 load_bigendian(const unsigned char *x) 12 | { 13 | return 14 | (uint32) (x[3]) \ 15 | | (((uint32) (x[2])) << 8) \ 16 | | (((uint32) (x[1])) << 16) \ 17 | | (((uint32) (x[0])) << 24) 18 | ; 19 | } 20 | 21 | static void store_bigendian(unsigned char *x,uint32 u) 22 | { 23 | x[3] = u; u >>= 8; 24 | x[2] = u; u >>= 8; 25 | x[1] = u; u >>= 8; 26 | x[0] = u; 27 | } 28 | 29 | #define SHR(x,c) ((x) >> (c)) 30 | #define ROTR(x,c) (((x) >> (c)) | ((x) << (32 - (c)))) 31 | 32 | #define Ch(x,y,z) ((x & y) ^ (~x & z)) 33 | #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) 34 | #define Sigma0(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 35 | #define Sigma1(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 36 | #define sigma0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 37 | #define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 38 | 39 | #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; 40 | 41 | #define EXPAND \ 42 | M(w0 ,w14,w9 ,w1 ) \ 43 | M(w1 ,w15,w10,w2 ) \ 44 | M(w2 ,w0 ,w11,w3 ) \ 45 | M(w3 ,w1 ,w12,w4 ) \ 46 | M(w4 ,w2 ,w13,w5 ) \ 47 | M(w5 ,w3 ,w14,w6 ) \ 48 | M(w6 ,w4 ,w15,w7 ) \ 49 | M(w7 ,w5 ,w0 ,w8 ) \ 50 | M(w8 ,w6 ,w1 ,w9 ) \ 51 | M(w9 ,w7 ,w2 ,w10) \ 52 | M(w10,w8 ,w3 ,w11) \ 53 | M(w11,w9 ,w4 ,w12) \ 54 | M(w12,w10,w5 ,w13) \ 55 | M(w13,w11,w6 ,w14) \ 56 | M(w14,w12,w7 ,w15) \ 57 | M(w15,w13,w8 ,w0 ) 58 | 59 | #define F(w,k) \ 60 | T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ 61 | T2 = Sigma0(a) + Maj(a,b,c); \ 62 | h = g; \ 63 | g = f; \ 64 | f = e; \ 65 | e = d + T1; \ 66 | d = c; \ 67 | c = b; \ 68 | b = a; \ 69 | a = T1 + T2; 70 | 71 | static int crypto_hashblocks_sha256(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) 72 | { 73 | uint32 state[8]; 74 | uint32 a; 75 | uint32 b; 76 | uint32 c; 77 | uint32 d; 78 | uint32 e; 79 | uint32 f; 80 | uint32 g; 81 | uint32 h; 82 | uint32 T1; 83 | uint32 T2; 84 | 85 | a = load_bigendian(statebytes + 0); state[0] = a; 86 | b = load_bigendian(statebytes + 4); state[1] = b; 87 | c = load_bigendian(statebytes + 8); state[2] = c; 88 | d = load_bigendian(statebytes + 12); state[3] = d; 89 | e = load_bigendian(statebytes + 16); state[4] = e; 90 | f = load_bigendian(statebytes + 20); state[5] = f; 91 | g = load_bigendian(statebytes + 24); state[6] = g; 92 | h = load_bigendian(statebytes + 28); state[7] = h; 93 | 94 | while (inlen >= 64) { 95 | uint32 w0 = load_bigendian(in + 0); 96 | uint32 w1 = load_bigendian(in + 4); 97 | uint32 w2 = load_bigendian(in + 8); 98 | uint32 w3 = load_bigendian(in + 12); 99 | uint32 w4 = load_bigendian(in + 16); 100 | uint32 w5 = load_bigendian(in + 20); 101 | uint32 w6 = load_bigendian(in + 24); 102 | uint32 w7 = load_bigendian(in + 28); 103 | uint32 w8 = load_bigendian(in + 32); 104 | uint32 w9 = load_bigendian(in + 36); 105 | uint32 w10 = load_bigendian(in + 40); 106 | uint32 w11 = load_bigendian(in + 44); 107 | uint32 w12 = load_bigendian(in + 48); 108 | uint32 w13 = load_bigendian(in + 52); 109 | uint32 w14 = load_bigendian(in + 56); 110 | uint32 w15 = load_bigendian(in + 60); 111 | 112 | F(w0 ,0x428a2f98) 113 | F(w1 ,0x71374491) 114 | F(w2 ,0xb5c0fbcf) 115 | F(w3 ,0xe9b5dba5) 116 | F(w4 ,0x3956c25b) 117 | F(w5 ,0x59f111f1) 118 | F(w6 ,0x923f82a4) 119 | F(w7 ,0xab1c5ed5) 120 | F(w8 ,0xd807aa98) 121 | F(w9 ,0x12835b01) 122 | F(w10,0x243185be) 123 | F(w11,0x550c7dc3) 124 | F(w12,0x72be5d74) 125 | F(w13,0x80deb1fe) 126 | F(w14,0x9bdc06a7) 127 | F(w15,0xc19bf174) 128 | 129 | EXPAND 130 | 131 | F(w0 ,0xe49b69c1) 132 | F(w1 ,0xefbe4786) 133 | F(w2 ,0x0fc19dc6) 134 | F(w3 ,0x240ca1cc) 135 | F(w4 ,0x2de92c6f) 136 | F(w5 ,0x4a7484aa) 137 | F(w6 ,0x5cb0a9dc) 138 | F(w7 ,0x76f988da) 139 | F(w8 ,0x983e5152) 140 | F(w9 ,0xa831c66d) 141 | F(w10,0xb00327c8) 142 | F(w11,0xbf597fc7) 143 | F(w12,0xc6e00bf3) 144 | F(w13,0xd5a79147) 145 | F(w14,0x06ca6351) 146 | F(w15,0x14292967) 147 | 148 | EXPAND 149 | 150 | F(w0 ,0x27b70a85) 151 | F(w1 ,0x2e1b2138) 152 | F(w2 ,0x4d2c6dfc) 153 | F(w3 ,0x53380d13) 154 | F(w4 ,0x650a7354) 155 | F(w5 ,0x766a0abb) 156 | F(w6 ,0x81c2c92e) 157 | F(w7 ,0x92722c85) 158 | F(w8 ,0xa2bfe8a1) 159 | F(w9 ,0xa81a664b) 160 | F(w10,0xc24b8b70) 161 | F(w11,0xc76c51a3) 162 | F(w12,0xd192e819) 163 | F(w13,0xd6990624) 164 | F(w14,0xf40e3585) 165 | F(w15,0x106aa070) 166 | 167 | EXPAND 168 | 169 | F(w0 ,0x19a4c116) 170 | F(w1 ,0x1e376c08) 171 | F(w2 ,0x2748774c) 172 | F(w3 ,0x34b0bcb5) 173 | F(w4 ,0x391c0cb3) 174 | F(w5 ,0x4ed8aa4a) 175 | F(w6 ,0x5b9cca4f) 176 | F(w7 ,0x682e6ff3) 177 | F(w8 ,0x748f82ee) 178 | F(w9 ,0x78a5636f) 179 | F(w10,0x84c87814) 180 | F(w11,0x8cc70208) 181 | F(w12,0x90befffa) 182 | F(w13,0xa4506ceb) 183 | F(w14,0xbef9a3f7) 184 | F(w15,0xc67178f2) 185 | 186 | a += state[0]; 187 | b += state[1]; 188 | c += state[2]; 189 | d += state[3]; 190 | e += state[4]; 191 | f += state[5]; 192 | g += state[6]; 193 | h += state[7]; 194 | 195 | state[0] = a; 196 | state[1] = b; 197 | state[2] = c; 198 | state[3] = d; 199 | state[4] = e; 200 | state[5] = f; 201 | state[6] = g; 202 | state[7] = h; 203 | 204 | in += 64; 205 | inlen -= 64; 206 | } 207 | 208 | store_bigendian(statebytes + 0,state[0]); 209 | store_bigendian(statebytes + 4,state[1]); 210 | store_bigendian(statebytes + 8,state[2]); 211 | store_bigendian(statebytes + 12,state[3]); 212 | store_bigendian(statebytes + 16,state[4]); 213 | store_bigendian(statebytes + 20,state[5]); 214 | store_bigendian(statebytes + 24,state[6]); 215 | store_bigendian(statebytes + 28,state[7]); 216 | 217 | return inlen; 218 | } 219 | 220 | static const char iv[32] = { 221 | 0x6a,0x09,0xe6,0x67, 222 | 0xbb,0x67,0xae,0x85, 223 | 0x3c,0x6e,0xf3,0x72, 224 | 0xa5,0x4f,0xf5,0x3a, 225 | 0x51,0x0e,0x52,0x7f, 226 | 0x9b,0x05,0x68,0x8c, 227 | 0x1f,0x83,0xd9,0xab, 228 | 0x5b,0xe0,0xcd,0x19, 229 | } ; 230 | 231 | int crypto_hash_sha256(unsigned char *out,const unsigned char *in,unsigned long long inlen) 232 | { 233 | unsigned char h[32]; 234 | unsigned char padded[128]; 235 | unsigned long long i; 236 | unsigned long long bits = inlen << 3; 237 | 238 | for (i = 0;i < 32;++i) h[i] = iv[i]; 239 | 240 | blocks(h,in,inlen); 241 | in += inlen; 242 | inlen &= 63; 243 | in -= inlen; 244 | 245 | for (i = 0;i < inlen;++i) padded[i] = in[i]; 246 | padded[inlen] = 0x80; 247 | 248 | if (inlen < 56) { 249 | for (i = inlen + 1;i < 56;++i) padded[i] = 0; 250 | padded[56] = bits >> 56; 251 | padded[57] = bits >> 48; 252 | padded[58] = bits >> 40; 253 | padded[59] = bits >> 32; 254 | padded[60] = bits >> 24; 255 | padded[61] = bits >> 16; 256 | padded[62] = bits >> 8; 257 | padded[63] = bits; 258 | blocks(h,padded,64); 259 | } else { 260 | for (i = inlen + 1;i < 120;++i) padded[i] = 0; 261 | padded[120] = bits >> 56; 262 | padded[121] = bits >> 48; 263 | padded[122] = bits >> 40; 264 | padded[123] = bits >> 32; 265 | padded[124] = bits >> 24; 266 | padded[125] = bits >> 16; 267 | padded[126] = bits >> 8; 268 | padded[127] = bits; 269 | blocks(h,padded,128); 270 | } 271 | 272 | for (i = 0;i < 32;++i) out[i] = h[i]; 273 | 274 | return 0; 275 | } 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /sign.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "crypto_int32.h" 7 | #include "crypto_sign.h" 8 | 9 | #include "oracle.h" 10 | #include "params.h" 11 | #include "ntt.h" 12 | #include "sample.h" 13 | #include "gauss/rnd/random.h" 14 | 15 | #include "cpucycles.h" 16 | 17 | unsigned long long rejwctr; 18 | unsigned long long rejyzctr; 19 | 20 | extern poly poly_a1; 21 | extern poly poly_a2; 22 | 23 | 24 | static void compress_sk(unsigned char *sk, poly poly_S, poly poly_E1, poly poly_E2) 25 | { 26 | int i; 27 | double *isk = (double *)sk; 28 | 29 | for(i=0; i>(8*(k))) & 0xff); 75 | } 76 | } 77 | 78 | 79 | static void decompress_sig(unsigned char *c, double vec_z[PARAM_N], const unsigned char *sm) 80 | { 81 | int i,k; 82 | int ptr =0; 83 | int32_t t; 84 | 85 | //store the hash value 86 | for (i=0; i<32; i++){ 87 | c[i] =sm[ptr++]; 88 | } 89 | 90 | //compress the signature vector z 91 | for(i=0; i>8); 97 | } 98 | } 99 | 100 | 101 | static int test_rejection(poly poly_z) 102 | { 103 | int i; 104 | for(i=0; i (PARAM_B-PARAM_U)){ 106 | return 1; 107 | } 108 | } 109 | return 0; 110 | } 111 | 112 | 113 | static int test_z(poly vec_z) 114 | { 115 | int i; 116 | int64_t val; 117 | 118 | for(i=0; i PARAM_Q/2){ 123 | val = val - PARAM_Q; 124 | } 125 | 126 | if (val < -PARAM_Q/2){ 127 | val = val + PARAM_Q; 128 | } 129 | 130 | if (abs(val) > (PARAM_B-PARAM_U)){ 131 | return -1; 132 | } 133 | } 134 | return 0; 135 | } 136 | 137 | 138 | static int test_w(poly poly_w) 139 | { 140 | int i; 141 | int64_t left, right, val; 142 | 143 | for(i=0; i right) 161 | { 162 | return -1; 163 | } 164 | } 165 | return 0; 166 | } 167 | 168 | //check the generated parameter 169 | static int check_E(poly poly_w) 170 | { 171 | int i,j,l; 172 | int bound = PARAM_KEYGEN_BOUND; 173 | int pos; 174 | 175 | int64_t vals[PARAM_N]; 176 | double max; 177 | double threshold =0; 178 | 179 | for(j=0; j max){ 189 | max = vals[l]; 190 | pos = l; 191 | } 192 | } 193 | vals[pos] = 0; 194 | threshold += max; 195 | } 196 | 197 | if (threshold > bound) 198 | return -1; 199 | 200 | 201 | return 0; 202 | } 203 | 204 | 205 | int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) 206 | { 207 | poly poly_S, poly_E1, poly_T1, poly_T2, poly_E2; 208 | 209 | 210 | unsigned long long ctr = 0; 211 | do 212 | { 213 | ctr++; 214 | sample_gauss_poly(poly_E2); 215 | } 216 | while(check_E(poly_E2) != 0); 217 | ctr=0; 218 | do 219 | { 220 | ctr++; 221 | sample_gauss_poly(poly_E1); 222 | } 223 | while(check_E(poly_E1) != 0); 224 | 225 | //Sample S 226 | sample_gauss_poly(poly_S); 227 | 228 | //Compute the public key T = AS+E 229 | poly_mul_fixed(poly_T1,poly_S,poly_a1); 230 | poly_add(poly_T1,poly_T1,poly_E1); 231 | poly_mul_fixed(poly_T2,poly_S,poly_a2); 232 | poly_add(poly_T2,poly_T2,poly_E2); 233 | 234 | //Compress everything for usage with supercop API 235 | compress_pk(pk, poly_T1, poly_T2); 236 | compress_sk(sk, poly_S, poly_E1, poly_E2); 237 | 238 | 239 | return 0; 240 | } 241 | 242 | //sparse polynomial multiplication 243 | static void computeEc(poly Ec, const unsigned char *sk, const uint32_t pos_list[PARAM_W]) 244 | { 245 | int i,j; 246 | int pos; 247 | double * e; 248 | e = (double*)sk; 249 | 250 | for(i=0;i>= 8; 30 | x[6] = u; u >>= 8; 31 | x[5] = u; u >>= 8; 32 | x[4] = u; u >>= 8; 33 | x[3] = u; u >>= 8; 34 | x[2] = u; u >>= 8; 35 | x[1] = u; u >>= 8; 36 | x[0] = u; 37 | } 38 | 39 | #define SHR(x,c) ((x) >> (c)) 40 | #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) 41 | 42 | #define Ch(x,y,z) ((x & y) ^ (~x & z)) 43 | #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) 44 | #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 45 | #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 46 | #define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) 47 | #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) 48 | 49 | #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; 50 | 51 | #define EXPAND \ 52 | M(w0 ,w14,w9 ,w1 ) \ 53 | M(w1 ,w15,w10,w2 ) \ 54 | M(w2 ,w0 ,w11,w3 ) \ 55 | M(w3 ,w1 ,w12,w4 ) \ 56 | M(w4 ,w2 ,w13,w5 ) \ 57 | M(w5 ,w3 ,w14,w6 ) \ 58 | M(w6 ,w4 ,w15,w7 ) \ 59 | M(w7 ,w5 ,w0 ,w8 ) \ 60 | M(w8 ,w6 ,w1 ,w9 ) \ 61 | M(w9 ,w7 ,w2 ,w10) \ 62 | M(w10,w8 ,w3 ,w11) \ 63 | M(w11,w9 ,w4 ,w12) \ 64 | M(w12,w10,w5 ,w13) \ 65 | M(w13,w11,w6 ,w14) \ 66 | M(w14,w12,w7 ,w15) \ 67 | M(w15,w13,w8 ,w0 ) 68 | 69 | #define F(w,k) \ 70 | T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ 71 | T2 = Sigma0(a) + Maj(a,b,c); \ 72 | h = g; \ 73 | g = f; \ 74 | f = e; \ 75 | e = d + T1; \ 76 | d = c; \ 77 | c = b; \ 78 | b = a; \ 79 | a = T1 + T2; 80 | 81 | int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) 82 | { 83 | uint64 state[8]; 84 | uint64 a; 85 | uint64 b; 86 | uint64 c; 87 | uint64 d; 88 | uint64 e; 89 | uint64 f; 90 | uint64 g; 91 | uint64 h; 92 | uint64 T1; 93 | uint64 T2; 94 | 95 | a = load_bigendian(statebytes + 0); state[0] = a; 96 | b = load_bigendian(statebytes + 8); state[1] = b; 97 | c = load_bigendian(statebytes + 16); state[2] = c; 98 | d = load_bigendian(statebytes + 24); state[3] = d; 99 | e = load_bigendian(statebytes + 32); state[4] = e; 100 | f = load_bigendian(statebytes + 40); state[5] = f; 101 | g = load_bigendian(statebytes + 48); state[6] = g; 102 | h = load_bigendian(statebytes + 56); state[7] = h; 103 | 104 | while (inlen >= 128) { 105 | uint64 w0 = load_bigendian(in + 0); 106 | uint64 w1 = load_bigendian(in + 8); 107 | uint64 w2 = load_bigendian(in + 16); 108 | uint64 w3 = load_bigendian(in + 24); 109 | uint64 w4 = load_bigendian(in + 32); 110 | uint64 w5 = load_bigendian(in + 40); 111 | uint64 w6 = load_bigendian(in + 48); 112 | uint64 w7 = load_bigendian(in + 56); 113 | uint64 w8 = load_bigendian(in + 64); 114 | uint64 w9 = load_bigendian(in + 72); 115 | uint64 w10 = load_bigendian(in + 80); 116 | uint64 w11 = load_bigendian(in + 88); 117 | uint64 w12 = load_bigendian(in + 96); 118 | uint64 w13 = load_bigendian(in + 104); 119 | uint64 w14 = load_bigendian(in + 112); 120 | uint64 w15 = load_bigendian(in + 120); 121 | 122 | F(w0 ,0x428a2f98d728ae22ULL) 123 | F(w1 ,0x7137449123ef65cdULL) 124 | F(w2 ,0xb5c0fbcfec4d3b2fULL) 125 | F(w3 ,0xe9b5dba58189dbbcULL) 126 | F(w4 ,0x3956c25bf348b538ULL) 127 | F(w5 ,0x59f111f1b605d019ULL) 128 | F(w6 ,0x923f82a4af194f9bULL) 129 | F(w7 ,0xab1c5ed5da6d8118ULL) 130 | F(w8 ,0xd807aa98a3030242ULL) 131 | F(w9 ,0x12835b0145706fbeULL) 132 | F(w10,0x243185be4ee4b28cULL) 133 | F(w11,0x550c7dc3d5ffb4e2ULL) 134 | F(w12,0x72be5d74f27b896fULL) 135 | F(w13,0x80deb1fe3b1696b1ULL) 136 | F(w14,0x9bdc06a725c71235ULL) 137 | F(w15,0xc19bf174cf692694ULL) 138 | 139 | EXPAND 140 | 141 | F(w0 ,0xe49b69c19ef14ad2ULL) 142 | F(w1 ,0xefbe4786384f25e3ULL) 143 | F(w2 ,0x0fc19dc68b8cd5b5ULL) 144 | F(w3 ,0x240ca1cc77ac9c65ULL) 145 | F(w4 ,0x2de92c6f592b0275ULL) 146 | F(w5 ,0x4a7484aa6ea6e483ULL) 147 | F(w6 ,0x5cb0a9dcbd41fbd4ULL) 148 | F(w7 ,0x76f988da831153b5ULL) 149 | F(w8 ,0x983e5152ee66dfabULL) 150 | F(w9 ,0xa831c66d2db43210ULL) 151 | F(w10,0xb00327c898fb213fULL) 152 | F(w11,0xbf597fc7beef0ee4ULL) 153 | F(w12,0xc6e00bf33da88fc2ULL) 154 | F(w13,0xd5a79147930aa725ULL) 155 | F(w14,0x06ca6351e003826fULL) 156 | F(w15,0x142929670a0e6e70ULL) 157 | 158 | EXPAND 159 | 160 | F(w0 ,0x27b70a8546d22ffcULL) 161 | F(w1 ,0x2e1b21385c26c926ULL) 162 | F(w2 ,0x4d2c6dfc5ac42aedULL) 163 | F(w3 ,0x53380d139d95b3dfULL) 164 | F(w4 ,0x650a73548baf63deULL) 165 | F(w5 ,0x766a0abb3c77b2a8ULL) 166 | F(w6 ,0x81c2c92e47edaee6ULL) 167 | F(w7 ,0x92722c851482353bULL) 168 | F(w8 ,0xa2bfe8a14cf10364ULL) 169 | F(w9 ,0xa81a664bbc423001ULL) 170 | F(w10,0xc24b8b70d0f89791ULL) 171 | F(w11,0xc76c51a30654be30ULL) 172 | F(w12,0xd192e819d6ef5218ULL) 173 | F(w13,0xd69906245565a910ULL) 174 | F(w14,0xf40e35855771202aULL) 175 | F(w15,0x106aa07032bbd1b8ULL) 176 | 177 | EXPAND 178 | 179 | F(w0 ,0x19a4c116b8d2d0c8ULL) 180 | F(w1 ,0x1e376c085141ab53ULL) 181 | F(w2 ,0x2748774cdf8eeb99ULL) 182 | F(w3 ,0x34b0bcb5e19b48a8ULL) 183 | F(w4 ,0x391c0cb3c5c95a63ULL) 184 | F(w5 ,0x4ed8aa4ae3418acbULL) 185 | F(w6 ,0x5b9cca4f7763e373ULL) 186 | F(w7 ,0x682e6ff3d6b2b8a3ULL) 187 | F(w8 ,0x748f82ee5defb2fcULL) 188 | F(w9 ,0x78a5636f43172f60ULL) 189 | F(w10,0x84c87814a1f0ab72ULL) 190 | F(w11,0x8cc702081a6439ecULL) 191 | F(w12,0x90befffa23631e28ULL) 192 | F(w13,0xa4506cebde82bde9ULL) 193 | F(w14,0xbef9a3f7b2c67915ULL) 194 | F(w15,0xc67178f2e372532bULL) 195 | 196 | EXPAND 197 | 198 | F(w0 ,0xca273eceea26619cULL) 199 | F(w1 ,0xd186b8c721c0c207ULL) 200 | F(w2 ,0xeada7dd6cde0eb1eULL) 201 | F(w3 ,0xf57d4f7fee6ed178ULL) 202 | F(w4 ,0x06f067aa72176fbaULL) 203 | F(w5 ,0x0a637dc5a2c898a6ULL) 204 | F(w6 ,0x113f9804bef90daeULL) 205 | F(w7 ,0x1b710b35131c471bULL) 206 | F(w8 ,0x28db77f523047d84ULL) 207 | F(w9 ,0x32caab7b40c72493ULL) 208 | F(w10,0x3c9ebe0a15c9bebcULL) 209 | F(w11,0x431d67c49c100d4cULL) 210 | F(w12,0x4cc5d4becb3e42b6ULL) 211 | F(w13,0x597f299cfc657e2aULL) 212 | F(w14,0x5fcb6fab3ad6faecULL) 213 | F(w15,0x6c44198c4a475817ULL) 214 | 215 | a += state[0]; 216 | b += state[1]; 217 | c += state[2]; 218 | d += state[3]; 219 | e += state[4]; 220 | f += state[5]; 221 | g += state[6]; 222 | h += state[7]; 223 | 224 | state[0] = a; 225 | state[1] = b; 226 | state[2] = c; 227 | state[3] = d; 228 | state[4] = e; 229 | state[5] = f; 230 | state[6] = g; 231 | state[7] = h; 232 | 233 | in += 128; 234 | inlen -= 128; 235 | } 236 | 237 | store_bigendian(statebytes + 0,state[0]); 238 | store_bigendian(statebytes + 8,state[1]); 239 | store_bigendian(statebytes + 16,state[2]); 240 | store_bigendian(statebytes + 24,state[3]); 241 | store_bigendian(statebytes + 32,state[4]); 242 | store_bigendian(statebytes + 40,state[5]); 243 | store_bigendian(statebytes + 48,state[6]); 244 | store_bigendian(statebytes + 56,state[7]); 245 | 246 | return 0; 247 | } 248 | 249 | /* END content of blocks.c */ 250 | 251 | #define blocks crypto_hashblocks_sha512 252 | 253 | static const unsigned char iv[64] = { 254 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 255 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 256 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 257 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 258 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 259 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 260 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 261 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 262 | } ; 263 | 264 | 265 | int crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen) 266 | { 267 | unsigned char h[64]; 268 | unsigned char padded[256]; 269 | unsigned long long i; 270 | unsigned long long bytes = inlen; 271 | 272 | for (i = 0;i < 64;++i) h[i] = iv[i]; 273 | 274 | blocks(h,in,inlen); 275 | in += inlen; 276 | inlen &= 127; 277 | in -= inlen; 278 | 279 | for (i = 0;i < inlen;++i) padded[i] = in[i]; 280 | padded[inlen] = 0x80; 281 | 282 | if (inlen < 112) { 283 | for (i = inlen + 1;i < 119;++i) padded[i] = 0; 284 | padded[119] = bytes >> 61; 285 | padded[120] = bytes >> 53; 286 | padded[121] = bytes >> 45; 287 | padded[122] = bytes >> 37; 288 | padded[123] = bytes >> 29; 289 | padded[124] = bytes >> 21; 290 | padded[125] = bytes >> 13; 291 | padded[126] = bytes >> 5; 292 | padded[127] = bytes << 3; 293 | blocks(h,padded,128); 294 | } else { 295 | for (i = inlen + 1;i < 247;++i) padded[i] = 0; 296 | padded[247] = bytes >> 61; 297 | padded[248] = bytes >> 53; 298 | padded[249] = bytes >> 45; 299 | padded[250] = bytes >> 37; 300 | padded[251] = bytes >> 29; 301 | padded[252] = bytes >> 21; 302 | padded[253] = bytes >> 13; 303 | padded[254] = bytes >> 5; 304 | padded[255] = bytes << 3; 305 | blocks(h,padded,256); 306 | } 307 | 308 | for (i = 0;i < 64;++i) out[i] = h[i]; 309 | 310 | return 0; 311 | } 312 | -------------------------------------------------------------------------------- /bitrev.code: -------------------------------------------------------------------------------- 1 | t = r[1]; 2 | r[1] = r[256]; 3 | r[256] = t; 4 | t = r[2]; 5 | r[2] = r[128]; 6 | r[128] = t; 7 | t = r[3]; 8 | r[3] = r[384]; 9 | r[384] = t; 10 | t = r[4]; 11 | r[4] = r[64]; 12 | r[64] = t; 13 | t = r[5]; 14 | r[5] = r[320]; 15 | r[320] = t; 16 | t = r[6]; 17 | r[6] = r[192]; 18 | r[192] = t; 19 | t = r[7]; 20 | r[7] = r[448]; 21 | r[448] = t; 22 | t = r[8]; 23 | r[8] = r[32]; 24 | r[32] = t; 25 | t = r[9]; 26 | r[9] = r[288]; 27 | r[288] = t; 28 | t = r[10]; 29 | r[10] = r[160]; 30 | r[160] = t; 31 | t = r[11]; 32 | r[11] = r[416]; 33 | r[416] = t; 34 | t = r[12]; 35 | r[12] = r[96]; 36 | r[96] = t; 37 | t = r[13]; 38 | r[13] = r[352]; 39 | r[352] = t; 40 | t = r[14]; 41 | r[14] = r[224]; 42 | r[224] = t; 43 | t = r[15]; 44 | r[15] = r[480]; 45 | r[480] = t; 46 | t = r[17]; 47 | r[17] = r[272]; 48 | r[272] = t; 49 | t = r[18]; 50 | r[18] = r[144]; 51 | r[144] = t; 52 | t = r[19]; 53 | r[19] = r[400]; 54 | r[400] = t; 55 | t = r[20]; 56 | r[20] = r[80]; 57 | r[80] = t; 58 | t = r[21]; 59 | r[21] = r[336]; 60 | r[336] = t; 61 | t = r[22]; 62 | r[22] = r[208]; 63 | r[208] = t; 64 | t = r[23]; 65 | r[23] = r[464]; 66 | r[464] = t; 67 | t = r[24]; 68 | r[24] = r[48]; 69 | r[48] = t; 70 | t = r[25]; 71 | r[25] = r[304]; 72 | r[304] = t; 73 | t = r[26]; 74 | r[26] = r[176]; 75 | r[176] = t; 76 | t = r[27]; 77 | r[27] = r[432]; 78 | r[432] = t; 79 | t = r[28]; 80 | r[28] = r[112]; 81 | r[112] = t; 82 | t = r[29]; 83 | r[29] = r[368]; 84 | r[368] = t; 85 | t = r[30]; 86 | r[30] = r[240]; 87 | r[240] = t; 88 | t = r[31]; 89 | r[31] = r[496]; 90 | r[496] = t; 91 | t = r[33]; 92 | r[33] = r[264]; 93 | r[264] = t; 94 | t = r[34]; 95 | r[34] = r[136]; 96 | r[136] = t; 97 | t = r[35]; 98 | r[35] = r[392]; 99 | r[392] = t; 100 | t = r[36]; 101 | r[36] = r[72]; 102 | r[72] = t; 103 | t = r[37]; 104 | r[37] = r[328]; 105 | r[328] = t; 106 | t = r[38]; 107 | r[38] = r[200]; 108 | r[200] = t; 109 | t = r[39]; 110 | r[39] = r[456]; 111 | r[456] = t; 112 | t = r[41]; 113 | r[41] = r[296]; 114 | r[296] = t; 115 | t = r[42]; 116 | r[42] = r[168]; 117 | r[168] = t; 118 | t = r[43]; 119 | r[43] = r[424]; 120 | r[424] = t; 121 | t = r[44]; 122 | r[44] = r[104]; 123 | r[104] = t; 124 | t = r[45]; 125 | r[45] = r[360]; 126 | r[360] = t; 127 | t = r[46]; 128 | r[46] = r[232]; 129 | r[232] = t; 130 | t = r[47]; 131 | r[47] = r[488]; 132 | r[488] = t; 133 | t = r[49]; 134 | r[49] = r[280]; 135 | r[280] = t; 136 | t = r[50]; 137 | r[50] = r[152]; 138 | r[152] = t; 139 | t = r[51]; 140 | r[51] = r[408]; 141 | r[408] = t; 142 | t = r[52]; 143 | r[52] = r[88]; 144 | r[88] = t; 145 | t = r[53]; 146 | r[53] = r[344]; 147 | r[344] = t; 148 | t = r[54]; 149 | r[54] = r[216]; 150 | r[216] = t; 151 | t = r[55]; 152 | r[55] = r[472]; 153 | r[472] = t; 154 | t = r[57]; 155 | r[57] = r[312]; 156 | r[312] = t; 157 | t = r[58]; 158 | r[58] = r[184]; 159 | r[184] = t; 160 | t = r[59]; 161 | r[59] = r[440]; 162 | r[440] = t; 163 | t = r[60]; 164 | r[60] = r[120]; 165 | r[120] = t; 166 | t = r[61]; 167 | r[61] = r[376]; 168 | r[376] = t; 169 | t = r[62]; 170 | r[62] = r[248]; 171 | r[248] = t; 172 | t = r[63]; 173 | r[63] = r[504]; 174 | r[504] = t; 175 | t = r[65]; 176 | r[65] = r[260]; 177 | r[260] = t; 178 | t = r[66]; 179 | r[66] = r[132]; 180 | r[132] = t; 181 | t = r[67]; 182 | r[67] = r[388]; 183 | r[388] = t; 184 | t = r[69]; 185 | r[69] = r[324]; 186 | r[324] = t; 187 | t = r[70]; 188 | r[70] = r[196]; 189 | r[196] = t; 190 | t = r[71]; 191 | r[71] = r[452]; 192 | r[452] = t; 193 | t = r[73]; 194 | r[73] = r[292]; 195 | r[292] = t; 196 | t = r[74]; 197 | r[74] = r[164]; 198 | r[164] = t; 199 | t = r[75]; 200 | r[75] = r[420]; 201 | r[420] = t; 202 | t = r[76]; 203 | r[76] = r[100]; 204 | r[100] = t; 205 | t = r[77]; 206 | r[77] = r[356]; 207 | r[356] = t; 208 | t = r[78]; 209 | r[78] = r[228]; 210 | r[228] = t; 211 | t = r[79]; 212 | r[79] = r[484]; 213 | r[484] = t; 214 | t = r[81]; 215 | r[81] = r[276]; 216 | r[276] = t; 217 | t = r[82]; 218 | r[82] = r[148]; 219 | r[148] = t; 220 | t = r[83]; 221 | r[83] = r[404]; 222 | r[404] = t; 223 | t = r[85]; 224 | r[85] = r[340]; 225 | r[340] = t; 226 | t = r[86]; 227 | r[86] = r[212]; 228 | r[212] = t; 229 | t = r[87]; 230 | r[87] = r[468]; 231 | r[468] = t; 232 | t = r[89]; 233 | r[89] = r[308]; 234 | r[308] = t; 235 | t = r[90]; 236 | r[90] = r[180]; 237 | r[180] = t; 238 | t = r[91]; 239 | r[91] = r[436]; 240 | r[436] = t; 241 | t = r[92]; 242 | r[92] = r[116]; 243 | r[116] = t; 244 | t = r[93]; 245 | r[93] = r[372]; 246 | r[372] = t; 247 | t = r[94]; 248 | r[94] = r[244]; 249 | r[244] = t; 250 | t = r[95]; 251 | r[95] = r[500]; 252 | r[500] = t; 253 | t = r[97]; 254 | r[97] = r[268]; 255 | r[268] = t; 256 | t = r[98]; 257 | r[98] = r[140]; 258 | r[140] = t; 259 | t = r[99]; 260 | r[99] = r[396]; 261 | r[396] = t; 262 | t = r[101]; 263 | r[101] = r[332]; 264 | r[332] = t; 265 | t = r[102]; 266 | r[102] = r[204]; 267 | r[204] = t; 268 | t = r[103]; 269 | r[103] = r[460]; 270 | r[460] = t; 271 | t = r[105]; 272 | r[105] = r[300]; 273 | r[300] = t; 274 | t = r[106]; 275 | r[106] = r[172]; 276 | r[172] = t; 277 | t = r[107]; 278 | r[107] = r[428]; 279 | r[428] = t; 280 | t = r[109]; 281 | r[109] = r[364]; 282 | r[364] = t; 283 | t = r[110]; 284 | r[110] = r[236]; 285 | r[236] = t; 286 | t = r[111]; 287 | r[111] = r[492]; 288 | r[492] = t; 289 | t = r[113]; 290 | r[113] = r[284]; 291 | r[284] = t; 292 | t = r[114]; 293 | r[114] = r[156]; 294 | r[156] = t; 295 | t = r[115]; 296 | r[115] = r[412]; 297 | r[412] = t; 298 | t = r[117]; 299 | r[117] = r[348]; 300 | r[348] = t; 301 | t = r[118]; 302 | r[118] = r[220]; 303 | r[220] = t; 304 | t = r[119]; 305 | r[119] = r[476]; 306 | r[476] = t; 307 | t = r[121]; 308 | r[121] = r[316]; 309 | r[316] = t; 310 | t = r[122]; 311 | r[122] = r[188]; 312 | r[188] = t; 313 | t = r[123]; 314 | r[123] = r[444]; 315 | r[444] = t; 316 | t = r[125]; 317 | r[125] = r[380]; 318 | r[380] = t; 319 | t = r[126]; 320 | r[126] = r[252]; 321 | r[252] = t; 322 | t = r[127]; 323 | r[127] = r[508]; 324 | r[508] = t; 325 | t = r[129]; 326 | r[129] = r[258]; 327 | r[258] = t; 328 | t = r[131]; 329 | r[131] = r[386]; 330 | r[386] = t; 331 | t = r[133]; 332 | r[133] = r[322]; 333 | r[322] = t; 334 | t = r[134]; 335 | r[134] = r[194]; 336 | r[194] = t; 337 | t = r[135]; 338 | r[135] = r[450]; 339 | r[450] = t; 340 | t = r[137]; 341 | r[137] = r[290]; 342 | r[290] = t; 343 | t = r[138]; 344 | r[138] = r[162]; 345 | r[162] = t; 346 | t = r[139]; 347 | r[139] = r[418]; 348 | r[418] = t; 349 | t = r[141]; 350 | r[141] = r[354]; 351 | r[354] = t; 352 | t = r[142]; 353 | r[142] = r[226]; 354 | r[226] = t; 355 | t = r[143]; 356 | r[143] = r[482]; 357 | r[482] = t; 358 | t = r[145]; 359 | r[145] = r[274]; 360 | r[274] = t; 361 | t = r[147]; 362 | r[147] = r[402]; 363 | r[402] = t; 364 | t = r[149]; 365 | r[149] = r[338]; 366 | r[338] = t; 367 | t = r[150]; 368 | r[150] = r[210]; 369 | r[210] = t; 370 | t = r[151]; 371 | r[151] = r[466]; 372 | r[466] = t; 373 | t = r[153]; 374 | r[153] = r[306]; 375 | r[306] = t; 376 | t = r[154]; 377 | r[154] = r[178]; 378 | r[178] = t; 379 | t = r[155]; 380 | r[155] = r[434]; 381 | r[434] = t; 382 | t = r[157]; 383 | r[157] = r[370]; 384 | r[370] = t; 385 | t = r[158]; 386 | r[158] = r[242]; 387 | r[242] = t; 388 | t = r[159]; 389 | r[159] = r[498]; 390 | r[498] = t; 391 | t = r[161]; 392 | r[161] = r[266]; 393 | r[266] = t; 394 | t = r[163]; 395 | r[163] = r[394]; 396 | r[394] = t; 397 | t = r[165]; 398 | r[165] = r[330]; 399 | r[330] = t; 400 | t = r[166]; 401 | r[166] = r[202]; 402 | r[202] = t; 403 | t = r[167]; 404 | r[167] = r[458]; 405 | r[458] = t; 406 | t = r[169]; 407 | r[169] = r[298]; 408 | r[298] = t; 409 | t = r[171]; 410 | r[171] = r[426]; 411 | r[426] = t; 412 | t = r[173]; 413 | r[173] = r[362]; 414 | r[362] = t; 415 | t = r[174]; 416 | r[174] = r[234]; 417 | r[234] = t; 418 | t = r[175]; 419 | r[175] = r[490]; 420 | r[490] = t; 421 | t = r[177]; 422 | r[177] = r[282]; 423 | r[282] = t; 424 | t = r[179]; 425 | r[179] = r[410]; 426 | r[410] = t; 427 | t = r[181]; 428 | r[181] = r[346]; 429 | r[346] = t; 430 | t = r[182]; 431 | r[182] = r[218]; 432 | r[218] = t; 433 | t = r[183]; 434 | r[183] = r[474]; 435 | r[474] = t; 436 | t = r[185]; 437 | r[185] = r[314]; 438 | r[314] = t; 439 | t = r[187]; 440 | r[187] = r[442]; 441 | r[442] = t; 442 | t = r[189]; 443 | r[189] = r[378]; 444 | r[378] = t; 445 | t = r[190]; 446 | r[190] = r[250]; 447 | r[250] = t; 448 | t = r[191]; 449 | r[191] = r[506]; 450 | r[506] = t; 451 | t = r[193]; 452 | r[193] = r[262]; 453 | r[262] = t; 454 | t = r[195]; 455 | r[195] = r[390]; 456 | r[390] = t; 457 | t = r[197]; 458 | r[197] = r[326]; 459 | r[326] = t; 460 | t = r[199]; 461 | r[199] = r[454]; 462 | r[454] = t; 463 | t = r[201]; 464 | r[201] = r[294]; 465 | r[294] = t; 466 | t = r[203]; 467 | r[203] = r[422]; 468 | r[422] = t; 469 | t = r[205]; 470 | r[205] = r[358]; 471 | r[358] = t; 472 | t = r[206]; 473 | r[206] = r[230]; 474 | r[230] = t; 475 | t = r[207]; 476 | r[207] = r[486]; 477 | r[486] = t; 478 | t = r[209]; 479 | r[209] = r[278]; 480 | r[278] = t; 481 | t = r[211]; 482 | r[211] = r[406]; 483 | r[406] = t; 484 | t = r[213]; 485 | r[213] = r[342]; 486 | r[342] = t; 487 | t = r[215]; 488 | r[215] = r[470]; 489 | r[470] = t; 490 | t = r[217]; 491 | r[217] = r[310]; 492 | r[310] = t; 493 | t = r[219]; 494 | r[219] = r[438]; 495 | r[438] = t; 496 | t = r[221]; 497 | r[221] = r[374]; 498 | r[374] = t; 499 | t = r[222]; 500 | r[222] = r[246]; 501 | r[246] = t; 502 | t = r[223]; 503 | r[223] = r[502]; 504 | r[502] = t; 505 | t = r[225]; 506 | r[225] = r[270]; 507 | r[270] = t; 508 | t = r[227]; 509 | r[227] = r[398]; 510 | r[398] = t; 511 | t = r[229]; 512 | r[229] = r[334]; 513 | r[334] = t; 514 | t = r[231]; 515 | r[231] = r[462]; 516 | r[462] = t; 517 | t = r[233]; 518 | r[233] = r[302]; 519 | r[302] = t; 520 | t = r[235]; 521 | r[235] = r[430]; 522 | r[430] = t; 523 | t = r[237]; 524 | r[237] = r[366]; 525 | r[366] = t; 526 | t = r[239]; 527 | r[239] = r[494]; 528 | r[494] = t; 529 | t = r[241]; 530 | r[241] = r[286]; 531 | r[286] = t; 532 | t = r[243]; 533 | r[243] = r[414]; 534 | r[414] = t; 535 | t = r[245]; 536 | r[245] = r[350]; 537 | r[350] = t; 538 | t = r[247]; 539 | r[247] = r[478]; 540 | r[478] = t; 541 | t = r[249]; 542 | r[249] = r[318]; 543 | r[318] = t; 544 | t = r[251]; 545 | r[251] = r[446]; 546 | r[446] = t; 547 | t = r[253]; 548 | r[253] = r[382]; 549 | r[382] = t; 550 | t = r[255]; 551 | r[255] = r[510]; 552 | r[510] = t; 553 | t = r[259]; 554 | r[259] = r[385]; 555 | r[385] = t; 556 | t = r[261]; 557 | r[261] = r[321]; 558 | r[321] = t; 559 | t = r[263]; 560 | r[263] = r[449]; 561 | r[449] = t; 562 | t = r[265]; 563 | r[265] = r[289]; 564 | r[289] = t; 565 | t = r[267]; 566 | r[267] = r[417]; 567 | r[417] = t; 568 | t = r[269]; 569 | r[269] = r[353]; 570 | r[353] = t; 571 | t = r[271]; 572 | r[271] = r[481]; 573 | r[481] = t; 574 | t = r[275]; 575 | r[275] = r[401]; 576 | r[401] = t; 577 | t = r[277]; 578 | r[277] = r[337]; 579 | r[337] = t; 580 | t = r[279]; 581 | r[279] = r[465]; 582 | r[465] = t; 583 | t = r[281]; 584 | r[281] = r[305]; 585 | r[305] = t; 586 | t = r[283]; 587 | r[283] = r[433]; 588 | r[433] = t; 589 | t = r[285]; 590 | r[285] = r[369]; 591 | r[369] = t; 592 | t = r[287]; 593 | r[287] = r[497]; 594 | r[497] = t; 595 | t = r[291]; 596 | r[291] = r[393]; 597 | r[393] = t; 598 | t = r[293]; 599 | r[293] = r[329]; 600 | r[329] = t; 601 | t = r[295]; 602 | r[295] = r[457]; 603 | r[457] = t; 604 | t = r[299]; 605 | r[299] = r[425]; 606 | r[425] = t; 607 | t = r[301]; 608 | r[301] = r[361]; 609 | r[361] = t; 610 | t = r[303]; 611 | r[303] = r[489]; 612 | r[489] = t; 613 | t = r[307]; 614 | r[307] = r[409]; 615 | r[409] = t; 616 | t = r[309]; 617 | r[309] = r[345]; 618 | r[345] = t; 619 | t = r[311]; 620 | r[311] = r[473]; 621 | r[473] = t; 622 | t = r[315]; 623 | r[315] = r[441]; 624 | r[441] = t; 625 | t = r[317]; 626 | r[317] = r[377]; 627 | r[377] = t; 628 | t = r[319]; 629 | r[319] = r[505]; 630 | r[505] = t; 631 | t = r[323]; 632 | r[323] = r[389]; 633 | r[389] = t; 634 | t = r[327]; 635 | r[327] = r[453]; 636 | r[453] = t; 637 | t = r[331]; 638 | r[331] = r[421]; 639 | r[421] = t; 640 | t = r[333]; 641 | r[333] = r[357]; 642 | r[357] = t; 643 | t = r[335]; 644 | r[335] = r[485]; 645 | r[485] = t; 646 | t = r[339]; 647 | r[339] = r[405]; 648 | r[405] = t; 649 | t = r[343]; 650 | r[343] = r[469]; 651 | r[469] = t; 652 | t = r[347]; 653 | r[347] = r[437]; 654 | r[437] = t; 655 | t = r[349]; 656 | r[349] = r[373]; 657 | r[373] = t; 658 | t = r[351]; 659 | r[351] = r[501]; 660 | r[501] = t; 661 | t = r[355]; 662 | r[355] = r[397]; 663 | r[397] = t; 664 | t = r[359]; 665 | r[359] = r[461]; 666 | r[461] = t; 667 | t = r[363]; 668 | r[363] = r[429]; 669 | r[429] = t; 670 | t = r[367]; 671 | r[367] = r[493]; 672 | r[493] = t; 673 | t = r[371]; 674 | r[371] = r[413]; 675 | r[413] = t; 676 | t = r[375]; 677 | r[375] = r[477]; 678 | r[477] = t; 679 | t = r[379]; 680 | r[379] = r[445]; 681 | r[445] = t; 682 | t = r[383]; 683 | r[383] = r[509]; 684 | r[509] = t; 685 | t = r[391]; 686 | r[391] = r[451]; 687 | r[451] = t; 688 | t = r[395]; 689 | r[395] = r[419]; 690 | r[419] = t; 691 | t = r[399]; 692 | r[399] = r[483]; 693 | r[483] = t; 694 | t = r[407]; 695 | r[407] = r[467]; 696 | r[467] = t; 697 | t = r[411]; 698 | r[411] = r[435]; 699 | r[435] = t; 700 | t = r[415]; 701 | r[415] = r[499]; 702 | r[499] = t; 703 | t = r[423]; 704 | r[423] = r[459]; 705 | r[459] = t; 706 | t = r[431]; 707 | r[431] = r[491]; 708 | r[491] = t; 709 | t = r[439]; 710 | r[439] = r[475]; 711 | r[475] = t; 712 | t = r[447]; 713 | r[447] = r[507]; 714 | r[507] = t; 715 | t = r[463]; 716 | r[463] = r[487]; 717 | r[487] = t; 718 | t = r[479]; 719 | r[479] = r[503]; 720 | r[503] = t; 721 | -------------------------------------------------------------------------------- /ntt_transform.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File taken from: lattisigns512-20130329/ntt_transform.c 3 | * Author: Gim Güneysu, Tobias Oder, Thomas Pöppelmann, Peter Schwabe 4 | * Public Domain 5 | */ 6 | 7 | 8 | #include "ntt.h" 9 | #include 10 | #include 11 | static void bitrev(poly r) 12 | { 13 | double t; 14 | #include "bitrev.code" 15 | } 16 | 17 | 18 | static const double _neg2[4] = {1.,-1.,1.,-1.}; 19 | static const double _neg4[4] = {1.,1.,-1.,-1.}; 20 | 21 | void ntt_transform(poly out, const poly o) 22 | { 23 | int s, pos = 0, offset; 24 | __m256d vt,vo0,vo10,vo11,vo20,vo21,vo22,vo23,vc,vp,vpinv,neg2,neg4; 25 | __m256d vx0,vx1,vx2,vx3,vx4,vx5,vx6,vx7; 26 | 27 | vpinv = _mm256_set_pd(PARAM_QINV, PARAM_QINV, PARAM_QINV, PARAM_QINV); 28 | vp = _mm256_set_pd(PARAM_Q, PARAM_Q, PARAM_Q, PARAM_Q); 29 | 30 | bitrev(out); 31 | vo10 = _mm256_load_pd(o+pos); 32 | vo20 = _mm256_load_pd(o+pos+4); 33 | neg2 = _mm256_load_pd(_neg2); 34 | neg4 = _mm256_load_pd(_neg4); 35 | 36 | // m = 2, m = 4, m = 8 (3 levels merged) 37 | for(s = 0; s 2 | #include "params.h" 3 | #include "ntt.h" 4 | 5 | poly poly_a1 = { 6 | -18881346.0,29684181.0,33681918.0,16134344.0,-4402692.0,-22309344.0,13127881.0,14041573.0,25225154.0,18889261.0,16739199.0,-5189795.0,2190541.0,-15290952.0,-17225172.0,3045106.0, 7 | 76293.0,-32019629.0,-4736869.0,-40255734.0,40072.0,-2655572.0,8008256.0,-14249745.0,-16910053.0,-9181045.0,-24714820.0,-4443012.0,16933173.0,4774199.0,33141845.0,-21594255.0, 8 | -37390192.0,30408143.0,22732042.0,25489576.0,6572827.0,-308270.0,-15893283.0,19119106.0,-27219950.0,11671670.0,-9673073.0,-26669319.0,-30873648.0,5748851.0,16221498.0,11134278.0, 9 | -18053681.0,1986593.0,29461820.0,-11174896.0,-19719291.0,18550519.0,31283196.0,8919449.0,-15062797.0,11721426.0,-25708556.0,4546466.0,-17977293.0,-17118214.0,-16016569.0,9995031.0, 10 | 15992829.0,8109551.0,2040027.0,3677625.0,-9153266.0,23506156.0,-7088092.0,-2237143.0,22960469.0,-21508372.0,-1044488.0,-19082438.0,-5898007.0,-43080396.0,807639.0,-11896358.0, 11 | -6930556.0,14553834.0,-1827484.0,31128520.0,-30919157.0,-11231820.0,23028693.0,-12814366.0,7208321.0,-33839529.0,-29424154.0,783758.0,-11606350.0,4560722.0,1133727.0,-14105593.0, 12 | -8636238.0,-31066602.0,-20036068.0,-2473500.0,10664634.0,23694039.0,14824546.0,33377997.0,-23800260.0,-23179637.0,-1805124.0,26904430.0,13028964.0,15526119.0,13753965.0,-21413754.0, 13 | -18782740.0,-12016997.0,2515974.0,1716332.0,18882087.0,11453662.0,4825531.0,-29864788.0,19620014.0,7716799.0,17283571.0,17982905.0,-15817538.0,-2051679.0,-33157151.0,-35142165.0, 14 | -2332685.0,-2319820.0,2478983.0,6545338.0,-3649811.0,13980758.0,-12304168.0,-14750182.0,2499360.0,10033821.0,11846689.0,5290978.0,-7251277.0,4835257.0,10043218.0,14229931.0, 15 | -23482871.0,24378260.0,-11447370.0,9641260.0,-20362013.0,7608647.0,-6689740.0,-14113486.0,15553320.0,5776388.0,-5188483.0,-304358.0,3099229.0,-16205934.0,-4603963.0,-181646.0, 16 | -5852177.0,-3082147.0,2542794.0,15412130.0,607650.0,-8577058.0,911473.0,-3316359.0,-21491256.0,-14847528.0,-15373019.0,-31491155.0,14320421.0,38679.0,-16167061.0,-4367659.0, 17 | -17933440.0,5470096.0,3763738.0,1806391.0,21159837.0,5923564.0,-7688148.0,-16799678.0,30359939.0,-28912305.0,-3767874.0,-6994350.0,22075056.0,-3739240.0,18003145.0,-4322741.0, 18 | -2100928.0,-10690253.0,18503809.0,-26190111.0,-3128709.0,-9239885.0,5304021.0,3353138.0,-14351392.0,-14169658.0,-21475714.0,1667543.0,8894738.0,-5061353.0,-9478379.0,-2607314.0, 19 | -12331806.0,-14136933.0,-28424913.0,6297201.0,-9191835.0,-5369225.0,9151863.0,-16036162.0,-2096692.0,-8748237.0,9065302.0,-25076555.0,6965679.0,9892890.0,-20898792.0,-10070085.0, 20 | 3279334.0,16643378.0,-10778845.0,-1425070.0,-21223971.0,-18463823.0,12621027.0,-10952234.0,17486753.0,-2347087.0,2997250.0,-8741150.0,29387115.0,14224580.0,-16090241.0,-8405145.0, 21 | 29113006.0,-8771445.0,16425961.0,12385151.0,26698189.0,-21098520.0,-2309984.0,18234922.0,-2837418.0,16789186.0,3341188.0,12851945.0,-26175484.0,-19765482.0,8216866.0,-12589625.0, 22 | -7470066.0,-14961596.0,-8208737.0,9863807.0,16185325.0,-2180342.0,-15668218.0,-13962298.0,6277761.0,-12345779.0,10911830.0,654161.0,-12543395.0,-5831826.0,14407867.0,-5814284.0, 23 | 14170910.0,1089156.0,12464910.0,7945137.0,-14409595.0,9451968.0,-16716089.0,4767841.0,13907517.0,5369259.0,-9391696.0,-8349295.0,-16481919.0,-7485267.0,-2876286.0,3856826.0, 24 | 13559971.0,2538193.0,-5911168.0,-4685610.0,-2465571.0,3836416.0,-1659688.0,-8938430.0,9211379.0,-13087010.0,8625113.0,3240607.0,4285893.0,-5344398.0,6177890.0,10624387.0, 25 | -9803073.0,2837510.0,1902442.0,-10873172.0,-7163229.0,-15783997.0,-13655693.0,11349331.0,1626007.0,15588822.0,-6364990.0,13469835.0,12910392.0,5441885.0,-6827999.0,-2531147.0, 26 | -14248436.0,12077934.0,2134151.0,-3515311.0,8892026.0,5696953.0,-11294561.0,5456287.0,-7439788.0,11601528.0,-13736360.0,10800682.0,-11175795.0,-12655900.0,-9908195.0,-10490762.0, 27 | 13941732.0,-6768000.0,-10607151.0,-2163440.0,-5964203.0,3656788.0,13878347.0,-5277340.0,-13863441.0,10072222.0,-4453806.0,13772331.0,3075147.0,-6393838.0,-7258867.0,-6765997.0, 28 | 6665749.0,-9940468.0,13219768.0,-2955046.0,1660222.0,9566871.0,-6294969.0,-13958120.0,-5303564.0,5308702.0,-14460002.0,-14994171.0,-581672.0,-10077351.0,-13092088.0,5203188.0, 29 | 1287180.0,-12473280.0,-4205749.0,2138207.0,-4104127.0,-5641823.0,10590219.0,7656877.0,-245340.0,-2039445.0,-4787623.0,10592836.0,-3155042.0,-9186716.0,-14873167.0,8794832.0, 30 | 4959707.0,2761885.0,-5810744.0,-16231592.0,-4825314.0,15528712.0,7265050.0,5825886.0,-13565150.0,1035297.0,11048029.0,16207553.0,-5771871.0,2424807.0,-2487296.0,-732429.0, 31 | 6250901.0,6368384.0,7487754.0,-10500262.0,3917583.0,11781278.0,7627528.0,3039410.0,1340142.0,-15171111.0,3215117.0,-8824335.0,-4665274.0,-11801146.0,6158823.0,567397.0, 32 | -12708749.0,15815450.0,-13816928.0,-5523692.0,-9718973.0,6230282.0,-1534309.0,-11936565.0,6656904.0,391264.0,16760013.0,-16517.0,14614441.0,-16104733.0,-15621083.0,-16746676.0, 33 | -12743278.0,-8434531.0,-12657332.0,-2237918.0,9689611.0,-8584469.0,1216588.0,4417188.0,-2567261.0,4326309.0,-7855491.0,4362374.0,-6974252.0,16741481.0,12335775.0,15760063.0, 34 | -7788186.0,15260953.0,182897.0,-3551675.0,7729774.0,6055351.0,16501439.0,11444621.0,3677438.0,-12501440.0,956892.0,1889074.0,5010056.0,-699587.0,-3422847.0,-8211382.0, 35 | 4655124.0,15760091.0,1424401.0,-3433145.0,-3655373.0,13386387.0,-15571124.0,-1023584.0,6689579.0,15257421.0,-2397746.0,-7050543.0,14851734.0,3504382.0,161568.0,16656058.0, 36 | -7102241.0,-4611396.0,13310920.0,-9312027.0,-10845475.0,-12888867.0,12325523.0,8966896.0,12818213.0,-3304713.0,-12629291.0,-14383155.0,-3797821.0,-420642.0,-1390997.0,13629476.0, 37 | 53780.0,-2039573.0,9657461.0,-13956190.0,-4399655.0,1069292.0,7871083.0,-9898078.0,13931256.0,10347820.0,-10576991.0,-14846987.0,2521498.0,-1653560.0,569080.0,6315607.0, 38 | }; 39 | poly poly_a2 = { 40 | 8325443.0,19167037.0,10357201.0,9150392.0,-8039719.0,6790608.0,-45387613.0,-1126515.0,-5708147.0,7910269.0,34696405.0,-35873123.0,-18572592.0,28759047.0,48606033.0,469482.0, 41 | -34229706.0,-12885330.0,18139283.0,-2076761.0,30591467.0,-37331710.0,5815430.0,18233057.0,-16164120.0,22311011.0,5989721.0,18257470.0,-30257802.0,23314630.0,-34868285.0,-14107879.0, 42 | -7051822.0,27765313.0,-22102739.0,-13821390.0,12483567.0,-908072.0,21763212.0,-841492.0,35535458.0,-7759151.0,-25027635.0,-13928611.0,27394861.0,-12299035.0,11787843.0,34663445.0, 43 | -24876387.0,17997496.0,-18432659.0,412477.0,6061159.0,16273693.0,-18518757.0,-271839.0,7853774.0,-21165266.0,1438733.0,-18027263.0,1542556.0,-4819520.0,-15748837.0,12192906.0, 44 | 22427539.0,-31283581.0,1379287.0,10102439.0,17764987.0,-16236839.0,12505542.0,-20107235.0,7510555.0,-29679105.0,3107578.0,-6779049.0,-34621532.0,8674885.0,13207260.0,-12114481.0, 45 | 22923112.0,-4496507.0,40018128.0,-2177042.0,-5744030.0,-1376653.0,11486955.0,-3290300.0,354802.0,-2101486.0,15422109.0,-15155884.0,20916156.0,8955973.0,-4816862.0,-6994082.0, 46 | -4463582.0,-24938080.0,9281088.0,-27119772.0,-26676624.0,13750461.0,5312259.0,7390860.0,20427657.0,25237261.0,-13724490.0,-1651754.0,-32150347.0,-18146691.0,10491236.0,-26419855.0, 47 | 10951911.0,-772652.0,26345644.0,-12806099.0,-9542704.0,-22203583.0,14000658.0,6643739.0,8340690.0,-13029333.0,14289937.0,22325613.0,15323509.0,-20890374.0,33585273.0,-17926906.0, 48 | -14787648.0,-10253414.0,13951082.0,-7438448.0,15149196.0,7476929.0,-27395687.0,-145683.0,-2208073.0,-14156842.0,5618198.0,5032193.0,1642097.0,1428100.0,9109234.0,-3178668.0, 49 | 5602320.0,559611.0,18439393.0,-4967300.0,24707065.0,-10582508.0,-4166942.0,2353395.0,19596800.0,-7843925.0,774473.0,1190544.0,-14538189.0,-16281979.0,6639138.0,15724417.0, 50 | 20099358.0,-13219412.0,-877872.0,-5709494.0,989353.0,17355846.0,28268777.0,-23425025.0,-1196307.0,-524734.0,30103216.0,-21440859.0,16681754.0,-1988040.0,7623951.0,12958364.0, 51 | 21508759.0,14147988.0,5475604.0,547065.0,-11895027.0,-2507050.0,-6954341.0,2824760.0,-22828498.0,4260089.0,-1822964.0,209835.0,-15532350.0,13267342.0,-19908682.0,26952217.0, 52 | -15358512.0,10792621.0,16530014.0,-29849167.0,7555651.0,31128780.0,13138183.0,5092215.0,-755117.0,-4264257.0,807159.0,4695108.0,11825237.0,-3515448.0,123807.0,18775998.0, 53 | -7616582.0,-5175616.0,-15363263.0,-7621960.0,-4244357.0,-13837403.0,4225055.0,7927849.0,-3799297.0,9617544.0,-6783144.0,4758575.0,-12334122.0,4346873.0,-31321535.0,7757306.0, 54 | 3283580.0,5013537.0,-4205275.0,20309574.0,-5377296.0,-14874.0,22993032.0,21095177.0,13772044.0,-11942552.0,10923331.0,16548614.0,-5351250.0,11612403.0,-7787285.0,13269582.0, 55 | -15169450.0,4419402.0,1810026.0,14609875.0,30307566.0,5542672.0,16653745.0,-14061494.0,-24819992.0,15667863.0,10906081.0,6607161.0,-14890564.0,2920669.0,-6558718.0,-6809905.0, 56 | -14968187.0,-11016658.0,15908402.0,2941982.0,-7822905.0,15509685.0,-14463056.0,4523124.0,5009638.0,-7684191.0,1555523.0,-11639485.0,-3574906.0,-13941564.0,-14518604.0,-5122692.0, 57 | -9101751.0,13102332.0,946637.0,9164121.0,-3918948.0,-7941282.0,10210631.0,-9139823.0,10848911.0,-5117301.0,-12295871.0,-12116894.0,13942087.0,11262102.0,-7719553.0,12238710.0, 58 | -8788128.0,242941.0,-3109217.0,-13444936.0,-15453070.0,16539589.0,1426073.0,15327158.0,12691594.0,11248934.0,-1846328.0,-5125339.0,-888509.0,12456653.0,5326529.0,-11502288.0, 59 | 8226928.0,-7731484.0,5818885.0,-8648647.0,-12238347.0,-2752091.0,14130339.0,3603478.0,-14649309.0,15420957.0,8654444.0,6682087.0,4726454.0,1057328.0,-7072479.0,14523943.0, 60 | 7861755.0,-15145905.0,-6198695.0,12632342.0,519539.0,13633357.0,-15188534.0,-771675.0,8729891.0,-16524391.0,-5140458.0,-6885266.0,-4600486.0,10725721.0,14549749.0,-6317397.0, 61 | -9198612.0,263817.0,11295832.0,2822776.0,868624.0,-5644614.0,-14909063.0,9021255.0,-5620079.0,-13826199.0,-10084453.0,-6334058.0,-4650408.0,11085868.0,6952498.0,-15904189.0, 62 | 11664501.0,-8900206.0,-8250590.0,4438216.0,-1197430.0,-10956633.0,-11857179.0,14272592.0,8592680.0,-11406218.0,-11706792.0,8259876.0,15552932.0,13146889.0,-5355364.0,6444909.0, 63 | 10634137.0,-13594909.0,-4955326.0,-432637.0,-3164486.0,-2804730.0,-6850837.0,2887259.0,-12623353.0,14512053.0,-7886881.0,16081411.0,-3762581.0,5575686.0,-9536106.0,14615682.0, 64 | 6285264.0,-14067616.0,9100260.0,14593859.0,11347994.0,-7361443.0,-5779979.0,-1681176.0,-7269932.0,5002530.0,-10886726.0,13285460.0,-11312966.0,-7127484.0,11161232.0,-15991589.0, 65 | 12717403.0,14388362.0,12995097.0,10133238.0,-7255401.0,-2329892.0,-9041975.0,-14000049.0,4238466.0,16180799.0,12893766.0,-13312070.0,-7313731.0,-9350797.0,11916825.0,-15903329.0, 66 | -11170212.0,-6753760.0,-14977308.0,-12499558.0,7047426.0,-13461042.0,-431295.0,6201795.0,-1193833.0,-4330625.0,-2334102.0,-8565229.0,10751244.0,-10004788.0,13306931.0,13300697.0, 67 | 6994607.0,6974824.0,11674935.0,-3239376.0,-15557082.0,-3971275.0,8733590.0,-16713399.0,-417294.0,-9317058.0,-10561578.0,7858229.0,-6263296.0,5182618.0,8258730.0,530377.0, 68 | 5306094.0,-9171347.0,15885376.0,-3468269.0,11690145.0,2301416.0,-253127.0,12166659.0,-2508012.0,-14656368.0,12456687.0,-5615671.0,12230113.0,5108233.0,-16685416.0,1100740.0, 69 | -7848318.0,-5569628.0,4984059.0,-8268505.0,9857602.0,-14183945.0,15740729.0,-171491.0,-9163887.0,9948598.0,15186690.0,3780811.0,-11035678.0,-10609317.0,1763261.0,5953098.0, 70 | -16273135.0,-6895207.0,-4566389.0,-11536286.0,8324929.0,11031216.0,3412528.0,6740623.0,-16549570.0,-14781945.0,11655843.0,-4104914.0,16380166.0,-10743009.0,14069073.0,700400.0, 71 | 15721282.0,15412474.0,-9214332.0,12953869.0,-1311502.0,-10110.0,-6635387.0,125630.0,5509122.0,4111019.0,731471.0,-12430050.0,842632.0,-10160304.0,3099274.0,13446793.0, 72 | }; 73 | const double q4x[4] = {PARAM_Q, PARAM_Q, PARAM_Q, PARAM_Q}; 74 | const double qinv4x[4] = {PARAM_QINV, PARAM_QINV, PARAM_QINV, PARAM_QINV}; 75 | double omegas[PARAM_N] = {1.0,1.0,1.0,20791006.0,1.0,6356706.0,20791006.0,19867748.0,1.0,11836922.0,6356706.0,22604314.0,20791006.0,31280465.0,19867748.0,17371284.0,1.0,19172065.0,11836922.0,878186.0,6356706.0,17619771.0,22604314.0,30292897.0,20791006.0,30651277.0,31280465.0,8597020.0,19867748.0,23460663.0,17371284.0,27341311.0,1.0,13663747.0,19172065.0,6519423.0,11836922.0,27535105.0,878186.0,33294892.0,6356706.0,1648639.0,17619771.0,8031498.0,22604314.0,22880749.0,30292897.0,13996293.0,20791006.0,29506803.0,30651277.0,21759655.0,31280465.0,14852863.0,8597020.0,26269093.0,19867748.0,27343436.0,23460663.0,10529006.0,17371284.0,5084772.0,27341311.0,9039793.0,1.0,4711250.0,13663747.0,28049154.0,19172065.0,6208165.0,6519423.0,2642327.0,11836922.0,33168177.0,27535105.0,3346823.0,878186.0,26884671.0,33294892.0,18882277.0,6356706.0,27376527.0,1648639.0,12620891.0,17619771.0,30009588.0,8031498.0,22930867.0,22604314.0,486199.0,22880749.0,31448620.0,30292897.0,14500877.0,13996293.0,1754428.0,20791006.0,9031846.0,29506803.0,16643459.0,30651277.0,11566352.0,21759655.0,6244019.0,31280465.0,606391.0,14852863.0,15531894.0,8597020.0,5541186.0,26269093.0,16123009.0,19867748.0,10320385.0,27343436.0,10090928.0,23460663.0,13137862.0,10529006.0,2356934.0,17371284.0,17539779.0,5084772.0,20460260.0,27341311.0,30235441.0,9039793.0,27634461.0,1.0,30971802.0,4711250.0,17854569.0,13663747.0,375524.0,28049154.0,11074316.0,19172065.0,10588996.0,6208165.0,2205546.0,6519423.0,3720230.0,2642327.0,2686341.0,11836922.0,31711762.0,33168177.0,5987573.0,27535105.0,31248672.0,3346823.0,18089846.0,878186.0,13107968.0,26884671.0,16736232.0,33294892.0,13657091.0,18882277.0,5983912.0,6356706.0,28235640.0,27376527.0,18664546.0,1648639.0,22736731.0,12620891.0,15111271.0,17619771.0,32693512.0,30009588.0,26216253.0,8031498.0,17173549.0,22930867.0,30728508.0,22604314.0,12710337.0,486199.0,27854551.0,22880749.0,25847514.0,31448620.0,32009659.0,30292897.0,29081776.0,14500877.0,26503217.0,13996293.0,31938797.0,1754428.0,6337426.0,20791006.0,15238786.0,9031846.0,1852603.0,29506803.0,22813874.0,16643459.0,4269300.0,30651277.0,10640467.0,11566352.0,26668797.0,21759655.0,8277873.0,6244019.0,16140428.0,31280465.0,21007196.0,606391.0,13038700.0,14852863.0,21999231.0,15531894.0,8236665.0,8597020.0,30750647.0,5541186.0,7076354.0,26269093.0,6160655.0,16123009.0,22880387.0,19867748.0,3492970.0,10320385.0,15916022.0,27343436.0,26459240.0,10090928.0,18628522.0,23460663.0,2271277.0,13137862.0,9283470.0,10529006.0,25469245.0,2356934.0,5433838.0,17371284.0,20784031.0,17539779.0,27393356.0,5084772.0,7828558.0,20460260.0,5809356.0,27341311.0,3590847.0,30235441.0,23100544.0,9039793.0,9490865.0,27634461.0,28698544.0,1.0,158302.0,30971802.0,19702709.0,4711250.0,9856327.0,17854569.0,32941947.0,13663747.0,8251204.0,375524.0,28553421.0,28049154.0,17826243.0,11074316.0,14162508.0,19172065.0,12748610.0,10588996.0,17307598.0,6208165.0,8464426.0,2205546.0,17536070.0,6519423.0,29333626.0,3720230.0,10784099.0,2642327.0,13597375.0,2686341.0,2631507.0,11836922.0,22104994.0,31711762.0,32624162.0,33168177.0,28115628.0,5987573.0,14210459.0,27535105.0,2408670.0,31248672.0,32037327.0,3346823.0,15402979.0,18089846.0,3337194.0,878186.0,19553981.0,13107968.0,29857897.0,26884671.0,3389855.0,16736232.0,9536185.0,33294892.0,24252032.0,13657091.0,28203876.0,18882277.0,2039313.0,5983912.0,5022566.0,6356706.0,4015571.0,28235640.0,14636455.0,27376527.0,28396527.0,18664546.0,24532987.0,1648639.0,28329792.0,22736731.0,23387739.0,12620891.0,23269069.0,15111271.0,5393742.0,17619771.0,4172010.0,32693512.0,6901341.0,30009588.0,17832061.0,26216253.0,9246517.0,8031498.0,12175781.0,17173549.0,23346688.0,22930867.0,23396119.0,30728508.0,21562797.0,22604314.0,30472430.0,12710337.0,24507547.0,486199.0,1801020.0,27854551.0,10991503.0,22880749.0,7496015.0,25847514.0,14711719.0,31448620.0,12687495.0,32009659.0,18541234.0,30292897.0,9412810.0,29081776.0,26712223.0,14500877.0,3773314.0,26503217.0,9065347.0,13996293.0,10469343.0,31938797.0,6757468.0,1754428.0,33321907.0,6337426.0,5033678.0,20791006.0,3322449.0,15238786.0,27520735.0,9031846.0,11674237.0,1852603.0,7264389.0,29506803.0,7360355.0,22813874.0,22956257.0,16643459.0,18432345.0,4269300.0,740072.0,30651277.0,8063703.0,10640467.0,12537949.0,11566352.0,562866.0,26668797.0,17897310.0,21759655.0,17356357.0,8277873.0,28339437.0,6244019.0,14217381.0,16140428.0,2568684.0,31280465.0,32382263.0,21007196.0,5288089.0,606391.0,5393925.0,13038700.0,2004823.0,14852863.0,30301666.0,21999231.0,30835499.0,15531894.0,26987280.0,8236665.0,13795999.0,8597020.0,23140309.0,30750647.0,3425390.0,5541186.0,7265307.0,7076354.0,22339152.0,26269093.0,19890284.0,6160655.0,2811894.0,16123009.0,29784117.0,22880387.0,17291365.0,19867748.0,28552842.0,3492970.0,1032843.0,10320385.0,3926055.0,15916022.0,8456955.0,27343436.0,23877617.0,26459240.0,25888389.0,10090928.0,15439012.0,18628522.0,25419029.0,23460663.0,15320011.0,2271277.0,22280362.0,13137862.0,31540368.0,9283470.0,20006666.0,10529006.0,15515989.0,25469245.0,21324026.0,2356934.0,27618628.0,5433838.0,23883070.0,17371284.0,22728237.0,20784031.0,6327120.0,17539779.0,23305812.0,27393356.0,8433925.0,5084772.0,23442177.0,7828558.0,27590747.0,20460260.0,17645214.0,5809356.0,17936342.0,27341311.0,22989237.0,3590847.0,28452340.0,30235441.0,6154425.0,23100544.0,9784636.0,9039793.0,28337762.0,9490865.0,5270033.0,27634461.0,29104466.0,28698544.0,19329455.0,}; 76 | double omegas_inv[PARAM_N] = {1.0,1.0,1.0,12759331.0,1.0,13682589.0,12759331.0,27193631.0,1.0,16179053.0,13682589.0,2269872.0,12759331.0,10946023.0,27193631.0,21713415.0,1.0,6209026.0,16179053.0,10089674.0,13682589.0,24953317.0,2269872.0,2899060.0,12759331.0,3257440.0,10946023.0,15930566.0,27193631.0,32672151.0,21713415.0,14378272.0,1.0,24510544.0,6209026.0,28465565.0,16179053.0,23021331.0,10089674.0,6206901.0,13682589.0,7281244.0,24953317.0,18697474.0,2269872.0,11790682.0,2899060.0,4043534.0,12759331.0,19554044.0,3257440.0,10669588.0,10946023.0,25518839.0,15930566.0,31901698.0,27193631.0,255445.0,32672151.0,6015232.0,21713415.0,27030914.0,14378272.0,19886590.0,1.0,5915876.0,24510544.0,3314896.0,6209026.0,13090077.0,28465565.0,16010558.0,16179053.0,31193403.0,23021331.0,20412475.0,10089674.0,23459409.0,6206901.0,23229952.0,13682589.0,17427328.0,7281244.0,28009151.0,24953317.0,18018443.0,18697474.0,32943946.0,2269872.0,27306318.0,11790682.0,21983985.0,2899060.0,16906878.0,4043534.0,24518491.0,12759331.0,31795909.0,19554044.0,19049460.0,3257440.0,2101717.0,10669588.0,33064138.0,10946023.0,10619470.0,25518839.0,3540749.0,15930566.0,20929446.0,31901698.0,6173810.0,27193631.0,14668060.0,255445.0,6665666.0,32672151.0,30203514.0,6015232.0,382160.0,21713415.0,30908010.0,27030914.0,27342172.0,14378272.0,5501183.0,19886590.0,28839087.0,1.0,4851793.0,5915876.0,24059472.0,24510544.0,10449793.0,3314896.0,29959490.0,6209026.0,27740981.0,13090077.0,25721779.0,28465565.0,6156981.0,16010558.0,12766306.0,16179053.0,28116499.0,31193403.0,8081092.0,23021331.0,24266867.0,20412475.0,31279060.0,10089674.0,14921815.0,23459409.0,7091097.0,6206901.0,17634315.0,23229952.0,30057367.0,13682589.0,10669950.0,17427328.0,27389682.0,7281244.0,26473983.0,28009151.0,2799690.0,24953317.0,25313672.0,18018443.0,11551106.0,18697474.0,20511637.0,32943946.0,12543141.0,2269872.0,17409909.0,27306318.0,25272464.0,11790682.0,6881540.0,21983985.0,22909870.0,2899060.0,29281037.0,16906878.0,10736463.0,4043534.0,31697734.0,24518491.0,18311551.0,12759331.0,27212911.0,31795909.0,1611540.0,19554044.0,7047120.0,19049460.0,4468561.0,3257440.0,1540678.0,2101717.0,7702823.0,10669588.0,5695786.0,33064138.0,20840000.0,10946023.0,2821829.0,10619470.0,16376788.0,25518839.0,7334084.0,3540749.0,856825.0,15930566.0,18439066.0,20929446.0,10813606.0,31901698.0,14885791.0,6173810.0,5314697.0,27193631.0,27566425.0,14668060.0,19893246.0,255445.0,16814105.0,6665666.0,20442369.0,32672151.0,15460491.0,30203514.0,2301665.0,6015232.0,27562764.0,382160.0,1838575.0,21713415.0,30863996.0,30908010.0,29830107.0,27030914.0,31344791.0,27342172.0,22961341.0,14378272.0,22476021.0,5501183.0,33174813.0,19886590.0,15695768.0,28839087.0,2578535.0,1.0,14220882.0,4851793.0,4445871.0,5915876.0,28280304.0,24059472.0,5212575.0,24510544.0,23765701.0,10449793.0,27395912.0,3314896.0,5097997.0,29959490.0,10561100.0,6209026.0,15613995.0,27740981.0,15905123.0,13090077.0,5959590.0,25721779.0,10108160.0,28465565.0,25116412.0,6156981.0,10244525.0,16010558.0,27223217.0,12766306.0,10822100.0,16179053.0,9667267.0,28116499.0,5931709.0,31193403.0,12226311.0,8081092.0,18034348.0,23021331.0,13543671.0,24266867.0,2009969.0,20412475.0,11269975.0,31279060.0,18230326.0,10089674.0,8131308.0,14921815.0,18111325.0,23459409.0,7661948.0,7091097.0,9672720.0,6206901.0,25093382.0,17634315.0,29624282.0,23229952.0,32517494.0,30057367.0,4997495.0,13682589.0,16258972.0,10669950.0,3766220.0,17427328.0,30738443.0,27389682.0,13660053.0,7281244.0,11211185.0,26473983.0,26285030.0,28009151.0,30124947.0,2799690.0,10410028.0,24953317.0,19754338.0,25313672.0,6563057.0,18018443.0,2714838.0,11551106.0,3248671.0,18697474.0,31545514.0,20511637.0,28156412.0,32943946.0,28262248.0,12543141.0,1168074.0,2269872.0,30981653.0,17409909.0,19332956.0,27306318.0,5210900.0,25272464.0,16193980.0,11790682.0,15653027.0,6881540.0,32987471.0,21983985.0,21012388.0,22909870.0,25486634.0,2899060.0,32810265.0,29281037.0,15117992.0,16906878.0,10594080.0,10736463.0,26189982.0,4043534.0,26285948.0,31697734.0,21876100.0,24518491.0,6029602.0,18311551.0,30227888.0,12759331.0,28516659.0,27212911.0,228430.0,31795909.0,26792869.0,1611540.0,23080994.0,19554044.0,24484990.0,7047120.0,29777023.0,19049460.0,6838114.0,4468561.0,24137527.0,3257440.0,15009103.0,1540678.0,20862842.0,2101717.0,18838618.0,7702823.0,26054322.0,10669588.0,22558834.0,5695786.0,31749317.0,33064138.0,9042790.0,20840000.0,3077907.0,10946023.0,11987540.0,2821829.0,10154218.0,10619470.0,10203649.0,16376788.0,21374556.0,25518839.0,24303820.0,7334084.0,15718276.0,3540749.0,26648996.0,856825.0,29378327.0,15930566.0,28156595.0,18439066.0,10281268.0,20929446.0,10162598.0,10813606.0,5220545.0,31901698.0,9017350.0,14885791.0,5153810.0,6173810.0,18913882.0,5314697.0,29534766.0,27193631.0,28527771.0,27566425.0,31511024.0,14668060.0,5346461.0,19893246.0,9298305.0,255445.0,24014152.0,16814105.0,30160482.0,6665666.0,3692440.0,20442369.0,13996356.0,32672151.0,30213143.0,15460491.0,18147358.0,30203514.0,1513010.0,2301665.0,31141667.0,6015232.0,19339878.0,27562764.0,5434709.0,382160.0,926175.0,1838575.0,11445343.0,21713415.0,30918830.0,30863996.0,19952962.0,30908010.0,22766238.0,29830107.0,4216711.0,27030914.0,16014267.0,31344791.0,25085911.0,27342172.0,16242739.0,22961341.0,20801727.0,14378272.0,19387829.0,22476021.0,15724094.0,5501183.0,4996916.0,33174813.0,25299133.0,19886590.0,608390.0,15695768.0,23694010.0,28839087.0,13847628.0,2578535.0,33392035.0,}; 77 | double psis[PARAM_N] = {1.000000,8853225.000000,158302.000000,18546786.000000,30971802.000000,3326502.000000,19702709.000000,19380389.000000,4711250.000000,10873187.000000,9856327.000000,14309363.000000,17854569.000000,16228734.000000,32941947.000000,24644904.000000,13663747.000000,3755637.000000,8251204.000000,12876734.000000,375524.000000,28470896.000000,28553421.000000,15257697.000000,28049154.000000,1639527.000000,17826243.000000,28546459.000000,11074316.000000,33111751.000000,14162508.000000,20156618.000000,19172065.000000,28142251.000000,12748610.000000,26669594.000000,10588996.000000,9862656.000000,17307598.000000,13237817.000000,6208165.000000,18857714.000000,8464426.000000,5506379.000000,2205546.000000,33053198.000000,17536070.000000,10992624.000000,6519423.000000,32585606.000000,29333626.000000,2287262.000000,3720230.000000,2912220.000000,10784099.000000,28620060.000000,2642327.000000,8779977.000000,13597375.000000,31658492.000000,2686341.000000,21011209.000000,2631507.000000,3097612.000000,11836922.000000,19999569.000000,22104994.000000,27771170.000000,31711762.000000,30445219.000000,32624162.000000,33148088.000000,33168177.000000,1718428.000000,28115628.000000,4456860.000000,5987573.000000,33365284.000000,14210459.000000,28734532.000000,27535105.000000,12744541.000000,2408670.000000,3914561.000000,31248672.000000,8111032.000000,32037327.000000,21190674.000000,3346823.000000,29180940.000000,15402979.000000,23014035.000000,18089846.000000,3774414.000000,3337194.000000,32883732.000000,878186.000000,24455492.000000,19553981.000000,13458491.000000,13107968.000000,26092445.000000,29857897.000000,3589309.000000,26884671.000000,19836223.000000,3389855.000000,3532168.000000,16736232.000000,32892631.000000,9536185.000000,24070836.000000,33294892.000000,15506034.000000,24252032.000000,26438674.000000,13657091.000000,24632146.000000,28203876.000000,30709278.000000,18882277.000000,30496004.000000,2039313.000000,20434278.000000,5983912.000000,31334101.000000,5022566.000000,1282737.000000,6356706.000000,13193050.000000,4015571.000000,11273187.000000,28235640.000000,25623444.000000,14636455.000000,6688788.000000,27376527.000000,33432593.000000,28396527.000000,14876684.000000,18664546.000000,10025527.000000,24532987.000000,29384043.000000,1648639.000000,33402295.000000,28329792.000000,16340879.000000,22736731.000000,29294421.000000,23387739.000000,4302665.000000,12620891.000000,15083393.000000,23269069.000000,20895070.000000,15111271.000000,3646310.000000,5393742.000000,18167872.000000,17619771.000000,8485030.000000,4172010.000000,9477265.000000,32693512.000000,33134738.000000,6901341.000000,2057959.000000,30009588.000000,5253348.000000,17832061.000000,3291877.000000,26216253.000000,6878570.000000,9246517.000000,15200805.000000,8031498.000000,20562796.000000,12175781.000000,10935978.000000,17173549.000000,23350493.000000,23346688.000000,21363911.000000,22930867.000000,8768848.000000,23396119.000000,14533058.000000,30728508.000000,31989089.000000,21562797.000000,16651783.000000,22604314.000000,27675050.000000,30472430.000000,12759640.000000,12710337.000000,12042532.000000,24507547.000000,26752324.000000,486199.000000,21555686.000000,1801020.000000,4079913.000000,27854551.000000,14400476.000000,10991503.000000,12953950.000000,22880749.000000,6045123.000000,7496015.000000,32349232.000000,25847514.000000,25986406.000000,14711719.000000,26122368.000000,31448620.000000,9862538.000000,12687495.000000,28108518.000000,32009659.000000,21171811.000000,18541234.000000,29110307.000000,30292897.000000,13931090.000000,9412810.000000,22207833.000000,29081776.000000,5867358.000000,26712223.000000,6976608.000000,14500877.000000,1006250.000000,3773314.000000,27937761.000000,26503217.000000,31568819.000000,9065347.000000,17388514.000000,13996293.000000,32694400.000000,10469343.000000,13272169.000000,31938797.000000,21693424.000000,6757468.000000,561739.000000,1754428.000000,16014128.000000,33321907.000000,5026936.000000,6337426.000000,27129706.000000,5033678.000000,8730853.000000,20791006.000000,5358891.000000,3322449.000000,2892037.000000,15238786.000000,20892809.000000,27520735.000000,14779195.000000,9031846.000000,10476869.000000,11674237.000000,15507517.000000,1852603.000000,26348181.000000,7264389.000000,25403159.000000,29506803.000000,27483198.000000,7360355.000000,5259321.000000,22813874.000000,9420287.000000,22956257.000000,4893698.000000,16643459.000000,4899466.000000,18432345.000000,12126303.000000,4269300.000000,1935714.000000,740072.000000,12169807.000000,30651277.000000,10886837.000000,8063703.000000,27910095.000000,10640467.000000,13529497.000000,12537949.000000,27121362.000000,11566352.000000,29872445.000000,562866.000000,14888914.000000,26668797.000000,139441.000000,17897310.000000,31217773.000000,21759655.000000,5462694.000000,17356357.000000,28999750.000000,8277873.000000,25812790.000000,28339437.000000,20088339.000000,6244019.000000,22648507.000000,14217381.000000,14292283.000000,16140428.000000,30007871.000000,2568684.000000,14430223.000000,31280465.000000,24916364.000000,32382263.000000,31985197.000000,21007196.000000,4446465.000000,5288089.000000,31782507.000000,606391.000000,25886594.000000,5393925.000000,27891871.000000,13038700.000000,13962831.000000,2004823.000000,14321065.000000,14852863.000000,23410203.000000,30301666.000000,12381297.000000,21999231.000000,6940491.000000,30835499.000000,20720543.000000,15531894.000000,21150844.000000,26987280.000000,31475636.000000,8236665.000000,28481528.000000,13795999.000000,20807711.000000,8597020.000000,30831073.000000,23140309.000000,19444319.000000,30750647.000000,32468610.000000,3425390.000000,1372494.000000,5541186.000000,30113113.000000,7265307.000000,33482155.000000,7076354.000000,9861550.000000,22339152.000000,5907490.000000,26269093.000000,18938779.000000,19890284.000000,22029275.000000,6160655.000000,22712933.000000,2811894.000000,13754487.000000,16123009.000000,13030448.000000,29784117.000000,4159862.000000,22880387.000000,22010025.000000,17291365.000000,28480100.000000,19867748.000000,29604814.000000,28552842.000000,22441983.000000,3492970.000000,32708610.000000,1032843.000000,14871010.000000,10320385.000000,17679078.000000,3926055.000000,32044701.000000,15916022.000000,29954313.000000,8456955.000000,24326968.000000,27343436.000000,32906802.000000,23877617.000000,19495899.000000,26459240.000000,11403542.000000,25888389.000000,27623399.000000,10090928.000000,22585266.000000,15439012.000000,1115927.000000,18628522.000000,10951649.000000,25419029.000000,21376197.000000,23460663.000000,7747674.000000,15320011.000000,6170176.000000,2271277.000000,240071.000000,22280362.000000,24737958.000000,13137862.000000,5792002.000000,31540368.000000,21891068.000000,9283470.000000,19088143.000000,20006666.000000,13661618.000000,10529006.000000,6729616.000000,15515989.000000,21371608.000000,25469245.000000,19407210.000000,21324026.000000,29348667.000000,2356934.000000,2666685.000000,27618628.000000,11228736.000000,5433838.000000,961675.000000,23883070.000000,17196881.000000,17371284.000000,26311882.000000,22728237.000000,16306488.000000,20784031.000000,20284933.000000,6327120.000000,9159159.000000,17539779.000000,1824226.000000,23305812.000000,10873693.000000,27393356.000000,27309501.000000,8433925.000000,19953167.000000,5084772.000000,29765569.000000,23442177.000000,5574210.000000,7828558.000000,1177983.000000,27590747.000000,4291820.000000,20460260.000000,9365390.000000,17645214.000000,4126087.000000,5809356.000000,9863558.000000,17936342.000000,21824873.000000,27341311.000000,7992397.000000,22989237.000000,29221624.000000,3590847.000000,21707899.000000,28452340.000000,10560273.000000,30235441.000000,33245084.000000,6154425.000000,23875211.000000,23100544.000000,14638335.000000,9784636.000000,23031254.000000,9039793.000000,11999255.000000,28337762.000000,20185418.000000,9490865.000000,24394019.000000,5270033.000000,11757375.000000,27634461.000000,11032175.000000,29104466.000000,19674989.000000,28698544.000000,11673957.000000,19329455.000000,24628717.000000,}; 78 | double psis_inv[PARAM_N] = {33484809.000000,32257202.000000,28204816.000000,23370696.000000,28252045.000000,23879293.000000,22091620.000000,7252061.000000,18621507.000000,20880469.000000,1103683.000000,19021004.000000,28355088.000000,21584816.000000,6366397.000000,1483708.000000,28355969.000000,30753178.000000,20687738.000000,16681050.000000,8342466.000000,9061761.000000,12110660.000000,26932605.000000,19926987.000000,17868519.000000,32708430.000000,8017546.000000,12508835.000000,16193871.000000,28590836.000000,5030046.000000,33431408.000000,23612982.000000,30763129.000000,25536656.000000,13356366.000000,25613390.000000,10318961.000000,26061853.000000,14900423.000000,15456226.000000,5909160.000000,25094924.000000,5095894.000000,4313961.000000,16794911.000000,29363937.000000,6542869.000000,943949.000000,17086336.000000,29106622.000000,21701794.000000,22848035.000000,5458833.000000,31580934.000000,12743703.000000,32942696.000000,22005051.000000,288021.000000,27153527.000000,20412888.000000,2904369.000000,13185266.000000,9664216.000000,22049349.000000,20791258.000000,9106514.000000,32360220.000000,4171861.000000,21177130.000000,12379584.000000,12969941.000000,20583999.000000,16340352.000000,23683232.000000,20722632.000000,14112307.000000,22314744.000000,26198057.000000,15575100.000000,28412470.000000,17391373.000000,17720807.000000,26062013.000000,33245469.000000,9374430.000000,16894912.000000,29724053.000000,10829332.000000,11096244.000000,29814772.000000,2944324.000000,4181741.000000,30047431.000000,5882388.000000,20333387.000000,12867266.000000,18101610.000000,31497579.000000,27878545.000000,18280133.000000,10716438.000000,28395041.000000,28288388.000000,31858185.000000,8664661.000000,18194512.000000,6763234.000000,31087723.000000,32520781.000000,3212129.000000,4926723.000000,20397223.000000,16431011.000000,17306416.000000,32863971.000000,10225309.000000,2547924.000000,15036911.000000,45371.000000,31555452.000000,9106375.000000,67172.000000,6939146.000000,33440977.000000,8987097.000000,30216115.000000,6513996.000000,6497175.000000,6584556.000000,11031244.000000,8539480.000000,24499348.000000,3414812.000000,3119894.000000,8421622.000000,7770968.000000,32889565.000000,6573967.000000,17746056.000000,31082775.000000,7038176.000000,26895019.000000,27535982.000000,2216414.000000,5198609.000000,28157780.000000,117235.000000,27915062.000000,1755066.000000,22548346.000000,21089194.000000,21883672.000000,7201390.000000,8455225.000000,28706733.000000,6187183.000000,30687437.000000,31458752.000000,1817993.000000,1990728.000000,10392007.000000,32970485.000000,7912801.000000,28508733.000000,17770907.000000,8084162.000000,24477137.000000,27153651.000000,19532647.000000,21676213.000000,8279089.000000,7380482.000000,31525314.000000,1723533.000000,16680631.000000,27821430.000000,22472189.000000,5149441.000000,7051558.000000,10364476.000000,317105.000000,25243249.000000,11990440.000000,6949421.000000,10015456.000000,16832012.000000,22762715.000000,2886289.000000,20315962.000000,25900424.000000,22021842.000000,954736.000000,32234760.000000,4069655.000000,9142396.000000,20613406.000000,10784352.000000,12209501.000000,11717317.000000,1205797.000000,15474786.000000,20263265.000000,24163665.000000,4530320.000000,4487533.000000,10866979.000000,10900677.000000,7081580.000000,22899845.000000,11598184.000000,16526497.000000,30506969.000000,11662885.000000,20714032.000000,17801026.000000,13707909.000000,6069616.000000,26774528.000000,5418042.000000,30284953.000000,14072771.000000,11839305.000000,25954751.000000,5152943.000000,15201051.000000,23193132.000000,15980494.000000,6201476.000000,22571160.000000,9033295.000000,25326830.000000,121498.000000,14698964.000000,33466410.000000,11619426.000000,3724824.000000,23248065.000000,4009058.000000,15865674.000000,18232697.000000,8701036.000000,9712211.000000,12250118.000000,3966920.000000,8168199.000000,21276138.000000,10860008.000000,20612455.000000,14558993.000000,8936530.000000,8488877.000000,17097160.000000,5301279.000000,19582406.000000,14506609.000000,14988860.000000,13488937.000000,23668149.000000,26329879.000000,7853542.000000,28439599.000000,19889235.000000,20703422.000000,4913503.000000,6015378.000000,32459519.000000,15467756.000000,6854518.000000,31367465.000000,8323728.000000,17075472.000000,31550535.000000,25341631.000000,28443023.000000,3159108.000000,31464403.000000,25286439.000000,11137795.000000,823542.000000,6277062.000000,10366780.000000,22923341.000000,11476128.000000,22563786.000000,13218272.000000,5346087.000000,27266011.000000,2236624.000000,11627771.000000,6445921.000000,28966386.000000,15016541.000000,8821500.000000,25798770.000000,2821809.000000,8336564.000000,27689611.000000,23408270.000000,14234621.000000,3082162.000000,21937240.000000,29541322.000000,32260616.000000,22909500.000000,26124205.000000,31163203.000000,14034117.000000,19453848.000000,20703331.000000,31804508.000000,20378259.000000,21178822.000000,10108974.000000,19110656.000000,29397248.000000,5741543.000000,15536148.000000,27860876.000000,1659579.000000,426173.000000,28069398.000000,23068906.000000,20646832.000000,29459216.000000,18236617.000000,22000282.000000,28459894.000000,12998346.000000,33504738.000000,14436082.000000,2915218.000000,11118401.000000,27563508.000000,23812031.000000,17414762.000000,2394847.000000,20230093.000000,23707702.000000,20721173.000000,14999483.000000,8156172.000000,14930124.000000,15930220.000000,15132949.000000,6080625.000000,9502372.000000,17235538.000000,9483050.000000,15325404.000000,10861076.000000,20606907.000000,4158308.000000,21875818.000000,23451903.000000,6719870.000000,22893990.000000,13387793.000000,25198821.000000,5938398.000000,21550309.000000,5917369.000000,22287833.000000,22693809.000000,26113757.000000,20913629.000000,28701554.000000,33481589.000000,23729274.000000,33174781.000000,3584459.000000,6385290.000000,757280.000000,32380899.000000,1048678.000000,26092203.000000,1297496.000000,27689758.000000,26423267.000000,24583381.000000,31628007.000000,30593734.000000,22646921.000000,14796913.000000,11595951.000000,23449215.000000,13896265.000000,10997017.000000,23419114.000000,1109993.000000,16977718.000000,14969033.000000,1905861.000000,23272883.000000,22100355.000000,169910.000000,1127866.000000,8340217.000000,7439907.000000,2818203.000000,11748027.000000,12104055.000000,14024277.000000,31944977.000000,25680078.000000,27187500.000000,20864690.000000,4075755.000000,12377782.000000,6822124.000000,27012103.000000,16749567.000000,3839866.000000,12346601.000000,21183308.000000,6944253.000000,1246334.000000,32102203.000000,30266565.000000,24472141.000000,9587667.000000,31619941.000000,729342.000000,25614912.000000,1138116.000000,30276892.000000,28816479.000000,18811032.000000,21026843.000000,14542512.000000,22844381.000000,16786917.000000,4399782.000000,26904254.000000,19069010.000000,16042666.000000,26988832.000000,11215903.000000,10219012.000000,19921259.000000,11992410.000000,2164233.000000,10621601.000000,1117567.000000,18948880.000000,27347531.000000,22043875.000000,33134050.000000,780286.000000,22208853.000000,17323883.000000,25485146.000000,33226392.000000,12489291.000000,13153980.000000,26664736.000000,18554054.000000,23241378.000000,31185641.000000,2482798.000000,10348957.000000,7937124.000000,25492277.000000,8309323.000000,32480419.000000,4552710.000000,852835.000000,23716829.000000,21679014.000000,2735644.000000,15820945.000000,10799995.000000,3709241.000000,30240133.000000,33531074.000000,21210391.000000,1651639.000000,21075117.000000,11150323.000000,14706355.000000,13197288.000000,4952467.000000,12975401.000000,17539875.000000,26876254.000000,29518312.000000,6746182.000000,16851441.000000,6326416.000000,13377472.000000,7283529.000000,14939651.000000,29200339.000000,21214957.000000,7659441.000000,169897.000000,19348154.000000,24770773.000000,25000000.000000,6845568.000000,32670525.000000,21408406.000000,23241204.000000,22139263.000000,10774268.000000,28597255.000000,2483567.000000,26805989.000000,6385520.000000,6159323.000000,15250733.000000,}; 79 | uint32_t bitrev_lut[PARAM_N] = {0,256,128,384,64,320,192,448,32,288,160,416,96,352,224,480,16,272,144,400,80,336,208,464,48,304,176,432,112,368,240,496,8,264,136,392,72,328,200,456,40,296,168,424,104,360,232,488,24,280,152,408,88,344,216,472,56,312,184,440,120,376,248,504,4,260,132,388,68,324,196,452,36,292,164,420,100,356,228,484,20,276,148,404,84,340,212,468,52,308,180,436,116,372,244,500,12,268,140,396,76,332,204,460,44,300,172,428,108,364,236,492,28,284,156,412,92,348,220,476,60,316,188,444,124,380,252,508,2,258,130,386,66,322,194,450,34,290,162,418,98,354,226,482,18,274,146,402,82,338,210,466,50,306,178,434,114,370,242,498,10,266,138,394,74,330,202,458,42,298,170,426,106,362,234,490,26,282,154,410,90,346,218,474,58,314,186,442,122,378,250,506,6,262,134,390,70,326,198,454,38,294,166,422,102,358,230,486,22,278,150,406,86,342,214,470,54,310,182,438,118,374,246,502,14,270,142,398,78,334,206,462,46,302,174,430,110,366,238,494,30,286,158,414,94,350,222,478,62,318,190,446,126,382,254,510,}; 80 | --------------------------------------------------------------------------------