{"id":20245559,"url":"https://github.com/noloader/aes-intrinsics","last_synced_at":"2025-04-10T20:55:01.546Z","repository":{"id":66160133,"uuid":"103740710","full_name":"noloader/AES-Intrinsics","owner":"noloader","description":"AES encryption function using Intel, ARMv8 and Power8 intrinsics","archived":false,"fork":false,"pushed_at":"2024-04-05T13:38:49.000Z","size":25,"stargazers_count":51,"open_issues_count":3,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-24T18:45:05.082Z","etag":null,"topics":["aes-intrinsics","aes-power8","armv8","c","crypto","cryptography","power8","powerpc","x86","x86-64"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noloader.png","metadata":{"files":{"readme":"README-p8.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-16T09:24:16.000Z","updated_at":"2025-03-08T08:44:13.000Z","dependencies_parsed_at":"2024-11-14T09:26:54.715Z","dependency_job_id":"9336878a-9337-460a-94f7-5279dcf17aa5","html_url":"https://github.com/noloader/AES-Intrinsics","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noloader%2FAES-Intrinsics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noloader%2FAES-Intrinsics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noloader%2FAES-Intrinsics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noloader%2FAES-Intrinsics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noloader","download_url":"https://codeload.github.com/noloader/AES-Intrinsics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248298028,"owners_count":21080313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aes-intrinsics","aes-power8","armv8","c","crypto","cryptography","power8","powerpc","x86","x86-64"],"created_at":"2024-11-14T09:22:04.560Z","updated_at":"2025-04-10T20:55:01.511Z","avatar_url":"https://github.com/noloader.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AES-Power8\n\nThis is a test implementation of Power 8's in-core crypto using xlC and GCC built-in's.\n\nThe test implementation side steps key scheduling by using a pre-expanded \"golden\" key from FIPS 197, Appendix B. The golden key is the big-endian byte array `2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c`, and it produces the key schedule hard-coded in the program.\n\nThe GCC Compile Farm (http://gcc.gnu.org/wiki/CompileFarm) offers two test machines. To test on a Power 8 little-endian machine use GCC112. To test on a big-endian machine use GCC119.\n\nAccording to data from GCC112, the naive impementation provided by `fips197-p8.c` achieves about 6 cycles-per-byte (cpb). It is mostly dull, but its still better than 20 to 30 cpb for C and C++. Running 4 or 8 blocks in parallel will increase performance to around 1 to 1.5 cpb.\n\n## Compiling\n\nTo compile the source file using GCC:\n\n    gcc -std=c99 -mcpu=power8 fips197-p8.c -o fips197-p8.exe\n\nTo compile the source file using IBM XL C/C++:\n\n    xlc -qarch=pwr8 -qaltivec fips197-p8.c -o fips197-p8.exe\n\n## Decryption\n\nThe decryption rountines are mostly a copy and paste of the encryption routines using the appropriate inverse function. However, you must build the key table using the algorithm discussed in FIPS 197, Sections 5.3.1 through 5.3.4 (pp. 20-23). You cannot use the \"Equivalent Inverse Cipher\" from Section 5.3.5 (p.23).\n\nIf you use the same key table as built for encryption, then you should index the subkey table in reverse order. That is, start with index `rounds`, then `rounds-1`, ..., then index `1`, and finally index `0`. (Remember, there are `N+1` subkeys for `N` rounds of AES).\n\n## Byte Order\n\nThe VSX unit only operates on big-endian data. However, the CPU will load the VSX register in little-endian format on a little-endian machine by default. On little-endian machines each 16-byte buffer must be byte reversed before loading. Conversely, the data needs to be stored in little endian format on little endian machines when moving from a VSX register to memory. You have two options when reversing the data to ensure it is properly loaded into a VSX register or saved from a VSX register. First you can reverse the in-memory byte buffer. Second, you can load the byte buffer and then permute the vector.\n\nA derivative of the test program used the first strategy for the subkey table. The subkey table is converted to big endian once so each subkey does not need a permute after loading. It was an optimization that benefited multiple encryptions under the same key. The test program used the second strategy on user data like input and output buffers.\n\nFor general reading on byte ordering, see \"Targeting your applications - what little endian and big endian IBM XL C/C++ compiler differences mean to you\" (http://www.ibm.com/developerworks/library/l-ibm-xl-c-cpp-compiler/index.html).\n\n## Optimizations\n\nThere are at least two optimizations available that your program should take. The first optimization is perform the byte reversal on little-endian machines for the subkey table once after it is built. You will still need to perform the endian conversions on user supplied input and output buffers as the data is streamed into the program.\n\nThe second optimization your program should take is to run 4 or 8 blocks of encryption or decryption in parallel. The VSX unit has 32 full size registers, so you should be able to raise the number of simultaneous transformations to 12 if desired.\n\nAs an example, instead of a single loop operating on a a single block:\n\n```\nVectorType s = VectorLoad(input);\nVectorType k = VectorLoadKey(subkeys);\n\ns = VectorXor(s, k);\nfor (size_t i=1; i\u003crounds-1; i+=2)\n{\n    s = VectorEncrypt(s, VectorLoadKey(  i*16,   subkeys));\n    s = VectorEncrypt(s, VectorLoadKey((i+1)*16, subkeys));\n}\n\ns = VectorEncrypt(s, VectorLoadKey((rounds-1)*16, subkeys));\ns = VectorEncryptLast(s, VectorLoadKey(rounds*16, subkeys));\n```\n\nRun multiple transformations simultaneously:\n\n```\nVectorType k = VectorLoadKey(subkeys);\nVectorType s0 = VectorLoad( 0, input);\nVectorType s1 = VectorLoad(16, input);\nVectorType s2 = VectorLoad(32, input);\nVectorType s3 = VectorLoad(64, input);\n\ns0 = VectorXor(s0, k);\ns1 = VectorXor(s1, k);\ns2 = VectorXor(s2, k);\ns3 = VectorXor(s3, k);\n\nfor (size_t i=1; i\u003crounds; ++i)\n{\n     k = VectorLoadKey(i*16, subkeys);\n    s0 = VectorEncrypt(s0, k);\n    s1 = VectorEncrypt(s1, k);\n    s2 = VectorEncrypt(s2, k);\n    s3 = VectorEncrypt(s3, k);\n}\n\n k = VectorLoadKey(rounds*16, subkeys);\ns0 = VectorEncryptLast(s0, k);\ns1 = VectorEncryptLast(s1, k);\ns2 = VectorEncryptLast(s2, k);\ns3 = VectorEncryptLast(s3, k);\n```\n\n## Field Implementations\n\nBoth Botan and Crypto++ used `fips197-p8.c` as a proof of concept. You can find the Botan issue to track the cut-in at Issue 1206, Add Power8 AES Encryption (http://github.com/randombit/botan/issues/1206). The issue to track the cut-in for Crypto++ can be found at Issue 497, Add Power8 AES Encryption (http://github.com/weidai11/cryptopp/issues/497).\n\n## Acknowledgements\n\nThanks to Bill Schmidt, George Wilson, and Michael Strosaker from the IBM Linux Technology Center for help with the implementation.\n\nMany thanks to Andy Polyakov for comments, helpful suggestions and answering questions about his ASM implmentation of Power 8 AES. Andy's implementation is lightening fast and available in the OpenSSL project and the Linux kernel. Andy's code and license terms can be found at http://www.openssl.org/~appro/cryptogams/.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoloader%2Faes-intrinsics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoloader%2Faes-intrinsics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoloader%2Faes-intrinsics/lists"}