/* ------------------------------------------------------------------------ Bob Jenkins, 1996 Code for breaking rc4. Doesn't work. ------------------------------------------------------------------------ */ #define ALPHA 6 #define SIZE (1<r correctly. */ static void rc4( rc4state *s) { int i,j,x,y,*m,*r; j = s->j; m = s->m; r = s->r; for (i=0; ij = j; } /* RC4 backwards SIZE steps. Leaves s->r invalid. */ static void rc4b( rc4state *s) { int i,j,x,y,*m; j = s->j; m = s->m; for (i=SIZE; i--; ) { x=m[i]; y=m[j]; m[i]=y; m[j]=x; j=(j-y)&MASK; } s->j = j; } /* Copy the state of rc4 */ static void rc4copy( rc4state *outs, rc4state *ins) { int i; outs->j = ins->j; for (i=0; im[i] = ins->m[i]; outs->r[i] = ins->r[i]; } } /* print out a message if s1 and s2 are not the same */ static int rc4test( rc4state *s1, rc4state *s2) { int i; if (s1->j != s2->j) printf( "rc4test: Accumulator is different, %d %d\n", s1->j, s2->j); for (i=0; im[i] != s2->m[i]) printf( "rc4test: memory [%d] is different, %d %d\n", i, s1->m[i], s2->m[i]); } /* initialize rc4 */ int rc4init( rc4state *s) { int i; int r[SIZE]; s->j = 10; for (i=0; im[i]=i; } /* ------------------------------------------------------------------------ Source of random values ------------------------------------------------------------------------ */ static int rng_i; static rc4state rng_s; int rng() /* return one random value */ { if (++rng_i >= SIZE) { rc4( &rng_s); rng_i=0; } return rng_s.r[rng_i]; } /* ------------------------------------------------------------------------ Tools for breaking rc4 ------------------------------------------------------------------------ */ /* * Count how many relevant r values match the stream generated by s. * * s - rc4 state, already run. * n - array size * r - array of results to compare against. * mask - array same size as r, true/false, pay attention to this value */ static int count_match( rc4state *s, int n, int *r, int *mask) { int i, count; count = 0; if (n <= SIZE) { for (i=0; ir[i] == r[i])) ++count; } else { rc4state s2; int j; rc4copy( &s2, s); for (j=0; jm[x]; s->m[x]=s->m[y]; s->m[y]=j;} /* swap */ rc4b( s); rc4( s); this = count_match( s, n, r, mask); if (this>best) { /* improvement, report progress */ /* printf( "this is %4d\n",this); */ i = 0; best = this; } else if (this==best) ; /* not losing ground, keep the change */ else {j=s->m[x]; s->m[x]=s->m[y]; s->m[y]=j;} /* bad, so unswap */ if (this==m) return 1; /* found a solution? stop */ } return 0; } int main() { long int i, j; /* counter */ int k = 10; /* how many relevant entries */ int r[RSIZE]; /* results to match */ int maska[RSIZE]; /* which results are relevant */ int mask[RSIZE]; /* which results are relevant */ int hit[SIZE]; rc4state s; /* rc4 internal state */ rc4state s2; /* extra internal state */ /* initialize randomness source */ rc4init( &rng_s); rc4( &rng_s); rc4( &rng_s); rc4( &rng_s); rc4( &rng_s); rc4( &rng_s); rng_i = 0; /* confirm that rc4 and rc4b work correctly, and initialize s->r */ rc4init( &s); rc4copy( &s2, &s); rc4b( &s); rc4( &s); rc4test( &s, &s2); /* initialize the results to be matched */ for (i=0; i SIZE-k && i < SIZE+k && i != SIZE) mask[i] = 1; else mask[i] = 0; if (i > SIZE-k/2 && i < SIZE+k/2 && i != SIZE) maska[i] = 1; else maska[i] = 0; } /* no hits so far */ for (i=0; i