static void KeccakPermutation(u64 st[25]) { int round, j; u64 t, bc[5]; for (round = 0; round < KECCAK_ROUNDS; round++) { // Theta #define THETA1(i) \ bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20] THETA1(0); THETA1(1); THETA1(2); THETA1(3); THETA1(4); #define THETA2(i) \ t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); \ st[0 + i] ^= t; \ st[5 + i] ^= t; \ st[10 + i] ^= t; \ st[15 + i] ^= t; \ st[20 + i] ^= t THETA2(0); THETA2(1); THETA2(2); THETA2(3); THETA2(4); // Rho Pi #define RHOPI(i, rotc, piln) \ bc[0] = st[piln]; \ st[piln] = ROTL64(t, rotc); \ t = bc[0] t = st[1]; RHOPI(0, 1, 10); RHOPI(1, 3, 7); RHOPI(2, 6, 11); RHOPI(3, 10, 17); RHOPI(4, 15, 18); RHOPI(5, 21, 3); RHOPI(6, 28, 5); RHOPI(7, 36, 16); RHOPI(8, 45, 8); RHOPI(9, 55, 21); RHOPI(10, 2, 24); RHOPI(11, 14, 4); RHOPI(12, 27, 15); RHOPI(13, 41, 23); RHOPI(14, 56, 19); RHOPI(15, 8, 13); RHOPI(16, 25, 12); RHOPI(17, 43, 2); RHOPI(18, 62, 20); RHOPI(19, 18, 14); RHOPI(20, 39, 22); RHOPI(21, 61, 9); RHOPI(22, 20, 6); RHOPI(23, 44, 1); // Chi #define CHI1(i,j) \ bc[i] = st[j + i] #define CHI2(i,j) \ st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5] for (j = 0; j < 25; j += 5) { CHI1(0,j); CHI1(1,j); CHI1(2,j); CHI1(3,j); CHI1(4,j); CHI2(0,j); CHI2(1,j); CHI2(2,j); CHI2(3,j); CHI2(4,j); } // Iota st[0] ^= keccakf_rndc[round]; } }
double OPTchi2(double *p, double *x, int m, int n, void *data) { static int i = 0; OPTparams *OPTpa = (OPTparams *) data; ODEparams *ODEpa = OPTpa->ODEpa; double *vdata = OPTpa->vdata; double *alpha = p; double *sp = OPTpa->spectrum; double *beta = p + ODEpa->nap; double *filter = p + ODEpa->nap + ODEpa->nbp; int k; ODEupdate(ODEpa, alpha, beta, filter); ODErun(vdata, OPTpa->tmax, OPTpa->dt, ODEpa); ODEfilter(vdata, OPTpa->target_ns, OPTpa->nfft, ODEpa); scaleData(1 / getABSmax(vdata, OPTpa->target_ns), vdata, OPTpa->target_ns); ODEtarget(x, vdata, OPTpa->target_ns, OPTpa->nfft, OPTpa->ntarget, OPTpa->nslices, &OPTpa->nchunks); return CHI2(OPTpa->spectrum, x, OPTpa->n); }