/* @(#)b-m.c 1.3 (QUALCOMM) 09/02/02 */ /* Berlekamp-Massey algorithm */ /* see Menezes et al, P.201 */ #include #include #include typedef unsigned char uchar; #define MAX 100000 int verbose = 0; int polyform = 0; uchar inbuf[MAX / 8]; /* byte-binary input buffer */ int n, N; /* current / total number of input bits */ int L; /* current linear complexity */ int m; uchar s[MAX], C[MAX], B[MAX], T[MAX]; /* polynomials */ uchar d; /* current discrepancy */ #define cp(x,y) memcpy(x,y,n+1); void pr(char *s, uchar *a) { register int i; int first = 1; if (!polyform) { printf("%s", s); for (i = 0; i <= L; ++i) { printf("%d", a[i]); } } else { for (i = 0; i <= L; ++i) { if (a[i]) { if (first) first = 0; else printf(" + "); } if (i == 0 && a[i]) printf("1"); else if (i == 1 && a[i]) printf("x"); else if (a[i]) printf("x^%d", i); } } printf("\n"); } int main(int ac, char **av) { int i, j; char *myname = av[0]; int warned = 0; while (ac >= 2 && av[1][0] == '-') { if (strcmp(av[1], "-v") == 0) { verbose = 1; ++av, --ac; } else if (strcmp(av[1], "-p") == 0) { polyform = 1; ++av, --ac; } } if (ac > 2) { fprintf(stderr, "Usage: %s [-v|-p] [bits]\n (or binary on stdin)\n", myname); return 1; } else if (ac == 2) { N = strlen(av[1]); for (i = 0; i < N; ++i) s[i] = av[1][i] == '0' ? 0 : 1; } else { N = fread(inbuf, 1, MAX/8, stdin); if (N <= 0) { fprintf(stderr, "%s: no input\n", myname); return 1; } /* expand inbuf to be one bit per byte */ for (i = 0; i < N; ++i) { for (j = 0; j < 8; ++j) { s[8*i + j] = (inbuf[i] >> (7 - j)) & 0x1; } } N *= 8; } /* s[0..N] is the input sequence */ /* initialise */ n = 0; C[n] = B[n] = 1; L = 0; m = -1; /* accept a bit of the input sequence, adjusting as needed */ while (n < N) { /* compute discrepancy d */ d = s[n]; for (i = 1; i <= L; ++i) d ^= C[i] & s[n - i]; /* recompute sequence if necessary */ if (d) { cp(T, C); for (i = n-m, j = 0; i <= n+1; ++i, ++j) C[i] ^= B[j]; if (L <= n/2) { /* we have a jump in linear complexity -- check if unusual */ if ((n/2 - L) > 6 && L > 2 && !warned) { printf("Large jump (%d) in linear complexity detected\n", n - 2*L); warned = 1; } L = n + 1 - L; m = n; cp(B, T); } if (verbose) { printf("n=%d s[%d]=%d d=%d L=%d m=%d\n", n, n-1, s[n-1], d, L, m); pr("T=", T); pr("C=", C); pr("B=", B); } } ++n; } /* count weight of polynomial -- don't include last bit */ for (i = j = 0; i < L; ++i) j += C[i]; printf("L=%d W=%d\n", L, j); pr("", C); if (L > (N/2-4)) { printf("Sequence is probably not linear"); if (N == MAX) printf(" up to MAX (%d) tested", MAX); printf("\n"); return warned; } return 2; }