void _Generate(FF_pike ctx) { for (int i = 0; i < 1024; ++i) { int carry = ctx.addikey[0].carry + ctx.addikey[1].carry + ctx.addikey[2].carry; if (carry == 0 || carry == 3) { _AddikeyNext(ctx.addikey[0]); _AddikeyNext(ctx.addikey[1]); _AddikeyNext(ctx.addikey[2]); } else { int flag = 0; if (carry == 2) { flag = 1; } for (int j = 0; j < 3; ++j) { if (ctx.addikey[j].carry == flag) { _AddikeyNext(ctx.addikey[j]); } } } uint tmp = ctx.addikey[0].buffer[ctx.addikey[0].index] ^ ctx.addikey[1].buffer[ctx.addikey[1].index] ^ ctx.addikey[2].buffer[ctx.addikey[2].index]; int base_ = i << 2; ctx.buffer[base_] = (byte)tmp; ctx.buffer[base_ + 1] = (byte)(tmp >> 8); ctx.buffer[base_ + 2] = (byte)(tmp >> 16); ctx.buffer[base_ + 3] = (byte)(tmp >> 24); } ctx.index = 0; }
FF_pike NewCtx(uint sd) { FF_pike ctx = new FF_pike(); ctx.sd = sd ^ GENIUS_NUMBER; ctx.addikey[0].sd = ctx.sd; ctx.addikey[0].sd = Linearity(ctx.addikey[0].sd); ctx.addikey[0].dis1 = 55; ctx.addikey[0].dis2 = 24; ctx.addikey[1].sd = ((ctx.sd & 0xAAAAAAAA) >> 1) | ((ctx.sd & 0x55555555) << 1); ctx.addikey[1].sd = Linearity(ctx.addikey[1].sd); ctx.addikey[1].dis1 = 57; ctx.addikey[1].dis2 = 7; ctx.addikey[2].sd = ~(((ctx.sd & 0xF0F0F0F0) >> 4) | ((ctx.sd & 0x0F0F0F0F) << 4)); ctx.addikey[2].sd = Linearity(ctx.addikey[2].sd); ctx.addikey[2].dis1 = 58; ctx.addikey[2].dis2 = 19; for (int i = 0; i < 3; ++i) { uint tmp = ctx.addikey[i].sd; for (int j = 0; j < 64; ++j) { for (int k = 0; k < 32; ++k) { tmp = Linearity(tmp); } ctx.addikey[i].buffer[j] = tmp; } ctx.addikey[i].carry = 0; ctx.addikey[i].index = 63; } ctx.index = 4096; return(ctx); }
void Codec(FF_pike ctx, ref byte[] data, int offset = 0) { if (data.Length - offset <= 0) { return; } unsafe { fixed(byte *pDataBase_ = data, pSequenceBase = ctx.buffer) { int len = data.Length - offset; byte *pDataBase = pDataBase_ + offset; byte *pData = pDataBase; while (true) { int n = 4096 - ctx.index; if (n <= 0) { _Generate(ctx); continue; } if (n > len - (int)(pData - pDataBase)) { n = len - (int)(pData - pDataBase); } byte *pSequence = pSequenceBase + ctx.index; int w = n / sizeof(uint); if (w > 0) { uint *dx = (uint *)pData; uint *ax = (uint *)pSequence; for (int i = 0; i < w; ++i) { *dx ^= *ax; ++dx; ++ax; } } pData += w * sizeof(uint); pSequence += w * sizeof(uint); for (int i = (n - n % sizeof(uint)); i < n; ++i) { *pData ^= *pSequence; ++pData; ++pSequence; } ctx.index += n; if (pData - pDataBase == len) { break; } } } } }
public Pike(uint key) { ctx = NewCtx(key); }