source: proiecte/HadoopA51/src/java/ro/pub/cs/pp/a51hadoop/algorithm/a51/A51Hashfn.java @ 166

Last change on this file since 166 was 166, checked in by (none), 14 years ago

HadoopA51: imported git repository from github

File size: 4.9 KB
Line 
1package ro.pub.cs.pp.a51hadoop.algorithm.a51;
2
3import ro.pub.cs.pp.a51hadoop.algorithm.Hashfn;
4import ro.pub.cs.pp.a51hadoop.algorithm.a51.A51Bitops;
5import ro.pub.cs.pp.a51hadoop.algorithm.a51.A51Constants;
6import ro.pub.cs.pp.a51hadoop.algorithm.a51.A51KeySetup;
7
8/*
9 * Apply a hash function on a given string.
10 */
11public class A51Hashfn implements Hashfn
12{
13
14
15
16        /* do we have a majority of set bits in the middle of the
17         * registers? */
18        public static boolean middle_bit_majority(final int[] R)
19        {
20                int sum = 0;
21                for (int i = 0; i < R.length; i++)
22                        sum += A51Bitops.get_ith_bit(R[i], A51Constants.R_middle_pos[i]);
23                return sum >= 2;
24        }
25
26
27        /* Clock two or three of R1, R2, R3, with clock control
28         * according to their middle bits.
29         *
30         * Specifically, we clock Ri whenever Ri's middle bit agrees
31         * with the majority value of the three middle bits.
32         */
33        public static int[] clock(final int[] R)
34        {
35                boolean non_zero_majority = middle_bit_majority(R);
36                int ret[] = new int[3];
37                for (int i = 0; i < R.length; i++)
38                {
39                        int middle_bit = R[i] & (1 << A51Constants.R_middle_pos[i]);
40                        boolean middle_bit_non_zero = (middle_bit != 0);
41                        boolean middle_bit_is_majoritar = middle_bit_non_zero == non_zero_majority;
42
43                        /*
44                         * Only clock Ri when it is the same as the
45                         * majority of middle bits
46                         */
47                        if (middle_bit_is_majoritar)
48                                ret[i] = A51Bitops.clockone(R[i], A51Constants.R_mask[i],
49                                                            A51Constants.R_feedback_taps[i]);
50                        else
51                                ret[i] = R[i];
52                }
53                return ret;
54        }
55
56
57
58
59
60        /*
61         * Generate an output bit from the current state.
62         *
63         * You grab a bit from each register via the output generation
64         * taps; then you XOR the resulting three bits.
65         */
66        private static int getbit(final int[] R)
67        {
68                int ret = 0;
69                /*
70                 * Original reference implementation XOR-ed
71                 * parity(R[i] & (1 << R_out[i])).
72                 *
73                 * Since R_output_taps[i] only contains single bits,
74                 * the argument passed to parity has one or zero bits.
75                 *
76                 * Moving the given bit with R_output_taps[i] to left
77                 * produces the same result.
78                 */
79                for (int i = 0; i < R.length; i++)
80                        ret ^= A51Bitops.get_ith_bit(R[i], A51Constants.R_output_taps[i]);
81                return ret;
82        }
83
84
85
86        /* Generate output.
87         *
88         * We generate 228 bits of keystream output.
89         *
90         * The first 114 bits is for the A->B frame;
91         * the next 114 bits is for the B->A frame.
92         *
93         * The buffers are allocate elsewhere each direction, and this
94         * function fills them. */
95        public static int[] run(int AtoBkeystream[], int BtoAkeystream[], int[] R)
96        {
97                int i;
98
99                /* Zero out the output buffers. */
100                for (i = 0; i <= 113/8; i++)
101                        AtoBkeystream[i] = BtoAkeystream[i] = 0;
102
103                /* Generate 114 bits of keystream for the
104                 * A->B direction.  Store it, MSB first. */
105                for (i = 0; i < 114; i++)
106                {
107                        R = clock(R);
108                        AtoBkeystream[i/8] |= getbit(R) << (7 - (i & 7));
109                }
110
111                /* Generate 114 bits of keystream for the
112                 * B->A direction.  Store it, MSB first. */
113                for (i = 0; i < 114; i++)
114                {
115                        R = clock(R);
116                        BtoAkeystream[i/8] |= getbit(R) << (7 - (i & 7));
117                }
118
119                return R;
120        }
121
122
123        private static void printf(String arg)
124        {
125                System.out.print(arg);
126        }
127
128        public static void test()
129        {
130                int i, failed = 0;
131                int key[] = {0x12, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
132                int frame = 0x134;
133                final int goodAtoB[] = { 0x53, 0x4E, 0xAA, 0x58, 0x2F, 0xE8, 0x15,
134                                    0x1A, 0xB6, 0xE1, 0x85, 0x5A, 0x72, 0x8C, 0x00 };
135                final int goodBtoA[] = { 0x24, 0xFD, 0x35, 0xA3, 0x5D, 0x5F, 0xB6,
136                                    0x52, 0x6D, 0x32, 0xF9, 0x06, 0xDF, 0x1A, 0xC0 };
137                int AtoB[], BtoA[];
138                AtoB = new int[15];
139                BtoA = new int[15];
140
141
142                A51KeySetup keysetup = new A51KeySetup(key, frame);
143                int[] R = keysetup.R;
144
145
146                int s = R[0] << 23 + 22 | R[1] << 23 | R[2];
147                R = run(AtoB, BtoA, R);
148
149                /* Compare against the test vector. */
150                for (i = 0; i < AtoB.length; i++)
151                        if (AtoB[i] != goodAtoB[i])
152                                failed = 1;
153                for (i = 0; i < BtoA.length; i++)
154                        if (BtoA[i] != goodBtoA[i])
155                                failed = 1;
156
157
158                printf("key: 0x");
159                for (i=0; i<8; i++)
160                        printf(String.format("%02X", key[i]));
161                printf("\n");
162                printf(String.format("frame number: 0x%06X\n", frame));
163                printf("known good output:\n");
164                printf(" A->B: 0x");
165                for (i=0; i<15; i++)
166                        printf(String.format("%02X", goodAtoB[i]));
167                printf("  B->A: 0x");
168                for (i=0; i<15; i++)
169                        printf(String.format("%02X", goodBtoA[i]));
170                printf("\n");
171                printf("observed output:\n");
172                printf(" A->B: 0x");
173                for (i=0; i<15; i++)
174                        printf(String.format("%02X", AtoB[i]));
175                printf("  B->A: 0x");
176                for (i=0; i<15; i++)
177                        printf(String.format("%02X", BtoA[i]));
178                printf("\n");
179
180                printf("failed=" + failed + "\n");
181
182                if (failed == 0)
183                {
184                        System.out.println("Self-check succeeded: everything looks ok.\n");
185                        return;
186                }
187                else
188                {
189                        // Problems!  The test vectors didn't compare
190                        System.out.println("\nI don't know why this broke; contact the authors.\n");
191                }
192
193
194        }
195
196        public String hashfn(String txt)
197        {
198                /*
199                 * dummy implementation
200                 */
201                return txt;
202        }
203
204
205        public static void main(String[] args)
206        {
207                test();
208        }
209}
Note: See TracBrowser for help on using the repository browser.