ข้อสังเกต: ถ้าไมโครคอนโทรลเลอร์มีวงจรที่ทำหน้าที่เป็น True Number Random Generator (Hardware RNG) ไมโครไพธอนมีคำสั่ง uos.urandom() ให้ใช้งาน แต่ถ้าไม่มี ให้ใช้คำสั่งของโมดูลชื่อ urandom แต่เป็นการทำงานแบบ Pseudo-Random (Software)
โค้ดไมโครไพธอนสำหรับทดสอบ มีดังนี้
import sysimport gcimport mathimport machineimport utime as timeimport uhashlib as hashlibimport ubinascii as binasciiimport urandom as randomimport ucryptolib as cryptolibimport uos as osimport sysif sys.platform.startswith('pyb'):import pybelif sys.platform =='esp32':# possible CPU freq. for ESP32# 20MHz, 40MHz, 80Mhz, 160MHz or 240MHz machine.freq(240*1000000 )try:from uos import urandom# uos.urandom() on ESP32 uses the hardware RNG. rand_bytes =lambdan: urandom( n )exceptImportError:# the urandom() modules uses a pseudo-RNG. rand_bytes =lambdan: bytes([random.getrandbits(8) for i inrange(n)])info = os.uname()sys_info = (info[0],info[3],)print( 'Micropython-{}{}'.format(*sys_info) )freq = machine.freq()iftype(freq)==listortype(freq)==tuple: freq = freq[0]print( 'CPU freq. [MHz]:', int( freq//1000000 ) )gc.collect()print( 'Free mem. [bytes]: {}\n'.format(gc.mem_free()) )###########################################################deftest1(N=1024):# generate a table of N sine values (N is the table size.) values = [math.sin(math.pi*i/N)for i inrange(N)]del values###########################################################deftest2(N=1024):# generate a table of 32-bit random values (N is the table size.) values = [random.getrandbits(32)for i inrange(N)]# sort the values in the table sorted_values =sorted(values)assert(sorted_values[0]==min(values),'error')assert(sorted_values[-1]==max(values),'error')del sorted_values, values###########################################################deftest3(N=1024):# calculate SHA256 hash value from random numbers buf =bytearray()for i inrange(N):# 4*N bytes x = random.getrandbits(32)# 32-bit integer buf += x.to_bytes(4,'litte')# 4 bytes sha = hashlib.sha256() sha.update( buf )#print( binascii.hexlify(sha.digest()).decode() )del buf###########################################################deftest4(N=256): # N is the plaintext size (in bytes) MODE_ECB, MODE_CBC, MODE_CTR =1,2,6 BLOCK_SIZE =16# block size (bytes) for CBC mode mode = MODE_CBC # use the Cipher Block Chaining (CBC) mode# either 128-bit (16 bytes) or 256-bit key (32 bytes) key =bytes([random.getrandbits(8) for i inrange(32)])# 128-bit or 16-byte initial vector (IV) iv =rand_bytes(BLOCK_SIZE)# random plaintext N bytes long plaintext =rand_bytes( N ) plaintext_size =len(plaintext)if plaintext_size %16!=0:# padding with zeros plaintext +=bytes((16- plaintext_size %16)*[0x00])#print( '>',binascii.hexlify(plaintext).decode() )# create an AES object for encryption aes = cryptolib.aes(key,MODE_CBC,iv)# perform encryption encrypted = aes.encrypt(plaintext)#print( '>', binascii.hexlify(encrypted).decode() )# create an AES object for decryption aes = cryptolib.aes(key,MODE_CBC,iv) decrypted = aes.decrypt(encrypted)#print( '>', binascii.hexlify(decrypted).decode() )assert(decrypted==plaintext)############################################################ list of the tests tests = [test1, test2, test3, test4]# specify the argument N for the testsN_args = [1024,1024,1024,512] NUM_TEST_RUNS =10for test in tests: values = [] mem_used_max =0for i,arg inzip(range(NUM_TEST_RUNS),N_args): gc.collect() mem_free = gc.mem_free()if sys.platform.startswith( 'pyb' ): start = pyb.micros()test(arg) exec_time = pyb.elapsed_micros(start)elif sys.platform =='esp32': start = time.ticks_us()test() finish = time.ticks_us() exec_time = time.ticks_diff( finish, start )else: exec_time =0 values.append( exec_time ) mem_used = (mem_free - gc.mem_free()) mem_used_max =max(mem_used_max, mem_used)# calculate min/avg/max value of execution times min_exec =min(values)/1000 avg_exec =sum(values)/len(values)/1000 max_exec =max(values)/1000 values = (min_exec, avg_exec, max_exec)print( test.__name__ )# show the test nameprint(' Exec. time: {:.3f}/{:.3f}/{:.3f} msec'.format(*values) )print(' Mem. used : {} bytes used (max.)'.format( mem_used_max) )del values
ผลการทดสอบและเปรียบเทียบ
1) บอร์ด ESP32 4MB Flash (no SPIRAM), 240MHz CPU clock