| #!/usr/bin/env python3 | |
| # Copyright lowRISC contributors. | |
| # Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| r"""Calculate Round Constant | |
| """ | |
| import argparse | |
| import bitarray as ba | |
| import logging as log | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| prog="keccak round constant generator", | |
| description= | |
| '''This tool generates the round constants based on the given max round number''' | |
| ) | |
| parser.add_argument( | |
| '-r', | |
| type=int, | |
| default=24, | |
| help='''Max Round value. Default is SHA3 Keccak round %(default)''') | |
| parser.add_argument('--verbose', '-v', action='store_true', help='Verbose') | |
| args = parser.parse_args() | |
| if (args.verbose): | |
| log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG) | |
| else: | |
| log.basicConfig(format="%(levelname)s: %(message)s") | |
| if args.r < 1: | |
| log.error("Max Round value should be greater than 0") | |
| # Create 0..255 bit array | |
| rc = ba.bitarray(256) | |
| rc.setall(0) | |
| r = ba.bitarray('10000000') | |
| rc[0] = True # t%255 == 0 -> 1 | |
| for i in range(1, 256): | |
| # Update from t=1 to t=255 | |
| r_d = ba.bitarray('0') + r | |
| if r_d[8]: | |
| #Flip 0,4,5,6 | |
| r = r_d[0:8] ^ ba.bitarray('10001110') | |
| else: | |
| r = r_d[0:8] | |
| rc[i] = r[0] | |
| ## Print rc | |
| print(rc) | |
| ## Round | |
| rcs = [] # Each entry represent the round | |
| for rnd in range(0, args.r): | |
| # Let RC=0 | |
| rndconst = ba.bitarray(64) | |
| rndconst.setall(0) | |
| # for j [0 .. L] RC[2**j-1] = rc(j+7*rnd) | |
| for j in range(0, 7): #0 to 6 | |
| rndconst[2**j - 1] = rc[(j + 7 * rnd) % 255] | |
| print("64'h{}, // Round {}".format(rndhex(rndconst), rnd)) | |
| def rndhex(bit) -> str: | |
| return bit[::-1].tobytes().hex() | |
| if __name__ == "__main__": | |
| main() |