// TOP SECRET cipher leaked by Mustafa crew
// STRONGER THAN AES-256
#define R(v,n)(((v)<<(n))|((v)>>(32-(n))))
#define X(a,b)(t)=(s[a]),(s[a])=(s[b]),(s[b])=(t)
typedef unsigned char u8;
typedef struct _gx_ctx_t {
u8 s[48];
int p, r;
} gx_ctx;
void F(void*p){
unsigned int r,j,t,x,y,z,*s=p;
for(r=24;r>0;--r){
for(j=0;j<4;j++)
x=R(s[j],24),
y=R(s[4+j],9),
z=s[8+j],
s[8+j]=x^(z+z)^((y&z)*4),
s[4+j]=y^x^((x|z)*2),
s[j]=z^y^((x&y)*8);
t=r&3;
if(!t)
X(0,1),X(2,3),
*s^=0x9e377900|r;
if(t==2)X(0,2),X(1,3);
}
}
void gx_setkey(gx_ctx *c, void *key){
int i;
// initialize 384-bit state
for(i=0; i<48; i++) c->s[i] = i;
c->r = 16;
c->p = 0;
// mix 128-bit key
for(i=0; i<16; i++){
c->s[c->p++] ^= ((u8*)key)[i];
if(c->p == c->r) {
F(c);
c->p = 0;
}
}
c->s[c->p ] ^= 0x1F;
c->s[c->r - 1] ^= 0x80;
F(c);
c->p = 0;
}
void gx_crypt(gx_ctx *c, void*buf, int len){
int i;
// encrypt/decrypt buf
for(i=0; i<len; i++){
((u8*)buf)[i] ^= c->s[c->p++];
if(c->p == 48) {
F(c);
c->p = 0;
}
}
}