Methods and apparatus for enhanced CMEA including a CMEA iteration preceded and followed by transformations and employing an involuntary lookup6876744Abstract Methods and apparatus for enhanced CMEA, or ECMEA, processing. A forward ECMEA and a reverse ECMEA process are provided. The forward ECMEA process decrypts text encrypted by the reverse ECMEA process and the reverse ECMEA process decrypts text encrypted by the forward ECMEA process. The forward ECMEA process employs a first transformation, an iteration of the CMEA process, and a second transformation. The reverse ECMEA process employs a first inverse transformation, an iteration of the CMEA process, and a second inverse transformation. The transformations and inverse transformations, and the iterations of the CMEA process, employ secret offsets to improve security. The transformations and the iteration of the CMEA process also employ an enhanced tbox function using an involutary lookup table. Claims We claim: Description FIELD OF THE INVENTION
tbox(z) = I(I(I(I(I(I(I(I(I(I(I(I(I(I(z+k0)XOR k1)+k2)XOR k3)+
k4)XOR k5)+k6)XOR k7)-k6)XOR k5)-k4)XOR k3)-k2)XOR k1)-k0
where "+" denotes modulo 256 addition,
"-" denotes modulo 256 subtraction,
"XOR" is the XOR function,
"z" is the function argument,
k0, . . . , k7 are the eight octets of ECMEA key,
and I( ) is the outcome of a known ibox 8-bit table look-up. The ibox table is an involutary lookup table with entries chosen to perform involutary mapping of 8-bit bytes onto 8-bit bytes. A preferred example of an ibox table is as follows:
0xa2, 0xfc, 0x5c, 0x12, 0x6b, 0xae, 0x70, 0x7c,
0x7e, 0x41, 0xd3, 0x86, 0xc1, 0x85, 0x89, 0x9a,
0x59, 0xab, 0x03, 0x7d, 0x62, 0xca, 0x4f, 0xdc,
0xa5, 0x48, 0xf6, 0x71, 0x56, 0xc0, 0x8c, 0x9e,
0x9f, 0xc3, 0x60, 0xd9, 0xc5, 0x53, 0xf9, 0x7f,
0xb1, 0x4a, 0x6c, 0xa8, 0x95, 0xab, 0x76, 0xba,
0x8e, 0x83, 0x43, 0x90, 0x7a, 0x37, 0xcf, 0x35,
0xb4, 0xfd, 0xf0, 0xa3, 0x51, 0xe5, 0x6e, 0xcb,
0x67, 0x09, 0x92, 0x32, 0xe7, 0x8b, 0xd0, 0xed,
0x19, 0xb7, 0x29, 0x80, 0xc4, 0xff, 0xa9, 0x16,
0xc6, 0x3c, 0xfb, 0x25, 0x98, 0xf8, 0x1c, 0xde,
0xaa, 0x10, 0xad, 0x8a, 0x02, 0x64, 0xd2, 0xf7,
0x22, 0xd6, 0x14, 0xbd, 0x5d, 0xa0, 0xe0, 0x40,
0xda, 0x88, 0xe9, 0x04, 0x2a, 0xaf, 0x3e, 0xf3,
0x06, 0x1b, 0xc7, 0xe4, 0x91, 0xd5, 0x2e, 0xc8,
0xdf, 0xf4, 0x34, 0xa4, 0x07, 0x13, 0x08, 0x27,
0x4b, 0xbf, 0xe1, 0x31, 0xce, 0x0d, 0x0b, 0xf2,
0x69, 0x0e, 0x5b, 0x45, 0x1e, 0xb6, 0x30, 0xec,
0x33, 0x74, 0x42, 0xa7, 0xb8, 0x2c, 0xee, 0xbc,
0x54, 0xd7, 0x0f, 0xd8, 0xb3, 0xfe, 0x1f, 0x20,
0x65, 0xcc, 0x00, 0x3b, 0x7b, 0x18, 0xfa, 0x93,
0x2b, 0x4e, 0x58, 0x2d, 0xe8, 0x5a, 0x05, 0x6d,
0xdd, 0x28, 0xef, 0x9c, 0x38, 0xdb, 0x8d, 0x49,
0x94, 0xe2, 0x2f, 0xcd, 0x97, 0x63, 0xea, 0x81,
0x1d, 0x0c, 0xe6, 0x21, 0x4c, 0x24, 0x50, 0x72,
0x77, 0xf5, 0x15, 0x3f, 0xa1, 0xbb, 0x84, 0x36,
0x46, 0xf1, 0x5e, 0x0a, 0xe3, 0x75, 0x61, 0x99,
0x9b, 0x23, 0x68, 0xb5, 0x17, 0xb0, 0x57, 0x78,
0x66, 0x82, 0xb9, 0xd4, 0x73, 0x3d, 0xc2, 0x44,
0xac, 0x6a, 0xbe, 0x11, 0x8f, 0x47, 0x96, 0xb2,
0x3a, 0xd1, 0x87, 0x6f, 0x79, 0xc9, 0x1a, 0x5f,
0x55, 0x26, 0xa6, 0x52, 0x01, 0x39, 0x9d, 0x4d
where the entries are in hexadecimal format. The ibox table entries are indexed from 0x00 to 0xff. This translates into decimal 0 to 255. For the above table, the first entry in the first row is indexed 0x00, the eighth entry in the first row is indexed 0x07, the fit entry in the second row is indexed 0x08, the eighth entry in the second row is indexed 0x0f, and so on. It is apparent from an examination of the table that it provides an involutary lookup. That is, ibox(ibox((z))=z. For example, ibox(0x00)=0xa2. Looking up the entry indexed 0xa2, it is seen that ibox(0xa2)=0x00. The enhanced tbox function is substituted for the TBOX function described above in connection with the discussion of FIG. 1. In order to further enhance security, the inputs to the tbox function are subjected to a permutation employing either the first or the second secret offset. Each tbox function input is subjected to a permutation to produce a permutation result. If a tbox function input is defined as x, for example, the permutation result is the value of (x.sym.offset1). The permutation result is subjected to the tbox function. Thus, for each tbox input x, the function used is tbox(x.sym.offset1). The permutation of the tbox inputs effectively causes the location of the tbox entries to shift with each message, greatly increasing the difficulty of an attack. At step 212, the intermediate ciphertext is subjected to a second transformation to produce a final processed text The second transformation is identical to the first transformation, except that the first and second offsets are reversed for the second transformation. That is, where the first offset is used in the first transformation, the second offset is used in the second transformation, and where the second offset is used in the first transformation, the first offset is used in the second transformation. The second transformation is described below in connection with the discussion of FIG. 4. FIG. 3 is a flowchart illustrating in detail the steps of the first transformation 208 performed in the forward ECMEA process 200 illustrated in FIG. 2. Steps 304-308 are performed for each octet n of the unprocessed message, for n=0 to n=n.sub.max -1, where n.sub.max is the number of octets in the message. At step 302, n is set to 0. At step 304, bit trading is performed between the octet n and the octet above it using the following formula:
If n < n.sub.max - 1,
j = O.sub.n .sym. O.sub.n+1
j = j AND tbox (j .sym. offset1)
O.sub.n = O.sub.n .sym. j
O.sub.n+1 = O.sub.n+1 .sym. j
where j is a temporary variable and On is the nth octet of the unprocessed message, and AND is the bitwise Boolean AND operator. At step 306, an involutary lookup with feedback is performed, according to the following formula:
If n < n.sub.max - 1,
O.sub.n = offset1 .sym. O.sub.n+1 .sym. tbox(O.sub.n .sym.
offset2)
If n = n.sub.max - 1,
O.sub.n = offset1 .sym. tbox(O.sub.n .sym. offset2)
At step 308, a random byte permutation is performed. That is, an octet may be exchanged with a random one below it according to the following formula:
If n > 0:
If n < n.sub.max - 1,
j = tbox(O.sub.n+1 .sym. offset1)
If n = n.sub.max - 1,
j = tbox(0x37 .sym. offset1)
j = ((n + 1) * j) >> 8;
z = O.sub.j
O.sub.j = O.sub.n
O.sub.n = z,
where j and z are buffer variables, * indicates multiplication, and >>8 indicates a right shift of 8 bits. At step 310 n is incremented. At step 312, n is compared to n.sub.max. If n<n.sub.max, control is returned to step 304. If n.gtoreq.n.sub.max, control passes to step 314 and the first transformation step is complete. FIG. 4 is a flowchart illustrating in detail the steps of the second transformation 212 performed in the forward ECMEA process 200 illustrated in FIG. 2. Steps 404-408 are performed for each octet n of the intermediate ciphertext message, for n=0 to n=n.sub.max -1, where n.sub.max is the number of octets in the message. At step 402, n is set to 0. At step 404, bit trading is performed between the octet n and the octet above it using the following formula:
If n < n.sub.max - 1,
j = O.sub.n .sym. O.sub.n+1
j = j AND tbox(j .sym. offset2)
O.sub.n = O.sub.n .sym. j
O.sub.n+1 = O.sub.n+1 .sym. j
where j is a temporary variable and O.sub.n is the nth octet of the intermediate ciphertext message. At step 406, an involutary lookup with feedback is performed, according to the following formula:
If n < n.sub.max - 1,
O.sub.n = offset2 .sym. O.sub.n+1 .sym. tbox(O.sub.n .sym.
offset1).
If n = n.sub.max - 1,
O.sub.n = offset2 .sym. tbox(O.sub.n .sym. offset1).
At step 408, a random byte permutation is performed. That is, an octet may be exchanged with a random one below it according to the following formula:
If n > 0:
If n < n.sub.max - 1,
j = tbox(O.sub.n+1 .sym. offset2)
If n = n.sub.max - 1,
j = tbox(0x37 .sym. offset2)
j = ((n + 1) * j) >> 8
z = O.sub.j
O.sub.j = O.sub.n
O.sub.n = z,
where j and z are temporary buffer variables, * indicates multiplication, and >>8 indicates a right-shift of 8 bits. At step 410, n is incremented. At step 412, n is compared to n.sub.max. If n<n.sub.max, control is returned to step 404. If n.ltoreq.n.sub.max, control passes to step 414 and the second transformation step is complete. FIG. 5 is a flowchart illustrating a reverse ECMEA process 500, suitable for decrypting text encrypted by the forward ECMEA process 200 illustrated in FIG. 2, or for encrypting text for decryption by the forward ECMEA process 200 illustrated in FIG. 2. The reverse ECMEA process 500 is identical to the forward ECMEA process 200, except that in the forward and reverse transformations, the first offset is replaced by the second offset, and the second offset is replaced by the first offset. At step 502, an unprocessed message is introduced into the encryption/decryption process. At step 504, in systems which implement tbox as a static table rather than as a function call, the static tbox table is derived. At step 506, a set of secret 8-bit values K.sub.0 -K.sub.3 is generated for use in generating the secret offsets and the offsets are calculated. The set of secret values may be generated using any of a number of techniques commonly known in the art. All the secret values K.sub.0 -K.sub.3 are preferably generated for each wireless telephone call and are preferably constant throughout the call. First and second offsets are generated, using the following formulas: offset1=((K.sub.0 +1)*CS mod 257).sym.K.sub.1 mod 256 offset2=((K.sub.2 +1)*CS mod 257).sym.K.sub.3 mod 256 where K.sub.0 -K.sub.3 are as defined above, and CS is a cryptosynchronization value. The CS.sub.n value is an external value for the nth message. The CS.sub.n value comprises 8 bits and is preferably implemented as a binary counter. Offset1 and offset2 are each 8-bit values. At step 508, a first inverse transformation is performed on the unprocessed message, using first and second secret offsets, to produce a first inverse transformed message. Details of the transformation are as similar to those discussed above in connection with the discussion of FIG. 3, except that the steps performed in the inverse transformation are in reverse order with respect to those of the transformation, and the message octets are processed in reverse order. Details of the first inverse transformation are discussed below in connection with the discussion of FIG. 6 and details of the second inverse transformation are discussed below in connection with the discussion of FIG. 7. At step 510, the first inverse transformed message is subjected to an iteration of the CMEA process, using a CMEA key, to produce a reverse intermediate ciphertext message. The CMEA function includes an enhanced tbox function, which performs an involutary lookup of each octet, and is given by the formula
tbox(z) = I(I(I(I(I(I(I(I(I(I(I(I(I(I(z+k0)XOR k1)+k2)XOR k3)+
k4)XOR k5)+k6)XOR k7)-k6)XOR k5)-k4)XOR k3)-k2)XOR k1)-k0
where "+" denotes modulo 256 addition,
"-" denotes modulo 256 subtraction,
"XOR" is the XOR function,
"z" is the function argument,
k0, . . . , k7 are the eight octets of ECMEA key,
and I( ) is the outcome of a known ibox 8-bit table look-up. The ibox table is an involutary lookup table with entries chosen to perform involutary mapping of 8-bit bytes onto 8-bit bytes. The ibox table is an involutary lookup table with entries chosen to perform involutary mapping of 8-bit bytes onto 8-bit bytes. A preferred example of an ibox table is as follows:
0xa2, 0xfc, 0x5c, 0x12, 0x6b, 0xae, 0x70, 0x7c,
0x7e, 0x41, 0xd3, 0x86, 0xc1, 0x85, 0x89, 0x9a,
0x59, 0xab, 0x03, 0x7d, 0x62, 0xca, 0x4f, 0xdc,
0xa5, 0x48, 0xf6, 0x71, 0x56, 0xc0, 0x8c, 0x9e,
0x9f, 0xc3, 0x60, 0xd9, 0xc5, 0x53, 0xf9, 0x7f,
0xb1, 0x4a, 0x6c, 0xa8, 0x95, 0xab, 0x76, 0xba,
0x8e, 0x83, 0x43, 0x90, 0x7a, 0x37, 0xcf, 0x35,
0xb4, 0xfd, 0xf0, 0xa3, 0x51, 0xe5, 0x6e, 0xcb,
0x67, 0x09, 0x92, 0x32, 0xe7, 0x8b, 0xd0, 0xed,
0x19, 0xb7, 0x29, 0x80, 0xc4, 0xff, 0xa9, 0x16,
0xc6, 0x3c, 0xfb, 0x25, 0x98, 0xf8, 0x1c, 0xde,
0xaa, 0x10, 0xad, 0x8a, 0x02, 0x64, 0xd2, 0xf7,
0x22, 0xd6, 0x14, 0xbd, 0x5b, 0xa0, 0xe0, 0x40,
0xda, 0x88, 0xe9, 0x04, 0x2a, 0xaf, 0x3e, 0xf3,
0x06, 0x1b, 0xc7, 0xe4, 0x91, 0xd5, 0x2e, 0xc8,
0xdf, 0xf4, 0x34, 0xa4, 0x07, 0x13, 0x08, 0x27,
0x4b, 0xbf, 0xe1, 0x31, 0xce, 0x0d, 0x0b, 0xf2,
0x69, 0x0e, 0x5b, 0x45, 0x1e, 0xb6, 0x30, 0xec,
0x33, 0x74, 0x42, 0xa7, 0xb8, 0x2c, 0xee, 0xbc,
0x54, 0xd7, 0x0f, 0xd8, 0xb3, 0xfe, 0x1f, 0x20,
0x65, 0xcc, 0x00, 0x3b, 0x7b, 0x18, 0xfa, 0x93,
0x2b, 0x4e, 0x58, 0x2d, 0xe8, 0x5a, 0x05, 0x6d,
0xdd, 0x28, 0xef, 0x9c, 0x38, 0xdb, 0x8d, 0x49,
0x94, 0xe2, 0x2f, 0xcd, 0x97, 0x63, 0xea, 0x81,
0x1d, 0x0c, 0xe6, 0x21, 0x4c, 0x24, 0x50, 0x72,
0x77, 0xf5, 0x15, 0x3f, 0xa1, 0xbb, 0x84, 0x36,
0x46, 0xf1, 0x5e, 0x0a, 0xe3, 0a75, 0x61, 0x99,
0x9b, 0x23, 0x68, 0xb5, 0x17, 0xb0, 0x57, 0x78,
0x66, 0x82, 0xb9, 0xd4, 0x73, 0x3d, 0xc2, 0x44,
0xac, 0x6a, 0xbe, 0x11, 0x8f, 0x47, 0x96, 0xb2,
0x3a, 0xd1, 0x87, 0x6f, 0x79, 0xc9, 0x1a, 0x5f,
0x55, 0x26, 0xa6, 0x52, 0x01, 0x39, 0x9d, 0x4d,
where the entries are in hexadecimal format. The ibox table entries are indexed from 0x00 to 0xff. This translates into decimal 0 to 255. For the above table, the first entry in the first row is indexed 0x00, the eighth entry in the first row is indexed 0x07, the first entry in the second row is indexed 0x08, the eighth entry in the second row is indexed 0x0f, and so on. It is apparent from an examination of the table that it provides an involutary lookup. That is, ibox(ibox((z))=z. For example, ibox(0x00)=0xa2. Looking up the entry indexed 0xa2, it is seen that ibox(0xa2)=0x00. The enhanced tbox function is substituted for the TBOX function described above in connection with the discussion of FIG. 1. In order to further enhance security, the inputs to the tbox function are subjected to a permutation employing the first secret offset. Each tbox function input is subjected to a permutation to produce a permutation result. If a tbox function input is defined as x, for example, the permutation result is the value of(x.sym. offset1). The permutation result is subjected to the tbox function. Thus, for each tbox input x, the function used is tbox(x.sym. offset1). The permutation of the tbox inputs effectively causes the location of the tbox entries to shift with each message, greatly increasing the difficulty of an attack. At step 512, the reverse intermediate ciphertext is subjected to a second inverse transformation to produce a final processed text. The second inverse transformation is identical to the first inverse transformation, except that the first and second offsets are exchanged for the second inverse transformation with respect to the first inverse transformation. That is, where the first offset is used for the first inverse transformation, the second offset is used for the second inverse transformation, and where the second offset is used for the first inverse transformation, the first offset is used for the second inverse transformation. FIG. 6 is a flowchart illustrating in detail the steps of the first inverse transformation 508 performed in the reverse ECMEA process 500 illustrated in FIG. 5. Steps 604-608 are performed for each octet n of the unprocessed message, for n=n.sub.max -1 to n=0, where n.sub.max is the number of octets in the message. At step 602, n is set to n.sub.max -1. At step 604, an inverse random byte permutation is performed. That is, an octet may be exchanged with a random one below it according to the following formula:
If n > 0,
If n < n.sub.max - 1,
j = tbox(O.sub.n+1 .sym. offset2)
If n = n.sub.max - 1,
j = tbox(0x37 .sym. offset2)
j = ((n + 1) * j) >> 8
z = O.sub.j
O.sub.j = O.sub.n
O.sub.n = z,
where O.sub.n is the nth octet of the unprocessed message, j and z are temporary variables, * indicates multiplication, and >>8 indicates a right shift of 8 bits. At step 604, an inverse involutary lookup with feedback is performed, according to the following formula:
If n < n.sub.max - 1,
O.sub.n = offset1 .sym. tbox(O.sub.n .sym. O.sub.n+1 .sym.
offset2)
If n = n.sub.max - 1,
O.sub.n = offset1 .sym. tbox(O.sub.n .sym. offset2)
At step 606, inverse bit trading is performed between the octet n and the octet above it using the following formula:
If n < n.sub.max - 1:
j = O.sub.n .sym. O.sub.n+1
j = j AND tbox(j .sym. offset2)
O.sub.n = O.sub.n .sym. j
O.sub.n+1 = O.sub.n+1 .sym. j
where j is a temporary variable. At step 610, n is decremented. At step 612, n is compared to 0. If n.gtoreq.0, control is returned to step 604. If n<0, control passes to step 614 and the first inverse transformation step is complete. FIG. 7 is a flowchart illustrating in detail the steps of the second inverse transformation 512 performed in the reverse ECMEA process 500 illustrated in FIG. 5. Steps 704-708 are performed for each octet n of the intermediate ciphertext message, for n=n.sub.max -1 to n=0, where n.sub.max is the number of octets in the message. At step 702, n is set to n.sub.max -1. At step 704, an inverse random byte permutation is performed. That is, an octet may be exchanged with a random one below it according to the following formula:
If n > 0,
If n < n.sub.max - 1,
j = tbox(O.sub.n+1 .sym. offset1)
If n = n.sub.max - 1,
j = tbox(0x37 .sym. offset1)
j = ((n + 1) * j) >> 8;
z = O.sub.j
O.sub.j = O.sub.n
O.sub.n = z,
where O.sub.n is the nth octet of the intermediate ciphertext message, j and z are temporary variables, * indicates multiplication, and >>8 indicates a right shift of 8 bits. At step 706, an inverse involutary lookup with feedback is performed, according to the following formula:
If n < n.sub.max - 1,
O.sub.n = offset2 .sym. tbox(O.sub.n .sym. O.sub.n+1 .sym.
offset1)
If n = n.sub.max - 1,
O.sub.n = offset2 .sym. tbox(O.sub.n .sym. offset1)
At step 708, inverse bit trading is performed between the octet n and the octet above it using the following formula:
If n < n.sub.max - 1:
j = O.sub.n .sym. O.sub.n+1
j = j AND tbox(j .sym. offset1)
O.sub.n = O.sub.n .sym. j
O.sub.n+1 = O.sub.n+1 .sym. j
where j is a temporary variable. At step 710, n is decremented. At step 712, n is compared to 0. If n.gtoreq.0, control is returned to step 704. If n<0, control passes to step 714 and the second inverse transformation step is complete. FIG. 8 is a diagram showing a wireless telephone system 800 including a handset 900 and a base station 1000. Both the handset 900 and the base station 1000 are equipped to perform message transmission and processing according to the present invention. The telephone handset 900 includes a transceiver 902, an input/output (I/O) interface 904, an encryption/decryption processor 906, and a key generator 908. The key generator 908 receives and employs stored secret data for key generation. Stored secret data is preferably stored in nonvolatile memory 910 such as an EEPROM or a Flash memory. The key generator also generates secret values K.sub.0 -K.sub.3 used to produce secret offsets. The key generator may be designed to generate secret values K.sub.0 -K.sub.3 using any of a number of techniques commonly known in the art. A set of secret values K.sub.0 -K.sub.3 is preferably generated for each wireless telephone call, and the values K.sub.0 -K.sub.3 are preferably held constant throughout the call. The key generator 908 stores the generated keys and secret values K.sub.0 -K.sub.3 in memory 912. The encryption/decryption processor also includes memory 914 for storage of keys received from the key generator 908, an initialization value used in production of secret offsets, ciphertext message octets, and a static tbox table which may be generated and used if it is desired to implement the tbox function as a static table. The telephone handset 900 also includes a message generator 916, which generates messages to be encrypted by the encryption/decryption processor 906 and transmitted by the transceiver 902. When an internally generated message is to be encrypted and transmitted by the telephone handset 900, the message is transmitted from message generator 916 to the I/O interface 904. The I/O interface 904 transmits the message, along with the identification, to the encryption/decryption processor 906. The encryption/decryption processor 906 receives a key from the key generator 908, which it then uses to encrypt the message. When the encryption/decryption processor 906 receives a plaintext message from the message generator 916, the message is subjected to a forward ECMEA process as described above in connection with the discussion of FIG. 2. The forward ECMEA process includes a first transformation, an iteration of the CMEA process, and a second transformation. The use of the ECMEA process as described above in FIG. 2 causes the location of the tbox entries to shift not merely with each message, but also for each iteration of the encryption of a single message. Upon completion of forward ECMEA process, a final ciphertext is produced and stored in memory 914, and also routed to the I/O interface 904 and to the transceiver 902 for transmission. When an encrypted message is received by the telephone handset 900 for the purpose of decryption, the transceiver 902 passes it to the I/O interface 904. The I/O interface passes the message to the encryption/decryption processor 906. The encryption/decryption processor 906 receives a key from the key generator 908 and decrypts the message using the forward ECMEA process described above in connection with the discussion of FIG. 2. The telephone handset 900 employs the forward ECMEA process for encrypting and decrypting messages, and is preferably adapted to communicate with the base station 1000 which employs the reverse ECMEA process, as described in connection with the discussion of FIG. 5, for encryption and decryption. The base station 1000 includes a transceiver 1002, I/O interface 1004, encryption/decryption processor 1006, key generator 1008, nonvolatile memory 1010, memory 1012, memory 1014, and message generator 1014. These components are similar to corresponding components of the handset 900, but are configured to implement the reverse ECMEA process. Thus, a message encrypted by the handset 900 is decrypted by the base station 1000, and a message encrypted by the base station 1000 is decrypted by the handset 900. Depending on speed requirements and memory constraints, the handset 900 or the base station 1000 may be designed to implement the tbox as a function or as a static table. Implementation of tbox as a static table requires increased memory but provides greater speed. The above-described enhancements to the CMEA process, while substantially increasing security, do not substantially increase processing or system resources, and are therefore well suited to use in an environment such as a wireless telephone system. Mobile units and base stations in such systems often have limited processing power. While the present invention is disclosed in the context of a presently preferred embodiment, it will be recognized that a wide variety of implementations may be employed by persons of ordinary skill in the art consistent with the above discussion and the claims which follow below.
|
Same subclass Same class Consider this |
||||||||||
