Auto-generate more KEM files for PQClean implementations

This commit is contained in:
Douglas Stebila 2019-05-12 14:52:59 -04:00
parent c2fa3b1b98
commit 2d9dec989b
15 changed files with 159 additions and 74 deletions

View File

@ -30,9 +30,11 @@ endif
if ENABLE_KEM_BIKE
liboqs_la_LIBADD += src/kem/bike/libkembike.la
endif
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_IF_ENABLE_KEM_START
if ENABLE_KEM_FRODOKEM
liboqs_la_LIBADD += src/kem/frodokem/libkemfrodokem.la
endif
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_IF_ENABLE_KEM_END
if ENABLE_KEM_SIKE
liboqs_la_LIBADD += src/kem/sike/libkemsike.la
endif

View File

@ -43,7 +43,9 @@ AC_DEFUN([CONFIG_FEATURE_FLAGS],
[AM_CONDITIONAL(ENABLE_KEM_BIKE, [false])]
)
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_ARG_DISBL_SET_WRAP_START
ARG_DISBL_SET_WRAP([kem-frodokem], [kem_frodokem], [ENABLE_KEM_FRODOKEM], [src/kem/frodokem])
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_ARG_DISBL_SET_WRAP_END
ARG_DISBL_SET_WRAP([kem-sike], [kem_sike], [ENABLE_KEM_SIKE], [src/kem/sike])
ARG_DISBL_SET_WRAP([kem-newhope], [kem_newhope], [ENABLE_KEM_NEWHOPE], [src/kem/newhopenist])
ARG_DISBL_SET_WRAP([kem-kyber], [kem_kyber], [ENABLE_KEM_KYBER], [src/kem/kyber])
@ -79,14 +81,16 @@ AC_DEFUN([CONFIG_FEATURES],
])
])
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_AM_COND_IF_START
AM_COND_IF([ENABLE_KEM_FRODOKEM], [
AC_DEFINE(OQS_ENABLE_KEM_frodokem_640_aes, 1, "Define to 1 when FrodoKEM-640-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_640_shake, 1, "Define to 1 when FrodoKEM-640-SHAKE enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_976_aes, 1, "Define to 1 when FrodoKEM-976-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_976_shake, 1, "Define to 1 when FrodoKEM-976-SHAKE enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_1344_aes, 1, "Define to 1 when FrodoKEM-1344-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_640_aes, 1, "Define to 1 when FrodoKEM-640-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_640_shake, 1, "Define to 1 when FrodoKEM-640-SHAKE enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_976_aes, 1, "Define to 1 when FrodoKEM-976-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_976_shake, 1, "Define to 1 when FrodoKEM-976-SHAKE enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_1344_aes, 1, "Define to 1 when FrodoKEM-1344-AES enabled")
AC_DEFINE(OQS_ENABLE_KEM_frodokem_1344_shake, 1, "Define to 1 when FrodoKEM-1344-SHAKE enabled")
])
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_AM_COND_IF_END
AM_COND_IF([ENABLE_KEM_SIKE], [
AC_DEFINE(OQS_ENABLE_KEM_sike_p503, 1, "Define to 1 when Sike-p503 enabled")

View File

@ -71,7 +71,9 @@ AC_CONFIG_FILES([Makefile
src/sig/picnic/Makefile
src/sig/qtesla/Makefile
src/kem/bike/Makefile
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_AC_CONFIG_FILES_START
src/kem/frodokem/Makefile
##### OQS_COPY_FROM_PQCLEAN_FRAGMENT_AC_CONFIG_FILES_END
src/kem/sike/Makefile
src/kem/newhopenist/Makefile
src/kem/kyber/Makefile

View File

@ -0,0 +1,5 @@
{% for family in families %}
if ENABLE_KEM_{{ family['name']|upper }}
liboqs_la_LIBADD += src/kem/{{ family['name'] }}/libkem{{ family['name'] }}.la
endif{% endfor %}

View File

@ -0,0 +1,5 @@
{% for family in families %}
AM_COND_IF([ENABLE_KEM_{{ family['name']|upper }}], [{% for scheme in family['schemes'] %}
AC_DEFINE(OQS_ENABLE_KEM_{{ family['name'] }}_{{ scheme['scheme'] }}, 1, "Define to 1 when {{ scheme['pretty_name_full'] }} enabled"){% endfor %}
]){% endfor %}

View File

@ -0,0 +1,3 @@
{% for family in families %}
ARG_DISBL_SET_WRAP([kem-{{ family['name'] }}], [kem_{{ family['name'] }}], [ENABLE_KEM_{{ family['name']|upper }}], [src/kem/{{ family['name'] }}]){% endfor %}

View File

@ -0,0 +1,3 @@
{% for family in families %}
src/kem/{{ family['name'] }}/Makefile{% endfor %}

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import copy
import glob
import jinja2
import os
import shutil
@ -19,25 +20,49 @@ def file_put_contents(filename, s, encoding=None):
with open(filename, mode='w', encoding=encoding) as fh:
fh.write(s)
def generator(destination_filename, template_filename, pqclean_dir, family, scheme_desired):
def generator(destination_filename, template_filename, family, scheme_desired):
template = file_get_contents(os.path.join('scripts', 'copy_from_pqclean', template_filename))
f = copy.deepcopy(family)
f['family'] = f['name']
if scheme_desired != None:
f['schemes'] = [x for x in f['schemes'] if x == scheme_desired]
assert(len(f['schemes']) == 1)
for scheme in f['schemes']:
scheme['metadata'] = yaml.safe_load(file_get_contents(os.path.join(pqclean_dir, 'crypto_kem', scheme['pqclean_scheme'], 'META.yml')))
scheme['metadata']['implementations'] = [imp for imp in scheme['metadata']['implementations'] if imp['name'] == scheme['implementation']]
assert(len(scheme['metadata']['implementations']) == 1)
scheme['metadata']['ind_cca'] = 'true'
file_put_contents(destination_filename, jinja2.Template(template).render(f))
instructions = file_get_contents(os.path.join('scripts', 'copy_from_pqclean', 'copy_from_pqclean.yml'), encoding='utf-8')
instructions = yaml.safe_load(instructions)
def replacer(filename, families, delimiter):
fragments = glob.glob(os.path.join('scripts', 'copy_from_pqclean', filename, '*.fragment'))
contents = file_get_contents(filename)
for fragment in fragments:
template = file_get_contents(fragment)
identifier = os.path.splitext(os.path.basename(fragment))[0]
identifier_start = '{} OQS_COPY_FROM_PQCLEAN_FRAGMENT_{}_START'.format(delimiter, identifier.upper())
identifier_end = '{} OQS_COPY_FROM_PQCLEAN_FRAGMENT_{}_END'.format(delimiter, identifier.upper())
preamble = contents[:contents.find(identifier_start)]
postamble = contents[contents.find(identifier_end):]
contents = preamble + identifier_start + jinja2.Template(template).render({'families': families}) + postamble
file_put_contents(filename, contents)
for family in instructions:
def load_kems():
instructions = file_get_contents(os.path.join('scripts', 'copy_from_pqclean', 'copy_from_pqclean.yml'), encoding='utf-8')
instructions = yaml.safe_load(instructions)
kems = instructions['kems']
for family in kems:
family['family'] = family['name']
for scheme in family['schemes']:
scheme['metadata'] = yaml.safe_load(file_get_contents(os.path.join(os.environ['PQCLEAN_DIR'], 'crypto_kem', scheme['pqclean_scheme'], 'META.yml')))
scheme['metadata']['ind_cca'] = 'true'
return kems
kems = load_kems()
for family in kems:
for scheme in family['schemes']:
try:
os.mkdir(os.path.join('src', 'kem', family['name']))
except:
pass
shutil.rmtree(os.path.join('src', 'kem', family['name'], 'pqclean_{}_clean'.format(scheme['pqclean_scheme'])), ignore_errors=True)
subprocess.run([
'cp',
@ -51,7 +76,6 @@ for family in instructions:
generator(
os.path.join('src', 'kem', family['name'], 'kem_{}.h'.format(family['name'])),
os.path.join('src', 'kem', 'family', 'kem_family.h'),
os.environ['PQCLEAN_DIR'],
family,
None,
)
@ -59,7 +83,6 @@ for family in instructions:
generator(
os.path.join('src', 'kem', family['name'], 'Makefile.am'),
os.path.join('src', 'kem', 'family', 'Makefile.am'),
os.environ['PQCLEAN_DIR'],
family,
None,
)
@ -68,7 +91,12 @@ for family in instructions:
generator(
os.path.join('src', 'kem', family['name'], 'kem_{}.c'.format(scheme['pqclean_scheme'])),
os.path.join('src', 'kem', 'family', 'kem_scheme.c'),
os.environ['PQCLEAN_DIR'],
family,
scheme,
)
replacer('config/features.m4', kems, '#####')
replacer('configure.ac', kems, '#####')
replacer('Makefile.am', kems, '#####')
replacer('src/kem/kem.c', kems, '/////')
replacer('src/kem/kem.h', kems, '/////')

View File

@ -1,57 +1,64 @@
-
name: frodokem
schemes:
-
scheme: 640_aes
pqclean_scheme: frodokem640aes
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 640_shake
pqclean_scheme: frodokem640shake
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c
-
scheme: 976_aes
pqclean_scheme: frodokem976aes
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 976_shake
pqclean_scheme: frodokem976shake
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c
-
scheme: 1344_aes
pqclean_scheme: frodokem1344aes
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 1344_shake
pqclean_scheme: frodokem1344shake
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c
kems:
-
name: frodokem
schemes:
-
scheme: 640_aes
pqclean_scheme: frodokem640aes
pretty_name_full: FrodoKEM-640-AES
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 640_shake
pqclean_scheme: frodokem640shake
pretty_name_full: FrodoKEM-640-SHAKE
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c
-
scheme: 976_aes
pqclean_scheme: frodokem976aes
pretty_name_full: FrodoKEM-976-AES
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 976_shake
pqclean_scheme: frodokem976shake
pretty_name_full: FrodoKEM-976-SHAKE
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c
-
scheme: 1344_aes
pqclean_scheme: frodokem1344aes
pretty_name_full: FrodoKEM-1344-AES
implementation: clean
sources:
- kem.c
- matrix_aes.c
- noise.c
- util.c
-
scheme: 1344_shake
pqclean_scheme: frodokem1344shake
pretty_name_full: FrodoKEM-1344-SHAKE
implementation: clean
sources:
- kem.c
- matrix_shake.c
- noise.c
- util.c

View File

@ -0,0 +1,3 @@
{% for family in families %}
{% for scheme in family['schemes'] %}OQS_KEM_alg_{{ family['name'] }}_{{ scheme['scheme'] }}, {% endfor %}{% endfor %}

View File

@ -0,0 +1,8 @@
{% for family in families %}{% for scheme in family['schemes'] %}
} else if (0 == strcasecmp(method_name, OQS_KEM_alg_{{ family['name'] }}_{{ scheme['scheme'] }})) {
#ifdef OQS_ENABLE_KEM_{{ family['name'] }}_{{ scheme['scheme'] }}
return OQS_KEM_{{ family['name'] }}_{{ scheme['scheme'] }}_new();
#else
return NULL;
#endif{% endfor %}{% endfor %}

View File

@ -0,0 +1,4 @@
{% for family in families %}{% for scheme in family['schemes'] %}
/** Algorithm identifier for {{ scheme['pretty_name_full'] }} KEM. */
#define OQS_KEM_alg_{{ family['name'] }}_{{ scheme['scheme'] }} "{{ scheme['pretty_name_full'] }}"{% endfor %}{% endfor %}

View File

@ -0,0 +1,3 @@
{% for family in families %}
#include <oqs/kem_{{ family['name'] }}.h>{% endfor %}

View File

@ -13,7 +13,9 @@ OQS_API const char *OQS_KEM_alg_identifier(size_t i) {
const char *a[OQS_KEM_algs_length] = {
OQS_KEM_alg_default,
OQS_KEM_alg_bike1_l1, OQS_KEM_alg_bike1_l3, OQS_KEM_alg_bike1_l5, OQS_KEM_alg_bike2_l1, OQS_KEM_alg_bike2_l3, OQS_KEM_alg_bike2_l5, OQS_KEM_alg_bike3_l1, OQS_KEM_alg_bike3_l3, OQS_KEM_alg_bike3_l5,
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_ALG_IDENTIFIER_START
OQS_KEM_alg_frodokem_640_aes, OQS_KEM_alg_frodokem_640_shake, OQS_KEM_alg_frodokem_976_aes, OQS_KEM_alg_frodokem_976_shake, OQS_KEM_alg_frodokem_1344_aes, OQS_KEM_alg_frodokem_1344_shake,
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_ALG_IDENTIFIER_END
OQS_KEM_alg_newhope_512_cca_kem, OQS_KEM_alg_newhope_1024_cca_kem,
OQS_KEM_alg_kyber_512_cca_kem, OQS_KEM_alg_kyber_768_cca_kem, OQS_KEM_alg_kyber_1024_cca_kem,
OQS_KEM_alg_sidh_p503, OQS_KEM_alg_sidh_p751,
@ -89,6 +91,7 @@ OQS_API OQS_KEM *OQS_KEM_new(const char *method_name) {
#else
return NULL;
#endif
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_NEW_CASE_START
} else if (0 == strcasecmp(method_name, OQS_KEM_alg_frodokem_640_aes)) {
#ifdef OQS_ENABLE_KEM_frodokem_640_aes
return OQS_KEM_frodokem_640_aes_new();
@ -125,6 +128,7 @@ OQS_API OQS_KEM *OQS_KEM_new(const char *method_name) {
#else
return NULL;
#endif
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_NEW_CASE_END
} else if (0 == strcasecmp(method_name, OQS_KEM_alg_newhope_512_cca_kem)) {
#ifdef OQS_ENABLE_KEM_newhope_512_cca_kem
return OQS_KEM_newhope_512_cca_kem_new();

View File

@ -45,6 +45,7 @@
#define OQS_KEM_alg_bike3_l3 "BIKE3-L3"
/** Algorithm identifier for BIKE3-L5 KEM. */
#define OQS_KEM_alg_bike3_l5 "BIKE3-L5"
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_ALG_IDENTIFIER_START
/** Algorithm identifier for FrodoKEM-640-AES KEM. */
#define OQS_KEM_alg_frodokem_640_aes "FrodoKEM-640-AES"
/** Algorithm identifier for FrodoKEM-640-SHAKE KEM. */
@ -57,6 +58,7 @@
#define OQS_KEM_alg_frodokem_1344_aes "FrodoKEM-1344-AES"
/** Algorithm identifier for FrodoKEM-1344-SHAKE KEM. */
#define OQS_KEM_alg_frodokem_1344_shake "FrodoKEM-1344-SHAKE"
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_ALG_IDENTIFIER_END
/** Algorithm identifier for NewHope-512-CCA-KEM KEM. */
#define OQS_KEM_alg_newhope_512_cca_kem "NewHope-512-CCA-KEM"
/** Algorithm identifier for NewHope-1024-CCA-KEM KEM. */
@ -242,7 +244,9 @@ OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, co
OQS_API void OQS_KEM_free(OQS_KEM *kem);
#include <oqs/kem_bike.h>
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_INCLUDE_START
#include <oqs/kem_frodokem.h>
///// OQS_COPY_FROM_PQCLEAN_FRAGMENT_INCLUDE_END
#include <oqs/kem_newhopenist.h>
#include <oqs/kem_kyber.h>
#include <oqs/kem_sike.h>