embedded techniques for everyone ; solve atleast one problem of the world a day ; provide the world what you do not get ; invent and service the world
Tuesday, September 18, 2012
Interview with an Embedded Engineer?
Embedded Jokes
② Why is it very difficult to meet deadlines in embedded?
③ Why did they keep name "Daughter" card, you know?
Monday, September 17, 2012
i.MX51/i.MX53: Interrupt occurs with no bit set in HIPND
Thursday, May 24, 2012
What is Hard Real Time OS?
Saturday, May 12, 2012
Linux Questions
build → make config
make dep
make
Change of memory map → Where?
Kernel Boot flow?
http://milindchoudhary.wordpress.com/2009/03/30/linux-boot-process
vmlinux image is compressed and zImage is created.
_zimage_start → ELF ENTRY → arch/powerpc/boot/zImage.lds.S
ordered as text, data, dtb(embedded Device tree blob), vmlinux, initrd, bss
To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary:
objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz
objcopy -j .kernel:System.map -O binary zImage System.map.gz
objcopy -j .kernel:.config -O binary zImage config.gz
objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz
_zimage_start → arch/powerpc/boot/crt0.S
Initialized stack, bss and C environment
call platform_init
branch to start
platform_init → arch/powerpc/boot/redboot-8xx.c
initialize serial console
display clock-frequency
assign the command line to loader_info
start → arch/powerpc/boot/main.c
"\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r"
prepare kernel (prep_kernel())
unzip _vmlinux_start, _vmlinux_end
"Allocating 0x%lx bytes for kernel ...\n\r"
"gunzipping (0x%p <- 0x%p:0x%p)...""done 0x%x bytes\n\r"
prepare ramdisk (prep_initrd())
"Attached initrd image at 0x%p-0x%p\n\r"
or
"Using loader supplied ramdisk at 0x%lx-0x%lx\n\r"
"Allocating 0x%lx bytes for initrd ...\n\r"
"Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r"
/* Tell the kernel initrd address via device tree */
"linux,initrd-start" "linux,initrd-end"
prepare command line (prep_cmdline())
"bootargs" "\n\rLinux/PowerPC load: %s"
/* If possible, edit the command line */
/* Put the command line back into the devtree for the kernel */
"bootargs", cmdline
Function pointer _vmlinux_start((unsigned long)initrd.addr, initrd.size, loader_info.promptr);
(Find the initial symbol of vmlinux image. Find vmlinux.lds. Makefile at top of Linux source.)
ENTRY(_stext) → arch/powerpc/kernel/vmlinux.lds
ENTRY(_stext) → arch/powerpc/kernel/head_8xx.S
to map the first 8M 1:1
call initial_mmu
call turn_on_mmu
/* Decide what sort of machine this is and initialize the MMU */
bl machine_init
bl MMU_init
branch to start_kernel
start_kernel → init/main.c
tick_init();
boot_cpu_init();
print linux banner
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
setup_command_line(command_line);
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
sched_init();
init_IRQ();
init_timers();
sched_clock_init();
calibrate_delay();
rest_init();
rest_init();
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
schedule();
/* Call into cpu_idle with preempt disabled */
preempt_disable();
cpu_idle();
kernel_init → init/main.c
wait for kthreadd to complete
smp_init();
sched_init_smp();
do_basic_setup();
init_post();
init_post() → init/main.c
/* shell specified in cmd prompt or defaults */
run_init_process("/sbin/init");
Howto list, load, unload modules?
What is use of mmap?
Howto allocate physical memory and virtual memory space?
Where is the assembly part of the scheduler?
what are the challenges you face when you port the kernel?
How will you debug kernel crash?
Now I give you a new CPU and board. How will you port Linux to it? What are all the steps you do to make the Linux to work on that?
Linux WiFi stack and Bluetooth stack names?
Howto debug Linux kernel in virtual memory mapping?
How uClinux is different from other flavor of Linux?
http://www.eetimes.com/electronics-news/4134390/How-uClinux-provides-MMU-less-processors-with-an-alternative
uClinux is for MCU with NO mmu.
Differences between uClinux and Linux
・little kernel and user space software is affected with NO mmu
・lack of both memory protection and of a virtual memory model
・One consequence of operating without memory protection is that an invalid
pointer reference by even an unprivileged process may trigger an address
error, and potentially corrupt or even shut down the system.
・three primary consequences of running Linux without virtual memory
1) processes which are loaded by the kernel must be able to run
independently of their position in memory. One way to achieve this is to
"fix up" address references in a program once it is loaded into RAM. The
other is to generate code that uses only relative addressing (referred to
as PIC, or Position Independent Code) - uClinux supports both of these
methods.
2) memory allocation and deallocation occurs within a flat memory model.
Very dynamic memory allocation can result in fragmentation which can
starve the system. One way to improve the robustness of applications
that perform dynamic memory allocation is to replace malloc() calls with
requests from a preallocated buffer pool.
3) swapping pages in and out of memory is not implemented, since it cannot
be guaranteed that the pages would be loaded to the same location in
RAM. In embedded systems it is also unlikely that it would be acceptable
to suspend an application in order to use more RAM than is physically
available.
・absence of the fork() and brk() system calls.
・Under Linux, fork() is implemented using copy-on-write pages. Without an
MMU, uClinux cannot completely and reliably clone a process, nor does it
have access to copy-on-write. uClinux implements vfork() in order to
compensate for the lack of fork(). When a parent process calls vfork() to
create a child, both processes share all their memory space including the
stack. vfork() then suspends the parent's execution until the child process
either calls exit() or execve(). Note that multitasking is not otherwise
affected. It does, however, mean that older-style network daemons that make
extensive use of fork() must be modified. Since child processes run in the
same address space as their parents, the behaviour of both processes may
require modification in particular situations.
・uClinux has neither an autogrow stack nor brk() and so user space programs
must use the mmap() command to allocate memory. For convenience, our C
library implements malloc() as a wrapper to mmap(). There is a compile-time
option to set the stack size of a program.
・Program loaders which support position independent code (PIC) were added.
A new binary object code format, named 'flat' was created, which supports PIC
and which has a very compact header. Other program loaders, such as that for
ELF, were modified to support other formats which, instead of using PIC, use
absolute references which it is the responsibility of the kernel to 'fix up'
at run time. Each method has advantages and disadvantages. Traditional PIC is
quick and compact but has a size restriction on some architectures. For
example, the 16-bit relative jump in Motorola 68k architectures limits PIC
programs to 32K. The runtime fix-up technique removes this size restriction,
but incurs overhead when the program is loaded by the kernel.
How a system call is processed?
Through Supervisor call, get into the Kernel space.
How does ping do not flood at user rights?
Code for Linux Semaphore, Spin lock, Interrupt Disabling, Kernel preemption disabling.
Monday, May 07, 2012
Howto program unsupported Flash using Computex CSIDE
Sunday, May 06, 2012
STM32F4: Exception occurs when enabling prefetch queue and branch caches
When the cache is enabled, "Cache Fill" reads more faster from Flash memory. So, if the number of wait states is not more enough, the read data or instruction will be inconsistent. Same phenomenon occurs, when 'Run'ning a program using debugger instead of single-step execution. 'When 'Run'ning a program, memory will be read more faster. So, make sure that enough wait states has been introduced.
Wednesday, April 25, 2012
Packet dumps: Sample packet data
Router Advertisement:
0000 33 33 00 00 00 01 00 d0 2b 64 a9 1b 86 dd 6e 00 33...... +d....n.
0010 00 00 00 40 3a ff fe 80 00 00 00 00 00 00 02 d0 ...@:... ........
0020 2b ff fe 64 a9 1b ff 02 00 00 00 00 00 00 00 00 +..d.... ........
0030 00 00 00 00 00 01 86 00 e1 78 40 00 07 08 00 00 ........ .x@.....
0040 00 00 00 00 00 00 01 01 00 d0 2b 64 a9 1b 05 01 ........ ..+d....
0050 00 00 00 00 05 dc 03 04 40 c0 00 00 03 84 00 00 ........ @.......
0060 03 84 00 00 00 00 20 01 0c 90 14 48 10 5c 00 00 ...... . ...H.\..
0070 00 00 00 00 00 00 ......
ICMPv6 Echo Request:
0000 00 10 dc 3f 53 10 00 00 00 00 01 83 86 dd 60 00 ...?S... ......`.
0010 00 00 00 18 3a 40 fe 80 00 00 00 00 00 00 02 00 ....:@.. ........
0020 00 ff fe 00 01 83 fe 80 00 00 00 00 00 00 02 10 ........ ........
0030 dc ff fe 3f 53 10 80 00 4f c8 00 00 00 00 ff ff ...?S... O.......
0040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ........ ......
ICMPv6 Neighbor Solicitation:
0000 33 33 ff 64 a9 1b 00 90 99 18 27 05 86 dd 60 00 33.d.... ..'...`.
0010 00 00 00 20 3a ff fe 80 00 00 00 00 00 00 55 7c ... :... ......U|
0020 39 cd 79 48 8d 6f ff 02 00 00 00 00 00 00 00 00 9.yH.o.. ........
0030 00 01 ff 64 a9 1b 87 00 a6 1e 00 00 00 00 fe 80 ...d.... ........
0040 00 00 00 00 00 00 02 d0 2b ff fe 64 a9 1b 01 01 ........ +..d....
0050 00 90 99 18 27 05 ....'.
ICMPv6 Neighbor Advertisement:
0000 33 33 00 00 00 01 00 00 00 00 01 83 86 dd 60 00 33...... ......`.
0010 00 00 00 18 3a ff fe 80 00 00 00 00 00 00 02 00 ....:... ........
0020 00 ff fe 00 01 83 ff 02 00 00 00 00 00 00 00 00 ........ ........
0030 00 00 00 00 00 01 88 00 36 a1 40 00 00 00 fe 80 ........ 6.@.....
0040 00 00 00 00 00 00 02 00 00 ff fe 00 01 83 ........ ......
MLD Query: ICMPv6 Multicast Listener Query:
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 86 dd 60 00 33...... ..F...`.
0010 00 00 00 20 00 01 fe 80 00 00 00 00 00 00 02 10 ... .... ........
0020 dc ff fe 93 46 d4 ff 02 00 00 00 00 00 00 00 00 ....F... ........
0030 00 00 00 00 00 01 3a 00 01 00 05 02 00 00 82 00 ......:. ........
0040 34 a0 27 10 00 00 00 00 00 00 00 00 00 00 00 00 4.'..... ........
0050 00 00 00 00 00 00 ......
MLD Address Specific Multicast Listener Query:
0000 33 33 80 00 90 00 08 00 46 be 93 8e 86 dd 60 00 33...... F.....`.
0010 00 00 00 24 00 01 fe 80 00 00 00 00 00 00 00 90 ...$.... ........
0020 1a 00 01 40 1f ce ff 3e 00 00 00 00 00 00 00 00 ...@...> ........
0030 00 00 80 00 90 00 3a 00 05 02 00 00 01 00 82 00 ......:. ........
0040 1e a5 03 e8 00 00 ff 3e 00 00 00 00 00 00 00 00 .......> ........
0050 00 00 80 00 90 00 02 7d 00 00 .......} ..
UDP multicast packet: Destination IP ff38::300/ Source & Destination Ports 1500
0000 ff ff ff ff ff ff 08 00 46 be 93 8e 86 dd 60 00 ........ F.....`.
0010 00 00 00 20 11 ff 20 01 00 00 00 00 00 00 00 00 ... .. . ........
0020 00 00 00 00 22 22 ff 38 00 00 00 00 00 00 00 00 ...."".8 ........
0030 00 00 00 00 03 00 05 dc 05 dc 00 20 70 b5 ab cd ........ ... p...
0040 de ad ab cd de ad ab cd de ad ab cd de ad ab cd ........ ........
0050 de ad ab cd de ad ......
IPv4:
IGMPv1 Membership Query:
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 08 00 46 00 33...... ..F...F.
0010 00 20 08 44 00 00 01 02 7b 72 c0 a8 00 78 e0 00 . .D.... {r...x..
0020 00 01 94 04 00 00 11 00 ee ff 00 00 00 00 00 00 ........ ........
IGMPv2 General Membership Query:
0000 ff ff ff ff ff ff 08 00 46 be 93 8e 08 00 45 00 ........ F.....E.
0010 00 1c ec b7 00 00 01 02 2c 36 c0 a8 00 49 e0 00 ........ ,6...I..
0020 00 01 11 64 ee 9b 00 00 00 00 4e 4f 54 49 46 59 ...d.... ..NOTIFY
0030 20 2a 20 48 54 54 50 2f 31 2e 31 0d * HTTP/ 1.1.
IGMPv2 Multicast Address specific Membership Query / Join Group 224.0.0.171
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 08 00 46 00 33...... ..F...F.
0010 00 20 08 44 00 00 01 02 7b 72 c0 a8 00 78 e0 00 . .D.... {r...x..
0020 00 01 94 04 00 00 11 64 0d f0 e0 00 00 ab 00 00 .......d ........
IGMPv2 Membership Report / Join Group 239.255.255.250
0000 01 00 5e 7f ff fa 00 90 99 18 27 05 08 00 46 00 ..^..... ..'...F.
0010 00 20 37 ff 00 00 01 02 3c 33 c0 a8 00 03 ef ff . 7..... <3......
0020 ff fa 94 04 00 00 16 00 fa 04 ef ff ff fa 00 00 ........ ........
0030 00 00 00 00 00 00 00 00 00 00 00 00 ........ ....
IGMPv3 General Membership Query:
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 08 00 46 00 33...... ..F...F.
0010 00 24 08 44 00 00 01 02 7b 6e c0 a8 00 78 e0 00 .$.D.... {n...x..
0020 00 01 94 04 00 00 11 64 ec 1e 00 00 00 00 02 7d .......d .......}
0030 00 00 00 00 ....
IGMPv3 Membership Query: Specific for group 230.230.230.231
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 08 00 46 00 33...... ..F...F.
0010 00 24 08 44 00 00 01 02 7b 6e c0 a8 00 78 e0 00 .$.D.... {n...x..
0020 00 01 94 04 00 00 11 32 1e 9b e6 e6 e6 e7 02 64 .......2 .......d
0030 00 00 00 00 ....
IGMPv3 Membership Query: Source and Group Specific/ for group 230.230.230.230, for sources 192.168.0.5 and 192.168.184.5
0000 33 33 00 00 00 01 00 10 dc 93 46 d4 08 00 46 00 33...... ..F...F.
0010 00 2c 08 44 00 00 01 02 7b 66 c0 a8 00 78 e0 00 .,.D.... {f...x..
0020 00 01 94 04 00 00 11 32 9d 2e e6 e6 e6 e6 02 64 .......2 .......d
0030 00 02 c0 a8 00 05 c0 b8 00 05 ........ ..
VLAN packet:
0000 01 00 5e 00 00 01 00 10 dc 93 46 d4 81 00 98 76 ..^..... ..F....v
0010 08 00 46 00 00 24 08 44 00 00 01 02 7b 6e c0 a8 ..F..$.D ....{n..
0020 00 78 e0 00 00 01 94 04 00 00 11 64 ec 1e 00 00 .x...... ...d....
0030 00 00 02 7d 00 00 00 00 ...}....
DVMRP V3 Probe:
0000 01 00 5e 00 00 04 00 09 41 4d 89 b0 08 00 45 c0 ..^..... AM....E.
0010 00 20 69 40 00 00 01 02 ae 2e c0 a8 01 01 e0 00 . i@.... ........
0020 00 04 13 01 0c 8d 00 0e ff 03 03 ab dd b4 00 00 ........ ........
0030 00 00 00 00 00 00 00 00 00 00 00 00 ........ ....
UDP packet: Source Port 49153/ Destination Port 7121
0000 ff ff ff ff ff ff 00 0c f4 00 2b 09 08 00 45 00 ........ ..+...E.
0010 00 5c 00 02 00 00 20 11 d9 83 c0 a8 00 64 ff ff .\.... . .....d..
0020 ff ff c0 01 1b d1 00 48 15 3f 16 16 16 03 38 44 .......H .?....8D
0030 82 87 00 00 00 40 00 00 00 00 31 35 30 30 00 00 .....@.. ..1500..
0040 03 e9 00 cd 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
0060 00 00 00 00 00 00 00 00 00 00 ........ ..
Wednesday, April 04, 2012
Tuesday, March 27, 2012
Difference between ARM and Thumb states
Thumb state is an added advantage in ARM to reduce the code size. Infact, ARM has single instruction set. Thumb is short hand 16-bit representation of a subset of those instructions. The processor fetches these 16-bit instructions and expands into 32-bit equivalent. So, ARM and Thumb differs only in how the instructions are fetched and interpreted, not in execution. So, speed is not at all changed. CPU has dedicated hardware within the chip to interpret the Thumb instructions.
ARM (Advanced RISC Machines) |
Thumb ("T" in the core's full name specifies Thumb. Eg: ARM7TDMI) |
Needs more memory than Thumb, since all are RISC 32-bit instructions | Reduced memory consumption with 16-bit insturctions (have some 32-bit instructions too) |
Totally 18 Registers: R1-R12, SP(R13), LR(R14), PC(R15), CPSR, SPSR used in exceptions | Totally 12 Registers: R1-R7, SP, LR, PC, CPSR (These 12 registers have to be used to pass data between ARM and Thumb state) |
T bit = 0 of CPSR represents ARM state | T bit = 1 of CPSR represents Thumb state |
Branch instruction (BX or BLX) to the address with LSB set to 0 enters ARM state. (Eg: BX 0x80000000) | Branch instruction (BX or BLX) to the address with LSB set to 1 enters Thumb state. (Eg: BX 0x80000001) |
When exception occurs, ARM state is entered. | - |
When return from Exception, if T bit of SPSR is set to 0, returns to ARM | When return from Exception, if T bit of SPSR is set to 1, returns to Thumb |
- | No way (instruction) to access status or coprocessor registers |
Load and store instructions of R13 register manipulates stack | Has stack mnemonics PUSH, POP |
- | Advantages: Reduced memory, 16-bit bus can be used without compromising with speed Disadvantages: As above said, No way (instruction) to access status or coprocessor registers. Some functions that can be accomplished in a single ARM instruction can only be simulated with a sequence of Thumb instructions. |
Reference:
http://www.eetimes.com/discussion/other/4024632/Introduction-to-ARM-thumb
Saturday, March 24, 2012
Howto trace/debug an exception in Cortex-M3 and Cortex-M4
2) If BIT2 of the Link Register is set (for example, 0xfffffffd), take Process Stack Pointer (PSP).
If BIT2 of the Link Register is 0 (for example, 0xfffffff9), take Main Stack Pointer (MSP).
3) The PC stored at offset 24 (0x18) of the MSP or PSP refers to the address of the instruction that caused the exception or the instruction next to the instruction that caused the exception. If the PC is invalid, the LR stored at offset 20 (0x14) of the MSP or PSP refers to the instruction next to the instruction that caused the exception.
LR is 5 th register from MSP or PSP; PC is 6 th register from MSP or PSP, as follows:
4) Find the cause from that instruction.
Cortex-M3/M4: Hardfault at SVC instruction
If you caught Hard Fault exception and the PC value stacked for the exception points to the next instruction of SVC call, then there may be problem in Base priority(BASEPRI) value or Exception Masking Register (PRIMASK) value. The causes and corresponding solutions can be cosidered as follows:
Cause 1) : SVC priority has been masked by Base Priority Mask Register (BASEPRI) :
If SVC is executed from the context which has higher priority than SVC, Hard Fault Exception will occur. An example is, SVC is executed from a Task where BASEPRI value is set lower or equal to the SVC priority value set by System Handler Priority Register 2. Another example is, SVC is executed from a interrupt service routine of higher priority interrupt than SVC.
To solve this, always initialize the SVC priority to be higher than the executing contexts.
Cause 2) : SVC has been disabled through Exception Masking Register (PRIMASK
= 1) :
When PRIMASK register is set to 1, only NMI and Hard Fault Exceptions are allowed. If SVC is executed when PRIMASK is set to 1, HardFault Exception will occur.
To solve this, instead of using PRIMASK to mask interrupts, use BASEPRI to mask particular interrupts.
Put your comments to improve this post!
Optimized AES source code for embedded systems
This AES implementation is based on rijndael-alg-fst.c (fast AES implementation) source.
Features of this AES cryptography algorithm implementation are:
1) Optimized for Embedded systems: Reduced Memory usage without compromising the Speed
2) Context-based: Uses context to support multiple sessions by saving intermediate values
3) Supports Encryption and Decryption by both CBC and ECB modes
4) Applications can use same buffer as input, as well as for output
5) Supports all 128, 192, 256 bit key sizes
6) Includes sample test application main program
AES resources can be found in the following link:
http://csrc.nist.gov/archive/aes/index.html
AES(ADVANCED ENCRYPTION STANDARD) specification can be found in the following link:
http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
Just copy and paste aes.h and aes.c with respective file names, compile and run.
aes.h
/* // AES context structure // key length in bytes // AES API function prototype int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode); |
aes.c
#include "stdio.h"
#include "aes.h"
static const unsigned int Te0[256] = {
0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
};
static const unsigned int Te1[256] = {
0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL,
};
static const unsigned int Te2[256] = {
0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL,
};
static const unsigned int Te3[256] = {
0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL,
};
static const unsigned int Te4[256] = {
0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL,
0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL,
0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL,
0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL,
0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL,
0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL,
0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL,
0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL,
0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL,
0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL,
0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL,
0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL,
0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL,
0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL,
0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL,
0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL,
0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL,
0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL,
0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL,
0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL,
0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL,
0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL,
0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL,
0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL,
0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL,
0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL,
0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL,
0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL,
0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL,
0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL,
0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL,
0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL,
0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL,
0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL,
0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL,
0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL,
0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL,
0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL,
0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL,
0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL,
0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL,
0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL,
0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL,
0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL,
0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL,
0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL,
0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL,
0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL,
0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL,
0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL,
0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL,
0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL,
0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL,
0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL,
0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL,
0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL,
0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL,
0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL,
0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL,
0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL,
0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL,
0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
};
static const unsigned int Td0[256] = {
0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL,
};
static const unsigned int Td1[256] = {
0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL,
};
static const unsigned int Td2[256] = {
0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL,
};
static const unsigned int Td3[256] = {
0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL,
};
static const unsigned int Td4[256] = {
0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL,
0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL,
0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL,
0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL,
0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL,
0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL,
0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL,
0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL,
0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL,
0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL,
0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL,
0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL,
0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL,
0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL,
0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL,
0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL,
0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL,
0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL,
0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL,
0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL,
0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL,
0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL,
0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL,
0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL,
0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL,
0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL,
0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL,
0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL,
0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL,
0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL,
0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL,
0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL,
0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL,
0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL,
0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL,
0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL,
0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL,
0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL,
0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL,
0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL,
0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL,
0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL,
0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL,
0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL,
0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL,
0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL,
0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL,
0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL,
0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL,
0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL,
0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL,
0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL,
0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL,
0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL,
0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL,
0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL,
0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL,
0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL,
0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL,
0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL,
0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL,
0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL,
0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL,
0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
};
static const unsigned int rcon[] = {
0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
0x1B000000UL, 0x36000000UL,
};
#define GETU32(pt) (((unsigned int)(pt)[0] << 24) ^ \
((unsigned int)(pt)[1] << 16) ^ \
((unsigned int)(pt)[2] << 8) ^ \
((unsigned int)(pt)[3]))
#define PUTU32(ct, st) { (ct)[0] = (unsigned char)((st) >> 24); \
(ct)[1] = (unsigned char)((st) >> 16); \
(ct)[2] = (unsigned char)((st) >> 8); \
(ct)[3] = (unsigned char)(st); }
/*
* Expand the cipher key into the encryption key schedule and return the
* number of rounds for the given cipher key size.
*/
int aes_setkey_enc(unsigned int rk[], const unsigned char cipherKey[], int keyBytes)
{
int i = 0;
unsigned int temp;
rk[0] = GETU32(cipherKey );
rk[1] = GETU32(cipherKey + 4);
rk[2] = GETU32(cipherKey + 8);
rk[3] = GETU32(cipherKey + 12);
if (keyBytes == 16) { // 128 bits
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
return 10;
}
rk += 4;
}
}
rk[4] = GETU32(cipherKey + 16);
rk[5] = GETU32(cipherKey + 20);
if (keyBytes == 24) { // 192 bits
for (;;) {
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
return 12;
}
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(cipherKey + 24);
rk[7] = GETU32(cipherKey + 28);
if (keyBytes == 32) { // 256 bits
for (;;) {
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
return 14;
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
return 0;
}
/*
* Expand the cipher key into encryption and decryption key schedule and
* return the number of rounds for the given cipher key size.
*/
int AesGenKeySched(unsigned int rk[], unsigned int rrk[], const unsigned char cipherKey[], int keyBytes)
{
int Nr, i;
// expand the cipher key
Nr = aes_setkey_enc(rk, cipherKey, keyBytes);
// invert the order of the first round keys
rrk += Nr * 4;
rrk[0] = rk[0];
rrk[1] = rk[1];
rrk[2] = rk[2];
rrk[3] = rk[3];
/*
* apply the inverse MixColumn transform to all round keys but the first
* and the last
*/
for (i = 1; i < Nr; i++) {
rrk -= 4;
rk += 4;
rrk[0] =
Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[0] ) & 0xff] & 0xff];
rrk[1] =
Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[1] ) & 0xff] & 0xff];
rrk[2] =
Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[2] ) & 0xff] & 0xff];
rrk[3] =
Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[3] ) & 0xff] & 0xff];
}
// invert the order of the last round keys
rrk -= 4;
rk += 4;
rrk[0] = rk[0];
rrk[1] = rk[1];
rrk[2] = rk[2];
rrk[3] = rk[3];
return Nr;
}
/*
* Encrypt the plain text into cipher
*/
void AesEncBlk(AesCtx *pCtx, const unsigned char pt[], unsigned char ct[])
{
unsigned int s0, s1, s2, s3, t0, t1, t2, t3, *iv;
const unsigned int *rk;
int r;
rk = pCtx->Ek;
iv = pCtx->Iv;
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(pt ) ^ rk[0];
s1 = GETU32(pt + 4) ^ rk[1];
s2 = GETU32(pt + 8) ^ rk[2];
s3 = GETU32(pt + 12) ^ rk[3];
if (pCtx->Mode) {
s0 = s0 ^ iv[0];
s1 = s1 ^ iv[1];
s2 = s2 ^ iv[2];
s3 = s3 ^ iv[3];
}
/*
* Nr - 1 full rounds:
*/
r = pCtx->Nr >> 1;
for (;;) {
t0 =
Te0[(s0 >> 24) ] ^
Te1[(s1 >> 16) & 0xff] ^
Te2[(s2 >> 8) & 0xff] ^
Te3[(s3 ) & 0xff] ^
rk[4];
t1 =
Te0[(s1 >> 24) ] ^
Te1[(s2 >> 16) & 0xff] ^
Te2[(s3 >> 8) & 0xff] ^
Te3[(s0 ) & 0xff] ^
rk[5];
t2 =
Te0[(s2 >> 24) ] ^
Te1[(s3 >> 16) & 0xff] ^
Te2[(s0 >> 8) & 0xff] ^
Te3[(s1 ) & 0xff] ^
rk[6];
t3 =
Te0[(s3 >> 24) ] ^
Te1[(s0 >> 16) & 0xff] ^
Te2[(s1 >> 8) & 0xff] ^
Te3[(s2 ) & 0xff] ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rk[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(ct , s0);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(ct + 4, s1);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(ct + 8, s2);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(ct + 12, s3);
if (pCtx->Mode) {
iv[0] = s0;
iv[1] = s1;
iv[2] = s2;
iv[3] = s3;
}
}
/*
* Decrypt the cipher into plain text
*/
void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[])
{
unsigned int s0, s1, s2, s3, t0, t1, t2, t3, v0, v1, v2, v3, *iv;
const unsigned int *rk;
int r;
rk = pCtx->Dk;
iv = pCtx->Iv;
/*
* map byte array block to cipher state
* and add initial round key:
*/
v0 = GETU32(ct ); s0 = v0 ^ rk[0];
v1 = GETU32(ct + 4); s1 = v1 ^ rk[1];
v2 = GETU32(ct + 8); s2 = v2 ^ rk[2];
v3 = GETU32(ct + 12); s3 = v3 ^ rk[3];
/*
* Nr - 1 full rounds:
*/
r = pCtx->Nr >> 1;
for (;;) {
t0 =
Td0[(s0 >> 24) ] ^
Td1[(s3 >> 16) & 0xff] ^
Td2[(s2 >> 8) & 0xff] ^
Td3[(s1 ) & 0xff] ^
rk[4];
t1 =
Td0[(s1 >> 24) ] ^
Td1[(s0 >> 16) & 0xff] ^
Td2[(s3 >> 8) & 0xff] ^
Td3[(s2 ) & 0xff] ^
rk[5];
t2 =
Td0[(s2 >> 24) ] ^
Td1[(s1 >> 16) & 0xff] ^
Td2[(s0 >> 8) & 0xff] ^
Td3[(s3 ) & 0xff] ^
rk[6];
t3 =
Td0[(s3 >> 24) ] ^
Td1[(s2 >> 16) & 0xff] ^
Td2[(s1 >> 8) & 0xff] ^
Td3[(s0 ) & 0xff] ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Td0[(t0 >> 24) ] ^
Td1[(t3 >> 16) & 0xff] ^
Td2[(t2 >> 8) & 0xff] ^
Td3[(t1 ) & 0xff] ^
rk[0];
s1 =
Td0[(t1 >> 24) ] ^
Td1[(t0 >> 16) & 0xff] ^
Td2[(t3 >> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
rk[1];
s2 =
Td0[(t2 >> 24) ] ^
Td1[(t1 >> 16) & 0xff] ^
Td2[(t0 >> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
rk[2];
s3 =
Td0[(t3 >> 24) ] ^
Td1[(t2 >> 16) & 0xff] ^
Td2[(t1 >> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
rk[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
if (pCtx->Mode) {
s0 = s0 ^ iv[0]; iv[0] = v0;
s1 = s1 ^ iv[1]; iv[1] = v1;
s2 = s2 ^ iv[2]; iv[2] = v2;
s3 = s3 ^ iv[3]; iv[3] = v3;
}
PUTU32(pt , s0);
PUTU32(pt + 4, s1);
PUTU32(pt + 8, s2);
PUTU32(pt + 12, s3);
}
//////////////////////////////////////////////////////////////////////////////
// API functions //
//////////////////////////////////////////////////////////////////////////////
/*
* initialize AES context
*/
int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode)
{
if (pKey == 0 || pCtx == 0 || (KeyLen != KEY128 && KeyLen != KEY192 && KeyLen != KEY256))
return -1;
// generate key schedule
pCtx->Nr = AesGenKeySched(pCtx->Ek, pCtx->Dk, pKey, KeyLen);
// initialize IV
if (pIV != 0) {
pCtx->Iv[0] = GETU32(pIV );
pCtx->Iv[1] = GETU32(pIV + 4 );
pCtx->Iv[2] = GETU32(pIV + 8 );
pCtx->Iv[3] = GETU32(pIV + 12);
}
// mode
pCtx->Mode = Mode;
return 0;
}
/*
* Encrypt plain text
*/
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen)
{
int i;
if (pData == 0 || pCipher == 0 || pCtx == 0 || (DataLen & 0xf) != 0)
return -1;
for (i = 0; i < DataLen; i += BLOCKSZ) {
// encrypt block by block
AesEncBlk(pCtx, pData, pCipher);
pCipher += BLOCKSZ;
pData += BLOCKSZ;
}
return DataLen;
}
/*
* Decrypt cipher
*/
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen)
{
int i;
if (pData == 0 || pCipher == 0 || pCtx == 0 || (CipherLen & 0xf) != 0)
return -1;
for (i = 0; i < CipherLen; i += BLOCKSZ) {
// decrypt block by block
AesDecBlk(pCtx, pCipher, pData);
pCipher += BLOCKSZ;
pData += BLOCKSZ;
}
return CipherLen;
}
//////////////////////////////////////////////////////////////////////////////
// Sample main program //
//////////////////////////////////////////////////////////////////////////////
#ifndef EMBEDDED
int main()
{
AesCtx ctx;
unsigned char iv[] = "INI VECTINI VECT";
unsigned char key[] = "This is a sample AESKey";
unsigned char databuf[] = "Data : AES Test"; // must be in multiple of 16
// initialize context and encrypt data at one end
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
printf("init error\n");
if (AesEncrypt(&ctx, databuf, databuf, sizeof databuf) < 0)
printf("error in encryption\n");
// initialize context and decrypt cipher at other end
if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0)
printf("init error\n");
if (AesDecrypt(&ctx, databuf, databuf, sizeof databuf) < 0)
printf("error in decryption\n");
printf("%s\n", databuf);
return 0;
}
#endif