ASCON Hashing and XOF (eXtendable-Output Functions)ASCON [2,7] was designed by Christoph Dobraunig, Maria Eichlseder, Florian Mendel and Martin Schläffer from Graz University of Technology, Infineon Technologies, and Radboud University. It is both a light-weight hashing and encryption method. ASCON uses a single lightweight permutation with a Sponge-based modes of operation and an SPN (substitution–permutation network) permutation. Overall it has an easy method of implementing within hardware (2.6 gate equivalents) and software. A 5-bit S-box (as used in Keccak’s S-box core) is used to enable a light weight approach and it has no known side-channel attacks. It can also achieve high throughputs such as throughputs of between 4.9 and 7.3 Gbps. It stores its current state with 320 bits. And, so, in Feb 2023, NIST annouced the ASCON was the winner, and would move to standardization. |
XOF
Our existing hashing functions are split into two main categories. The first is the cryptography hashes, such as MD5, SHA-1, SHA-256 and SHA-3. These are typically fast methods and which can take any amount of data as an input and produce a fixed hash output — a fingerprint of the data. The other type of hash is the non-cryptographic hash and these tend to be even faster than the cryptographic hashes, but have a lesser security strength. Typical non-cryptographic methods are SipHash, xxHash and FarmHash. These hashes are typically used for indexing such as with hash tables and Bloom filters. But, there’s another type of permutated output, and these are defined as eXtendable-Output Functions (XOFs).
XOFs differ from hashing functions in that they can produce any length of output — from one byte to an infinitely long byte stream. They can thus be used in applications where we need something larger or smaller than the 256-bit (16 bytes) or 512-bit (32 bytes) output value that our cryptographic hashing methods produce. For cryptographic methods, most modern applications now use SHA-256 (256-bit hash), SHA-512 (512-bit hash) or SHA-3 (256-bit).
In designing a modern hashing the focus is typically on a fixed hash output, but designers also implement a variable-length output for XOF. Overall, the main XOF methods are SHAKE128, SHAKE256, SHAKE128, SHAKE256, BLAKE2XB and BLAKE2XS. With the SHA-3 hashing method, we have four different cryptographic hashing methods (SHA3–224, SHA3–256, SHA3–384, and SHA3–512) and two XOF functions (SHAKE128 and SHAKE256). With BLAKE2b — one of the fastest cryptographic hashing methods — we have an XOF of BLAKE2XB, and for BLAKE2s we have an XOF of BLAKE2XS. With a string input, we will get a digest output of a given byte length. For a random input, we can generate a digest of the random values for a given output size.
The applications of XOF include creating hashes of variable lengths and in creating encryption keys based on passwords. While HKDF focuses on creating an encryption key from passwords, XOFs have the advantage of producing a variable output size for the key. As XOFs always produce the same output for a given input, it is strongly recommended that a salt value is used with the password (and then stored for recovery). There are also applications of XOF into stream encryption, where we can create a seed value and then produce an infinitely long encryption key. This input key can then simply be XOR-ed with the data stream to produce the cipher stream.
Outline
Since 2016, NIST has been assessing light-weight encryption methods, and, in 2022, NIST published the final 10: ASCON, Elephant, GIFT-COFB, Grain128-AEAD, ISAP, Photon-Beetle, Romulus, Sparkle, TinyJambu, and Xoodyak (Table 1). A particular focus is on the security of the methods, along with their performance on low-cost FPGAs/embedded processes and their robustness against side-channel attacks.
Table 1: Specifications of the NIST LWC finalist algorithms [3]
Generally, ASCON does well in most tests and is a good all-rounder. Itwas designed by Christoph Dobraunig, Maria Eichlseder, Florian Mendel and Martin Schläffer from Graz University of Technology, Infineon Technologies, and Radboud University. It is both a lightweight hashing and encryption method.
ASCON uses a single lightweight permutation with Sponge-based modes of operation and an SPN (substitution–permutation network) permutation. Overall it has an easy method of implementing within hardware (2.6 gate equivalents) and software. A 5-bit S-box (as used in Keccak’s S-box core) is used to enable a light-weight approach and it has no known side-channel attacks. It can also achieve high throughputs such as throughputs of between 4.9 and 7.3 Gbps. It stores its current state with 320 bits.
Evaluation (Performance)
The current set of benchmarks includes running on an Arduino Uno R3 (AVR ARmega 328P — Figure 1), Arduino Nano Every (AVR ARmega 4809), Arduino MKR Zero (ARM Cortex M10+) and Arduino Nano 33 BLE (ARM Cortex M4F). These are just 8-bit processors and fit into an Arduino board. Along with their processing limitations, they are also limited in their memory footprint (to run code and also to store it). The lightweight cryptography method must thus overcome these limitations and still, be secure and provide a good performance level. Running AES in block modes on these devices is often not possible, as there are insufficient resources. Overall we use a benchmark for encryption — with AEAD (Authenticated Encryption with Additional Data) and for hashing. With AEAD we add extra information — such as the session ID — into the encryption process. This type of method can bind the encryption to a specific stream.
ARM Cortex M3
In Table 2 [5], we see a sample run using an Arduino Due with an ARM Cortex M3 running at 84MHz. The tests are taken in comparison with the ChaCha20 stream cipher and defined for AEAD, and where the higher the value, the better the performance. We can see that Sparkle, Xoodyak and ASCON are the fastest of all. Sparkle has a 100% improvement, and Xoodyak gives a 60% increase in speed over ChaCha20. Elephant, ISAP and PHOTON-Beetle have the worst performance for encryption (with around 1/20th of the speed of ChaCha20).
Table 2: Arduino Due with an ARM Cortex M3 running at 84MHz for encryption against ChaCha20 [5]
Not all of the finalists can do hash functions. Table 3 outlines these.
Table 3: Arduino Due with an ARM Cortex M3 running at 84MHz for hashing against BLAKE2s [5]
Again, we see Sparkle and Xoodyak in the lead, with Sparkle actually faster in the test than BLAKE2s, and Xoodyak just a little bit slower. ASCON has a weaker performance, and PHOTON-Beetle is relatively slow. For all the tests, the ranking for authenticated encryption is (and where the higher the rank, the better):
and for hashing Sparkle and Xoodyak are ranked the same:
Uno Nano performance
For AEAD on Uno Nano Every [6], the benchmark is against AES GCM. We can see in Table 4, that Sparkle is 4.7 times faster than AES GCM for 128-bit data sizes, and Xoodyak comes in second with a 3.3 times improvement over AES GCM. When it comes to 8-bit data sizes, TinyJambu is actually the fastest, but where Sparkle and Xoodyak still perform well. PHOTON-Beetle, Grain128 and ISAP do not do well and only slightly improves on AES GCM. In fact, Grain128 and ISAP are actually slower than AES GCM.
Table 4: Uno Nano for AEAD against AES GCM and showing cycles [6] (showing fastest of the method)
And so for AEAD (performance):
1. Sparkle. 2. Xoodyak. 3. ASCON. 4. GIFT-COFB. 5. Elephant. 6. Romulus. 7. Tiny Jambu. 8. PHOTON-Beetle. 9. Grain128. 10. ISAP.
For hashing on an Uno Nano Every [6], Table 5 shows a similar performance level as the ARM Cortex M3 assessment. In this case, the benchmark hash is SHA-256, and we can see that it takes Sparkle twice as many cycles for a 128-bit hash and 2.9 times for Xoodyak. PHOTON-Beetle is way behind with a 128-bit hash and which is 17.4 times slower than SHA-256. That said, though, PHOTON-Beetle could be more focused on reducing power consumption rather than speed. GIMLI and SKINNY are included to show a comparison with well-designed methods in lightweight hashing. It can be seen that every method beats SKINNY, but only Sparkle and Xoodyak beat GIMLI.
Table 5: Uno Nano for hashing against SHA-256 and showing cycles [6] (showing fastest of the method for hashing)
And so for hashing (performance):
1. Sparkle. 2. Xoodyak. 3. ASCON. 4. PHOTON-Beetle.
Evaluation (Energy)
The key evaluators for the best method include their overall security; the their general performance (as measured with the number of cycles taken to conduct an operation); the gate count; the chip size; and energy consumption. When it comes to energy consumption and hardware requirements, Elsadek et al [4] performed a review of the 10 contenders.
In terms of the size of each implementation, we see that TinyJambu and Grain128 have the smallest footprint, while Sparkle has by far the largest footprint. In terms of gate equivalent (GE), TinyJambu requires 3,600 GEs, while Sparkle needs 39,500:
The energy efficiency is then defined as:
\(Energy efficiency (bit/J) = \frac{Throughput (bits/sec)}{Power (J/sec)}\)
and where we measure the bits per Joule. Figure 2 outlines the average energy efficiency, and where TinyJambu, Xoodyak and ASCON do well for energy, while ISAP, Elephant and Grain128-AEAD were poorest.
Figure 2: Average energy efficiency [1]
Coding
An outline of the Python code is [1]:
#!/usr/bin/env python3 import sys # Code from: https://github.com/meichlseder/pyascon/blob/master/ascon.py """ Implementation of Ascon v1.2, an authenticated cipher and hash function http://ascon.iaik.tugraz.at/ """ debug = False debugpermutation = False # === Ascon hash/xof === def ascon_hash(message, variant="Ascon-Hash", hashlength=32): """ Ascon hash function and extendable-output function. message: a bytes object of arbitrary length variant: "Ascon-Hash", "Ascon-Hasha" (both with 256-bit output for 128-bit security), "Ascon-Xof", or "Ascon-Xofa" (both with arbitrary output length, security=min(128, bitlen/2)) hashlength: the requested output bytelength (must be 32 for variant "Ascon-Hash"; can be arbitrary for Ascon-Xof, but should be >= 32 for 128-bit security) returns a bytes object containing the hash tag """ assert variant in ["Ascon-Hash", "Ascon-Hasha", "Ascon-Xof", "Ascon-Xofa"] if variant in ["Ascon-Hash", "Ascon-Hasha"]: assert(hashlength == 32) a = 12 # rounds b = 8 if variant in ["Ascon-Hasha", "Ascon-Xofa"] else 12 rate = 8 # bytes # Initialization tagspec = int_to_bytes(256 if variant in ["Ascon-Hash", "Ascon-Hasha"] else 0, 4) S = bytes_to_state(to_bytes([0, rate * 8, a, a-b]) + tagspec + zero_bytes(32)) if debug: printstate(S, "initial value:") ascon_permutation(S, a) if debug: printstate(S, "initialization:") # Message Processing (Absorbing) m_padding = to_bytes([0x80]) + zero_bytes(rate - (len(message) % rate) - 1) m_padded = message + m_padding # first s-1 blocks for block in range(0, len(m_padded) - rate, rate): S[0] ^= bytes_to_int(m_padded[block:block+8]) # rate=8 ascon_permutation(S, b) # last block block = len(m_padded) - rate S[0] ^= bytes_to_int(m_padded[block:block+8]) # rate=8 if debug: printstate(S, "process message:") # Finalization (Squeezing) H = b"" ascon_permutation(S, a) while len(H) < hashlength: H += int_to_bytes(S[0], 8) # rate=8 ascon_permutation(S, b) if debug: printstate(S, "finalization:") return H[:hashlength] # === Ascon permutation === def ascon_permutation(S, rounds=1): """ Ascon core permutation for the sponge construction - internal helper function. S: Ascon state, a list of 5 64-bit integers rounds: number of rounds to perform returns nothing, updates S """ assert(rounds <= 12) if debugpermutation: printwords(S, "permutation input:") for r in range(12-rounds, 12): # --- add round constants --- S[2] ^= (0xf0 - r*0x10 + r*0x1) if debugpermutation: printwords(S, "round constant addition:") # --- substitution layer --- S[0] ^= S[4] S[4] ^= S[3] S[2] ^= S[1] T = [(S[i] ^ 0xFFFFFFFFFFFFFFFF) & S[(i+1)%5] for i in range(5)] for i in range(5): S[i] ^= T[(i+1)%5] S[1] ^= S[0] S[0] ^= S[4] S[3] ^= S[2] S[2] ^= 0XFFFFFFFFFFFFFFFF if debugpermutation: printwords(S, "substitution layer:") # --- linear diffusion layer --- S[0] ^= rotr(S[0], 19) ^ rotr(S[0], 28) S[1] ^= rotr(S[1], 61) ^ rotr(S[1], 39) S[2] ^= rotr(S[2], 1) ^ rotr(S[2], 6) S[3] ^= rotr(S[3], 10) ^ rotr(S[3], 17) S[4] ^= rotr(S[4], 7) ^ rotr(S[4], 41) if debugpermutation: printwords(S, "linear diffusion layer:") # === helper functions === def get_random_bytes(num): import os return to_bytes(os.urandom(num)) def zero_bytes(n): return n * b"\x00" def to_bytes(l): # where l is a list or bytearray or bytes return bytes(bytearray(l)) def bytes_to_int(bytes): return sum([bi << ((len(bytes) - 1 - i)*8) for i, bi in enumerate(to_bytes(bytes))]) def bytes_to_state(bytes): return [bytes_to_int(bytes[8*w:8*(w+1)]) for w in range(5)] def int_to_bytes(integer, nbytes): return to_bytes([(integer >> ((nbytes - 1 - i) * 8)) % 256 for i in range(nbytes)]) def rotr(val, r): return (val >> r) | ((val & (1<1): message=sys.argv[1].encode() if (len(sys.argv)>2): variant=sys.argv[2] if (len(sys.argv)>3): hashlength=int(sys.argv[3]) if (variant=="Ascon-Hash" or variant=="Ascon-Hash"): hashlength=32 tag = ascon_hash(message, variant, hashlength) print ("== ASCON Hash ==") print ("Plaintext: ",message.decode()) print ("Type: ",variant) print ("Hash length: ",hashlength) print ("\nHash: ",bytes(tag).hex())
Ans a sample run is:
== ASCON Hash == Plaintext: qwerty Type: Ascon-Hash Hash length: 32 Hash: 6f1429052cd2803f108b2ceeb71a7c8d5135f62759cef7671d61c5a105c98658
and for Xof with 256 bytes:
== ASCON Hash == Plaintext: qwerty Type: Ascon-Xof Hash length: 256 Hash: db8a088938201b0e2577673cbbc451fdc88b8e7748ca5a3a9b11df5d3226fc9cf45da8dd7bf3a9b74714a164926c56ffb8ba76260340fcd26ed3f7d6d152aaa4da7b7d29a0aed14dd5429788629bfe325b6f7120c566e663b99b48141743dbd898e5ce44c6e147f8f13cd277ac0ba087de13c75d46f39a1ca34eb2556143be464549ada0512a507fa813eb3cd188186c79a407fd4853cd55fb07d03cf084efdff420d764392221729a3a0a6e22d0796acd763ff6a08c45b58eb3de0dfea43a1a4b0a55e2b145819a57a9e2f81965be9c827e136339ba187708472126e7c3abad9a4814e5d9639a2cc96ef3814468b8fbbcc7422ce6bf03ce76890bd4d8772f61
References
[1] ASCON GitHub [here].
[2] Dobraunig, C., Eichlseder, M., Mendel, F., & Schläffer, M. (2016). Ascon v1. 2. Submission to the CAESAR Competition.
[3] Madushan, H., Salam, I., & Alawatugoda, J. (2022). A Review of the NIST Lightweight Cryptography Finalists and Their Fault Analyses. Electronics, 11(24), 4199.
[4] Elsadek, I., Aftabjahani, S., Gardner, D., MacLean, E., Wallrabenstein, J. R., & Tawfik, E. Y. (2022, May). Hardware and Energy Efficiency Evaluation of NIST Lightweight Cryptography Standardization Finalists. In 2022 IEEE International Symposium on Circuits and Systems (ISCAS) (pp. 133–137). IEEE.
[5] https://rweather.github.io/lightweight-crypto/performance.html
[6] https://github.com/usnistgov/Lightweight-Cryptography-Benchmarking/blob/main/benchmarks/results_nano_every_hash_all.csv
[7] Dobraunig, C., Eichlseder, M., Mendel, F., & Schläffer, M. (2021). Ascon v1. 2: Lightweight authenticated encryption and hashing. Journal of Cryptology, 34, 1-42.