#! python3
# -*- coding: utf-8 -*-
"""Some tests for ``crsysapi.py`` the Python interface to CryptoSys API"""
# test_crsysapi.py: version 6.22.1
# $Date: 2024-01-05 13:53:00 $
# ************************** LICENSE *****************************************
# Copyright (C) 2023-24 David Ireland, DI Management Services Pty Limited.
# All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
# The code in this module is licensed under the terms of the MIT license.
# For a copy, see <http://opensource.org/licenses/MIT>
# ****************************************************************************
import crsysapi
import os
import sys
import pytest
import shutil
from glob import iglob
_MIN_API_VERSION = 62201
print("crsysapi version =", crsysapi.__version__)
# Show some info about the core native DLL
print("API core version =", crsysapi.Gen.version())
print("module_name =", crsysapi.Gen.module_name())
print("compile_time =", crsysapi.Gen.compile_time())
print("platform =", crsysapi.Gen.core_platform())
print("licence_type =", crsysapi.Gen.licence_type())
print("module_info =", crsysapi.Gen.module_info())
# Show some system values
print("sys.getdefaultencoding()=", sys.getdefaultencoding())
print("sys.getfilesystemencoding()=", sys.getfilesystemencoding())
print("sys.platform()=", sys.platform)
print("cwd =", os.getcwd())
if crsysapi.Gen.version() < _MIN_API_VERSION:
raise Exception('Require API version ' +
str(_MIN_API_VERSION) + ' or greater')
# GLOBAL VARS
# Remember CWD where we started
start_dir = os.getcwd()
# We use a subdir `work` for our temp files
work_dir = os.path.join(start_dir, "work")
def setup_work_dir():
if not os.path.isdir(work_dir):
os.mkdir(work_dir)
# Set CWD here
os.chdir(work_dir)
print("Working in directory:", os.getcwd())
def reset_start_dir():
if not os.path.isdir(start_dir):
return
if (work_dir == start_dir):
return
os.chdir(start_dir)
print("")
# print("CWD:", os.getcwd())
# JIGGERY_POKERY FOR py.test
@pytest.fixture(scope="module", autouse=True)
def divider_module(request):
print("\n --- module %s() start ---" % request.module.__name__)
setup_work_dir()
def fin():
print("\n --- module %s() done ---" % request.module.__name__)
reset_start_dir()
request.addfinalizer(fin)
@pytest.fixture(scope="function", autouse=True)
def divider_function(request):
print("\n --- function %s() start ---" % request.function.__name__)
os.chdir(work_dir)
def fin():
print("\n --- function %s() done ---" % request.function.__name__)
os.chdir(start_dir)
request.addfinalizer(fin)
# FILE-RELATED UTILITIES
def read_binary_file(fname):
with open(fname, "rb") as f:
return bytearray(f.read())
def write_binary_file(fname, data):
with open(fname, "wb") as f:
f.write(data)
def read_text_file(fname, enc='utf8'):
with open(fname, encoding=enc) as f:
return f.read()
def write_text_file(fname, s, enc='utf8'):
with open(fname, "w", encoding=enc) as f:
f.write(s)
def _print_file(fname):
"""Print contents of text file."""
s = read_text_file(fname)
print(s)
def _print_file_hex(fname):
"""Print contents of file encoded in hexadecimal."""
b = read_binary_file(fname)
print(crsysapi.Cnv.tohex(b))
def _dump_file(fname):
"""Print contents of text file with filename header and rulers."""
s = read_text_file(fname)
ndash = (24 if len(s) > 24 else len(s))
print("FILE:", fname)
print("-" * ndash)
print(s)
print("-" * ndash)
def textwrap(text, width=64):
"""Simple textwrap to display string."""
return "\n".join([text[i:i + width] for i in range(0, len(text) - 1, width)])
#############
# THE TESTS #
#############
def test_error_lookup():
print("\nLOOKUP SOME ERROR CODES...")
for n in range(13):
s = crsysapi.Gen.error_lookup(n)
if (len(s) > 0):
print("error_lookup(" + str(n) + ")=" + s)
def test_cnv():
print("\nTEST CNV FUNCTIONS...")
# hex --> bytes --> base64
b = crsysapi.Cnv.fromhex("FE DC BA 98 76 54 32 10")
print("b=0x" + crsysapi.Cnv.tohex(b))
print("b64(b)=" + crsysapi.Cnv.tobase64(b))
assert(crsysapi.Cnv.tobase64(b) == "/ty6mHZUMhA=")
# base64 --> bytes --> hex --> base64
b = crsysapi.Cnv.frombase64("/ty6mHZUMhA=")
print("b=0x" + crsysapi.Cnv.tohex(b))
assert(crsysapi.Cnv.tohex(b) == "FEDCBA9876543210")
print("b64(b)=" + crsysapi.Cnv.tobase64(b))
assert(crsysapi.Cnv.tobase64(b) == "/ty6mHZUMhA=")
def test_cipher():
print("\nTEST BLOCK CIPHER FUNCTIONS...")
algstr = "Tdea/CBC/PKCS5"
print(algstr)
key = bytearray.fromhex('737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32')
iv = bytearray.fromhex("B36B6BFB6231084E")
pt = bytearray.fromhex("5468697320736F6D652073616D706520636F6E74656E742E")
ct = crsysapi.Cipher.encrypt(pt, key, iv, algstr)
print(crsysapi.Cnv.tohex(ct))
b = bytearray.fromhex("5468697320736F6D652073616D706520636F6E74656E742E")
print(b)
assert(ct == bytearray.fromhex(
"D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4"))
p1 = crsysapi.Cipher.decrypt(ct, key, iv, algstr)
print(p1)
assert(p1 == pt)
print("Use default ECB mode (IV is ignored)")
ct = crsysapi.Cipher.encrypt(pt, key, alg=crsysapi.Cipher.Alg.TDEA)
print(crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Cipher.decrypt(ct, key, alg=crsysapi.Cipher.Alg.TDEA)
print(p1)
assert(p1 == pt)
ct = crsysapi.Cipher.encrypt(pt, key, iv, mode=crsysapi.Cipher.Mode.CBC,
alg=crsysapi.Cipher.Alg.TDEA)
print(crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Cipher.decrypt(ct, key, iv, mode=crsysapi.Cipher.Mode.CBC,
alg=crsysapi.Cipher.Alg.TDEA)
print(p1)
assert(p1 == pt)
algstr = "Aes128/CBC/pkcs5"
print(algstr)
key = bytearray.fromhex('0123456789ABCDEFF0E1D2C3B4A59687')
iv = bytearray.fromhex("FEDCBA9876543210FEDCBA9876543210")
# In Python 3 we must must pass plaintext as bytes; ASCII strings no longer work
pt = b"Now is the time for all good men to"
ct = crsysapi.Cipher.encrypt(pt, key, iv, algstr)
print(crsysapi.Cnv.tohex(ct))
assert(ct == bytearray.fromhex(
"C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E17753C7E8DF5975A36677355F5C6584228B"))
# Now decrypt using flags instead of alg string
p1 = crsysapi.Cipher.decrypt(ct, key, iv, alg=crsysapi.Cipher.Alg.AES128,
mode=crsysapi.Cipher.Mode.CBC, pad=crsysapi.Cipher.Pad.PKCS5)
print("P':", p1)
assert(p1 == pt)
algstr = "Aes128/ECB/OneAndZeroes"
print(algstr)
ct = crsysapi.Cipher.encrypt(pt, key, algmodepad=algstr)
print("CT:", crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Cipher.decrypt(ct, key, algmodepad="Aes128/ECB/NoPad")
print("Pn:", crsysapi.Cnv.tohex(p1))
p1 = crsysapi.Cipher.decrypt(ct, key, algmodepad=algstr)
print("P':", crsysapi.Cnv.tohex(p1))
print("P':", p1)
assert(p1 == pt)
def test_cipher_hex():
print("\nTEST CIPHER FUNCTIONS USING HEX-ENCODED PARAMETERS...")
algstr = "Tdea/CBC/PKCS5"
print("ALG:", algstr)
keyhex = '737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32'
ivhex = "B36B6BFB6231084E"
pthex = "5468697320736F6D652073616D706520636F6E74656E742E"
okhex = "D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4"
print("KY:", keyhex)
print("IV:", ivhex)
print("PT:", pthex)
cthex = crsysapi.Cipher.encrypt_hex(pthex, keyhex, ivhex, algstr)
print("CT:", cthex)
print("OK:", okhex)
assert cthex == okhex, "crsysapi.Cipher.encrypt_hex failed"
print("About to decrypt...")
# Decrypt using flags instead of alg string
p1hex = crsysapi.Cipher.decrypt_hex(cthex, keyhex, ivhex, alg=crsysapi.Cipher.Alg.TDEA, mode=crsysapi.Cipher.Mode.CBC, pad=crsysapi.Cipher.Pad.PKCS5)
print("P':", p1hex)
assert p1hex == pthex
# Another example, this time with the IV prefixed to the ciphertext
algstr = "Aes128/CBC/OneAndZeroes"
keyhex = '0123456789ABCDEFF0E1D2C3B4A59687'
ivhex = "FEDCBA9876543210FEDCBA9876543210"
pthex = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F"
# IV||CT
okhex = "FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
print("KY:", keyhex)
print("IV:", ivhex)
print("PT:", pthex)
cthex = crsysapi.Cipher.encrypt_hex(pthex, keyhex, ivhex, algstr, opts=crsysapi.Cipher.Opts.PREFIXIV)
print("CT:", cthex)
print("OK:", okhex)
assert cthex == okhex, "crsysapi.Cipher.encrypt_hex failed"
# Decrypt using flags instead of alg string - this time we don't need the IV argument
p1hex = crsysapi.Cipher.decrypt_hex(cthex, keyhex, None, alg=crsysapi.Cipher.Alg.AES128, mode=crsysapi.Cipher.Mode.CBC, pad=crsysapi.Cipher.Pad.ONEANDZEROES, opts=crsysapi.Cipher.Opts.PREFIXIV)
print("P':", p1hex)
assert(p1hex == pthex)
# Test in ECB mode
# SP 800-38A F.1.3 ECB-AES192.Encrypt
keyhex = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"
pthex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51" \
+ "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
okhex = "bd334f1d6e45f25ff712a214571fa5cc974104846d0ad3ad7734ecb3ecee4eef" \
+ "ef7afd2270e2e60adce0ba2face6444e9a4b41ba738d6c72fb16691603c18e0e"
print("PT:", pthex)
cthex = crsysapi.Cipher.encrypt_hex(pthex, keyhex, algmodepad="Aes192-ECB-Nopad").lower()
print("CT:", cthex)
print("OK:", okhex)
assert cthex == okhex, "crsysapi.Cipher.encrypt_hex failed"
p1hex = crsysapi.Cipher.decrypt_hex(cthex, keyhex, alg=crsysapi.Cipher.Alg.AES192, pad=crsysapi.Cipher.Pad.NOPAD).lower()
print("P':", p1hex)
assert(p1hex == pthex)
def test_cipher_file():
print("\nTEST CIPHER FILE FUNCTIONS...")
file_pt = "hello.txt"
write_text_file(file_pt, "hello world\r\n")
print(file_pt + ":",)
_print_file_hex(file_pt)
key = crsysapi.Cnv.fromhex("fedcba9876543210fedcba9876543210")
iv = crsysapi.Rng.bytestring(crsysapi.Cipher.blockbytes(crsysapi.Cipher.Alg.AES128))
print("IV:", crsysapi.Cnv.tohex(iv))
file_ct = "hello.aes128.enc.dat"
n = crsysapi.Cipher.file_encrypt(file_ct, file_pt, key, iv, "aes128-ctr", opts=crsysapi.Cipher.Opts.PREFIXIV)
assert(n == 0)
print(file_ct + ":",)
_print_file_hex(file_ct)
file_chk = "hello.aes128.chk.txt"
n = crsysapi.Cipher.file_decrypt(file_chk, file_ct, key, iv, "aes128-ctr", opts=crsysapi.Cipher.Opts.PREFIXIV)
assert(n == 0)
print(file_chk + ":",)
_print_file_hex(file_chk)
# check files are equal
assert(read_binary_file(file_pt) == read_binary_file(file_chk))
def test_cipher_pad():
print("\nTEST CIPHER PAD....")
data = crsysapi.Cnv.fromhex('FFFFFFFFFF')
print("Input data :", crsysapi.Cnv.tohex(data))
padded = crsysapi.Cipher.pad(data, crsysapi.Cipher.Alg.TDEA)
print("Padded data:", crsysapi.Cnv.tohex(padded))
unpadded = crsysapi.Cipher.unpad(padded, crsysapi.Cipher.Alg.TDEA)
print("Unpadded :", crsysapi.Cnv.tohex(unpadded))
padded = crsysapi.Cipher.pad(data, crsysapi.Cipher.Alg.TDEA,
crsysapi.Cipher.Pad.ONEANDZEROES)
print("Padded data:", crsysapi.Cnv.tohex(padded))
unpadded = crsysapi.Cipher.unpad(padded, crsysapi.Cipher.Alg.TDEA,
crsysapi.Cipher.Pad.ONEANDZEROES)
print("Unpadded :", crsysapi.Cnv.tohex(unpadded))
# Pad the empty string
data = crsysapi.Cnv.fromhex('')
print("Input data :", crsysapi.Cnv.tohex(data))
padded = crsysapi.Cipher.pad(data, crsysapi.Cipher.Alg.AES128)
print("Padded data:", crsysapi.Cnv.tohex(padded))
unpadded = crsysapi.Cipher.unpad(padded, crsysapi.Cipher.Alg.AES128)
print("Unpadded :", crsysapi.Cnv.tohex(unpadded))
# Pass data as hex strings
datahex = 'aaaaaa'
print("Input data :", datahex)
paddedhex = crsysapi.Cipher.pad_hex(datahex, crsysapi.Cipher.Alg.TDEA)
print("Padded data:", paddedhex)
unpaddedhex = crsysapi.Cipher.unpad_hex(paddedhex, crsysapi.Cipher.Alg.TDEA)
print("Unpadded :", unpaddedhex)
paddedhex = crsysapi.Cipher.pad_hex(
datahex, crsysapi.Cipher.Alg.TDEA, crsysapi.Cipher.Pad.ONEANDZEROES)
print("Padded data:", paddedhex)
unpaddedhex = crsysapi.Cipher.unpad_hex(
paddedhex, crsysapi.Cipher.Alg.TDEA, crsysapi.Cipher.Pad.ONEANDZEROES)
print("Unpadded :", unpaddedhex)
def test_cipher_block():
print("\nTEST CIPHER FUNCTIONS WITH EXACT BLOCK LENGTHS...")
key = crsysapi.Cnv.fromhex("0123456789ABCDEFF0E1D2C3B4A59687")
iv = crsysapi.Cnv.fromhex("FEDCBA9876543210FEDCBA9876543210")
print("KY:", crsysapi.Cnv.tohex(key))
print("IV:", crsysapi.Cnv.tohex(iv))
# In Python 3 plaintext must be bytes, not ASCII string
pt = b"Now is the time for all good men"
print("PT:", pt)
print("PT:", crsysapi.Cnv.tohex(pt))
okhex = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E177"
ct = crsysapi.Cipher.encrypt_block(
pt, key, iv, alg=crsysapi.Cipher.Alg.AES128, mode=crsysapi.Cipher.Mode.CBC)
print("CT:", crsysapi.Cnv.tohex(ct))
print("OK:", okhex)
assert(okhex.upper() == crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Cipher.decrypt_block(
ct, key, iv, alg=crsysapi.Cipher.Alg.AES128, mode=crsysapi.Cipher.Mode.CBC)
print("P1:", crsysapi.Cnv.tohex(p1))
print("P1:", p1)
# Using defaults (TDEA/ECB)
key = crsysapi.Rng.bytestring(crsysapi.Cipher.keybytes(crsysapi.Cipher.Alg.TDEA))
print("KY:", crsysapi.Cnv.tohex(key))
ct = crsysapi.Cipher.encrypt_block(pt, key)
print("CT:", crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Cipher.decrypt_block(ct, key)
print("P1:", crsysapi.Cnv.tohex(p1))
print("P1:", p1)
def test_blowfish():
print("\nTEST BLOWFISH CIPHER...")
key = crsysapi.Cnv.fromhex("0123456789ABCDEFF0E1D2C3B4A59687")
iv = crsysapi.Cnv.fromhex("FEDCBA9876543210")
print("KY:", crsysapi.Cnv.tohex(key))
print("IV:", crsysapi.Cnv.tohex(iv))
pt = crsysapi.Cnv.fromhex("37363534333231204E6F77206973207468652074696D6520666F722000000000")
print("PT:", crsysapi.Cnv.tohex(pt))
okhex = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"
ct = crsysapi.Blowfish.encrypt_block(pt, key, "CBC", iv)
print("CT:", crsysapi.Cnv.tohex(ct))
print("OK:", okhex)
assert(okhex.upper() == crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Blowfish.decrypt_block(ct, key, "CBC", iv)
print("P1:", crsysapi.Cnv.tohex(p1))
print("P1:", bytes(p1))
assert(p1 == pt)
# Using default ECB mode
key = crsysapi.Cnv.fromhex("FEDCBA9876543210")
print("KY:", crsysapi.Cnv.tohex(key))
pt = crsysapi.Cnv.fromhex("0123456789ABCDEF0123456789ABCDEF")
print("PT:", crsysapi.Cnv.tohex(pt))
okhex = "0ACEAB0FC6A0A28D0ACEAB0FC6A0A28D"
ct = crsysapi.Blowfish.encrypt_block(pt, key)
print("CT:", crsysapi.Cnv.tohex(ct))
print("OK:", okhex)
assert(okhex.upper() == crsysapi.Cnv.tohex(ct))
p1 = crsysapi.Blowfish.decrypt_block(ct, key)
print("P1:", crsysapi.Cnv.tohex(p1))
assert(p1 == pt)
def test_aead():
print("\nTEST AEAD ENCRYPTION....")
# GCM Test Case #03 (AES-128)
key = crsysapi.Cnv.fromhex("feffe9928665731c6d6a8f9467308308")
iv = crsysapi.Cnv.fromhex("cafebabefacedbaddecaf888")
pt = crsysapi.Cnv.fromhex("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255")
okhex = "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4"
print("KY =", crsysapi.Cnv.tohex(key))
print("IV =", crsysapi.Cnv.tohex(iv))
print("PT =", crsysapi.Cnv.tohex(pt))
# Do the business
ct = crsysapi.Aead.encrypt_with_tag(pt, key, iv, crsysapi.Aead.AeadAlg.AES_128_GCM)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
assert (okhex.lower() == crsysapi.Cnv.tohex(ct).lower())
# Decrypt, passing IV as an argument
dt = crsysapi.Aead.decrypt_with_tag(ct, key, iv, crsysapi.Aead.AeadAlg.AES_128_GCM)
print("DT =", crsysapi.Cnv.tohex(dt))
assert (crsysapi.Cnv.tohex(pt) == crsysapi.Cnv.tohex(dt))
print("Repeat but prepend IV to output..")
ct = crsysapi.Aead.encrypt_with_tag(pt, key, iv, crsysapi.Aead.AeadAlg.AES_128_GCM, opts=crsysapi.Aead.Opts.PREFIXIV)
print("IV|CT =", crsysapi.Cnv.tohex(ct))
# Decrypt, IV is prepended to ciphertext
dt = crsysapi.Aead.decrypt_with_tag(ct, key, None, crsysapi.Aead.AeadAlg.AES_128_GCM, opts=crsysapi.Aead.Opts.PREFIXIV)
print("DT =", crsysapi.Cnv.tohex(dt))
assert (crsysapi.Cnv.tohex(pt) == crsysapi.Cnv.tohex(dt))
print("RFC7739 ChaCha20_Poly1305 Sunscreen test with AAD")
key = crsysapi.Cnv.fromhex("808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F")
iv = crsysapi.Cnv.fromhex("070000004041424344454647")
aad = crsysapi.Cnv.fromhex("50515253C0C1C2C3C4C5C6C7")
pt = crsysapi.Cnv.fromhex("4C616469657320616E642047656E746C656D656E206F662074686520636C617373206F66202739393A204966204920636F756C64206F6666657220796F75206F6E6C79206F6E652074697020666F7220746865206675747572652C2073756E73637265656E20776F756C642062652069742E")
okhex = "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691"
print("KY =", crsysapi.Cnv.tohex(key))
print("IV =", crsysapi.Cnv.tohex(iv))
print("AD =", crsysapi.Cnv.tohex(aad))
print("PT =", crsysapi.Cnv.tohex(pt))
# Do the business
ct = crsysapi.Aead.encrypt_with_tag(pt, key, iv, crsysapi.Aead.AeadAlg.CHACHA20_POLY1305, aad=aad)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
assert (okhex.lower() == crsysapi.Cnv.tohex(ct).lower())
dt = crsysapi.Aead.decrypt_with_tag(ct, key, iv, crsysapi.Aead.AeadAlg.CHACHA20_POLY1305, aad=aad)
print("DT =", crsysapi.Cnv.tohex(dt))
print(f"DT ='{dt}'")
assert (crsysapi.Cnv.tohex(pt) == crsysapi.Cnv.tohex(dt))
def test_crc():
print("\nTEST CRC FUNCTIONS...")
crc = crsysapi.Crc.bytes(b"123456789")
print(f"crc={crc}=0x{crc:08x}")
crc = 0
fname = "1-9.txt"
write_text_file(fname, "123456789")
crc = crsysapi.Crc.file(fname)
print(f"crc={crc}=0x{crc:08x}")
def test_rng():
print("\nTESTING RANDOM NUMBER GENERATOR...")
# Initialize from seed file. File is created if it does not exist.
# Optional but recommended for extra security
seedfile = 'myseedfile.dat'
n = crsysapi.Rng.initialize(seedfile)
assert(0 == n)
print('crsysapi.Rng.initialize() returns', n, ". Contents of seed file:")
sd = read_binary_file(seedfile)
print(crsysapi.Cnv.tohex(sd))
assert(len(sd) == crsysapi.Rng.SEED_BYTES)
print("5 random byte arrays")
for i in range(5):
b = crsysapi.Rng.bytestring((i + 2) * 2)
print(crsysapi.Cnv.tohex(b).lower())
print("5 random numbers in the range [-1 million, +1 million]")
for i in range(5):
r = crsysapi.Rng.number(-1000000, 1000000)
print(r)
assert(-1000000 <= r <= 1000000)
print("5 random octet values")
s = "" # fudge to do in one line
for i in range(5):
r = crsysapi.Rng.octet()
assert(0 <= r <= 255)
s += str(r) + " "
print(s)
# Update seedfile
n = crsysapi.Rng.update_seedfile(seedfile)
assert(0 == n)
print('crsysapi.Rng.update_seedfile() returns', n, ". Contents of seed file:")
sd = read_binary_file(seedfile)
print(textwrap(crsysapi.Cnv.tohex(sd)))
assert(len(sd) == crsysapi.Rng.SEED_BYTES)
# Carry out DRBGVS test
# Ref: drbgtestvectors/drbgvectors_pr_false/HMAC_DRBG.txt (line 22654)
# CAVS 14.3 DRBG800-90A information for "drbg_pr" COUNT = 0
s = crsysapi.Rng.test_drbgvs(2048, "da740cbc36057a8e282ae717fe7dfbb245e9e5d49908a0119c5dbcf0a1f2d5ab", "46561ff612217ba3ff91baa06d4b5440",
"fc227293523ecb5b1e28c87863626627d958acc558a672b148ce19e2abd2dde4", "b7998998eaf9e5d34e64ff7f03de765b31f407899d20535573e670c1b402c26a",
"1d61d4d8a41c3254b92104fd555adae0569d1835bb52657ec7fbba0fe03579c5", "b9ed8e35ad018a375b61189c8d365b00507cb1b4510d21cac212356b5bbaa8b2",
"2089d49d63e0c4df58879d0cb1ba998e5b3d1a7786b785e7cf13ca5ea5e33cfd")
ok = "5b70f3e4da95264233efbab155b828d4e231b67cc92757feca407cc9615a6608" + \
"71cb07ad1a2e9a99412feda8ee34dc9c57fa08d3f8225b30d29887d20907d123" + \
"30fffd14d1697ba0756d37491b0a8814106e46c8677d49d9157109c402ad0c24" + \
"7a2f50cd5d99e538c850b906937a05dbb8888d984bc77f6ca00b0e3bc97b16d6" + \
"d25814a54aa12143afddd8b2263690565d545f4137e593bb3ca88a37b0aadf79" + \
"726b95c61906257e6dc47acd5b6b7e4b534243b13c16ad5a0a1163c0099fce43" + \
"f428cd27c3e6463cf5e9a9621f4b3d0b3d4654316f4707675df39278d5783823" + \
"049477dcce8c57fdbd576711c91301e9bd6bb0d3e72dc46d480ed8f61fd63811"
print("crsysapi.Rng.test_drbgvs returns:")
print(textwrap(s))
print("Expected:\n", ok[:64], ' ... ', ok[-32:], sep='')
assert(s == ok)
# Explicity call this function to test the random-number generator prompts
# This does not begin with "test_" so as not to fire in py.test
def do_rng_prompt():
# FUNCS THAT OPEN A DIALOG BOX FOR KEYBOARD PROMPTS...
n = crsysapi.Rng.make_seedfile('newseed.dat', strength=crsysapi.Rng.Strength.BITS_128)
print("crsysapi.Rng.make_seedfile returns", n)
b = crsysapi.Rng.bytes_with_prompt(32, crsysapi.Rng.Strength.BITS_192, "Type random keys until done")
print("crsysapi.Rng.bytes_with_prompt:", crsysapi.Cnv.tohex(b).lower())
def test_hash():
print("\nTESTING HASH...")
# write a file containing the 3 bytes 'abc'
write_text_file('abc.txt', 'abc')
_dump_file('abc.txt')
abc_hex = crsysapi.Cnv.tohex(b'abc')
print("'abc' in hex:", abc_hex)
# Use default SHA-1 algorithm
print("Using default SHA-1...")
b = crsysapi.Hash.data(b'abc')
print("crsysapi.Hash.data('abc'):", crsysapi.Cnv.tohex(b))
h = crsysapi.Hash.hex_from_data(b'abc')
print("crsysapi.Hash.hex_from_data('abc'):", h)
h = crsysapi.Hash.hex_from_data(bytearray.fromhex('616263'))
print("crsysapi.Hash.hex_from_data('abc'):", h)
h = crsysapi.Hash.hex_from_hex(abc_hex)
print("crsysapi.Hash.hex_from_hex(abc_hex):", h)
b = crsysapi.Hash.file('abc.txt')
print("crsysapi.Hash.file('abc.txt'):", crsysapi.Cnv.tohex(b))
h = crsysapi.Hash.hex_from_file('abc.txt')
print("crsysapi.Hash.hex_from_file('abc.txt'):", h)
print("Using SHA-256...")
b = crsysapi.Hash.data(b'abc', crsysapi.Hash.Alg.SHA256)
print("crsysapi.Hash.data('abc'):", crsysapi.Cnv.tohex(b))
h = crsysapi.Hash.hex_from_hex(abc_hex, crsysapi.Hash.Alg.SHA256)
print("crsysapi.Hash.hex_from_hex(abc_hex):", h)
b = crsysapi.Hash.file('abc.txt', crsysapi.Hash.Alg.SHA256)
print("crsysapi.Hash.file('abc.txt'):", crsysapi.Cnv.tohex(b))
h = crsysapi.Hash.hex_from_file('abc.txt', crsysapi.Hash.Alg.SHA256)
print("crsysapi.Hash.hex_from_file('abc.txt'):", h)
# write a file containing the 3 bytes 'abc'
write_text_file('abc.txt', 'abc')
_dump_file('abc.txt')
abc_hex = crsysapi.Cnv.tohex(b'abc')
print("'abc' in hex:", abc_hex)
b = crsysapi.Hash.data(b'abc', crsysapi.Hash.Alg.SHA3_224)
print("crsysapi.Hash.data('abc'):", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf'))
h = crsysapi.Hash.hex_from_hex(abc_hex, crsysapi.Hash.Alg.SHA3_256)
print("crsysapi.Hash.hex_from_hex(abc_hex):", h)
assert(crsysapi.Cnv.fromhex(h) == crsysapi.Cnv.fromhex('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'))
b = crsysapi.Hash.file('abc.txt', crsysapi.Hash.Alg.SHA3_384)
print("crsysapi.Hash.file('abc.txt'):", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25'))
h = crsysapi.Hash.hex_from_file('abc.txt', crsysapi.Hash.Alg.SHA3_512)
print("crsysapi.Hash.hex_from_file('abc.txt'):", h)
assert(crsysapi.Cnv.fromhex(h) == crsysapi.Cnv.fromhex('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0'))
def test_hash_bits():
print("\nTESTING HASH BITS...")
h = crsysapi.Hash.hex_from_bits(crsysapi.Cnv.fromhex("5180"), 9, crsysapi.Hash.Alg.SHA1)
print("Input bits (9) = 0101 0001 1")
print("hex_from_bits(SHA-1) =", h)
assert(crsysapi.Cnv.fromhex(h) == crsysapi.Cnv.fromhex('0f582fa68b71ecdf1dcfc4946019cf5a18225bd2'))
# Ref: SHAVS-SHA3 CAVS 19.0 "SHA3-256 ShortMsg"
h = crsysapi.Hash.hex_from_bits(crsysapi.Cnv.fromhex("2590A0"), 22, crsysapi.Hash.Alg.SHA3_256)
print("Input bits (22) = 1001 0110 0100 0010 1000 00")
print("hex_from_bits(SHA-3-256) =", h)
assert(crsysapi.Cnv.fromhex(h) == crsysapi.Cnv.fromhex('d5863d4b1ff41551c92a9e08c52177e32376c9bd100c611c607db840096eb22f'))
def test_hash_length():
print("\nTEST HASH LENGTH...")
print("Hash.length(SHA-1) =", crsysapi.Hash.length(crsysapi.Hash.Alg.SHA1))
print("Hash.length(SHA-256) =", crsysapi.Hash.length(crsysapi.Hash.Alg.SHA256))
print("Hash.length(SHA-384) =", crsysapi.Hash.length(crsysapi.Hash.Alg.SHA384))
print("Hash.length(SHA-512) =", crsysapi.Hash.length(crsysapi.Hash.Alg.SHA512))
print("Hash.length(RMD160) =", crsysapi.Hash.length(crsysapi.Hash.Alg.RMD160))
print("Hash.length(ASCON-HASH) =", crsysapi.Hash.length(crsysapi.Hash.Alg.ASCON_HASH))
def test_mac():
print("\nTESTING MAC...")
print("Test case 4 from RFC 2202 and RFC 4231")
key = crsysapi.Cnv.fromhex('0102030405060708090a0b0c0d0e0f10111213141516171819')
print("key: ", crsysapi.Cnv.tohex(key))
# data = 0xcd repeated 50 times
data = bytearray([0xcd] * 50)
print("data:", crsysapi.Cnv.tohex(data))
b = crsysapi.Mac.data(data, key)
print("HMAC-SHA-1: ", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('4c9007f4026250c6bc8414f9bf50c86c2d7235da'))
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_MD5)
print("HMAC-MD5: ", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('697eaf0aca3a3aea3a75164746ffaa79'))
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_SHA256)
print("HMAC-SHA-256:", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex(
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b'))
h = crsysapi.Mac.hex_from_data(data, key, crsysapi.Mac.Alg.HMAC_SHA256)
print("HMAC-SHA-256:", h)
assert(h == '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b')
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_SHA512)
print("HMAC-SHA-512:", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex(
'b0ba465637458c6990e5a8c5f61d4af7 e576d97ff94b872de76f8050361ee3db a91ca5c11aa25eb4d679275cc5788063 a5f19741120c4f2de2adebeb10a298dd'))
print("Test case 7 from RFC 4231")
key = bytearray([0xaa] * 131)
print("key: ", crsysapi.Cnv.tohex(key).lower())
data = b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."
print("data:", data)
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_SHA224)
print("HMAC-SHA-224:", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex(
'3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1'))
# HMAC hex <-- hex
print("Test case 1 from RFC 2202 and RFC 4231")
keyhex = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" # (20 bytes)
datahex = "4869205468657265" # ("Hi There")
print("key: ", keyhex)
print("data:", datahex)
h = crsysapi.Mac.hex_from_hex(datahex, keyhex)
print("HMAC-SHA-1:", h)
assert(h == "b617318655057264e28bc0b6fb378c8ef146be00")
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.HMAC_SHA256)
print("HMAC-SHA-256:", h)
assert(h == "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7")
# HMAC hex <-- string
h = crsysapi.Mac.hex_from_string("Hi There", crsysapi.Cnv.fromhex(keyhex), crsysapi.Mac.Alg.HMAC_SHA1)
print("HMAC-SHA-1:", h)
print("\nTESTING Mac(SHA-3)...")
print("NIST HMAC_SHA3-256.pdf Sample #1")
key = crsysapi.Cnv.fromhex('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
print("key: ", crsysapi.Cnv.tohex(key))
data = b'Sample message for keylen<blocklen'
print("data:", data.decode())
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_SHA3_256)
print("HMAC-SHA-3-256:", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205'))
print("NIST HMAC_SHA3-512.pdf Sample #3")
key = crsysapi.Cnv.fromhex("""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F
8081828384858687""")
print("key: ", crsysapi.Cnv.tohex(key))
data = b'Sample message for keylen>blocklen'
print("data:", data.decode())
b = crsysapi.Mac.data(data, key, crsysapi.Mac.Alg.HMAC_SHA3_512)
print("HMAC-SHA-3-512:", crsysapi.Cnv.tohex(b))
assert(b == crsysapi.Cnv.fromhex('5f464f5e5b7848e3885e49b2c385f0694985d0e38966242dc4a5fe3fea4b37d46b65ceced5dcf59438dd840bab22269f0ba7febdb9fcf74602a35666b2a32915'))
print("CMAC tests from SP800-38B...")
# CMAC-AES-128 on the empty string
keyhex = "2b7e151628aed2a6abf7158809cf4f3c"
datahex = ""
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.CMAC_AES128)
print("CMAC-AES-128(K128, '')=", h)
assert(h == "bb1d6929e95937287fa37d129b756746")
# CMAC_AES-256 on Example 12: Mlen = 512
keyhex = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"
datahex = "6bc1bee22e409f96e93d7e117393172a" + \
"ae2d8a571e03ac9c9eb76fac45af8e51" + \
"30c81c46a35ce411e5fbc1191a0a52ef" + \
"f69f2445df4f9b17ad2b417be66c3710"
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.CMAC_AES256)
print("CMAC-AES-256(K256, M512)=", h)
assert(h == "e1992190549f6ed5696a2c056c315410")
# POLY1305 AUTHENTICATION ALGORITHM
# Ref: Test vector from `RFC 7539` section 2.5.2
print("Poly1305 tests...")
keyhex = "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"
datahex = crsysapi.Cnv.tohex(b"Cryptographic Forum Research Group")
print(f"key={keyhex}")
print(f"msg='{crsysapi.Cnv.fromhex(datahex).decode()}'")
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.MAC_POLY1305)
print(f"POLY1305={h}")
assert(h == "a8061dc1305136c6c22b8baf0c0127a9")
# KMAC
# Ref: `KMAC_samples.pdf` "Secure Hashing - KMAC-Samples" 2017-02-27
print("KMAC tests...")
keyhex = "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"
datahex = "00010203"
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.KMAC_128)
print("KMAC128=", h)
assert(h == "e5780b0d3ea6f7d3a429c5706aa43a00fadbd7d49628839e3187243f456ee14e")
keyhex = "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"
datahex = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7"
h = crsysapi.Mac.hex_from_hex(datahex, keyhex, crsysapi.Mac.Alg.KMAC_256)
print("KMAC256=", h)
assert(h == "75358cf39e41494e949707927cee0af20a3ff553904c86b08f21cc414bcfd691589d27cf5e15369cbbff8b9a4c2eb17800855d0235ff635da82533ec6b759b69")
def test_prf():
print("\nTEST PRF FUNCTIONS...")
# `KMAC_samples.pdf` "Secure Hashing - KMAC-Samples" 2017-02-27
# Sample #1
# "standard" KMAC output length KMAC128 => 256 bits, no custom string
nbytes = 256 // 8
msg = crsysapi.Cnv.fromhex("00010203")
key = crsysapi.Cnv.fromhex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
okhex = "E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E"
kmac = crsysapi.Prf.bytes(nbytes, msg, key, crsysapi.Prf.Alg.KMAC128)
print("KMAC=", crsysapi.Cnv.tohex(kmac))
print("OK =", okhex)
assert crsysapi.Cnv.tohex(kmac).upper() == okhex, "KMAC failed"
# "standard" KMAC output length KMAC256 => 512 bits, no custom string
# Sample #6
nbytes = 512 // 8
# Length of data is 1600 bits
msg = crsysapi.Cnv.fromhex("""000102030405060708090A0B0C0D0E0F
101112131415161718191A1B1C1D1E1F
202122232425262728292A2B2C2D2E2F
303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F
505152535455565758595A5B5C5D5E5F
606162636465666768696A6B6C6D6E6F
707172737475767778797A7B7C7D7E7F
808182838485868788898A8B8C8D8E8F
909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAF
B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF
C0C1C2C3C4C5C6C7""")
key = crsysapi.Cnv.fromhex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
okhex = "75358CF39E41494E949707927CEE0AF20A3FF553904C86B08F21CC414BCFD691589D27CF5E15369CBBFF8B9A4C2EB17800855D0235FF635DA82533EC6B759B69"
kmac = crsysapi.Prf.bytes(nbytes, msg, key, crsysapi.Prf.Alg.KMAC256)
print("KMAC=", crsysapi.Cnv.tohex(kmac))
print("OK =", okhex)
assert crsysapi.Cnv.tohex(kmac).upper() == okhex, "KMAC failed"
# Sample #2
# Same as Sample #1 except with custom string
nbytes = 256 // 8
msg = crsysapi.Cnv.fromhex("00010203")
key = crsysapi.Cnv.fromhex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
custom = "My Tagged Application"
okhex = "3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5"
kmac = crsysapi.Prf.bytes(nbytes, msg, key, crsysapi.Prf.Alg.KMAC128, custom)
print("KMAC=", crsysapi.Cnv.tohex(kmac))
print("OK =", okhex)
assert crsysapi.Cnv.tohex(kmac).upper() == okhex, "KMAC failed"
# Request a lot of output (> single KECCAK block)
nbytes = 1600 // 8
msg = crsysapi.Cnv.fromhex("00010203")
key = crsysapi.Cnv.fromhex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
okhex = """38158A1CAE4E1A25D85F2031246ADE69
7B3292FEF88B0923A59A02D1D53B7046
53EE7242662A10796BA20779D300D52D
7432018741233D587252D31DC48BDB82
33285D4A4ACD65848509B051A448D873
649228B6626E5EF817C7AF2DEDC91F12
0F8CA535A1EE301FAE8186FDEDE5A761
81A472A32CFAD1DDD1391E162F124D4A
7572AD8A20076601BCF81E4B0391F3E9
5AEFFA708C33C1217C96BE6A4F02FBBC
2D3B3B6FFAEB5BFD3BE4A2E02B75993F
CC04DA6FAC4BFCB2A9F05792A1A5CC80
CA34186243EFDB31"""
okhex = okhex.replace("\n", "")
kmac = crsysapi.Prf.bytes(nbytes, msg, key, crsysapi.Prf.Alg.KMAC128)
print("KMAC=", crsysapi.Cnv.tohex(kmac))
print("OK =", okhex)
assert crsysapi.Cnv.tohex(kmac).upper() == okhex, "KMAC failed"
def test_xof():
print("\nTEST XOF FUNCTIONS...")
# Ref: "SHA-3 XOF Test Vectors for Byte-Oriented Output"
# File `SHAKE256VariableOut.rsp` COUNT = 1244
nbytes = 2000 // 8
msg = crsysapi.Cnv.fromhex("6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b")
okhex = """b9b92544fb25cfe4ec6fe437d8da2bbe
00f7bdaface3de97b8775a44d753c3ad
ca3f7c6f183cc8647e229070439aa953
9ae1f8f13470c9d3527fffdeef6c94f9
f0520ff0c1ba8b16e16014e1af43ac6d
94cb7929188cce9d7b02f81a2746f52b
a16988e5f6d93298d778dfe05ea0ef25
6ae3728643ce3e29c794a0370e9ca6a8
bf3e7a41e86770676ac106f7ae79e670
27ce7b7b38efe27d253a52b5cb54d6eb
4367a87736ed48cb45ef27f42683da14
0ed3295dfc575d3ea38cfc2a3697cc92
864305407369b4abac054e497378dd9f
d0c4b352ea3185ce1178b3dc1599df69
db29259d4735320c8e7d33e8226620c9
a1d22761f1d35bdff79a"""
okhex = okhex.replace("\n", "")
xof = crsysapi.Xof.bytes(nbytes, msg, crsysapi.Xof.Alg.SHAKE256)
print("OUT=", crsysapi.Cnv.tohex(xof))
print("OK =", okhex)
assert(crsysapi.Cnv.tohex(xof).lower() == okhex)
# TODO: add MGF-1
def test_compress():
print("\nTEST COMPRESSION....")
print("Using zlib...")
message = b"hello, hello, hello. This is a 'hello world' message for the world, repeat, for the world."
print("MSG:", message)
comprdata = crsysapi.Compr.compress(message)
print("Compressed = (0x)" + crsysapi.Cnv.tohex(comprdata))
print(f"Compressed {len(message)} bytes to {len(comprdata)}")
# Now uncompresss (inflate)
uncomprdata = crsysapi.Compr.uncompress(comprdata)
print("Uncompressed = '" + str(uncomprdata) + "'")
assert (uncomprdata == message)
print("Using Zstandard...")
comprdata = crsysapi.Compr.compress(message, crsysapi.Compr.Alg.ZSTD)
print("Compressed = (0x)" + crsysapi.Cnv.tohex(comprdata))
print(f"Compressed {len(message)} bytes to {len(comprdata)}")
# Now uncompresss (inflate)
uncomprdata = crsysapi.Compr.uncompress(comprdata, crsysapi.Compr.Alg.ZSTD)
print("Uncompressed = '" + str(uncomprdata) + "'")
assert (uncomprdata == message)
def test_pbe():
print("\nTESTING PASSWORD-BASED ENCRYPTION (PBE)...")
password = 'password'
salt = crsysapi.Cnv.fromhex('78 57 8E 5A 5D 63 CB 06')
count = 2048
print("password = '" + password + "'")
print("salt = 0x" + crsysapi.Cnv.tohex(salt))
print("count =", count)
dklen = 24
print("dklen =", dklen)
dk = crsysapi.Pbe.kdf2(dklen, password, salt, count)
print("dk =", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk) == "BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
# Same params but derive a longer key (CAUTION: never use the same salt in
# practice)
dklen = 64
print("dklen =", dklen)
dk = crsysapi.Pbe.kdf2(dklen, password, salt, count)
print("dk =", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk) == \
"BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643C4B150DEF77511224479994567F2E9B4E3BD0DF7AEDA3022B1F26051D81505C794F8940C04DF1144"
# Use different HMAC algorithms
dklen = 24
dk = crsysapi.Pbe.kdf2(dklen, password, salt, count, prfalg=crsysapi.Pbe.PrfAlg.HMAC_SHA1)
print("dk(HMAC-SHA-1) =", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk) == "BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
dk = crsysapi.Pbe.kdf2(dklen, password, salt, count, prfalg=crsysapi.Pbe.PrfAlg.HMAC_SHA256)
print("dk(HMAC-SHA-256) =", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk) == "97B5A91D35AF542324881315C4F849E327C4707D1BC9D322"
dk = crsysapi.Pbe.kdf2(dklen, password, salt, count, prfalg=crsysapi.Pbe.PrfAlg.HMAC_SHA224)
print("dk(HMAC-SHA-224) =", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk) == "10CFFEDFB13503519969151E466F587028E0720B387F9AEF"
# Use SCRYPT examples from RFC7914
dk = crsysapi.Pbe.scrypt(64, b'password', b'NaCl', 1024, 8, 16)
print("dk(SCRYPT)=", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk)== 'FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B373162' \
+ '2EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640'
# Pass empty string for both password and salt with (N=16, r=1, p=1)
dk = crsysapi.Pbe.scrypt(64, b'', b'', 16, 1, 1)
print("dk(SCRYPT)=", crsysapi.Cnv.tohex(dk))
assert crsysapi.Cnv.tohex(dk)== '77D6576238657B203B19CA42C18A0497F16B4844E3074AE8DFDFFA3FEDE21442' \
+ 'FCD0069DED0948F8326A753A0FC81F17E8D3E0FB2E0D3628CF35E20C38D18906'
def test_wipe():
print("\nTESTING Wipe...")
print("Note that Wipe.data() just zeroizes the data, it does not change the length")
b = crsysapi.Cnv.fromhex('3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1')
print("BEFORE b=", crsysapi.Cnv.tohex(b))
crsysapi.Wipe.data(b)
print("AFTER Wipe.data() b=", crsysapi.Cnv.tohex(b))
print("AFTER Wipe.data()", str(b))
print([c for c in b])
assert all([c == 0 for c in b])
# works with a bytes type but not with an immutable string type
s = b"a string"
print("BEFORE s='" + str(s) + "'")
print([c for c in s])
crsysapi.Wipe.data(s)
print("AFTER Wipe.data()", str(s))
print([c for c in s])
assert all([c == 0 for c in s])
# write a file containing some text
fname = 'tobedeleted.txt'
write_text_file(fname, 'Some secret text in this file.')
_dump_file(fname)
assert(os.path.isfile(fname))
crsysapi.Wipe.file(fname)
print("After Wipe.file(), isfile() returns", os.path.isfile(fname))
assert(not os.path.isfile(fname))
def test_cipherstream():
print("\nTESTING CipherStream...")
print("Using ARCFOUR...")
key = crsysapi.Cnv.fromhex("0123456789abcdef")
pt = crsysapi.Cnv.fromhex("0123456789abcdef")
okhex = "75b7878099e0c596"
print("KY =", crsysapi.Cnv.tohex(key))
print("PT =", crsysapi.Cnv.tohex(pt))
# Do the business
ct = crsysapi.CipherStream.bytes(pt, key, None, crsysapi.CipherStream.Alg.ARCFOUR)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
assert (okhex.lower() == crsysapi.Cnv.tohex(ct).lower())
# Repeat to decrypt
dt = crsysapi.CipherStream.bytes(ct, key, None, crsysapi.CipherStream.Alg.ARCFOUR)
print("DT =", crsysapi.Cnv.tohex(dt))
assert (pt == dt)
# Create and encrypt a file
ptfile = "arcfour.dat"
encfile = "arcfour.enc"
write_binary_file(ptfile, crsysapi.Cnv.fromhex("0123456789abcdef"))
r = crsysapi.CipherStream.file(encfile, ptfile, key, b'', crsysapi.CipherStream.Alg.ARCFOUR)
print("CipherStream.file returns ", r, "(expected 0)")
ct = read_binary_file(encfile)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
print("Using Salsa20...")
# Set 6, vector# 0:
key = crsysapi.Cnv.fromhex("0053A6F94C9FF24598EB3E91E4378ADD")
iv = crsysapi.Cnv.fromhex("0D74DB42A91077DE")
pt = b'\x00' * 64
okhex = "05E1E7BEB697D999656BF37C1B978806735D0B903A6007BD329927EFBE1B0E2A8137C1AE291493AA83A821755BEE0B06CD14855A67E46703EBF8F3114B584CBA"
print("KY =", crsysapi.Cnv.tohex(key))
print("IV =", crsysapi.Cnv.tohex(iv))
print("PT =", crsysapi.Cnv.tohex(pt))
# Do the business
ct = crsysapi.CipherStream.bytes(pt, key, iv, crsysapi.CipherStream.Alg.SALSA20)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
assert (okhex.lower() == crsysapi.Cnv.tohex(ct).lower())
# Repeat to decrypt
dt = crsysapi.CipherStream.bytes(ct, key, iv, crsysapi.CipherStream.Alg.SALSA20)
print("DT =", crsysapi.Cnv.tohex(dt))
assert (pt == dt)
print("Using ChaCha20 with counter=1...")
key = crsysapi.Cnv.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
iv = crsysapi.Cnv.fromhex("000000000000004a00000000")
pt = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
okhex = "6E2E359A2568F98041BA0728DD0D6981E97E7AEC1D4360C20A27AFCCFD9FAE0BF91B65C5524733AB8F593DABCD62B3571639D624E65152AB8F530C359F0861D807CA0DBF500D6A6156A38E088A22B65E52BC514D16CCF806818CE91AB77937365AF90BBF74A35BE6B40B8EEDF2785E42874D"
print("KY =", crsysapi.Cnv.tohex(key))
print("IV =", crsysapi.Cnv.tohex(iv))
print("PT =", crsysapi.Cnv.tohex(pt))
print(f"PT = {pt}")
# Do the business
ct = crsysapi.CipherStream.bytes(pt, key, iv, crsysapi.CipherStream.Alg.CHACHA20, counter=1)
print("CT =", crsysapi.Cnv.tohex(ct))
print("OK =", okhex)
assert (okhex.lower() == crsysapi.Cnv.tohex(ct).lower())
# Repeat to decrypt
dt = crsysapi.CipherStream.bytes(ct, key, iv, crsysapi.CipherStream.Alg.CHACHA20, counter=1)
print("DT =", crsysapi.Cnv.tohex(dt))
assert (pt == dt)
def test_keywrap():
print("\nTESTING CipherKeyWrap...")
keydata = crsysapi.Cnv.fromhex("00112233 44556677 8899aabb ccddeeff")
kek = crsysapi.Cnv.fromhex("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
print("KD =", crsysapi.Cnv.tohex(keydata))
print("KEK =", crsysapi.Cnv.tohex(kek))
wk = crsysapi.Cipher.key_wrap(keydata, kek, crsysapi.Cipher.Alg.AES128)
print("WK(AES-128) =", crsysapi.Cnv.tohex(wk))
print("OK =", "503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054")
# Reverse
kd = crsysapi.Cipher.key_unwrap(wk, kek, crsysapi.Cipher.Alg.AES128)
print("KD' =", crsysapi.Cnv.tohex(kd))
keydata = crsysapi.Cnv.fromhex("8cbedec4 8d063e1b a46be8e3 69a9c398 d8e30ee5 42bc347c 4f30e928 ddd7db49")
kek = crsysapi.Cnv.fromhex("9e84ee99 e6a84b50 c76cd414 a2d2ec05 8af41bfe 4bf3715b f894c8da 1cd445f6")
print("KD =", crsysapi.Cnv.tohex(keydata))
print("KEK =", crsysapi.Cnv.tohex(kek))
wk = crsysapi.Cipher.key_wrap(keydata, kek, crsysapi.Cipher.Alg.AES256)
print("WK(AES-256) =", crsysapi.Cnv.tohex(wk))
print("OK =", "EAFB901F82B98D37F17497063DE3E5EC7246AB57200AE73EDDDDF24AA403DAFA0C5AE151D1746FA4")
# Reverse
kd = crsysapi.Cipher.key_unwrap(wk, kek, crsysapi.Cipher.Alg.AES256)
print("KD' =", crsysapi.Cnv.tohex(kd))
keydata = crsysapi.Cnv.fromhex("84E7F2D878F89FCCCD2D5EBAFC56DAF73300F27EF771CD68")
kek = crsysapi.Cnv.fromhex("8AD8274E56F467738EDD83D4394E5E29AF7C4089E4F8D9F4")
print("KD =", crsysapi.Cnv.tohex(keydata))
print("KEK =", crsysapi.Cnv.tohex(kek))
wk = crsysapi.Cipher.key_wrap(keydata, kek, crsysapi.Cipher.Alg.TDEA)
print("WK(3DES) =", crsysapi.Cnv.tohex(wk))
# NOTE: output for Triple DES key wrap is different each time
# Reverse
kd = crsysapi.Cipher.key_unwrap(wk, kek, crsysapi.Cipher.Alg.TDEA)
print("KD' =", crsysapi.Cnv.tohex(kd))
def test_ascon_aead():
print("\nTEST ASCON AEAD...")
# Ref: ascon128v12/LWC_AEAD_KAT_128_128.txt, Count = 303
key = crsysapi.Cnv.fromhex("000102030405060708090A0B0C0D0E0F")
nonce = crsysapi.Cnv.fromhex("000102030405060708090A0B0C0D0E0F")
pt = crsysapi.Cnv.fromhex("000102030405060708")
ad = crsysapi.Cnv.fromhex("0001020304")
print("K =", crsysapi.Cnv.tohex(key))
print("N =", crsysapi.Cnv.tohex(nonce))
print("P =", crsysapi.Cnv.tohex(pt))
print("A =", crsysapi.Cnv.tohex(ad))
ct = crsysapi.Aead.encrypt_with_tag(pt, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128, aad=ad)
print("C =", crsysapi.Cnv.tohex(ct))
assert(crsysapi.Cnv.tohex(ct) == "0E6A8B0CA517F53D3D375623AC11C852FF0A98098CCB7429F2")
# Check decrypted text
dt = crsysapi.Aead.decrypt_with_tag(ct, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128, aad=ad)
print("D =", crsysapi.Cnv.tohex(dt))
assert(crsysapi.Cnv.tohex(dt) == crsysapi.Cnv.tohex(pt))
# Same but prepending iv (nonce) to ciphertext
ct = crsysapi.Aead.encrypt_with_tag(pt, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128, aad=ad, opts=crsysapi.Aead.Opts.PREFIXIV)
print("C =", crsysapi.Cnv.tohex(ct))
dt = crsysapi.Aead.decrypt_with_tag(ct, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128, aad=ad, opts=crsysapi.Aead.Opts.PREFIXIV)
print("D =", crsysapi.Cnv.tohex(dt))
assert(crsysapi.Cnv.tohex(dt) == crsysapi.Cnv.tohex(pt))
# Use ASCON-128A with no AAD on empty string
# Ref: ascon128av12/LWC_AEAD_KAT_128_128.txt, Count = 1
pt = crsysapi.Cnv.fromhex("") # Empty string
print("P =", crsysapi.Cnv.tohex(pt))
ct = crsysapi.Aead.encrypt_with_tag(pt, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128A)
print("C =", crsysapi.Cnv.tohex(ct))
assert(crsysapi.Cnv.tohex(ct) == "7A834E6F09210957067B10FD831F0078")
dt = crsysapi.Aead.decrypt_with_tag(ct, key, nonce, crsysapi.Aead.AeadAlg.AEAD_ASCON_128A)
print("D =", crsysapi.Cnv.tohex(dt))
assert(crsysapi.Cnv.tohex(dt) == crsysapi.Cnv.tohex(pt))
def test_ascon_hash():
print("\nTEST ASCON HASH...")
# Ref: asconhashv12/LWC_HASH_KAT_256.txt; Count = 513
msg = crsysapi.Cnv.fromhex("""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F1011121314151617
18191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F
404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667
68696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F
909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7
B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF""")
digest = crsysapi.Hash.data(msg, crsysapi.Hash.Alg.ASCON_HASH)
print("MD =", crsysapi.Cnv.tohex(digest))
assert(crsysapi.Cnv.tohex(digest) == "7039284FA1CB4C798250B1A62E2378718040E10F206527BFCEB2FF3887884484")
# Ref: asconhashav12/LWC_HASH_KAT_256.txt; Count = 1
# ASCON-HASHA of empty string
digesthex = crsysapi.Hash.hex_from_string("", crsysapi.Hash.Alg.ASCON_HASHA).upper()
print("MD =", digesthex)
assert(digesthex == "AECD027026D0675F9DE7A8AD8CCF512DB64B1EDCF0B20C388A0C7CC617AAA2C4")
# Compute digest of file - ah! cannot use ASCON for files
print("<<EXPECTING AN ERROR HERE...")
print("Cannot hash file using ASCON:")
try:
write_binary_file("ascon_data.dat", msg);
digest = crsysapi.Hash.file("ascon_data.dat", crsysapi.Hash.Alg.ASCON_HASH)
print("MD =", crsysapi.Cnv.tohex(digest))
except Exception as e:
print("\t", e)
print(">>")
def test_ascon_xof():
print("\nTEST ASCON XOF...")
# Ref: asconxofv12/LWC_HASH_KAT_256.txt, Count = 17
msg = crsysapi.Cnv.fromhex("000102030405060708090A0B0C0D0E0F")
md = crsysapi.Xof.bytes(32, msg, crsysapi.Xof.Alg.ASCON_XOF)
print("MD =", crsysapi.Cnv.tohex(md))
assert(crsysapi.Cnv.tohex(md) == "C861A89CFB1335F278C96CF7FFC9753C290CBE1A4E186D2923B496BB4EA5E519")
# Repeat but ask for more or fewer bytes in output
md = crsysapi.Xof.bytes(20, msg, crsysapi.Xof.Alg.ASCON_XOF)
print("MD =", crsysapi.Cnv.tohex(md))
md = crsysapi.Xof.bytes(40, msg, crsysapi.Xof.Alg.ASCON_XOF)
print("MD =", crsysapi.Cnv.tohex(md))
# ASCON-XOFA of empty string
# Ref: asconxofav12/LWC_HASH_KAT_256.txt, Count = 1
md = crsysapi.Xof.bytes(32, b"", crsysapi.Xof.Alg.ASCON_XOFA)
print("MD =", crsysapi.Cnv.tohex(md))
assert(crsysapi.Cnv.tohex(md) == "7C10DFFD6BB03BE262D72FBE1B0F530013C6C4EADAABDE278D6F29D579E3908D")
md = crsysapi.Xof.bytes(20, b"", crsysapi.Xof.Alg.ASCON_XOFA)
print("MD =", crsysapi.Cnv.tohex(md))
md = crsysapi.Xof.bytes(40, b"", crsysapi.Xof.Alg.ASCON_XOFA)
print("MD =", crsysapi.Cnv.tohex(md))
def test_xof_mgf1():
print("\nTEST XOF MGF1...")
msg = crsysapi.Cnv.fromhex("012345ff")
md = crsysapi.Xof.bytes(24, msg, crsysapi.Xof.Alg.MGF1_SHA1)
print("MD(mgf1_sha1) =", crsysapi.Cnv.tohex(md))
assert(crsysapi.Cnv.tohex(md) == "242FB2E7A338AE07E580047F82B7ACFF83A41EC5D8FF9BAB")
# MGF1-SHA-1 of empty string
md = crsysapi.Xof.bytes(24, b'', crsysapi.Xof.Alg.MGF1_SHA1)
print("MD(mgf1_sha1) =", crsysapi.Cnv.tohex(md))
assert(crsysapi.Cnv.tohex(md) == "9069CA78E7450A285173431B3E52C5C25299E473479E04F3")
# Example from SPHINCS+ submission October 2020
msg = crsysapi.Cnv.fromhex("3b5c056af3ebba70d4c805380420585562b32410a778f558ff951252407647e3")
md = crsysapi.Xof.bytes(34, msg, crsysapi.Xof.Alg.MGF1_SHA256)
print("MD(mgf1_sha256) =", crsysapi.Cnv.tohex(md))
assert(crsysapi.Cnv.tohex(md) == "5B7EB772AECF04C74AF07D9D9C1C1F8D3A90DCDA00D5BAB1DC28DAECDC86EB87611E")
md = crsysapi.Xof.bytes(34, msg, crsysapi.Xof.Alg.MGF1_SHA512)
print("MD(mgf1_sha512) =", crsysapi.Cnv.tohex(md))
def test_shortpathname():
print("\nTEST SHORTNAMEPATH...")
fname = "你好.txt"
write_text_file(fname, "你好")
print("filename =", fname)
shortname = crsysapi.Cnv.shortpathname(fname)
print("shortname=", shortname)
# Create an empty file with Unicode name for encrypted output
file_ct = "你好加密.enc"
write_text_file(file_ct, "")
key = crsysapi.Cnv.fromhex("fedcba9876543210fedcba9876543210")
iv = crsysapi.Rng.bytestring(crsysapi.Cipher.blockbytes(crsysapi.Cipher.Alg.AES128))
# Get shortname for output file
shortname_ct = crsysapi.Cnv.shortpathname(file_ct)
print("shortname_ct=", shortname_ct)
# Carry out file encryption using shortpath names
n = crsysapi.Cipher.file_encrypt(shortname_ct, shortname, key, iv, "aes128-ctr", opts=crsysapi.Cipher.Opts.PREFIXIV)
assert(n == 0)
# Note we can use the Unicode name with pure Python functions,
# but we must use the shortpathname when calling cryptosyspki functions.
print(file_ct + ":",)
_print_file_hex(file_ct)
file_chk = "nihao.aes128.chk.txt"
# Use shortpathname for filein argument
n = crsysapi.Cipher.file_decrypt(file_chk, shortname_ct, key, None, "aes128-ctr", opts=crsysapi.Cipher.Opts.PREFIXIV)
assert(n == 0)
print(file_chk + ":",)
_print_file(file_chk)
# check files are equal
assert(read_binary_file(fname) == read_binary_file(file_chk))
def test_rng_initialize_ex():
print("\nTESTING RNG_INITIALIZE_EX...")
n = crsysapi.Rng.initialize_ex()
print(f"Rng.initialize_ex returns {n} (if >0 then Intel(R) DRNG is supported)")
# Explicitly turn off support for rest of session
# NB this is a demonstration; you would not do this under normal circumstances.
n = crsysapi.Rng.initialize_ex(crsysapi.Rng.Opts.NO_INTEL_DRNG)
print(f"Rng.initialize_ex(NO_INTEL_DRNG) returns {n} (expected -214)")
# Check again, should now be off
n = crsysapi.Rng.initialize_ex()
print(f"Rng.initialize_ex returns {n} (expected -214)")
def quick_version():
print("\nDETAILS OF CORE DLL...")
print("DLL Version=" + str(crsysapi.Gen.version())
+ " [" + crsysapi.Gen.core_platform() + "] Lic="
+ crsysapi.Gen.licence_type()
+ " Compiled=["
+ crsysapi.Gen.compile_time() + "]")
print("[" + crsysapi.Gen.module_info() + "]")
print("[" + crsysapi.Gen.module_name() + "]")
def main():
# Act on any arguments in command line
do_all = True
for arg in sys.argv:
if (arg == 'some'):
do_all = False
setup_work_dir()
# DO THE TESTS - EITHER SOME OR ALL
if (do_all):
print("DOING ALL TESTS...")
test_error_lookup()
test_cnv()
test_cipher()
test_cipher_hex()
test_cipher_file()
test_cipher_block()
test_cipher_pad()
test_crc()
test_rng()
test_hash()
test_hash_bits()
test_hash_length()
test_mac()
test_prf()
test_xof()
test_wipe()
test_compress()
test_blowfish()
test_pbe()
test_aead()
test_cipherstream()
test_keywrap()
test_ascon_aead()
test_ascon_hash()
test_ascon_xof()
test_xof_mgf1()
test_shortpathname()
test_rng_initialize_ex()
else: # just do some tests: comment out as necessary
print("DOING SOME TESTS...")
# test_error_lookup()
# test_cnv()
# test_cipher()
# test_cipher_hex()
# test_cipher_block()
# test_cipher_file()
# test_cipher_pad()
# test_crc()
# test_rng()
# test_hash()
# test_hash_length()
# test_hash_bits()
# test_mac()
# test_prf()
# test_xof()
# test_wipe()
# test_compress()
# test_blowfish()
# test_pbe()
# test_aead()
# test_cipherstream()
# test_keywrap()
# test_ascon_aead()
# test_ascon_hash()
# test_ascon_xof()
# test_xof_mgf1()
# test_shortpathname()
test_rng_initialize_ex()
# Uncomment the next line to test the Pwd dialog procedure
# Do not do in py.test (unless you want to interact!)
# ##do_rng_prompt()
reset_start_dir()
quick_version()
print("crsysapi.__version__=", crsysapi.__version__)
print("ALL DONE.")
if __name__ == "__main__":
main()