static FFelem FFpow(FFelem b, int e) { if (e == 0) return 1; if (e < 0) return FFpow(FFdiv(1, b), -e); if (e == 1) return b; if (e&1) return FFmul(b, FFpow(FFmul(b, b), (e-1)/2)); return FFpow(FFmul(b, b), e/2); }
DUPFF DUPFFexgcd(DUPFF *fcofac, DUPFF *gcofac, const DUPFF f, const DUPFF g) { DUPFF u, v, uf, ug, vf, vg; FFelem q, lcu, lcvrecip, p; int df, dg, du, dv; if (DUPFFdeg(f) < DUPFFdeg(g)) return DUPFFexgcd(gcofac, fcofac, g, f); if (DUPFFdeg(f) != 2 || DUPFFdeg(g) != 1) abort(); if (f->coeffs[0] == 0) return f; p = 2; df = DUPFFdeg(f); if (df < 0) df = 0; /* both inputs are zero */ dg = DUPFFdeg(g); if (dg < 0) dg = 0; /* one input is zero */ u = DUPFFcopy(f); v = DUPFFcopy(g); uf = DUPFFnew(dg); uf->coeffs[0] = 1; uf->deg = 0; ug = DUPFFnew(df); vf = DUPFFnew(dg); vg = DUPFFnew(df); vg->coeffs[0] = 1; vg->deg = 0; while (DUPFFdeg(v) > 0) { dv = DUPFFdeg(v); lcvrecip = FFmul(1, v->coeffs[dv]); while (DUPFFdeg(u) >= dv) { du = DUPFFdeg(u); lcu = u->coeffs[du]; q = FFmul(lcu, lcvrecip); DUPFFshift_add(u, v, du-dv, p-q); DUPFFshift_add(uf, vf, du-dv, p-q); DUPFFshift_add(ug, vg, du-dv, p-q); } DUPFFswap(u, v); DUPFFswap(uf, vf); DUPFFswap(ug, vg); } if (DUPFFdeg(v) == 0) { DUPFFswap(u, v); DUPFFswap(uf, vf); DUPFFswap(ug, vg); } DUPFFfree(vf); DUPFFfree(vg); DUPFFfree(v); *fcofac = uf; *gcofac = ug; return u; }
void DUPFFformal_deriv2(DUPFF fprime, const DUPFF f) /* fprime and f may be identical */ { int df, dans, j, p; p = CurrentFF.prime; df = DUPFFdeg(f); /* find degree of the answer */ for (dans=df; dans >= 1; dans--) if (f->coeffs[dans] != 0 && (dans%p != 0)) break; dans--; if (dans < 0) { fprime->deg = -1; return; } if (fprime->maxdeg < dans) { JERROR(JERROR_DEG_TOO_LOW); return; } fprime->deg = dans; for (j = 1; j <= dans+1; j++) fprime->coeffs[j-1] = FFmul(j%p, f->coeffs[j]); return; }
void AES::InvMixColumns(unsigned char state[][4]) { unsigned char t[4]; int r,c; for(c=0; c< 4; c++) { for(r=0; r<4; r++) { t[r] = state[r][c]; } for(r=0; r<4; r++) { state[r][c] = FFmul(0x0e, t[r]) ^ FFmul(0x0b, t[(r+1)%4]) ^ FFmul(0x0d, t[(r+2)%4]) ^ FFmul(0x09, t[(r+3)%4]); } } }
void CBm53AES::MixColumns(unsigned char state[][4]) { unsigned char t[4]; int r,c; for(c=0; c< 4; c++) { for(r=0; r<4; r++) { t[r] = state[r][c]; } for(r=0; r<4; r++) { state[r][c] = FFmul(0x02, t[r]) ^ FFmul(0x03, t[(r+1)%4]) ^ FFmul(0x01, t[(r+2)%4]) ^ FFmul(0x01, t[(r+3)%4]); } } }
static void InvMixColumns(unsigned char data[bytes_row_size][bytes_columns_size]) { unsigned char v[bytes_columns_size]; for(size_t col = 0; col < bytes_columns_size; ++col) { //提取一列数据 for(size_t row = 0; row < bytes_row_size; ++row) { v[row] = data[row][col]; } //列混淆 for(size_t row = 0; row < bytes_row_size; ++row) { data[row][col] = FFmul(0x0e, v[row]) ^ FFmul(0x0b, v[(row+1)%4]) ^ FFmul(0x0d, v[(row+2)%4]) ^ FFmul(0x09, v[(row+3)%4]); } } }
void InvMixColumns(unsigned int *state){ unsigned int b[16]={0}; int i=0; for(i=0;i<4;i++){ b[i*4]=(state[i]&0xff000000)>>24; b[i*4+1]=(state[i]&0xff0000)>>16; b[i*4+2]=(state[i]&0xff00)>>8; b[i*4+3]=state[i]&0xff; } for(i=0;i<4;i++){ state[i]=0; int j=0; for(j=0;j<4;j++){ state[i] += FFmul(b[i*4],InvMC_Matrix[j*4]) ^ FFmul(b[i*4+1],InvMC_Matrix[j*4+1]) ^ FFmul(b[i*4+2],InvMC_Matrix[j*4+2]) ^ FFmul(b[i*4+3],InvMC_Matrix[j*4+3]); if(j<3) state[i] <<= 8; } } }
DUPFF DMPZ_to_DUPFF(DMPZ f, int var, int *substitution) { FFelem p = CurrentFF.prime; int df, d, c, i; DUPFF ans; DMPZ iter; df = DMPZdeg(f, var); ans = DUPFFnew(df); for(i=0; i<=df;i++) ans->coeffs[i] = 0; for(iter=f;iter;iter = iter->next) { d = iter->exps[var]; c = mpz_fdiv_ui(iter->coeff, p); for(i=0; c!=0 && i<NVARS;i++) if (i != var) c = FFmul(c, FFpow(substitution[i], iter->exps[i])); ans->coeffs[d] += c; if (ans->coeffs[d] >= p) ans->coeffs[d] -= p; } for(i=df;i>=0;i--) if (ans->coeffs[i] != 0) break; ans->deg = i; return ans; }