Mercurial > dropbear
view libtomcrypt/notes/rsa-testvectors/rt.py @ 1672:3a97f14c0235
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93)
* Add Chacha20-Poly1305 authenticated encryption
* Add general AEAD approach.
* Add [email protected] algo using LibTomCrypt chacha and
poly1305 routines.
Chacha20-Poly1305 is generally faster than AES256 on CPU w/o dedicated
AES instructions, having the same key size.
Compiling in will add ~5,5kB to binary size on x86-64.
function old new delta
chacha_crypt - 1397 +1397
_poly1305_block - 608 +608
poly1305_done - 595 +595
dropbear_chachapoly_crypt - 457 +457
.rodata 26976 27392 +416
poly1305_process - 290 +290
poly1305_init - 221 +221
chacha_setup - 218 +218
encrypt_packet 1068 1270 +202
dropbear_chachapoly_getlength - 147 +147
decrypt_packet 756 897 +141
chacha_ivctr64 - 137 +137
read_packet 543 637 +94
dropbear_chachapoly_start - 94 +94
read_kex_algos 792 880 +88
chacha_keystream - 69 +69
dropbear_mode_chachapoly - 48 +48
sshciphers 280 320 +40
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_chachapoly_mac - 24 +24
dropbear_chachapoly - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 5388/0) Total: 5388 bytes
* Add AES128-GCM and AES256-GCM authenticated encryption
* Add general AES-GCM mode.
* Add [email protected] and [email protected] algo using
LibTomCrypt gcm routines.
AES-GCM is combination of AES CTR mode and GHASH, slower than AES-CTR on
CPU w/o dedicated AES/GHASH instructions therefore disabled by default.
Compiling in will add ~6kB to binary size on x86-64.
function old new delta
gcm_process - 1060 +1060
.rodata 26976 27808 +832
gcm_gf_mult - 820 +820
gcm_add_aad - 660 +660
gcm_shift_table - 512 +512
gcm_done - 471 +471
gcm_add_iv - 384 +384
gcm_init - 347 +347
dropbear_gcm_crypt - 309 +309
encrypt_packet 1068 1270 +202
decrypt_packet 756 897 +141
gcm_reset - 118 +118
read_packet 543 637 +94
read_kex_algos 792 880 +88
sshciphers 280 360 +80
gcm_mult_h - 80 +80
dropbear_gcm_start - 62 +62
dropbear_mode_gcm - 48 +48
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_ghash - 24 +24
dropbear_gcm_getlength - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 6434/0) Total: 6434 bytes
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Mon, 25 May 2020 20:50:25 +0500 |
parents | 6dba84798cd5 |
children |
line wrap: on
line source
#!/usr/bin/env python import sys import os import hashlib def md5_for_file(path, block_size=256*128): ''' Block size directly depends on the block size of your filesystem to avoid performances issues Here I have blocks of 4096 octets (Default NTFS) ''' md5 = hashlib.md5() with open(path,'rb') as f: for chunk in iter(lambda: f.read(block_size), b''): md5.update(chunk) f.close() return md5.hexdigest() def read_until_ends(f, s): while True: l = f.readline() if l.strip().endswith(s): break return l def read_until_start(f, s): while True: l = f.readline() if l.startswith(s): break return l def read_hex(f): t = [] while True: l = f.readline() if l.strip() == '': break t.extend(l.strip().split(' ')) return t class NamedData(object): def __init__(self, name, data): self.name = name self.data = data def __str__(self): return " /* {0} */\n {1},\n {{ {2} }}\n".format(self.name, len(self.data), ', '.join('0x' + x for x in self.data)) def read_part(f, s): name = read_until_start(f, s).strip().lstrip('# ').rstrip(':') data = read_hex(f) e = NamedData(name, data) return e class RsaKey(object): def __init__(self, n, e, d, p, q, dP, dQ, qInv): self.n = n self.e = e self.d = d self.p = p self.q = q self.dP = dP self.dQ = dQ self.qInv = qInv def __str__(self): return "{{\n{0},\n{1},\n{2},\n{3},\n{4},\n{5},\n{6},\n{7}\n}}\n".format(self.n, self.e, self.d, self.p, self.q, self.dP, self.dQ, self.qInv) def read_key(f): if ftype.version == 1: read_until_start(f, '# Private key') n = read_part(f, ftype.n) e = read_part(f, ftype.e) d = read_part(f, ftype.d) p = read_part(f, ftype.p) q = read_part(f, ftype.q) dP = read_part(f, ftype.dP) dQ = read_part(f, ftype.dQ) qInv = read_part(f, ftype.qInv) k = RsaKey(n, e, d, p, q, dP, dQ, qInv) return k class Data(object): def __init__(self, name, obj1, obj2, obj3): self.name = name self.obj1 = obj1 self.obj2 = obj2 self.obj3 = obj3 def __str__(self): if self.obj3 == None: return "{{\n \"{0}\",\n{1},\n{2}\n}}\n,".format(self.name, self.obj1, self.obj2) else: return "{{\n \"{0}\",\n{1},\n{2},\n{3}\n}}\n,".format(self.name, self.obj1, self.obj2, self.obj3) def read_data(f): name = read_until_start(f, ftype.o).strip().lstrip('# ') obj1 = read_part(f, ftype.o1) obj2 = read_part(f, ftype.o2) if ftype.name == 'emsa': obj3 = None else: obj3 = read_part(f, ftype.o3) s = Data(name, obj1, obj2, obj3) return s class Example(object): def __init__(self, name, key, data): self.name = name self.key = key self.data = data def __str__(self): res = "{{\n \"{0}\",\n{1},\n{{".format(self.name, str(self.key)) for idx, d in enumerate(self.data, 1): if idx == 2: res += '#ifdef LTC_TEST_EXT\n' res += str(d) + '\n' if idx == ftype.numcases: res += '#endif /* LTC_TEST_EXT */\n' res += '}\n},' return res def read_example(f): name = read_until_start(f, '# Example').strip().lstrip('# ') key = read_key(f) l = read_until_start(f, ftype.sod) d = [] while l.strip().startswith(ftype.sod): if ftype.version == 1: f.seek(-len(l), os.SEEK_CUR) data = read_data(f) d.append(data) l = read_until_start(f, '#') e = Example(name, key, d) f.seek(-len(l), os.SEEK_CUR) return e class PkcsType(object): def __init__(self, name): if name == 'pss': self.o = '# RSASSA-PSS Signature Example' self.o1 = '# Message to be signed' self.o2 = '# Salt' self.o3 = '# Signature' elif name == 'oaep': self.o = '# RSAES-OAEP Encryption Example' self.o1 = '# Message to be encrypted' self.o2 = '# Seed' self.o3 = '# Encryption' elif name == 'emsa': self.o = '# PKCS#1 v1.5 Signature Example' self.o1 = '# Message to be signed' self.o2 = '# Signature' elif name == 'eme': self.o = '# PKCS#1 v1.5 Encryption Example' self.o1 = '# Message' self.o2 = '# Seed' self.o3 = '# Encryption' else: raise ValueError('Type unknown: ' + name) if name == 'pss' or name == 'oaep': self.version = 2 self.numcases = 6 self.n = '# RSA modulus n' self.e = '# RSA public exponent e' self.d = '# RSA private exponent d' self.p = '# Prime p' self.q = '# Prime q' self.dP = '# p\'s CRT exponent dP' self.dQ = '# q\'s CRT exponent dQ' self.qInv = '# CRT coefficient qInv' self.sod = '# --------------------------------' elif name == 'emsa' or name == 'eme': self.version = 1 self.numcases = 20 self.n = '# Modulus' self.e = '# Public exponent' self.d = '# Exponent' self.p = '# Prime 1' self.q = '# Prime 2' self.dP = '# Prime exponent 1' self.dQ = '# Prime exponent 2' self.qInv = '# Coefficient' self.sod = self.o self.name = name ftype = PkcsType(sys.argv[2]) print('/* Generated from file: %s\n * with md5 hash: %s\n */\n' % (sys.argv[1], md5_for_file(sys.argv[1]))) print(''' typedef struct rsaKey { int n_l; unsigned char n[256]; int e_l; unsigned char e[256]; int d_l; unsigned char d[256]; int p_l; unsigned char p[256]; int q_l; unsigned char q[256]; int dP_l; unsigned char dP[256]; int dQ_l; unsigned char dQ[256]; int qInv_l; unsigned char qInv[256]; } rsaKey_t; typedef struct rsaData { const char* name; int o1_l; unsigned char o1[256]; int o2_l; unsigned char o2[256];''') if ftype.name != 'emsa': print(''' int o3_l; unsigned char o3[256];''') print('''} rsaData_t; typedef struct testcase { const char* name; rsaKey_t rsa; #ifdef LTC_TEST_EXT rsaData_t data[%d]; #else rsaData_t data[1]; #endif /* LTC_TEST_EXT */ } testcase_t; testcase_t testcases_%s[] = {''' % (ftype.numcases, sys.argv[2])) with open(sys.argv[1], 'rb') as f: ex = [] while read_until_ends(f, '============================================='): if f.tell() == os.path.getsize(sys.argv[1]): break e = read_example(f) ex.append(e) for i in ex: print(i) f.close() print('};\n')