summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/ntru
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2014-03-11 20:48:48 +0100
committerYves-Alexis Perez <corsac@debian.org>2014-03-11 20:48:48 +0100
commit15fb7904f4431a6e7c305fd08732458f7f885e7e (patch)
treec93b60ee813af70509f00f34e29ebec311762427 /src/libstrongswan/plugins/ntru
parent5313d2d78ca150515f7f5eb39801c100690b6b29 (diff)
downloadvyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.tar.gz
vyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.zip
Imported Upstream version 5.1.2
Diffstat (limited to 'src/libstrongswan/plugins/ntru')
-rw-r--r--src/libstrongswan/plugins/ntru/Makefile.am33
-rw-r--r--src/libstrongswan/plugins/ntru/Makefile.in812
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h235
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c581
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h183
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c1034
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c360
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h167
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c384
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h101
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c242
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h96
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_drbg.c279
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_drbg.h77
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_ke.c396
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_ke.h50
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_mgf1.c182
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_mgf1.h77
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_plugin.c83
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_plugin.h42
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_poly.c416
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_poly.h99
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_trits.c133
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_trits.h61
24 files changed, 6123 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am
new file mode 100644
index 000000000..b33cbc8c9
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/Makefile.am
@@ -0,0 +1,33 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ -rdynamic @COVERAGE_CFLAGS@
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-ntru.la
+else
+plugin_LTLIBRARIES = libstrongswan-ntru.la
+endif
+
+libstrongswan_ntru_la_SOURCES = \
+ ntru_plugin.h ntru_plugin.c \
+ ntru_drbg.h ntru_drbg.c \
+ ntru_ke.h ntru_ke.c \
+ ntru_mgf1.h ntru_mgf1.c \
+ ntru_poly.h ntru_poly.c \
+ ntru_trits.h ntru_trits.c \
+ ntru_crypto/ntru_crypto.h \
+ ntru_crypto/ntru_crypto_ntru_convert.h \
+ ntru_crypto/ntru_crypto_ntru_convert.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt_key.h \
+ ntru_crypto/ntru_crypto_ntru_encrypt_key.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h \
+ ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c \
+ ntru_crypto/ntru_crypto_ntru_poly.h \
+ ntru_crypto/ntru_crypto_ntru_poly.c
+
+libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
+
+
diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in
new file mode 100644
index 000000000..af192d203
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/Makefile.in
@@ -0,0 +1,812 @@
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/ntru
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/split-package-version.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_ntru_la_LIBADD =
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_drbg.lo \
+ ntru_ke.lo ntru_mgf1.lo ntru_poly.lo ntru_trits.lo \
+ ntru_crypto/ntru_crypto_ntru_convert.lo \
+ ntru_crypto/ntru_crypto_ntru_encrypt.lo \
+ ntru_crypto/ntru_crypto_ntru_encrypt_key.lo \
+ ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.lo \
+ ntru_crypto/ntru_crypto_ntru_poly.lo
+libstrongswan_ntru_la_OBJECTS = $(am_libstrongswan_ntru_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libstrongswan_ntru_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_ntru_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_ntru_la_rpath = -rpath $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_ntru_la_rpath =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libstrongswan_ntru_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_ntru_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ -rdynamic @COVERAGE_CFLAGS@
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-ntru.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-ntru.la
+libstrongswan_ntru_la_SOURCES = \
+ ntru_plugin.h ntru_plugin.c \
+ ntru_drbg.h ntru_drbg.c \
+ ntru_ke.h ntru_ke.c \
+ ntru_mgf1.h ntru_mgf1.c \
+ ntru_poly.h ntru_poly.c \
+ ntru_trits.h ntru_trits.c \
+ ntru_crypto/ntru_crypto.h \
+ ntru_crypto/ntru_crypto_ntru_convert.h \
+ ntru_crypto/ntru_crypto_ntru_convert.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt_key.h \
+ ntru_crypto/ntru_crypto_ntru_encrypt_key.c \
+ ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h \
+ ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c \
+ ntru_crypto/ntru_crypto_ntru_poly.h \
+ ntru_crypto/ntru_crypto_ntru_poly.c
+
+libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/ntru/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/ntru/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+ntru_crypto/$(am__dirstamp):
+ @$(MKDIR_P) ntru_crypto
+ @: > ntru_crypto/$(am__dirstamp)
+ntru_crypto/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) ntru_crypto/$(DEPDIR)
+ @: > ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ntru_crypto/ntru_crypto_ntru_convert.lo: ntru_crypto/$(am__dirstamp) \
+ ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ntru_crypto/ntru_crypto_ntru_encrypt.lo: ntru_crypto/$(am__dirstamp) \
+ ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ntru_crypto/ntru_crypto_ntru_encrypt_key.lo: \
+ ntru_crypto/$(am__dirstamp) \
+ ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.lo: \
+ ntru_crypto/$(am__dirstamp) \
+ ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ntru_crypto/ntru_crypto_ntru_poly.lo: ntru_crypto/$(am__dirstamp) \
+ ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+
+libstrongswan-ntru.la: $(libstrongswan_ntru_la_OBJECTS) $(libstrongswan_ntru_la_DEPENDENCIES) $(EXTRA_libstrongswan_ntru_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_ntru_la_LINK) $(am_libstrongswan_ntru_la_rpath) $(libstrongswan_ntru_la_OBJECTS) $(libstrongswan_ntru_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f ntru_crypto/*.$(OBJEXT)
+ -rm -f ntru_crypto/*.lo
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_drbg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_ke.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_mgf1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_poly.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_trits.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_convert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_encrypt_param_sets.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ntru_crypto/$(DEPDIR)/ntru_crypto_ntru_poly.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf ntru_crypto/.libs ntru_crypto/_libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f ntru_crypto/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ntru_crypto/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR) ntru_crypto/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR) ntru_crypto/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-pluginLTLIBRARIES install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h
new file mode 100644
index 000000000..72f47035e
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto.h
@@ -0,0 +1,235 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto.h is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+
+/******************************************************************************
+ *
+ * File: ntru_crypto.h
+ *
+ * Contents: Public header file for NTRUEncrypt.
+ *
+ *****************************************************************************/
+
+#ifndef NTRU_CRYPTO_H
+#define NTRU_CRYPTO_H
+
+#include <library.h>
+
+#include "ntru_drbg.h"
+
+#if !defined( NTRUCALL )
+ #if !defined(WIN32) || defined (NTRUCRYPTO_STATIC)
+ // Linux, or a Win32 static library
+ #define NTRUCALL extern uint32_t
+ #elif defined (NTRUCRYPTO_EXPORTS)
+ // Win32 DLL build
+ #define NTRUCALL extern __declspec(dllexport) uint32_t
+ #else
+ // Win32 DLL import
+ #define NTRUCALL extern __declspec(dllimport) uint32_t
+ #endif
+#endif /* NTRUCALL */
+
+/* parameter set ID list */
+
+typedef enum _NTRU_ENCRYPT_PARAM_SET_ID {
+ NTRU_EES401EP1,
+ NTRU_EES449EP1,
+ NTRU_EES677EP1,
+ NTRU_EES1087EP2,
+ NTRU_EES541EP1,
+ NTRU_EES613EP1,
+ NTRU_EES887EP1,
+ NTRU_EES1171EP1,
+ NTRU_EES659EP1,
+ NTRU_EES761EP1,
+ NTRU_EES1087EP1,
+ NTRU_EES1499EP1,
+ NTRU_EES401EP2,
+ NTRU_EES439EP1,
+ NTRU_EES593EP1,
+ NTRU_EES743EP1,
+} NTRU_ENCRYPT_PARAM_SET_ID;
+
+
+/* error codes */
+
+#define NTRU_OK 0
+#define NTRU_FAIL 1
+#define NTRU_BAD_PARAMETER 2
+#define NTRU_BAD_LENGTH 3
+#define NTRU_BUFFER_TOO_SMALL 4
+#define NTRU_INVALID_PARAMETER_SET 5
+#define NTRU_BAD_PUBLIC_KEY 6
+#define NTRU_BAD_PRIVATE_KEY 7
+#define NTRU_OUT_OF_MEMORY 8
+#define NTRU_BAD_ENCODING 9
+#define NTRU_OID_NOT_RECOGNIZED 10
+#define NTRU_DRBG_FAIL 11
+#define NTRU_MGF1_FAIL 12
+
+/* function declarations */
+
+/* ntru_crypto_ntru_encrypt
+ *
+ * Implements NTRU encryption (SVES) for the parameter set specified in
+ * the public key blob.
+ *
+ * Before invoking this function, a DRBG must be instantiated using
+ * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
+ * instantiation the requested security strength must be at least as large
+ * as the security strength of the NTRU parameter set being used.
+ * Failure to instantiate the DRBG with the proper security strength will
+ * result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
+ *
+ * The required minimum size of the output ciphertext buffer (ct) may be
+ * queried by invoking this function with ct = NULL. In this case, no
+ * encryption is performed, NTRU_OK is returned, and the required minimum
+ * size for ct is returned in ct_len.
+ *
+ * When ct != NULL, at invocation *ct_len must be the size of the ct buffer.
+ * Upon return it is the actual size of the ciphertext.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_DRBG_FAIL if the DRBG handle is invalid.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
+ * Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is
+ * zero, or if pt_len exceeds the maximum plaintext length for the parameter set.
+ * Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid
+ * (unknown format, corrupt, bad length).
+ * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ */
+
+NTRUCALL
+ntru_crypto_ntru_encrypt(
+ ntru_drbg_t *drbg , /* in - handle for DRBG */
+ uint16_t pubkey_blob_len, /* in - no. of octets in public key
+ blob */
+ uint8_t const *pubkey_blob, /* in - pointer to public key */
+ uint16_t pt_len, /* in - no. of octets in plaintext */
+ uint8_t const *pt, /* in - pointer to plaintext */
+ uint16_t *ct_len, /* in/out - no. of octets in ct, addr for
+ no. of octets in ciphertext */
+ uint8_t *ct); /* out - address for ciphertext */
+
+
+/* ntru_crypto_ntru_decrypt
+ *
+ * Implements NTRU decryption (SVES) for the parameter set specified in
+ * the private key blob.
+ *
+ * The maximum size of the output plaintext may be queried by invoking
+ * this function with pt = NULL. In this case, no decryption is performed,
+ * NTRU_OK is returned, and the maximum size the plaintext could be is
+ * returned in pt_len.
+ * Note that until the decryption is performed successfully, the actual size
+ * of the resulting plaintext cannot be known.
+ *
+ * When pt != NULL, at invocation *pt_len must be the size of the pt buffer.
+ * Upon return it is the actual size of the plaintext.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pt) is NULL.
+ * Returns NTRU_BAD_LENGTH if a length argument (privkey_blob) is zero, or if
+ * ct_len is invalid for the parameter set.
+ * Returns NTRU_BAD_PRIVATE_KEY if the private-key blob is invalid
+ * (unknown format, corrupt, bad length).
+ * Returns NTRU_BUFFER_TOO_SMALL if the plaintext buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ * Returns NTRU_FAIL if a decryption error occurs.
+ */
+
+NTRUCALL
+ntru_crypto_ntru_decrypt(
+ uint16_t privkey_blob_len, /* in - no. of octets in private key
+ blob */
+ uint8_t const *privkey_blob, /* in - pointer to private key */
+ uint16_t ct_len, /* in - no. of octets in ciphertext */
+ uint8_t const *ct, /* in - pointer to ciphertext */
+ uint16_t *pt_len, /* in/out - no. of octets in pt, addr for
+ no. of octets in plaintext */
+ uint8_t *pt); /* out - address for plaintext */
+
+
+/* ntru_crypto_ntru_encrypt_keygen
+ *
+ * Implements key generation for NTRUEncrypt for the parameter set specified.
+ *
+ * Before invoking this function, a DRBG must be instantiated using
+ * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
+ * instantiation the requested security strength must be at least as large
+ * as the security strength of the NTRU parameter set being used.
+ * Failure to instantiate the DRBG with the proper security strength will
+ * result in this function returning NTRU_DRBG_FAIL.
+ *
+ * The required minimum size of the output public-key buffer (pubkey_blob)
+ * may be queried by invoking this function with pubkey_blob = NULL.
+ * In this case, no key generation is performed, NTRU_OK is returned, and
+ * the required minimum size for pubkey_blob is returned in pubkey_blob_len.
+ *
+ * The required minimum size of the output private-key buffer (privkey_blob)
+ * may be queried by invoking this function with privkey_blob = NULL.
+ * In this case, no key generation is performed, NTRU_OK is returned, and
+ * the required minimum size for privkey_blob is returned in privkey_blob_len.
+ *
+ * The required minimum sizes of both pubkey_blob and privkey_blob may be
+ * queried as described above, in a single invocation of this function.
+ *
+ * When pubkey_blob != NULL and privkey_blob != NULL, at invocation
+ * *pubkey_blob_len must be the size of the pubkey_blob buffer and
+ * *privkey_blob_len must be the size of the privkey_blob buffer.
+ * Upon return, *pubkey_blob_len is the actual size of the public-key blob
+ * and *privkey_blob_len is the actual size of the private-key blob.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pubkey_blob
+ * or privkey_blob) is NULL.
+ * Returns NTRU_INVALID_PARAMETER_SET if the parameter-set ID is invalid.
+ * Returns NTRU_BAD_LENGTH if a length argument is invalid.
+ * Returns NTRU_BUFFER_TOO_SMALL if either the pubkey_blob buffer or the
+ * privkey_blob buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ * Returns NTRU_FAIL if the polynomial generated for f is not invertible in
+ * (Z/qZ)[X]/(X^N - 1), which is extremely unlikely.
+ * Should this occur, this function should simply be invoked again.
+ */
+
+NTRUCALL
+ntru_crypto_ntru_encrypt_keygen(
+ ntru_drbg_t *drbg, /* in - handle of DRBG */
+ NTRU_ENCRYPT_PARAM_SET_ID param_set_id, /* in - parameter set ID */
+ uint16_t *pubkey_blob_len, /* in/out - no. of octets in
+ pubkey_blob, addr
+ for no. of octets
+ in pubkey_blob */
+ uint8_t *pubkey_blob, /* out - address for
+ public key blob */
+ uint16_t *privkey_blob_len, /* in/out - no. of octets in
+ privkey_blob, addr
+ for no. of octets
+ in privkey_blob */
+ uint8_t *privkey_blob); /* out - address for
+ private key blob */
+#endif /* NTRU_CRYPTO_H */
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c
new file mode 100644
index 000000000..3d6dfde41
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.c
@@ -0,0 +1,581 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_convert.c is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_convert.c
+ *
+ * Contents: Conversion routines for NTRUEncrypt, including packing, unpacking,
+ * and others.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "ntru_crypto_ntru_convert.h"
+
+
+/* 3-bit to 2-trit conversion tables: 2 represents -1 */
+
+static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2};
+static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1};
+
+
+/* ntru_bits_2_trits
+ *
+ * Each 3 bits in an array of octets is converted to 2 trits in an array
+ * of trits.
+ *
+ * The octet array may overlap the end of the trit array.
+ */
+
+void
+ntru_bits_2_trits(
+ uint8_t const *octets, /* in - pointer to array of octets */
+ uint16_t num_trits, /* in - number of trits to produce */
+ uint8_t *trits) /* out - address for array of trits */
+{
+ uint32_t bits24;
+ uint32_t bits3;
+ uint32_t shift;
+
+ assert(octets);
+ assert(trits);
+
+ while (num_trits >= 16) {
+
+ /* get next three octets */
+
+ bits24 = ((uint32_t)(*octets++)) << 16;
+ bits24 |= ((uint32_t)(*octets++)) << 8;
+ bits24 |= (uint32_t)(*octets++);
+
+ /* for each 3 bits in the three octets, output 2 trits */
+
+ bits3 = (bits24 >> 21) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 18) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 15) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 12) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 9) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 6) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 3) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = bits24 & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ num_trits -= 16;
+ }
+ if (num_trits == 0)
+ return;
+
+ /* get three octets */
+
+ bits24 = ((uint32_t)(*octets++)) << 16;
+ bits24 |= ((uint32_t)(*octets++)) << 8;
+ bits24 |= (uint32_t)(*octets++);
+
+ shift = 21;
+ while (num_trits) {
+
+ /* for each 3 bits in the three octets, output up to 2 trits
+ * until all trits needed are produced
+ */
+
+ bits3 = (bits24 >> shift) & 0x7;
+ shift -= 3;
+ *trits++ = bits_2_trit1[bits3];
+ if (--num_trits) {
+ *trits++ = bits_2_trit2[bits3];
+ --num_trits;
+ }
+ }
+}
+
+
+/* ntru_trits_2_bits
+ *
+ * Each 2 trits in an array of trits is converted to 3 bits, and the bits
+ * are packed in an array of octets. A multiple of 3 octets is output.
+ * Any bits in the final octets not derived from trits are zero.
+ *
+ * Returns TRUE if all trits were valid.
+ * Returns FALSE if invalid trits were found.
+ */
+
+bool
+ntru_trits_2_bits(
+ uint8_t const *trits, /* in - pointer to array of trits */
+ uint32_t num_trits, /* in - number of trits to convert */
+ uint8_t *octets) /* out - address for array of octets */
+{
+ bool all_trits_valid = TRUE;
+ uint32_t bits24;
+ uint32_t bits3;
+ uint32_t shift;
+
+ assert(octets);
+ assert(trits);
+
+ while (num_trits >= 16) {
+
+ /* convert each 2 trits to 3 bits and pack */
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 = (bits3 << 21);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 18);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 15);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 12);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 9);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 6);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 3);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= bits3;
+
+ num_trits -= 16;
+
+ /* output three octets */
+
+ *octets++ = (uint8_t)((bits24 >> 16) & 0xff);
+ *octets++ = (uint8_t)((bits24 >> 8) & 0xff);
+ *octets++ = (uint8_t)(bits24 & 0xff);
+ }
+
+ bits24 = 0;
+ shift = 21;
+ while (num_trits) {
+
+ /* convert each 2 trits to 3 bits and pack */
+
+ bits3 = *trits++ * 3;
+ if (--num_trits) {
+ bits3 += *trits++;
+ --num_trits;
+ }
+ if (bits3 > 7) {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << shift);
+ shift -= 3;
+ }
+
+ /* output three octets */
+
+ *octets++ = (uint8_t)((bits24 >> 16) & 0xff);
+ *octets++ = (uint8_t)((bits24 >> 8) & 0xff);
+ *octets++ = (uint8_t)(bits24 & 0xff);
+
+ return all_trits_valid;
+}
+
+
+/* ntru_coeffs_mod4_2_octets
+ *
+ * Takes an array of ring element coefficients mod 4 and packs the
+ * results into an octet string.
+ */
+
+void
+ntru_coeffs_mod4_2_octets(
+ uint16_t num_coeffs, /* in - number of coefficients */
+ uint16_t const *coeffs, /* in - pointer to coefficients */
+ uint8_t *octets) /* out - address for octets */
+{
+ uint8_t bits2;
+ int shift;
+ uint16_t i;
+
+ assert(coeffs);
+ assert(octets);
+
+ *octets = 0;
+ shift = 6;
+ for (i = 0; i < num_coeffs; i++) {
+ bits2 = (uint8_t)(coeffs[i] & 0x3);
+ *octets |= bits2 << shift;
+ shift -= 2;
+ if (shift < 0) {
+ ++octets;
+ *octets = 0;
+ shift = 6;
+ }
+ }
+}
+
+
+/* ntru_trits_2_octet
+ *
+ * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
+ */
+
+void
+ntru_trits_2_octet(
+ uint8_t const *trits, /* in - pointer to trits */
+ uint8_t *octet) /* out - address for octet */
+{
+ int i;
+
+ assert(trits);
+ assert(octet);
+
+ *octet = 0;
+ for (i = 4; i >= 0; i--) {
+ *octet = (*octet * 3) + trits[i];
+ }
+}
+
+
+/* ntru_octet_2_trits
+ *
+ * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
+ */
+
+void
+ntru_octet_2_trits(
+ uint8_t octet, /* in - octet to be unpacked */
+ uint8_t *trits) /* out - address for trits */
+{
+ int i;
+
+ assert(trits);
+
+ for (i = 0; i < 5; i++) {
+ trits[i] = octet % 3;
+ octet = (octet - trits[i]) / 3;
+ }
+}
+
+
+/* ntru_indices_2_trits
+ *
+ * Converts a list of the nonzero indices of a polynomial into an array of
+ * trits.
+ */
+
+void
+ntru_indices_2_trits(
+ uint16_t in_len, /* in - no. of indices */
+ uint16_t const *in, /* in - pointer to list of indices */
+ bool plus1, /* in - if list is +1 cofficients */
+ uint8_t *out) /* out - address of output polynomial */
+{
+ uint8_t trit = plus1 ? 1 : 2;
+ uint16_t i;
+
+ assert(in);
+ assert(out);
+
+ for (i = 0; i < in_len; i++) {
+ out[in[i]] = trit;
+ }
+}
+
+
+/* ntru_packed_trits_2_indices
+ *
+ * Unpacks an array of N trits and creates a list of array indices
+ * corresponding to trits = +1, and list of array indices corresponding to
+ * trits = -1.
+ */
+
+void
+ntru_packed_trits_2_indices(
+ uint8_t const *in, /* in - pointer to packed-trit octets */
+ uint16_t num_trits, /* in - no. of packed trits */
+ uint16_t *indices_plus1, /* out - address for indices of +1 trits */
+ uint16_t *indices_minus1) /* out - address for indices of -1 trits */
+{
+ uint8_t trits[5];
+ uint16_t i = 0;
+ int j;
+
+ assert(in);
+ assert(indices_plus1);
+ assert(indices_minus1);
+
+ while (num_trits >= 5) {
+ ntru_octet_2_trits(*in++, trits);
+ num_trits -= 5;
+ for (j = 0; j < 5; j++, i++) {
+ if (trits[j] == 1) {
+ *indices_plus1 = i;
+ ++indices_plus1;
+ } else if (trits[j] == 2) {
+ *indices_minus1 = i;
+ ++indices_minus1;
+ }
+ }
+ }
+ if (num_trits) {
+ ntru_octet_2_trits(*in, trits);
+ for (j = 0; num_trits && (j < 5); j++, i++) {
+ if (trits[j] == 1) {
+ *indices_plus1 = i;
+ ++indices_plus1;
+ } else if (trits[j] == 2) {
+ *indices_minus1 = i;
+ ++indices_minus1;
+ }
+ --num_trits;
+ }
+ }
+}
+
+
+/* ntru_indices_2_packed_trits
+ *
+ * Takes a list of array indices corresponding to elements whose values
+ * are +1 or -1, and packs the N-element array of trits described by these
+ * lists into octets, 5 trits per octet.
+ */
+
+void
+ntru_indices_2_packed_trits(
+ uint16_t const *indices, /* in - pointer to indices */
+ uint16_t num_plus1, /* in - no. of indices for +1 trits */
+ uint16_t num_minus1, /* in - no. of indices for -1 trits */
+ uint16_t num_trits, /* in - N, no. of trits in array */
+ uint8_t *buf, /* in - temp buf, N octets */
+ uint8_t *out) /* out - address for packed octets */
+{
+ assert(indices);
+ assert(buf);
+ assert(out);
+
+ /* convert indices to an array of trits */
+
+ memset(buf, 0, num_trits);
+ ntru_indices_2_trits(num_plus1, indices, TRUE, buf);
+ ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf);
+
+ /* pack the array of trits */
+
+ while (num_trits >= 5) {
+ ntru_trits_2_octet(buf, out);
+ num_trits -= 5;
+ buf += 5;
+ ++out;
+ }
+ if (num_trits) {
+ uint8_t trits[5];
+
+ memcpy(trits, buf, num_trits);
+ memset(trits + num_trits, 0, sizeof(trits) - num_trits);
+ ntru_trits_2_octet(trits, out);
+ }
+}
+
+
+/* ntru_elements_2_octets
+ *
+ * Packs an array of n-bit elements into an array of
+ * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
+ */
+
+void
+ntru_elements_2_octets(
+ uint16_t in_len, /* in - no. of elements to be packed */
+ uint16_t const *in, /* in - ptr to elements to be packed */
+ uint8_t n_bits, /* in - no. of bits in input element */
+ uint8_t *out) /* out - addr for output octets */
+{
+ uint16_t temp;
+ int shift;
+ uint16_t i;
+
+ assert(in_len);
+ assert(in);
+ assert((n_bits > 8) && (n_bits < 16));
+ assert(out);
+
+ /* pack */
+
+ temp = 0;
+ shift = n_bits - 8;
+ i = 0;
+ while (i < in_len) {
+
+ /* add bits to temp to fill an octet and output the octet */
+
+ temp |= in[i] >> shift;
+ *out++ = (uint8_t)(temp & 0xff);
+ shift = 8 - shift;
+ if (shift < 1) {
+
+ /* next full octet is in current input word */
+
+ shift += n_bits;
+ temp = 0;
+
+ } else {
+
+ /* put remaining bits of input word in temp as partial octet,
+ * and increment index to next input word
+ */
+ temp = in[i] << (uint16_t)shift;
+
+ ++i;
+ }
+ shift = n_bits - shift;
+ }
+
+ /* output any bits remaining in last input word */
+
+ if (shift != n_bits - 8) {
+ *out++ = (uint8_t)(temp & 0xff);
+ }
+}
+
+
+/* ntru_octets_2_elements
+ *
+ * Unpacks an octet string into an array of ((in_len * 8) / n_bits)
+ * n-bit elements, 8 < n_bits < 16. Any extra bits are discarded.
+ */
+
+void
+ntru_octets_2_elements(
+ uint16_t in_len, /* in - no. of octets to be unpacked */
+ uint8_t const *in, /* in - ptr to octets to be unpacked */
+ uint8_t n_bits, /* in - no. of bits in output element */
+ uint16_t *out) /* out - addr for output elements */
+{
+ uint16_t temp;
+ uint16_t mask = (1 << n_bits) - 1;
+ int shift;
+ uint16_t i;
+
+ assert(in_len > 1);
+ assert(in);
+ assert((n_bits > 8) && (n_bits < 16));
+ assert(out);
+
+ /* unpack */
+
+ temp = 0;
+ shift = n_bits;
+ i = 0;
+ while (i < in_len) {
+ shift = 8 - shift;
+ if (shift < 0) {
+
+ /* the current octet will not fill the current element */
+
+ shift += n_bits;
+
+ } else {
+
+ /* add bits from the current octet to fill the current element and
+ * output the element
+ */
+
+ temp |= ((uint16_t)in[i]) >> shift;
+ *out++ = temp & mask;
+ temp = 0;
+ }
+
+ /* add the remaining bits of the current octet to start an element */
+
+ shift = n_bits - shift;
+ temp |= ((uint16_t)in[i]) << shift;
+ ++i;
+ }
+}
+
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h
new file mode 100644
index 000000000..1c4b35b24
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_convert.h
@@ -0,0 +1,183 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_convert.h is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_convert.h
+ *
+ * Contents: Definitions and declarations for conversion routines
+ * for NTRUEncrypt, including packing, unpacking and others.
+ *
+ *****************************************************************************/
+
+#ifndef NTRU_CRYPTO_NTRU_CONVERT_H
+#define NTRU_CRYPTO_NTRU_CONVERT_H
+
+#include "ntru_crypto.h"
+
+
+/* function declarations */
+
+/* ntru_bits_2_trits
+ *
+ * Each 3 bits in an array of octets is converted to 2 trits in an array
+ * of trits.
+ */
+
+extern void
+ntru_bits_2_trits(
+ uint8_t const *octets, /* in - pointer to array of octets */
+ uint16_t num_trits, /* in - number of trits to produce */
+ uint8_t *trits); /* out - address for array of trits */
+
+
+/* ntru_trits_2_bits
+ *
+ * Each 2 trits in an array of trits is converted to 3 bits, and the bits
+ * are packed in an array of octets. A multiple of 3 octets is output.
+ * Any bits in the final octets not derived from trits are zero.
+ *
+ * Returns TRUE if all trits were valid.
+ * Returns FALSE if invalid trits were found.
+ */
+
+extern bool
+ntru_trits_2_bits(
+ uint8_t const *trits, /* in - pointer to array of trits */
+ uint32_t num_trits, /* in - number of trits to convert */
+ uint8_t *octets); /* out - address for array of octets */
+
+
+/* ntru_coeffs_mod4_2_octets
+ *
+ * Takes an array of coefficients mod 4 and packs the results into an
+ * octet string.
+ */
+
+extern void
+ntru_coeffs_mod4_2_octets(
+ uint16_t num_coeffs, /* in - number of coefficients */
+ uint16_t const *coeffs, /* in - pointer to coefficients */
+ uint8_t *octets); /* out - address for octets */
+
+
+/* ntru_trits_2_octet
+ *
+ * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
+ */
+
+extern void
+ntru_trits_2_octet(
+ uint8_t const *trits, /* in - pointer to trits */
+ uint8_t *octet); /* out - address for octet */
+
+
+/* ntru_octet_2_trits
+ *
+ * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
+ */
+
+extern void
+ntru_octet_2_trits(
+ uint8_t octet, /* in - octet to be unpacked */
+ uint8_t *trits); /* out - address for trits */
+
+
+/* ntru_indices_2_trits
+ *
+ * Converts a list of the nonzero indices of a polynomial into an array of
+ * trits.
+ */
+
+extern void
+ntru_indices_2_trits(
+ uint16_t in_len, /* in - no. of indices */
+ uint16_t const *in, /* in - pointer to list of indices */
+ bool plus1, /* in - if list is +1 coefficients */
+ uint8_t *out); /* out - address of output polynomial */
+
+
+/* ntru_packed_trits_2_indices
+ *
+ * Unpacks an array of N trits and creates a list of array indices
+ * corresponding to trits = +1, and list of array indices corresponding to
+ * trits = -1.
+ */
+
+extern void
+ntru_packed_trits_2_indices(
+ uint8_t const *in, /* in - pointer to packed-trit octets */
+ uint16_t num_trits, /* in - no. of packed trits */
+ uint16_t *indices_plus1, /* out - address for indices of +1 trits */
+ uint16_t *indices_minus1); /* out - address for indices of -1 trits */
+
+
+/* ntru_indices_2_packed_trits
+ *
+ * Takes a list of array indices corresponding to elements whose values
+ * are +1 or -1, and packs the N-element array of trits described by these
+ * lists into octets, 5 trits per octet.
+ */
+
+extern void
+ntru_indices_2_packed_trits(
+ uint16_t const *indices, /* in - pointer to indices */
+ uint16_t num_plus1, /* in - no. of indices for +1 trits */
+ uint16_t num_minus1, /* in - no. of indices for -1 trits */
+ uint16_t num_trits, /* in - N, no. of trits in array */
+ uint8_t *buf, /* in - temp buf, N octets */
+ uint8_t *out); /* out - address for packed octets */
+
+
+/* ntru_elements_2_octets
+ *
+ * Packs an array of n-bit elements into an array of
+ * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
+ */
+
+extern void
+ntru_elements_2_octets(
+ uint16_t in_len, /* in - no. of elements to be packed */
+ uint16_t const *in, /* in - ptr to elements to be packed */
+ uint8_t n_bits, /* in - no. of bits in input element */
+ uint8_t *out); /* out - addr for output octets */
+
+
+/* ntru_octets_2_elements
+ *
+ * Unpacks an octet string into an array of ((in_len * 8) / n_bits)
+ * n-bit elements, 8 < n < 16. Any extra bits are discarded.
+ */
+
+extern void
+ntru_octets_2_elements(
+ uint16_t in_len, /* in - no. of octets to be unpacked */
+ uint8_t const *in, /* in - ptr to octets to be unpacked */
+ uint8_t n_bits, /* in - no. of bits in output element */
+ uint16_t *out); /* out - addr for output elements */
+
+
+#endif /* NTRU_CRYPTO_NTRU_CONVERT_H */
+
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c
new file mode 100644
index 000000000..dba81915a
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt.c
@@ -0,0 +1,1034 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_encrypt.c is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_encrypt.c
+ *
+ * Contents: Routines implementing NTRUEncrypt encryption and decryption and
+ * key generation.
+ *
+ *****************************************************************************/
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "ntru_crypto.h"
+#include "ntru_crypto_ntru_encrypt_param_sets.h"
+#include "ntru_crypto_ntru_encrypt_key.h"
+#include "ntru_crypto_ntru_convert.h"
+#include "ntru_crypto_ntru_poly.h"
+#
+#include "ntru_trits.h"
+#include "ntru_poly.h"
+
+/* ntru_crypto_ntru_encrypt
+ *
+ * Implements NTRU encryption (SVES) for the parameter set specified in
+ * the public key blob.
+ *
+ * Before invoking this function, a DRBG must be instantiated using
+ * ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
+ * instantiation the requested security strength must be at least as large
+ * as the security strength of the NTRU parameter set being used.
+ * Failure to instantiate the DRBG with the proper security strength will
+ * result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
+ *
+ * The required minimum size of the output ciphertext buffer (ct) may be
+ * queried by invoking this function with ct = NULL. In this case, no
+ * encryption is performed, NTRU_OK is returned, and the required minimum
+ * size for ct is returned in ct_len.
+ *
+ * When ct != NULL, at invocation *ct_len must be the size of the ct buffer.
+ * Upon return it is the actual size of the ciphertext.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_DRBG_FAIL if the DRBG handle is invalid.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
+ * Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is
+ * zero, or if pt_len exceeds the maximum plaintext length for the parameter set.
+ * Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid
+ * (unknown format, corrupt, bad length).
+ * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ */
+
+uint32_t
+ntru_crypto_ntru_encrypt(
+ ntru_drbg_t *drbg, /* in - handle of DRBG */
+ uint16_t pubkey_blob_len, /* in - no. of octets in public key
+ blob */
+ uint8_t const *pubkey_blob, /* in - pointer to public key */
+ uint16_t pt_len, /* in - no. of octets in plaintext */
+ uint8_t const *pt, /* in - pointer to plaintext */
+ uint16_t *ct_len, /* in/out - no. of octets in ct, addr for
+ no. of octets in ciphertext */
+ uint8_t *ct) /* out - address for ciphertext */
+{
+ NTRU_ENCRYPT_PARAM_SET *params = NULL;
+ uint8_t const *pubkey_packed = NULL;
+ uint8_t pubkey_pack_type = 0x00;
+ uint16_t packed_ct_len;
+ size_t scratch_buf_len;
+ uint32_t dr;
+ uint32_t dr1 = 0;
+ uint32_t dr2 = 0;
+ uint32_t dr3 = 0;
+ uint16_t ring_mult_tmp_len;
+ int16_t m1 = 0;
+ uint16_t *scratch_buf = NULL;
+ uint16_t *ringel_buf = NULL;
+ uint8_t *b_buf = NULL;
+ uint8_t *tmp_buf = NULL;
+ bool msg_rep_good = FALSE;
+ hash_algorithm_t hash_algid;
+ uint16_t mprime_len = 0;
+ uint16_t mod_q_mask;
+ uint32_t result = NTRU_OK;
+ ntru_trits_t *mask;
+ uint8_t *mask_trits;
+ chunk_t seed;
+ ntru_poly_t *r_poly;
+
+ /* check for bad parameters */
+
+ if (!pubkey_blob || !pt || !ct_len)
+ {
+ return NTRU_BAD_PARAMETER;
+ }
+ if ((pubkey_blob_len == 0) || (pt_len == 0))
+ {
+ return NTRU_BAD_LENGTH;
+ }
+
+ /* get a pointer to the parameter-set parameters, the packing type for
+ * the public key, and a pointer to the packed public key
+ */
+
+ if (!ntru_crypto_ntru_encrypt_key_parse(TRUE /* pubkey */, pubkey_blob_len,
+ pubkey_blob, &pubkey_pack_type,
+ NULL, &params, &pubkey_packed,
+ NULL))
+ {
+ return NTRU_BAD_PUBLIC_KEY;
+ }
+
+ /* return the ciphertext size if requested */
+
+ packed_ct_len = (params->N * params->q_bits + 7) >> 3;
+ if (!ct)
+ {
+ *ct_len = packed_ct_len;
+ return NTRU_OK;
+ }
+
+ /* check the ciphertext buffer size */
+
+ if (*ct_len < packed_ct_len)
+ {
+ return NTRU_BUFFER_TOO_SMALL;
+ }
+
+ /* check the plaintext length */
+
+ if (pt_len > params->m_len_max)
+ {
+ return NTRU_BAD_LENGTH;
+ }
+
+ /* allocate memory for all operations */
+
+ if (params->is_product_form)
+ {
+ ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */
+ dr1 = params->dF_r & 0xff;
+ dr2 = (params->dF_r >> 8) & 0xff;
+ dr3 = (params->dF_r >> 16) & 0xff;
+ dr = dr1 + dr2 + dr3;
+ }
+ else
+ {
+ ring_mult_tmp_len = params->N; /* N 16-bit word buffer */
+ dr = params->dF_r;
+ }
+ scratch_buf_len = (ring_mult_tmp_len << 1) +
+ /* X-byte temp buf for ring mult and
+ other intermediate results */
+ (params->N << 1) + /* 2N-byte buffer for ring elements
+ and overflow from temp buffer */
+ (dr << 2) + /* buffer for r indices */
+ params->sec_strength_len;
+ /* buffer for b */
+ scratch_buf = malloc(scratch_buf_len);
+ if (!scratch_buf)
+ {
+ return NTRU_OUT_OF_MEMORY;
+ }
+ ringel_buf = scratch_buf + ring_mult_tmp_len;
+ b_buf = (uint8_t *)(ringel_buf + params->N);
+ tmp_buf = (uint8_t *)scratch_buf;
+
+ /* set hash algorithm based on security strength */
+ hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256;
+
+ /* set constants */
+ mod_q_mask = params->q - 1;
+
+ /* loop until a message representative with proper weight is achieved */
+
+ do {
+ uint8_t *ptr = tmp_buf;
+
+ /* get b */
+ if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE,
+ params->sec_strength_len, b_buf))
+ {
+ result = NTRU_OK;
+ }
+ else
+ {
+ result = NTRU_FAIL;
+ }
+
+ if (result == NTRU_OK)
+ {
+
+ /* form sData (OID || m || b || hTrunc) */
+ memcpy(ptr, params->OID, 3);
+ ptr += 3;
+ memcpy(ptr, pt, pt_len);
+ ptr += pt_len;
+ memcpy(ptr, b_buf, params->sec_strength_len);
+ ptr += params->sec_strength_len;
+ memcpy(ptr, pubkey_packed, params->sec_strength_len);
+ ptr += params->sec_strength_len;
+
+ DBG2(DBG_LIB, "generate polynomial r");
+
+ seed = chunk_create(tmp_buf, ptr - tmp_buf);
+ r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
+ params->N, params->q,
+ params->dF_r, params->dF_r,
+ params->is_product_form);
+ if (!r_poly)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ uint16_t pubkey_packed_len;
+
+ /* unpack the public key */
+ assert(pubkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS);
+ pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
+ ntru_octets_2_elements(pubkey_packed_len, pubkey_packed,
+ params->q_bits, ringel_buf);
+
+ /* form R = h * r */
+ r_poly->ring_mult(r_poly, ringel_buf, ringel_buf);
+ r_poly->destroy(r_poly);
+
+ /* form R mod 4 */
+ ntru_coeffs_mod4_2_octets(params->N, ringel_buf, tmp_buf);
+
+ /* form mask */
+ seed = chunk_create(tmp_buf, (params->N + 3)/4);
+ mask = ntru_trits_create(params->N, hash_algid, seed);
+ if (!mask)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ uint8_t *Mtrin_buf = tmp_buf + params->N;
+ uint8_t *M_buf = Mtrin_buf + params->N -
+ (params->sec_strength_len + params->m_len_len +
+ params->m_len_max + 2);
+ uint16_t i;
+
+ /* form the padded message M */
+ ptr = M_buf;
+ memcpy(ptr, b_buf, params->sec_strength_len);
+ ptr += params->sec_strength_len;
+ if (params->m_len_len == 2)
+ *ptr++ = (uint8_t)((pt_len >> 8) & 0xff);
+ *ptr++ = (uint8_t)(pt_len & 0xff);
+ memcpy(ptr, pt, pt_len);
+ ptr += pt_len;
+
+ /* add an extra zero byte in case without it the bit string
+ * is not a multiple of 3 bits and therefore might not be
+ * able to produce enough trits
+ */
+
+ memset(ptr, 0, params->m_len_max - pt_len + 2);
+
+ /* convert M to trits (Mbin to Mtrin) */
+ mprime_len = params->N;
+ if (params->is_product_form)
+ {
+ --mprime_len;
+ }
+
+ ntru_bits_2_trits(M_buf, mprime_len, Mtrin_buf);
+ mask_trits = mask->get_trits(mask);
+
+ /* form the msg representative m' by adding Mtrin to mask, mod p */
+ if (params->is_product_form)
+ {
+ for (i = 0; i < mprime_len; i++)
+ {
+ tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
+ if (tmp_buf[i] >= 3)
+ {
+ tmp_buf[i] -= 3;
+ }
+ if (tmp_buf[i] == 1)
+ {
+ ++m1;
+ }
+ else if (tmp_buf[i] == 2)
+ {
+ --m1;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < mprime_len; i++)
+ {
+ tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
+ if (tmp_buf[i] >= 3)
+ {
+ tmp_buf[i] -= 3;
+ }
+ }
+ }
+ mask->destroy(mask);
+
+ /* check that message representative meets minimum weight
+ * requirements
+ */
+
+ if (params->is_product_form)
+ msg_rep_good = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) :
+ (bool)( m1 <= params->min_msg_rep_wt);
+ else
+ msg_rep_good = ntru_poly_check_min_weight(mprime_len, tmp_buf,
+ params->min_msg_rep_wt);
+ msg_rep_good = TRUE;
+ }
+ } while ((result == NTRU_OK) && !msg_rep_good);
+
+ if (result == NTRU_OK)
+ {
+ uint16_t i;
+
+ /* form ciphertext e by adding m' to R mod q */
+
+ for (i = 0; i < mprime_len; i++) {
+ if (tmp_buf[i] == 1)
+ ringel_buf[i] = (ringel_buf[i] + 1) & mod_q_mask;
+ else if (tmp_buf[i] == 2)
+ ringel_buf[i] = (ringel_buf[i] - 1) & mod_q_mask;
+ }
+ if (params->is_product_form)
+ ringel_buf[i] = (ringel_buf[i] - m1) & mod_q_mask;
+
+ /* pack ciphertext */
+ ntru_elements_2_octets(params->N, ringel_buf, params->q_bits, ct);
+ *ct_len = packed_ct_len;
+ }
+
+ /* cleanup */
+ memset(scratch_buf, 0, scratch_buf_len);
+ free(scratch_buf);
+
+ return result;
+}
+
+
+/* ntru_crypto_ntru_decrypt
+ *
+ * Implements NTRU decryption (SVES) for the parameter set specified in
+ * the private key blob.
+ *
+ * The maximum size of the output plaintext may be queried by invoking
+ * this function with pt = NULL. In this case, no decryption is performed,
+ * NTRU_OK is returned, and the maximum size the plaintext could be is
+ * returned in pt_len.
+ * Note that until the decryption is performed successfully, the actual size
+ * of the resulting plaintext cannot be known.
+ *
+ * When pt != NULL, at invocation *pt_len must be the size of the pt buffer.
+ * Upon return it is the actual size of the plaintext.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pt) is NULL.
+ * Returns NTRU_BAD_LENGTH if a length argument (privkey_blob) is zero, or if
+ * ct_len is invalid for the parameter set.
+ * Returns NTRU_BAD_PRIVATE_KEY if the private-key blob is invalid
+ * (unknown format, corrupt, bad length).
+ * Returns NTRU_BUFFER_TOO_SMALL if the plaintext buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ * Returns NTRU_FAIL if a decryption error occurs.
+ */
+
+uint32_t
+ntru_crypto_ntru_decrypt(
+ uint16_t privkey_blob_len, /* in - no. of octets in private key
+ blob */
+ uint8_t const *privkey_blob, /* in - pointer to private key */
+ uint16_t ct_len, /* in - no. of octets in ciphertext */
+ uint8_t const *ct, /* in - pointer to ciphertext */
+ uint16_t *pt_len, /* in/out - no. of octets in pt, addr for
+ no. of octets in plaintext */
+ uint8_t *pt) /* out - address for plaintext */
+{
+ NTRU_ENCRYPT_PARAM_SET *params = NULL;
+ uint8_t const *privkey_packed = NULL;
+ uint8_t const *pubkey_packed = NULL;
+ uint8_t privkey_pack_type = 0x00;
+ uint8_t pubkey_pack_type = 0x00;
+ size_t scratch_buf_len;
+ uint32_t dF_r;
+ uint32_t dF_r1 = 0;
+ uint32_t dF_r2 = 0;
+ uint32_t dF_r3 = 0;
+ uint16_t ring_mult_tmp_len;
+ int16_t m1 = 0;
+ uint16_t *scratch_buf = NULL;
+ uint16_t *ringel_buf1 = NULL;
+ uint16_t *ringel_buf2 = NULL;
+ uint16_t *i_buf = NULL;
+ uint8_t *m_buf = NULL;
+ uint8_t *tmp_buf = NULL;
+ uint8_t *Mtrin_buf = NULL;
+ uint8_t *M_buf = NULL;
+ uint8_t *ptr = NULL;
+ hash_algorithm_t hash_algid;
+ uint16_t cmprime_len;
+ uint16_t mod_q_mask;
+ uint16_t q_mod_p;
+ uint16_t cm_len = 0;
+ uint16_t num_zeros;
+ uint16_t i;
+ bool decryption_ok = TRUE;
+ uint32_t result = NTRU_OK;
+ ntru_trits_t *mask;
+ uint8_t *mask_trits;
+ chunk_t seed;
+ ntru_poly_t *F_poly, *r_poly;
+
+ /* check for bad parameters */
+ if (!privkey_blob || !ct || !pt_len)
+ {
+ return NTRU_BAD_PARAMETER;
+ }
+ if ((privkey_blob_len == 0) || (ct_len == 0))
+ {
+ return NTRU_BAD_LENGTH;
+ }
+
+ /* get a pointer to the parameter-set parameters, the packing types for
+ * the public and private keys, and pointers to the packed public and
+ * private keys
+ */
+
+ if (!ntru_crypto_ntru_encrypt_key_parse(FALSE /* privkey */,
+ privkey_blob_len,
+ privkey_blob, &pubkey_pack_type,
+ &privkey_pack_type, &params,
+ &pubkey_packed, &privkey_packed))
+ {
+ return NTRU_BAD_PRIVATE_KEY;
+ }
+
+ /* return the max plaintext size if requested */
+
+ if (!pt)
+ {
+ *pt_len = params->m_len_max;
+ return NTRU_OK;
+ }
+
+ /* cannot check the plaintext buffer size until after the plaintext
+ * is derived, if we allow plaintext buffers only as large as the
+ * actual plaintext
+ */
+
+ /* check the ciphertext length */
+
+ if (ct_len != (params->N * params->q_bits + 7) >> 3)
+ {
+ return NTRU_BAD_LENGTH;
+ }
+
+ /* allocate memory for all operations */
+
+ if (params->is_product_form)
+ {
+ ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */
+ dF_r1 = params->dF_r & 0xff;
+ dF_r2 = (params->dF_r >> 8) & 0xff;
+ dF_r3 = (params->dF_r >> 16) & 0xff;
+ dF_r = dF_r1 + dF_r2 + dF_r3;
+ } else {
+ ring_mult_tmp_len = params->N; /* N 16-bit word buffer */
+ dF_r = params->dF_r;
+ }
+ scratch_buf_len = (ring_mult_tmp_len << 1) +
+ /* X-byte temp buf for ring mult and
+ other intermediate results */
+ (params->N << 2) + /* 2 2N-byte bufs for ring elements
+ and overflow from temp buffer */
+ (dF_r << 2) + /* buffer for F, r indices */
+ params->m_len_max; /* buffer for plaintext */
+ scratch_buf = malloc(scratch_buf_len);
+ if (!scratch_buf)
+ {
+ return NTRU_OUT_OF_MEMORY;
+ }
+ ringel_buf1 = scratch_buf + ring_mult_tmp_len;
+ ringel_buf2 = ringel_buf1 + params->N;
+ i_buf = ringel_buf2 + params->N;
+ m_buf = (uint8_t *)(i_buf + (dF_r << 1));
+ tmp_buf = (uint8_t *)scratch_buf;
+ Mtrin_buf = (uint8_t *)ringel_buf1;
+ M_buf = Mtrin_buf + params->N;
+
+ /* set hash algorithm based on security strength */
+ hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256;
+
+ /* set constants */
+ mod_q_mask = params->q - 1;
+ q_mod_p = params->q % 3;
+
+ /* unpack the ciphertext */
+ ntru_octets_2_elements(ct_len, ct, params->q_bits, ringel_buf2);
+
+ /* unpack the private key */
+ if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_TRITS)
+ {
+ ntru_packed_trits_2_indices(privkey_packed, params->N, i_buf,
+ i_buf + dF_r);
+
+ }
+ else if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_INDICES)
+ {
+ ntru_octets_2_elements(
+ (((uint16_t)dF_r << 1) * params->N_bits + 7) >> 3,
+ privkey_packed, params->N_bits, i_buf);
+
+ }
+ else
+ {
+ assert(FALSE);
+ }
+
+ /* form cm':
+ * F * e
+ * A = e * (1 + pF) mod q = e + pFe mod q
+ * a = A in the range [-q/2, q/2)
+ * cm' = a mod p
+ */
+ F_poly = ntru_poly_create_from_data(i_buf, params->N, params->q,
+ params->dF_r, params->dF_r,
+ params->is_product_form);
+ F_poly->ring_mult(F_poly, ringel_buf2, ringel_buf1);
+ F_poly->destroy(F_poly);
+
+ cmprime_len = params->N;
+ if (params->is_product_form)
+ {
+ --cmprime_len;
+ for (i = 0; i < cmprime_len; i++)
+ {
+ ringel_buf1[i] = (ringel_buf2[i] + 3 * ringel_buf1[i]) & mod_q_mask;
+ if (ringel_buf1[i] >= (params->q >> 1))
+ {
+ ringel_buf1[i] = ringel_buf1[i] - q_mod_p;
+ }
+ Mtrin_buf[i] = (uint8_t)(ringel_buf1[i] % 3);
+ if (Mtrin_buf[i] == 1)
+ {
+ ++m1;
+ }
+ else if (Mtrin_buf[i] == 2)
+ {
+ --m1;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < cmprime_len; i++)
+ {
+ ringel_buf1[i] = (ringel_buf2[i] + 3 * ringel_buf1[i]) & mod_q_mask;
+ if (ringel_buf1[i] >= (params->q >> 1))
+ {
+ ringel_buf1[i] = ringel_buf1[i] - q_mod_p;
+ }
+ Mtrin_buf[i] = (uint8_t)(ringel_buf1[i] % 3);
+ }
+ }
+
+ /* check that the candidate message representative meets minimum weight
+ * requirements
+ */
+
+ if (params->is_product_form)
+ {
+ decryption_ok = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) :
+ (bool)( m1 <= params->min_msg_rep_wt);
+ }
+ else
+ {
+ decryption_ok = ntru_poly_check_min_weight(cmprime_len, Mtrin_buf,
+ params->min_msg_rep_wt);
+ }
+
+ /* form cR = e - cm' mod q */
+ for (i = 0; i < cmprime_len; i++)
+ {
+ if (Mtrin_buf[i] == 1)
+ {
+ ringel_buf2[i] = (ringel_buf2[i] - 1) & mod_q_mask;
+ }
+ else if (Mtrin_buf[i] == 2)
+ {
+ ringel_buf2[i] = (ringel_buf2[i] + 1) & mod_q_mask;
+ }
+ }
+ if (params->is_product_form)
+ {
+ ringel_buf2[i] = (ringel_buf2[i] + m1) & mod_q_mask;
+ }
+
+ /* form cR mod 4 */
+ ntru_coeffs_mod4_2_octets(params->N, ringel_buf2, tmp_buf);
+
+ /* form mask */
+ seed = chunk_create(tmp_buf, (params->N + 3)/4);
+ mask = ntru_trits_create(params->N, hash_algid, seed);
+ if (!mask)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ else
+ {
+ mask_trits = mask->get_trits(mask);
+
+ /* form cMtrin by subtracting mask from cm', mod p */
+ for (i = 0; i < cmprime_len; i++)
+ {
+ Mtrin_buf[i] = Mtrin_buf[i] - mask_trits[i];
+ if (Mtrin_buf[i] >= 3)
+ {
+ Mtrin_buf[i] += 3;
+ }
+ }
+ mask->destroy(mask);
+
+ if (params->is_product_form)
+
+ /* set the last trit to zero since that's what it was, and
+ * because it can't be calculated from (cm' - mask) since
+ * we don't have the correct value for the last cm' trit
+ */
+
+ Mtrin_buf[i] = 0;
+
+ /* convert cMtrin to cM (Mtrin to Mbin) */
+
+ if (!ntru_trits_2_bits(Mtrin_buf, params->N, M_buf))
+ decryption_ok = FALSE;
+
+ /* validate the padded message cM and copy cm to m_buf */
+
+ ptr = M_buf + params->sec_strength_len;
+ if (params->m_len_len == 2)
+ cm_len = (uint16_t)(*ptr++) << 16;
+ cm_len |= (uint16_t)(*ptr++);
+ if (cm_len > params->m_len_max) {
+ cm_len = params->m_len_max;
+ decryption_ok = FALSE;
+ }
+ memcpy(m_buf, ptr, cm_len);
+ ptr += cm_len;
+ num_zeros = params->m_len_max - cm_len + 1;
+ for (i = 0; i < num_zeros; i++) {
+ if (ptr[i] != 0)
+ decryption_ok = FALSE;
+ }
+
+ /* form sData (OID || m || b || hTrunc) */
+
+ ptr = tmp_buf;
+ memcpy(ptr, params->OID, 3);
+ ptr += 3;
+ memcpy(ptr, m_buf, cm_len);
+ ptr += cm_len;
+ memcpy(ptr, M_buf, params->sec_strength_len);
+ ptr += params->sec_strength_len;
+ memcpy(ptr, pubkey_packed, params->sec_strength_len);
+ ptr += params->sec_strength_len;
+
+ /* generate cr */
+ DBG2(DBG_LIB, "generate polynomial r");
+
+ seed = chunk_create(tmp_buf, ptr - tmp_buf);
+ r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
+ params->N, params->q,
+ params->dF_r, params->dF_r,
+ params->is_product_form);
+ if (!r_poly)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ /* unpack the public key */
+ {
+ uint16_t pubkey_packed_len;
+
+ assert(pubkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS);
+ pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
+ ntru_octets_2_elements(pubkey_packed_len, pubkey_packed,
+ params->q_bits, ringel_buf1);
+ }
+
+ /* form cR' = h * cr */
+ r_poly->ring_mult(r_poly, ringel_buf1, ringel_buf1);
+ r_poly->destroy(r_poly);
+
+ /* compare cR' to cR */
+ for (i = 0; i < params->N; i++)
+ {
+ if (ringel_buf1[i] != ringel_buf2[i])
+ {
+ decryption_ok = FALSE;
+ }
+ }
+
+ /* output plaintext and plaintext length */
+ if (decryption_ok)
+ {
+ if (*pt_len < cm_len)
+ {
+ return NTRU_BUFFER_TOO_SMALL;
+ }
+ memcpy(pt, m_buf, cm_len);
+ *pt_len = cm_len;
+ }
+ }
+
+ /* cleanup */
+ memset(scratch_buf, 0, scratch_buf_len);
+ free(scratch_buf);
+
+ if (!decryption_ok)
+ {
+ return NTRU_FAIL;
+ }
+
+ return result;
+}
+
+
+/* ntru_crypto_ntru_encrypt_keygen
+ *
+ * Implements key generation for NTRUEncrypt for the parameter set specified.
+ *
+ * The required minimum size of the output public-key buffer (pubkey_blob)
+ * may be queried by invoking this function with pubkey_blob = NULL.
+ * In this case, no key generation is performed, NTRU_OK is returned, and
+ * the required minimum size for pubkey_blob is returned in pubkey_blob_len.
+ *
+ * The required minimum size of the output private-key buffer (privkey_blob)
+ * may be queried by invoking this function with privkey_blob = NULL.
+ * In this case, no key generation is performed, NTRU_OK is returned, and
+ * the required minimum size for privkey_blob is returned in privkey_blob_len.
+ *
+ * The required minimum sizes of both pubkey_blob and privkey_blob may be
+ * queried as described above, in a single invocation of this function.
+ *
+ * When pubkey_blob != NULL and privkey_blob != NULL, at invocation
+ * *pubkey_blob_len must be the size of the pubkey_blob buffer and
+ * *privkey_blob_len must be the size of the privkey_blob buffer.
+ * Upon return, *pubkey_blob_len is the actual size of the public-key blob
+ * and *privkey_blob_len is the actual size of the private-key blob.
+ *
+ * Returns NTRU_OK if successful.
+ * Returns NTRU_BAD_PARAMETER if an argument pointer (other than pubkey_blob or
+ * privkey_blob) is NULL.
+ * Returns NTRU_INVALID_PARAMETER_SET if the parameter-set ID is invalid.
+ * Returns NTRU_BAD_LENGTH if a length argument is invalid.
+ * Returns NTRU_BUFFER_TOO_SMALL if either the pubkey_blob buffer or the
+ * privkey_blob buffer is too small.
+ * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
+ * Returns NTRU_FAIL if the polynomial generated for f is not invertible in
+ * (Z/qZ)[X]/(X^N - 1), which is extremely unlikely.
+ * Should this occur, this function should simply be invoked again.
+ */
+
+uint32_t
+ntru_crypto_ntru_encrypt_keygen(
+ ntru_drbg_t *drbg, /* in - handle of DRBG */
+ NTRU_ENCRYPT_PARAM_SET_ID param_set_id, /* in - parameter set ID */
+ uint16_t *pubkey_blob_len, /* in/out - no. of octets in
+ pubkey_blob, addr
+ for no. of octets
+ in pubkey_blob */
+ uint8_t *pubkey_blob, /* out - address for
+ public key blob */
+ uint16_t *privkey_blob_len, /* in/out - no. of octets in
+ privkey_blob, addr
+ for no. of octets
+ in privkey_blob */
+ uint8_t *privkey_blob) /* out - address for
+ private key blob */
+{
+ NTRU_ENCRYPT_PARAM_SET *params = NULL;
+ uint16_t public_key_blob_len;
+ uint16_t private_key_blob_len;
+ uint8_t pubkey_pack_type;
+ uint8_t privkey_pack_type;
+ size_t scratch_buf_len;
+ uint32_t dF;
+ uint32_t dF1 = 0;
+ uint32_t dF2 = 0;
+ uint32_t dF3 = 0;
+ uint16_t *scratch_buf = NULL;
+ uint16_t *ringel_buf1 = NULL;
+ uint16_t *ringel_buf2 = NULL;
+ uint8_t *tmp_buf = NULL;
+ uint16_t mod_q_mask;
+ hash_algorithm_t hash_algid;
+ uint16_t seed_len;
+ chunk_t seed;
+ uint32_t result = NTRU_OK;
+ ntru_poly_t *F_poly = NULL;
+ ntru_poly_t *g_poly = NULL;
+ uint16_t *F_indices;
+
+ /* get a pointer to the parameter-set parameters */
+
+ if ((params = ntru_encrypt_get_params_with_id(param_set_id)) == NULL)
+ {
+ return NTRU_INVALID_PARAMETER_SET;
+ }
+
+ /* check for bad parameters */
+
+ if (!pubkey_blob_len || !privkey_blob_len)
+ {
+ return NTRU_BAD_PARAMETER;
+ }
+
+ /* get public and private key packing types and blob lengths */
+
+ ntru_crypto_ntru_encrypt_key_get_blob_params(params, &pubkey_pack_type,
+ &public_key_blob_len,
+ &privkey_pack_type,
+ &private_key_blob_len);
+
+ /* return the pubkey_blob size and/or privkey_blob size if requested */
+
+ if (!pubkey_blob || !privkey_blob)
+ {
+ if (!pubkey_blob)
+ *pubkey_blob_len = public_key_blob_len;
+ if (!privkey_blob)
+ *privkey_blob_len = private_key_blob_len;
+ return NTRU_OK;
+ }
+
+ /* check size of output buffers */
+
+ if ((*pubkey_blob_len < public_key_blob_len) ||
+ (*privkey_blob_len < private_key_blob_len))
+ {
+ return NTRU_BUFFER_TOO_SMALL;
+ }
+
+ /* allocate memory for all operations */
+ if (params->is_product_form) {
+ dF1 = params->dF_r & 0xff;
+ dF2 = (params->dF_r >> 8) & 0xff;
+ dF3 = (params->dF_r >> 16) & 0xff;
+ dF = dF1 + dF2 + dF3;
+ } else {
+ dF = params->dF_r;
+ }
+
+ scratch_buf_len = (params->N * 8) + /* 4N-byte temp buffer for ring inv
+ and other intermediate results,
+ 2N-byte buffer for f, g indices
+ and overflow from temp buffer,
+ 2N-byte buffer for f^-1 */
+ (dF << 2); /* buffer for F indices */
+ scratch_buf = malloc(scratch_buf_len);
+ if (!scratch_buf)
+ {
+ return NTRU_OUT_OF_MEMORY;
+ }
+ ringel_buf1 = scratch_buf + (params->N << 1);
+ ringel_buf2 = ringel_buf1 + params->N;
+ tmp_buf = (uint8_t *)scratch_buf;
+
+ /* set hash algorithm and seed length based on security strength */
+ if (params->sec_strength_len <= 20)
+ {
+ hash_algid = HASH_SHA1;
+ }
+ else
+ {
+ hash_algid = HASH_SHA256;
+ }
+ seed_len = params->sec_strength_len + 8;
+
+ /* set constants */
+
+ mod_q_mask = params->q - 1;
+
+ /* get random bytes for seed for generating trinary F
+ * as a list of indices
+ */
+
+ if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE,
+ seed_len, tmp_buf))
+ {
+ result = NTRU_OK;
+ }
+ else
+ {
+ result = NTRU_DRBG_FAIL;
+ }
+
+ if (result == NTRU_OK)
+ {
+ DBG2(DBG_LIB, "generate polynomial F");
+
+ seed = chunk_create(tmp_buf, seed_len);
+ F_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
+ params->N, params->q,
+ params->dF_r, params->dF_r,
+ params->is_product_form);
+ if (!F_poly)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ int i;
+
+ F_poly->get_array(F_poly, ringel_buf1);
+
+ /* form f = 1 + pF */
+ for (i = 0; i < params->N; i++)
+ {
+ ringel_buf1[i] = (ringel_buf1[i] * 3) & mod_q_mask;
+ }
+ ringel_buf1[0] = (ringel_buf1[0] + 1) & mod_q_mask;
+
+ /* find f^-1 in (Z/qZ)[X]/(X^N - 1) */
+ if (!ntru_ring_inv(ringel_buf1, params->N, params->q,
+ scratch_buf, ringel_buf2))
+ {
+ result = NTRU_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+
+ /* get random bytes for seed for generating trinary polynomial g
+ * as a list of indices
+ */
+ if (!drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE,
+ seed_len, tmp_buf))
+ {
+ result = NTRU_DRBG_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ DBG2(DBG_LIB, "generate polynomial g");
+
+ seed = chunk_create(tmp_buf, seed_len);
+ g_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
+ params->N, params->q,
+ params->dg + 1, params->dg, FALSE);
+ if (!g_poly)
+ {
+ result = NTRU_MGF1_FAIL;
+ }
+ }
+
+ if (result == NTRU_OK)
+ {
+ uint16_t i;
+
+ /* compute h = p * (f^-1 * g) mod q */
+ g_poly->ring_mult(g_poly, ringel_buf2, ringel_buf2);
+ g_poly->destroy(g_poly);
+
+ for (i = 0; i < params->N; i++)
+ {
+ ringel_buf2[i] = (ringel_buf2[i] * 3) & mod_q_mask;
+ }
+
+ /* create public key blob */
+ ntru_crypto_ntru_encrypt_key_create_pubkey_blob(params, ringel_buf2,
+ pubkey_pack_type,
+ pubkey_blob);
+ *pubkey_blob_len = public_key_blob_len;
+
+ /* create private key blob */
+ F_indices = F_poly->get_indices(F_poly);
+ ntru_crypto_ntru_encrypt_key_create_privkey_blob(params, ringel_buf2,
+ F_indices,
+ privkey_pack_type,
+ tmp_buf, privkey_blob);
+ *privkey_blob_len = private_key_blob_len;
+ }
+
+ /* cleanup */
+ DESTROY_IF(F_poly);
+ memset(scratch_buf, 0, scratch_buf_len);
+ free(scratch_buf);
+
+ return result;
+}
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c
new file mode 100644
index 000000000..90baaadf3
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.c
@@ -0,0 +1,360 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_encrypt_key.c
+ *
+ * Contents: Routines for exporting and importing public and private keys
+ * for NTRUEncrypt.
+ *
+ *****************************************************************************/
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "ntru_crypto_ntru_encrypt_key.h"
+
+
+/* ntru_crypto_ntru_encrypt_key_parse
+ *
+ * Parses an NTRUEncrypt key blob.
+ * If the blob is not corrupt, returns packing types for public and private
+ * keys, a pointer to the parameter set, a pointer to the public key, and
+ * a pointer to the private key if it exists.
+ *
+ * Returns TRUE if successful.
+ * Returns FALSE if the blob is invalid.
+ */
+
+bool
+ntru_crypto_ntru_encrypt_key_parse(
+ bool pubkey_parse, /* in - if parsing pubkey
+ blob */
+ uint16_t key_blob_len, /* in - no. octets in key
+ blob */
+ uint8_t const *key_blob, /* in - pointer to key blob */
+ uint8_t *pubkey_pack_type, /* out - addr for pubkey
+ packing type */
+ uint8_t *privkey_pack_type, /* out - addr for privkey
+ packing type */
+ NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to
+ parameter set */
+ uint8_t const **pubkey, /* out - addr for ptr to
+ packed pubkey */
+ uint8_t const **privkey) /* out - addr for ptr to
+ packed privkey */
+{
+ uint8_t tag;
+
+ assert(key_blob_len);
+ assert(key_blob);
+ assert(pubkey_pack_type);
+ assert(params);
+ assert(pubkey);
+
+ /* parse key blob based on tag */
+
+ tag = key_blob[0];
+ switch (tag) {
+ case NTRU_ENCRYPT_PUBKEY_TAG:
+ if (!pubkey_parse)
+ return FALSE;
+ break;
+ case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG:
+ case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG:
+ case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG:
+ assert(privkey_pack_type);
+ assert(privkey);
+ if (pubkey_parse)
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+
+ switch (tag) {
+ case NTRU_ENCRYPT_PUBKEY_TAG:
+ case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG:
+ case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG:
+ case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG:
+
+ /* Version 0:
+ * byte 0: tag
+ * byte 1: no. of octets in OID
+ * bytes 2-4: OID
+ * bytes 5- : packed pubkey
+ * [packed privkey]
+ */
+
+ {
+ NTRU_ENCRYPT_PARAM_SET *p = NULL;
+ uint16_t pubkey_packed_len;
+
+ /* check OID length and minimum blob length for tag and OID */
+
+ if ((key_blob_len < 5) || (key_blob[1] != 3))
+ return FALSE;
+
+ /* get a pointer to the parameter set corresponding to the OID */
+
+ if ((p = ntru_encrypt_get_params_with_OID(key_blob + 2)) == NULL)
+ return FALSE;
+
+ /* check blob length and assign pointers to blob fields */
+
+ pubkey_packed_len = (p->N * p->q_bits + 7) / 8;
+ if (pubkey_parse) { /* public-key parsing */
+ if (key_blob_len != 5 + pubkey_packed_len)
+ return FALSE;
+
+ *pubkey = key_blob + 5;
+
+ } else { /* private-key parsing */
+ uint16_t privkey_packed_len;
+ uint16_t privkey_packed_trits_len = (p->N + 4) / 5;
+ uint16_t privkey_packed_indices_len;
+ uint16_t dF;
+
+ /* check packing type for product-form private keys */
+
+ if (p->is_product_form &&
+ (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG))
+ return FALSE;
+
+ /* set packed-key length for packed indices */
+
+ if (p->is_product_form)
+ dF = (uint16_t)( (p->dF_r & 0xff) + /* df1 */
+ ((p->dF_r >> 8) & 0xff) + /* df2 */
+ ((p->dF_r >> 16) & 0xff)); /* df3 */
+ else
+ dF = (uint16_t)p->dF_r;
+ privkey_packed_indices_len = ((dF << 1) * p->N_bits + 7) >> 3;
+
+ /* set private-key packing type if defaulted */
+
+ if (tag == NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG) {
+ if (p->is_product_form ||
+ (privkey_packed_indices_len <=
+ privkey_packed_trits_len))
+ tag = NTRU_ENCRYPT_PRIVKEY_INDICES_TAG;
+ else
+ tag = NTRU_ENCRYPT_PRIVKEY_TRITS_TAG;
+ }
+
+ if (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG)
+ privkey_packed_len = privkey_packed_trits_len;
+ else
+ privkey_packed_len = privkey_packed_indices_len;
+
+ if (key_blob_len != 5 + pubkey_packed_len + privkey_packed_len)
+ return FALSE;
+
+ *pubkey = key_blob + 5;
+ *privkey = *pubkey + pubkey_packed_len;
+ *privkey_pack_type = (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG) ?
+ NTRU_ENCRYPT_KEY_PACKED_TRITS :
+ NTRU_ENCRYPT_KEY_PACKED_INDICES;
+ }
+
+ /* return parameter set pointer */
+
+ *pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS;
+ *params = p;
+ }
+ default:
+ break; /* can't get here */
+ }
+ return TRUE;
+}
+
+
+/* ntru_crypto_ntru_encrypt_key_get_blob_params
+ *
+ * Returns public and private key packing types and blob lengths given
+ * a packing format. For now, only a default packing format exists.
+ *
+ * Only public-key params may be returned by setting privkey_pack_type
+ * and privkey_blob_len to NULL.
+ */
+
+void
+ntru_crypto_ntru_encrypt_key_get_blob_params(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint8_t *pubkey_pack_type, /* out - addr for pubkey
+ packing type */
+ uint16_t *pubkey_blob_len, /* out - addr for no. of
+ bytes in
+ pubkey blob */
+ uint8_t *privkey_pack_type, /* out - addr for privkey
+ packing type */
+ uint16_t *privkey_blob_len) /* out - addr for no. of
+ bytes in
+ privkey blob */
+{
+ uint16_t pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
+
+ assert(params);
+ assert(pubkey_pack_type);
+ assert(pubkey_blob_len);
+
+ *pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS;
+ *pubkey_blob_len = 5 + pubkey_packed_len;
+
+ if (privkey_pack_type && privkey_blob_len) {
+ uint16_t privkey_packed_trits_len = (params->N + 4) / 5;
+ uint16_t privkey_packed_indices_len;
+ uint16_t dF;
+
+ if (params->is_product_form)
+ dF = (uint16_t)( (params->dF_r & 0xff) + /* df1 */
+ ((params->dF_r >> 8) & 0xff) + /* df2 */
+ ((params->dF_r >> 16) & 0xff)); /* df3 */
+ else
+ dF = (uint16_t)params->dF_r;
+ privkey_packed_indices_len = ((dF << 1) * params->N_bits + 7) >> 3;
+
+ if (params->is_product_form ||
+ (privkey_packed_indices_len <= privkey_packed_trits_len)) {
+ *privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_INDICES;
+ *privkey_blob_len =
+ 5 + pubkey_packed_len + privkey_packed_indices_len;
+ } else {
+ *privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_TRITS;
+ *privkey_blob_len =
+ 5 + pubkey_packed_len + privkey_packed_trits_len;
+ }
+ }
+}
+
+
+/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
+ *
+ * Returns a public key blob, packed according to the packing type provided.
+ */
+
+void
+ntru_crypto_ntru_encrypt_key_create_pubkey_blob(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint16_t const *pubkey, /* in - pointer to the
+ coefficients
+ of the pubkey */
+ uint8_t pubkey_pack_type, /* out - pubkey packing
+ type */
+ uint8_t *pubkey_blob) /* out - addr for the
+ pubkey blob */
+{
+ assert(params);
+ assert(pubkey);
+ assert(pubkey_blob);
+
+ switch (pubkey_pack_type) {
+ case NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS:
+ *pubkey_blob++ = NTRU_ENCRYPT_PUBKEY_TAG;
+ *pubkey_blob++ = (uint8_t)sizeof(params->OID);
+ memcpy(pubkey_blob, params->OID, sizeof(params->OID));
+ pubkey_blob += sizeof(params->OID);
+ ntru_elements_2_octets(params->N, pubkey, params->q_bits,
+ pubkey_blob);
+ break;
+ default:
+ assert(FALSE);
+ }
+}
+
+
+/* ntru_crypto_ntru_encrypt_key_create_privkey_blob
+ *
+ * Returns a private key blob, packed according to the packing type provided.
+ */
+
+void
+ntru_crypto_ntru_encrypt_key_create_privkey_blob(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint16_t const *pubkey, /* in - pointer to the
+ coefficients
+ of the pubkey */
+ uint16_t const *privkey, /* in - pointer to the
+ indices of the
+ privkey */
+ uint8_t privkey_pack_type, /* in - privkey packing
+ type */
+ uint8_t *buf, /* in - temp, N bytes */
+ uint8_t *privkey_blob) /* out - addr for the
+ privkey blob */
+{
+ assert(params);
+ assert(pubkey);
+ assert(privkey);
+ assert(privkey_blob);
+
+ switch (privkey_pack_type) {
+ case NTRU_ENCRYPT_KEY_PACKED_TRITS:
+ case NTRU_ENCRYPT_KEY_PACKED_INDICES:
+
+ /* format header and packed public key */
+
+ *privkey_blob++ = NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG;
+ *privkey_blob++ = (uint8_t)sizeof(params->OID);
+ memcpy(privkey_blob, params->OID, sizeof(params->OID));
+ privkey_blob += sizeof(params->OID);
+ ntru_elements_2_octets(params->N, pubkey, params->q_bits,
+ privkey_blob);
+ privkey_blob += (params->N * params->q_bits + 7) >> 3;
+
+ /* add packed private key */
+
+ if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_TRITS) {
+ ntru_indices_2_packed_trits(privkey, (uint16_t)params->dF_r,
+ (uint16_t)params->dF_r,
+ params->N, buf, privkey_blob);
+ } else {
+ uint32_t dF;
+
+ if (params->is_product_form) {
+ dF = (params->dF_r & 0xff) +
+ ((params->dF_r >> 8) & 0xff) +
+ ((params->dF_r >> 16) & 0xff);
+ } else {
+ dF = params->dF_r;
+ }
+ ntru_elements_2_octets((uint16_t)dF << 1, privkey,
+ params->N_bits, privkey_blob);
+ }
+ break;
+ default:
+ assert(FALSE);
+ break;
+ }
+}
+
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h
new file mode 100644
index 000000000..6734f2a4c
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_key.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_cencrypt_key.h is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+
+#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
+#define NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
+
+#include "ntru_crypto_ntru_convert.h"
+#include "ntru_crypto_ntru_encrypt_param_sets.h"
+
+
+/* key-blob definitions */
+
+#define NTRU_ENCRYPT_PUBKEY_TAG 0x01
+#define NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG 0x02
+#define NTRU_ENCRYPT_PRIVKEY_TRITS_TAG 0xfe
+#define NTRU_ENCRYPT_PRIVKEY_INDICES_TAG 0xff
+
+/* packing types */
+
+#define NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS 0x01
+#define NTRU_ENCRYPT_KEY_PACKED_INDICES 0x02
+#define NTRU_ENCRYPT_KEY_PACKED_TRITS 0x03
+
+/* function declarations */
+
+
+/* ntru_crypto_ntru_encrypt_key_parse
+ *
+ * Parses an NTRUEncrypt key blob.
+ * If the blob is not corrupt, returns packing types for public and private
+ * keys, a pointer to the parameter set, a pointer to the public key, and
+ * a pointer to the private key if it exists.
+ *
+ * Returns TRUE if successful.
+ * Returns FALSE if the blob is invalid.
+ */
+
+extern bool
+ntru_crypto_ntru_encrypt_key_parse(
+ bool pubkey_parse, /* in - if parsing pubkey
+ blob */
+ uint16_t key_blob_len, /* in - no. octets in key
+ blob */
+ uint8_t const *key_blob, /* in - pointer to key blob */
+ uint8_t *pubkey_pack_type, /* out - addr for pubkey
+ packing type */
+ uint8_t *privkey_pack_type, /* out - addr for privkey
+ packing type */
+ NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to
+ parameter set */
+ uint8_t const **pubkey, /* out - addr for ptr to
+ packed pubkey */
+ uint8_t const **privkey); /* out - addr for ptr to
+ packed privkey */
+
+
+/* ntru_crypto_ntru_encrypt_key_get_blob_params
+ *
+ * Returns public and private key packing types and blob lengths given
+ * a packing format. For now, only a default packing format exists.
+ *
+ * Only public-key params may be returned by setting privkey_pack_type
+ * and privkey_blob_len to NULL.
+ */
+
+extern void
+ntru_crypto_ntru_encrypt_key_get_blob_params(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint8_t *pubkey_pack_type, /* out - addr for pubkey
+ packing type */
+ uint16_t *pubkey_blob_len, /* out - addr for no. of
+ bytes in
+ pubkey blob */
+ uint8_t *privkey_pack_type, /* out - addr for privkey
+ packing type */
+ uint16_t *privkey_blob_len); /* out - addr for no. of
+ bytes in
+ privkey blob */
+
+
+/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
+ *
+ * Returns a public key blob, packed according to the packing type provided.
+ */
+
+extern void
+ntru_crypto_ntru_encrypt_key_create_pubkey_blob(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint16_t const *pubkey, /* in - pointer to the
+ coefficients
+ of the pubkey */
+ uint8_t pubkey_pack_type, /* out - addr for pubkey
+ packing type */
+ uint8_t *pubkey_blob); /* out - addr for the
+ pubkey blob */
+
+
+/* ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob
+ *
+ * Returns a public key blob, recreated from an already-packed public key.
+ */
+
+extern void
+ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint16_t packed_pubkey_len, /* in - no. octets in
+ packed pubkey */
+ uint8_t const *packed_pubkey, /* in - pointer to the
+ packed pubkey */
+ uint8_t pubkey_pack_type, /* out - pubkey packing
+ type */
+ uint8_t *pubkey_blob); /* out - addr for the
+ pubkey blob */
+
+
+/* ntru_crypto_ntru_encrypt_key_create_privkey_blob
+ *
+ * Returns a privlic key blob, packed according to the packing type provided.
+ */
+
+extern void
+ntru_crypto_ntru_encrypt_key_create_privkey_blob(
+ NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
+ param set
+ parameters */
+ uint16_t const *pubkey, /* in - pointer to the
+ coefficients
+ of the pubkey */
+ uint16_t const *privkey, /* in - pointer to the
+ indices of the
+ privkey */
+ uint8_t privkey_pack_type, /* in - privkey packing
+ type */
+ uint8_t *buf, /* in - temp, N bytes */
+ uint8_t *privkey_blob); /* out - addr for the
+ privkey blob */
+
+
+#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H */
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c
new file mode 100644
index 000000000..5ddf91d2a
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c
@@ -0,0 +1,384 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_param_sets.c is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_encrypt_param_sets.c
+ *
+ * Contents: Defines the NTRUEncrypt parameter sets.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "ntru_crypto_ntru_encrypt_param_sets.h"
+
+
+/* parameter sets */
+
+static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = {
+
+ {
+ NTRU_EES401EP1, /* parameter-set id */
+ {0x00, 0x02, 0x04}, /* OID */
+ 0x22, /* DER id */
+ 9, /* no. of bits in N (i.e., in an index) */
+ 401, /* N */
+ 14, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 113, /* df, dr */
+ 133, /* dg */
+ 60, /* maxMsgLenBytes */
+ 113, /* dm0 */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES449EP1, /* parameter-set id */
+ {0x00, 0x03, 0x03}, /* OID */
+ 0x23, /* DER id */
+ 9, /* no. of bits in N (i.e., in an index) */
+ 449, /* N */
+ 16, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 134, /* df, dr */
+ 149, /* dg */
+ 67, /* maxMsgLenBytes */
+ 134, /* dm0 */
+ 9, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES677EP1, /* parameter-set id */
+ {0x00, 0x05, 0x03}, /* OID */
+ 0x24, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 677, /* N */
+ 24, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 157, /* df, dr */
+ 225, /* dg */
+ 101, /* maxMsgLenBytes */
+ 157, /* dm0 */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES1087EP2, /* parameter-set id */
+ {0x00, 0x06, 0x03}, /* OID */
+ 0x25, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 1087, /* N */
+ 32, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 120, /* df, dr */
+ 362, /* dg */
+ 170, /* maxMsgLenBytes */
+ 120, /* dm0 */
+ 13, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES541EP1, /* parameter-set id */
+ {0x00, 0x02, 0x05}, /* OID */
+ 0x26, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 541, /* N */
+ 14, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 49, /* df, dr */
+ 180, /* dg */
+ 86, /* maxMsgLenBytes */
+ 49, /* dm0 */
+ 12, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES613EP1, /* parameter-set id */
+ {0x00, 0x03, 0x04}, /* OID */
+ 0x27, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 613, /* N */
+ 16, /* securuity strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 55, /* df, dr */
+ 204, /* dg */
+ 97, /* maxMsgLenBytes */
+ 55, /* dm0 */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES887EP1, /* parameter-set id */
+ {0x00, 0x05, 0x04}, /* OID */
+ 0x28, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 887, /* N */
+ 24, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 81, /* df, dr */
+ 295, /* dg */
+ 141, /* maxMsgLenBytes */
+ 81, /* dm0 */
+ 10, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES1171EP1, /* parameter-set id */
+ {0x00, 0x06, 0x04}, /* OID */
+ 0x29, /* DER id */
+ 11, /* no. of bits in N (i.e., in an index) */
+ 1171, /* N */
+ 32, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 106, /* df, dr */
+ 390, /* dg */
+ 186, /* maxMsgLenBytes */
+ 106, /* dm0 */
+ 12, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES659EP1, /* parameter-set id */
+ {0x00, 0x02, 0x06}, /* OID */
+ 0x2a, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 659, /* N */
+ 14, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 38, /* df, dr */
+ 219, /* dg */
+ 108, /* maxMsgLenBytes */
+ 38, /* dm0 */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES761EP1, /* parameter-set id */
+ {0x00, 0x03, 0x05}, /* OID */
+ 0x2b, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 761, /* N */
+ 16, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 42, /* df, dr */
+ 253, /* dg */
+ 125, /* maxMsgLenBytes */
+ 42, /* dm0 */
+ 12, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES1087EP1, /* parameter-set id */
+ {0x00, 0x05, 0x05}, /* OID */
+ 0x2c, /* DER id */
+ 11, /* no. of bits in N (i.e., in an index) */
+ 1087, /* N */
+ 24, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 63, /* df, dr */
+ 362, /* dg */
+ 178, /* maxMsgLenBytes */
+ 63, /* dm0 */
+ 13, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES1499EP1, /* parameter-set id */
+ {0x00, 0x06, 0x05}, /* OID */
+ 0x2d, /* DER id */
+ 11, /* no. of bits in N (i.e., in an index) */
+ 1499, /* N */
+ 32, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ FALSE, /* product form */
+ 79, /* df, dr */
+ 499, /* dg */
+ 247, /* maxMsgLenBytes */
+ 79, /* dm0 */
+ 13, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES401EP2, /* parameter-set id */
+ {0x00, 0x02, 0x10}, /* OID */
+ 0x2e, /* DER id */
+ 9, /* no. of bits in N (i.e., in an index) */
+ 401, /* N */
+ 14, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ TRUE, /* product form */
+ 8 + (8 << 8) + (6 << 16), /* df, dr */
+ 133, /* dg */
+ 60, /* maxMsgLenBytes */
+ 136, /* m(1)_max */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES439EP1, /* parameter-set id */
+ {0x00, 0x03, 0x10}, /* OID */
+ 0x2f, /* DER id */
+ 9, /* no. of bits in N (i.e., in an index) */
+ 439, /* N */
+ 16, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ TRUE, /* product form */
+ 9 + (8 << 8) + (5 << 16), /* df, dr */
+ 146, /* dg */
+ 65, /* maxMsgLenBytes */
+ 126, /* m(1)_max */
+ 9, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES593EP1, /* parameter-set id */
+ {0x00, 0x05, 0x10}, /* OID */
+ 0x30, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 593, /* N */
+ 24, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ TRUE, /* product form */
+ 10 + (10 << 8) + (8 << 16), /* df, dr */
+ 197, /* dg */
+ 86, /* maxMsgLenBytes */
+ 90, /* m(1)_max */
+ 11, /* c */
+ 1, /* lLen */
+ },
+
+ {
+ NTRU_EES743EP1, /* parameter-set id */
+ {0x00, 0x06, 0x10}, /* OID */
+ 0x31, /* DER id */
+ 10, /* no. of bits in N (i.e., in an index) */
+ 743, /* N */
+ 32, /* security strength in octets */
+ 2048, /* q */
+ 11, /* no. of bits in q (i.e., in a coeff) */
+ TRUE, /* product form */
+ 11 + (11 << 8) + (15 << 16), /* df, dr */
+ 247, /* dg */
+ 106, /* maxMsgLenBytes */
+ 60, /* m(1)_max */
+ 13, /* c */
+ 1, /* lLen */
+ },
+
+};
+
+static size_t numParamSets =
+ sizeof(ntruParamSets)/sizeof(NTRU_ENCRYPT_PARAM_SET);
+
+
+/* functions */
+
+/* ntru_encrypt_get_params_with_id
+ *
+ * Looks up a set of NTRUEncrypt parameters based on the id of the
+ * parameter set.
+ *
+ * Returns a pointer to the parameter set parameters if successful.
+ * Returns NULL if the parameter set cannot be found.
+ */
+
+NTRU_ENCRYPT_PARAM_SET *
+ntru_encrypt_get_params_with_id(
+ NTRU_ENCRYPT_PARAM_SET_ID id) /* in - parameter-set id */
+{
+ size_t i;
+
+ for (i = 0; i < numParamSets; i++) {
+ if (ntruParamSets[i].id == id) {
+ return &(ntruParamSets[i]);
+ }
+ }
+ return NULL;
+}
+
+
+/* ntru_encrypt_get_params_with_OID
+ *
+ * Looks up a set of NTRUEncrypt parameters based on the OID of the
+ * parameter set.
+ *
+ * Returns a pointer to the parameter set parameters if successful.
+ * Returns NULL if the parameter set cannot be found.
+ */
+
+NTRU_ENCRYPT_PARAM_SET *
+ntru_encrypt_get_params_with_OID(
+ uint8_t const *oid) /* in - pointer to parameter-set OID */
+{
+ size_t i;
+
+ for (i = 0; i < numParamSets; i++) {
+ if (!memcmp(ntruParamSets[i].OID, oid, 3)) {
+ return &(ntruParamSets[i]);
+ }
+ }
+ return NULL;
+}
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h
new file mode 100644
index 000000000..e5e977a0e
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_encrypt_param_sets.h is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_encrypt_param_sets.h
+ *
+ * Contents: Definitions and declarations for the NTRUEncrypt parameter sets.
+ *
+ *****************************************************************************/
+
+#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H
+#define NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H
+
+#include "ntru_crypto.h"
+
+/* structures */
+
+typedef struct _NTRU_ENCRYPT_PARAM_SET {
+ NTRU_ENCRYPT_PARAM_SET_ID id; /* parameter-set ID */
+ uint8_t const OID[3]; /* pointer to OID */
+ uint8_t der_id; /* parameter-set DER id */
+ uint8_t N_bits; /* no. of bits in N (i.e. in
+ an index */
+ uint16_t N; /* ring dimension */
+ uint16_t sec_strength_len; /* no. of octets of
+ security strength */
+ uint16_t q; /* big modulus */
+ uint8_t q_bits; /* no. of bits in q (i.e. in
+ a coefficient */
+ bool is_product_form; /* if product form used */
+ uint32_t dF_r; /* no. of 1 or -1 coefficients
+ in ring elements F, r */
+ uint16_t dg; /* no. - 1 of 1 coefficients
+ or no. of -1 coefficients
+ in ring element g */
+ uint16_t m_len_max; /* max no. of plaintext
+ octets */
+ uint16_t min_msg_rep_wt; /* min. message
+ representative weight */
+ uint8_t c_bits; /* no. bits in candidate for
+ deriving an index in
+ IGF-2 */
+ uint8_t m_len_len; /* no. of octets to hold
+ mLenOctets */
+} NTRU_ENCRYPT_PARAM_SET;
+
+
+
+/* function declarations */
+
+/* ntru_encrypt_get_params_with_id
+ *
+ * Looks up a set of NTRU Encrypt parameters based on the id of the
+ * parameter set.
+ *
+ * Returns a pointer to the parameter set parameters if successful.
+ * Returns NULL if the parameter set cannot be found.
+ */
+
+extern NTRU_ENCRYPT_PARAM_SET *
+ntru_encrypt_get_params_with_id(
+ NTRU_ENCRYPT_PARAM_SET_ID id); /* in - parameter-set id */
+
+
+/* ntru_encrypt_get_params_with_OID
+ *
+ * Looks up a set of NTRU Encrypt parameters based on the OID of the
+ * parameter set.
+ *
+ * Returns a pointer to the parameter set parameters if successful.
+ * Returns NULL if the parameter set cannot be found.
+ */
+
+extern NTRU_ENCRYPT_PARAM_SET *
+ntru_encrypt_get_params_with_OID(
+ uint8_t const *oid); /* in - pointer to parameter-set OID */
+
+#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H */
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c
new file mode 100644
index 000000000..8e4eede87
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.c
@@ -0,0 +1,242 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_poly.c is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "ntru_crypto_ntru_poly.h"
+
+/* ntru_poly_check_min_weight
+ *
+ * Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
+ * a minimum weight.
+ */
+
+bool
+ntru_poly_check_min_weight(
+ uint16_t num_els, /* in - degree of polynomial */
+ uint8_t *ringels, /* in - pointer to trinary ring elements */
+ uint16_t min_wt) /* in - minimum weight */
+{
+ uint16_t wt[3];
+ uint16_t i;
+
+ wt[0] = wt[1] = wt[2] = 0;
+ for (i = 0; i < num_els; i++) {
+ ++wt[ringels[i]];
+ }
+ if ((wt[0] < min_wt) || (wt[1] < min_wt) || (wt[2] < min_wt)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* ntru_ring_mult_coefficients
+ *
+ * Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
+ * to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
+ * This is a convolution operation.
+ *
+ * Ring element "b" has coefficients in the range [0,N).
+ *
+ * This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
+ * beyond 16 bits does not matter.
+ */
+
+void
+ntru_ring_mult_coefficients(
+ uint16_t const *a, /* in - pointer to polynomial a */
+ uint16_t const *b, /* in - pointer to polynomial b */
+ uint16_t N, /* in - no. of coefficients in a, b, c */
+ uint16_t q, /* in - large modulus */
+ uint16_t *c) /* out - address for polynomial c */
+{
+ uint16_t const *bptr = b;
+ uint16_t mod_q_mask = q - 1;
+ uint16_t i, k;
+
+ /* c[k] = sum(a[i] * b[k-i]) mod q */
+ memset(c, 0, N * sizeof(uint16_t));
+ for (k = 0; k < N; k++) {
+ i = 0;
+ while (i <= k)
+ c[k] += a[i++] * *bptr--;
+ bptr += N;
+ while (i < N)
+ c[k] += a[i++] * *bptr--;
+ c[k] &= mod_q_mask;
+ ++bptr;
+ }
+}
+
+
+/* ntru_ring_inv
+ *
+ * Finds the inverse of a polynomial, a, in (Z/2^rZ)[X]/(X^N - 1).
+ *
+ * This assumes q is 2^r where 8 < r < 16, so that operations mod q can
+ * wait until the end, and only 16-bit arrays need to be used.
+ */
+
+bool
+ntru_ring_inv(
+ uint16_t *a, /* in - pointer to polynomial a */
+ uint16_t N, /* in - no. of coefficients in a */
+ uint16_t q, /* in - large modulus */
+ uint16_t *t, /* in - temp buffer of 2N elements */
+ uint16_t *a_inv) /* out - address for polynomial a^-1 */
+{
+ uint8_t *b = (uint8_t *)t; /* b cannot be in a_inv since it must be
+ rotated and copied there as a^-1 mod 2 */
+ uint8_t *c = b + N; /* c cannot be in a_inv since it exchanges
+ with b, and b cannot be in a_inv */
+ uint8_t *f = c + N;
+ uint8_t *g = (uint8_t *)a_inv; /* g needs N + 1 bytes */
+ uint16_t *t2 = t + N;
+ uint16_t deg_b;
+ uint16_t deg_c;
+ uint16_t deg_f;
+ uint16_t deg_g;
+ uint16_t k = 0;
+ bool done = FALSE;
+ uint16_t i, j;
+
+ /* form a^-1 in (Z/2Z)[X]/X^N - 1) */
+ memset(b, 0, (N << 1)); /* clear to init b, c */
+
+ /* b(X) = 1 */
+ b[0] = 1;
+ deg_b = 0;
+
+ /* c(X) = 0 (cleared above) */
+ deg_c = 0;
+
+ /* f(X) = a(X) mod 2 */
+ for (i = 0; i < N; i++)
+ f[i] = (uint8_t)(a[i] & 1);
+ deg_f = N - 1;
+
+ /* g(X) = X^N - 1 */
+ g[0] = 1;
+ memset(g + 1, 0, N - 1);
+ g[N] = 1;
+ deg_g = N;
+
+ /* until f(X) = 1 */
+
+ while (!done)
+ {
+
+ /* while f[0] = 0, f(X) /= X, c(X) *= X, k++ */
+
+ for (i = 0; (i <= deg_f) && (f[i] == 0); ++i);
+ if (i > deg_f)
+ return FALSE;
+ if (i) {
+ f = f + i;
+ deg_f = deg_f - i;
+ deg_c = deg_c + i;
+ for (j = deg_c; j >= i; j--)
+ c[j] = c[j-i];
+ for (j = 0; j < i; j++)
+ c[j] = 0;
+ k = k + i;
+ }
+
+ /* adjust degree of f(X) if the highest coefficients are zero
+ * Note: f[0] = 1 from above so the loop will terminate.
+ */
+
+ while (f[deg_f] == 0)
+ --deg_f;
+
+ /* if f(X) = 1, done
+ * Note: f[0] = 1 from above, so only check the x term and up
+ */
+
+ for (i = 1; (i <= deg_f) && (f[i] == 0); ++i);
+ if (i > deg_f) {
+ done = TRUE;
+ break;
+ }
+
+ /* if deg_f < deg_g, f <-> g, b <-> c */
+
+ if (deg_f < deg_g) {
+ uint8_t *x;
+
+ x = f;
+ f = g;
+ g = x;
+ deg_f ^= deg_g;
+ deg_g ^= deg_f;
+ deg_f ^= deg_g;
+ x = b;
+ b = c;
+ c = x;
+ deg_b ^= deg_c;
+ deg_c ^= deg_b;
+ deg_b ^= deg_c;
+ }
+
+ /* f(X) += g(X), b(X) += c(X) */
+
+ for (i = 0; i <= deg_g; i++)
+ f[i] ^= g[i];
+
+ if (deg_c > deg_b)
+ deg_b = deg_c;
+ for (i = 0; i <= deg_c; i++)
+ b[i] ^= c[i];
+ }
+
+ /* a^-1 in (Z/2Z)[X]/(X^N - 1) = b(X) shifted left k coefficients */
+
+ j = 0;
+ if (k >= N)
+ k = k - N;
+ for (i = k; i < N; i++)
+ a_inv[j++] = (uint16_t)(b[i]);
+ for (i = 0; i < k; i++)
+ a_inv[j++] = (uint16_t)(b[i]);
+
+ /* lift a^-1 in (Z/2Z)[X]/(X^N - 1) to a^-1 in (Z/qZ)[X]/(X^N -1) */
+
+ for (j = 0; j < 4; ++j) { /* assumes 256 < q <= 65536 */
+
+ /* a^-1 = a^-1 * (2 - a * a^-1) mod q */
+
+ memcpy(t2, a_inv, N * sizeof(uint16_t));
+ ntru_ring_mult_coefficients(a, t2, N, q, t);
+ for (i = 0; i < N; ++i)
+ t[i] = q - t[i];
+ t[0] = t[0] + 2;
+ ntru_ring_mult_coefficients(t2, t, N, q, a_inv);
+ }
+
+ return TRUE;
+
+
+}
+
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h
new file mode 100644
index 000000000..1e9d467ed
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_crypto/ntru_crypto_ntru_poly.h
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * NTRU Cryptography Reference Source Code
+ * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
+ *
+ * ntru_crypto_ntru_poly.h is a component of ntru-crypto.
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * File: ntru_crypto_ntru_poly.h
+ *
+ * Contents: Public header file for generating and operating on polynomials
+ * in the NTRU algorithm.
+ *
+ *****************************************************************************/
+
+
+#ifndef NTRU_CRYPTO_NTRU_POLY_H
+#define NTRU_CRYPTO_NTRU_POLY_H
+
+
+#include "ntru_crypto.h"
+
+#include <crypto/hashers/hasher.h>
+
+
+/* function declarations */
+
+/* ntru_poly_check_min_weight
+ *
+ * Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
+ * a minimum weight.
+ */
+
+extern bool
+ntru_poly_check_min_weight(
+ uint16_t num_els, /* in - degree of polynomial */
+ uint8_t *ringels, /* in - pointer to trinary ring elements */
+ uint16_t min_wt); /* in - minimum weight */
+
+/* ntru_ring_mult_coefficients
+ *
+ * Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
+ * to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
+ * This is a convolution operation.
+ *
+ * Ring element "b" has coefficients in the range [0,N).
+ *
+ * This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
+ * beyond 16 bits does not matter.
+ */
+
+extern void
+ntru_ring_mult_coefficients(
+ uint16_t const *a, /* in - pointer to polynomial a */
+ uint16_t const *b, /* in - pointer to polynomial b */
+ uint16_t N, /* in - no. of coefficients in a, b, c */
+ uint16_t q, /* in - large modulus */
+ uint16_t *c); /* out - address for polynomial c */
+
+
+/* ntru_ring_inv
+ *
+ * Finds the inverse of a polynomial, a, in (Z/2^rZ)[X]/(X^N - 1).
+ *
+ * This assumes q is 2^r where 8 < r < 16, so that operations mod q can
+ * wait until the end, and only 16-bit arrays need to be used.
+ */
+
+extern bool
+ntru_ring_inv(
+ uint16_t *a, /* in - pointer to polynomial a */
+ uint16_t N, /* in - no. of coefficients in a */
+ uint16_t q, /* in - large modulus */
+ uint16_t *t, /* in - temp buffer of 2N elements */
+ uint16_t *a_inv); /* out - address for polynomial a^-1 */
+
+
+#endif /* NTRU_CRYPTO_NTRU_POLY_H */
diff --git a/src/libstrongswan/plugins/ntru/ntru_drbg.c b/src/libstrongswan/plugins/ntru/ntru_drbg.c
new file mode 100644
index 000000000..181a58939
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_drbg.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_drbg.h"
+
+#include <utils/debug.h>
+#include <utils/test.h>
+
+#define MAX_STRENGTH_BITS 256
+#define MAX_DRBG_REQUESTS 0xfffffffe
+
+typedef struct private_ntru_drbg_t private_ntru_drbg_t;
+
+/**
+ * Private data of an ntru_drbg_t object.
+ */
+struct private_ntru_drbg_t {
+ /**
+ * Public ntru_drbg_t interface.
+ */
+ ntru_drbg_t public;
+
+ /**
+ * Security strength in bits of the DRBG
+ */
+ u_int32_t strength;
+
+ /**
+ * Number of requests for pseudorandom bits
+ */
+ u_int32_t reseed_counter;
+
+ /**
+ * Maximum number of requests for pseudorandom bits
+ */
+ u_int32_t max_requests;
+
+ /**
+ * True entropy source
+ */
+ rng_t *entropy;
+
+ /**
+ * HMAC-SHA256
+ */
+ signer_t *hmac;
+
+ /**
+ * Internal state of HMAC-SHA256: key
+ */
+ chunk_t key;
+
+ /**
+ * Internal state of HMAC-SHA256: value
+ */
+ chunk_t value;
+
+};
+
+/**
+ * Update the internal state of the HMAC_DRBG
+ */
+static bool update(private_ntru_drbg_t *this, chunk_t data)
+{
+ chunk_t ch_00 = chunk_from_chars(0x00);
+ chunk_t ch_01 = chunk_from_chars(0x01);
+
+ if (!this->hmac->set_key(this->hmac, this->key) ||
+ !this->hmac->get_signature(this->hmac, this->value, NULL) ||
+ !this->hmac->get_signature(this->hmac, ch_00, NULL) ||
+ !this->hmac->get_signature(this->hmac, data, this->key.ptr) ||
+ !this->hmac->set_key(this->hmac, this->key) ||
+ !this->hmac->get_signature(this->hmac, this->value,
+ this->value.ptr))
+ {
+ return FALSE;
+ }
+
+ if (data.len > 0)
+ {
+ if (!this->hmac->set_key(this->hmac, this->key) ||
+ !this->hmac->get_signature(this->hmac, this->value, NULL) ||
+ !this->hmac->get_signature(this->hmac, ch_01, NULL) ||
+ !this->hmac->get_signature(this->hmac, data, this->key.ptr) ||
+ !this->hmac->set_key(this->hmac, this->key) ||
+ !this->hmac->get_signature(this->hmac, this->value,
+ this->value.ptr))
+ {
+ return FALSE;
+ }
+ }
+ DBG4(DBG_LIB, "HMAC_DRBG V: %B", &this->value);
+ DBG4(DBG_LIB, "HMAC_DRBG K: %B", &this->key);
+
+ return TRUE;
+}
+
+METHOD(ntru_drbg_t, get_strength, u_int32_t,
+ private_ntru_drbg_t *this)
+{
+ return this->strength;
+}
+
+METHOD(ntru_drbg_t, reseed, bool,
+ private_ntru_drbg_t *this)
+{
+ chunk_t seed;
+
+ seed = chunk_alloc(this->strength / BITS_PER_BYTE);
+ DBG2(DBG_LIB, "DRBG requests %u bytes of entropy", seed.len);
+
+ if (!this->entropy->get_bytes(this->entropy, seed.len, seed.ptr))
+ {
+ chunk_free(&seed);
+ return FALSE;
+ }
+ if (!update(this, seed))
+ {
+ chunk_free(&seed);
+ return FALSE;
+ }
+ chunk_clear(&seed);
+ this->reseed_counter = 1;
+
+ return TRUE;
+}
+
+METHOD(ntru_drbg_t, generate, bool,
+ private_ntru_drbg_t *this, u_int32_t strength, u_int32_t len, u_int8_t *out)
+{
+ size_t delta;
+ chunk_t output;
+
+ DBG2(DBG_LIB, "DRBG generates %u pseudorandom bytes", len);
+ if (!out || len == 0)
+ {
+ return FALSE;
+ }
+ output = chunk_create(out, len);
+
+ if (this->reseed_counter > this->max_requests)
+ {
+ if (!reseed(this))
+ {
+ return FALSE;
+ }
+ }
+ while (len)
+ {
+ if (!this->hmac->get_signature(this->hmac, this->value,
+ this->value.ptr))
+ {
+ return FALSE;
+ }
+ delta = min(len, this->value.len);
+ memcpy(out, this->value.ptr, delta);
+ len -= delta;
+ out += delta;
+ }
+ DBG4(DBG_LIB, "HMAC_DRBG Out: %B", &output);
+
+ if (!update(this, chunk_empty))
+ {
+ return FALSE;
+ }
+ this->reseed_counter++;
+
+ return TRUE;
+}
+
+METHOD(ntru_drbg_t, destroy, void,
+ private_ntru_drbg_t *this)
+{
+ this->hmac->destroy(this->hmac);
+ chunk_clear(&this->key);
+ chunk_clear(&this->value);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
+ rng_t *entropy)
+{
+ private_ntru_drbg_t *this;
+ chunk_t seed;
+ signer_t *hmac;
+ size_t entropy_len;
+ u_int32_t max_requests;
+
+ if (strength > MAX_STRENGTH_BITS)
+ {
+ return NULL;
+ }
+ if (strength <= 112)
+ {
+ strength = 112;
+ }
+ else if (strength <= 128)
+ {
+ strength = 128;
+ }
+ else if (strength <= 192)
+ {
+ strength = 192;
+ }
+ else
+ {
+ strength = 256;
+ }
+
+ hmac = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA2_256_256);
+ if (!hmac)
+ {
+ DBG1(DBG_LIB, "could not instantiate HMAC-SHA256");
+ return NULL;
+ }
+
+ max_requests = lib->settings->get_int(lib->settings,
+ "%s.plugins.ntru.max_drbg_requests",
+ MAX_DRBG_REQUESTS, lib->ns);
+
+ INIT(this,
+ .public = {
+ .get_strength = _get_strength,
+ .reseed = _reseed,
+ .generate = _generate,
+ .destroy = _destroy,
+ },
+ .strength = strength,
+ .entropy = entropy,
+ .hmac = hmac,
+ .key = chunk_alloc(hmac->get_key_size(hmac)),
+ .value = chunk_alloc(hmac->get_block_size(hmac)),
+ .max_requests = max_requests,
+ .reseed_counter = 1,
+ );
+
+ memset(this->key.ptr, 0x00, this->key.len);
+ memset(this->value.ptr, 0x01, this->value.len);
+
+ entropy_len = (strength + strength/2) / BITS_PER_BYTE;
+ seed = chunk_alloc(entropy_len + pers_str.len);
+ DBG2(DBG_LIB, "DRBG requests %u bytes of entropy", entropy_len);
+
+ if (!this->entropy->get_bytes(this->entropy, entropy_len, seed.ptr))
+ {
+ chunk_free(&seed);
+ destroy(this);
+ return NULL;
+ }
+ memcpy(seed.ptr + entropy_len, pers_str.ptr, pers_str.len);
+ DBG4(DBG_LIB, "seed: %B", &seed);
+
+ if (!update(this, seed))
+ {
+ chunk_free(&seed);
+ destroy(this);
+ return NULL;
+ }
+ chunk_clear(&seed);
+
+ return &this->public;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create);
diff --git a/src/libstrongswan/plugins/ntru/ntru_drbg.h b/src/libstrongswan/plugins/ntru/ntru_drbg.h
new file mode 100644
index 000000000..38ac718ae
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_drbg.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_drbg ntru_drbg
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_DRBG_H_
+#define NTRU_DRBG_H_
+
+typedef struct ntru_drbg_t ntru_drbg_t;
+
+#include <library.h>
+
+/**
+ * Implements a HMAC Deterministic Random Bit Generator (HMAC_DRBG)
+ * compliant with NIST SP 800-90A
+ */
+struct ntru_drbg_t {
+
+ /**
+ * Reseed the instantiated DRBG
+ *
+ * @return configured security strength in bits
+ */
+ u_int32_t (*get_strength)(ntru_drbg_t *this);
+
+ /**
+ * Reseed the instantiated DRBG
+ *
+ * @return TRUE if successful
+ */
+ bool (*reseed)(ntru_drbg_t *this);
+
+ /**
+ * Generate pseudorandom bytes.
+ * If the maximum number of requests has been reached, reseeding occurs
+ *
+ * @param strength requested security strength in bits
+ * @param len number of octets to generate
+ * @param out address of output buffer
+ * @return TRUE if successful
+ */
+ bool (*generate)(ntru_drbg_t *this, u_int32_t strength, u_int32_t len,
+ u_int8_t *out);
+
+ /**
+ * Uninstantiate and destroy the DRBG object
+ */
+ void (*destroy)(ntru_drbg_t *this);
+};
+
+/**
+ * Create and instantiate a new DRBG objet.
+ *
+ * @param strength security strength in bits
+ * @param pers_str personalization string
+ * @param entropy entropy source to use
+ */
+ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
+ rng_t *entropy);
+
+#endif /** NTRU_DRBG_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c
new file mode 100644
index 000000000..39fb261cd
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_ke.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_ke.h"
+#include "ntru_drbg.h"
+
+#include "ntru_crypto/ntru_crypto.h"
+
+#include <crypto/diffie_hellman.h>
+#include <utils/debug.h>
+
+typedef struct private_ntru_ke_t private_ntru_ke_t;
+typedef struct param_set_t param_set_t;
+
+/**
+ * Defines an NTRU parameter set by ID or OID
+ */
+struct param_set_t {
+ NTRU_ENCRYPT_PARAM_SET_ID id;
+ char oid[3];
+ char *name;
+};
+
+/* Best bandwidth and speed, no X9.98 compatibility */
+static param_set_t param_sets_optimum[] = {
+ { NTRU_EES401EP2, {0x00, 0x02, 0x10}, "ees401ep2" },
+ { NTRU_EES439EP1, {0x00, 0x03, 0x10}, "ees439ep1" },
+ { NTRU_EES593EP1, {0x00, 0x05, 0x10}, "ees593ep1" },
+ { NTRU_EES743EP1, {0x00, 0x06, 0x10}, "ees743ep1" }
+};
+
+/* X9.98/IEEE 1363.1 parameter sets for best speed */
+static param_set_t param_sets_x9_98_speed[] = {
+ { NTRU_EES659EP1, {0x00, 0x02, 0x06}, "ees659ep1" },
+ { NTRU_EES761EP1, {0x00, 0x03, 0x05}, "ees761ep1" },
+ { NTRU_EES1087EP1, {0x00, 0x05, 0x05}, "ees1087ep1" },
+ { NTRU_EES1499EP1, {0x00, 0x06, 0x05}, "ees1499ep1" }
+};
+
+/* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */
+static param_set_t param_sets_x9_98_bandwidth[] = {
+ { NTRU_EES401EP1, {0x00, 0x02, 0x04}, "ees401ep1" },
+ { NTRU_EES449EP1, {0x00, 0x03, 0x03}, "ees449ep1" },
+ { NTRU_EES677EP1, {0x00, 0x05, 0x03}, "ees677ep1" },
+ { NTRU_EES1087EP2, {0x00, 0x06, 0x03}, "ees1087ep2" }
+};
+
+/* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */
+static param_set_t param_sets_x9_98_balance[] = {
+ { NTRU_EES541EP1, {0x00, 0x02, 0x05}, "ees541ep1" },
+ { NTRU_EES613EP1, {0x00, 0x03, 0x04}, "ees613ep1" },
+ { NTRU_EES887EP1, {0x00, 0x05, 0x04}, "ees887ep1" },
+ { NTRU_EES1171EP1, {0x00, 0x06, 0x04}, "ees1171ep1" }
+};
+
+/**
+ * Private data of an ntru_ke_t object.
+ */
+struct private_ntru_ke_t {
+ /**
+ * Public ntru_ke_t interface.
+ */
+ ntru_ke_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * NTRU Parameter Set
+ */
+ param_set_t *param_set;
+
+ /**
+ * Cryptographical strength in bits of the NTRU Parameter Set
+ */
+ u_int32_t strength;
+
+ /**
+ * NTRU Public Key
+ */
+ chunk_t pub_key;
+
+ /**
+ * NTRU Private Key
+ */
+ chunk_t priv_key;
+
+ /**
+ * NTRU encrypted shared secret
+ */
+ chunk_t ciphertext;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if peer is responder
+ */
+ bool responder;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+
+ /**
+ * True Random Generator
+ */
+ rng_t *entropy;
+
+ /**
+ * Deterministic Random Bit Generator
+ */
+ ntru_drbg_t *drbg;
+};
+
+METHOD(diffie_hellman_t, get_my_public_value, void,
+ private_ntru_ke_t *this, chunk_t *value)
+{
+ uint16_t pub_key_len, priv_key_len;
+
+ *value = chunk_empty;
+
+ if (this->responder)
+ {
+ if (this->ciphertext.len)
+ {
+ *value = chunk_clone(this->ciphertext);
+ }
+ }
+ else
+ {
+ if (this->pub_key.len == 0)
+ {
+ /* determine the NTRU public and private key sizes */
+ if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set->id,
+ &pub_key_len, NULL,
+ &priv_key_len, NULL) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "error determining NTRU public and private key "
+ "sizes");
+ return;
+ }
+ this->pub_key = chunk_alloc(pub_key_len);
+ this->priv_key = chunk_alloc(priv_key_len);
+
+ /* generate a random NTRU public/private key pair */
+ if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set->id,
+ &pub_key_len, this->pub_key.ptr,
+ &priv_key_len, this->priv_key.ptr) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "NTRU keypair generation failed");
+ chunk_free(&this->priv_key);
+ chunk_free(&this->pub_key);
+ return;
+ }
+ DBG3(DBG_LIB, "NTRU public key: %B", &this->pub_key);
+ DBG4(DBG_LIB, "NTRU private key: %B", &this->priv_key);
+ }
+ *value = chunk_clone(this->pub_key);
+ }
+}
+
+METHOD(diffie_hellman_t, get_shared_secret, status_t,
+ private_ntru_ke_t *this, chunk_t *secret)
+{
+ if (!this->computed || !this->shared_secret.len)
+ {
+ *secret = chunk_empty;
+ return FAILED;
+ }
+ *secret = chunk_clone(this->shared_secret);
+
+ return SUCCESS;
+}
+
+
+METHOD(diffie_hellman_t, set_other_public_value, void,
+ private_ntru_ke_t *this, chunk_t value)
+{
+ u_int16_t plaintext_len, ciphertext_len;
+
+ if (this->priv_key.len)
+ {
+ /* initiator decrypting shared secret */
+ if (value.len == 0)
+ {
+ DBG1(DBG_LIB, "empty NTRU ciphertext");
+ return;
+ }
+ this->ciphertext = chunk_clone(value);
+ DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
+
+ /* determine the size of the maximum plaintext */
+ if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr,
+ this->ciphertext.len, this->ciphertext.ptr,
+ &plaintext_len, NULL) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "error determining maximum plaintext size");
+ return;
+ }
+ this->shared_secret = chunk_alloc(plaintext_len);
+
+ /* decrypt the shared secret */
+ if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr,
+ this->ciphertext.len, this->ciphertext.ptr,
+ &plaintext_len, this->shared_secret.ptr) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
+ chunk_free(&this->shared_secret);
+ return;
+ }
+ this->shared_secret.len = plaintext_len;
+ this->computed = TRUE;
+ }
+ else
+ {
+ /* responder generating and encrypting the shared secret */
+ this->responder = TRUE;
+
+ /* check the NTRU public key format */
+ if (value.len < 5 || value.ptr[0] != 1 || value.ptr[1] != 3)
+ {
+ DBG1(DBG_LIB, "received NTRU public key with invalid header");
+ return;
+ }
+ if (!memeq(value.ptr + 2, this->param_set->oid, 3))
+ {
+ DBG1(DBG_LIB, "received NTRU public key with wrong OID");
+ return;
+ }
+ this->pub_key = chunk_clone(value);
+
+ /* shared secret size is chosen as twice the cryptographical strength */
+ this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
+
+ /* generate the random shared secret */
+ if (!this->drbg->generate(this->drbg, this->strength,
+ this->shared_secret.len, this->shared_secret.ptr))
+ {
+ DBG1(DBG_LIB, "generation of shared secret failed");
+ chunk_free(&this->shared_secret);
+ return;
+ }
+ this->computed = TRUE;
+
+ /* determine the size of the ciphertext */
+ if (ntru_crypto_ntru_encrypt(this->drbg,
+ this->pub_key.len, this->pub_key.ptr,
+ this->shared_secret.len, this->shared_secret.ptr,
+ &ciphertext_len, NULL) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "error determining ciphertext size");
+ return;
+ }
+ this->ciphertext = chunk_alloc(ciphertext_len);
+
+ /* encrypt the shared secret */
+ if (ntru_crypto_ntru_encrypt(this->drbg,
+ this->pub_key.len, this->pub_key.ptr,
+ this->shared_secret.len, this->shared_secret.ptr,
+ &ciphertext_len, this->ciphertext.ptr) != NTRU_OK)
+ {
+ DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
+ chunk_free(&this->ciphertext);
+ return;
+ }
+ DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
+ }
+}
+
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ private_ntru_ke_t *this)
+{
+ return this->group;
+}
+
+METHOD(diffie_hellman_t, destroy, void,
+ private_ntru_ke_t *this)
+{
+ this->drbg->destroy(this->drbg);
+ this->entropy->destroy(this->entropy);
+ chunk_free(&this->pub_key);
+ chunk_free(&this->ciphertext);
+ chunk_clear(&this->priv_key);
+ chunk_clear(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
+{
+ private_ntru_ke_t *this;
+ param_set_t *param_sets, *param_set;
+ rng_t *entropy;
+ ntru_drbg_t *drbg;
+ char *parameter_set;
+ u_int32_t strength;
+
+ parameter_set = lib->settings->get_str(lib->settings,
+ "%s.plugins.ntru.parameter_set", "optimum", lib->ns);
+
+ if (streq(parameter_set, "x9_98_speed"))
+ {
+ param_sets = param_sets_x9_98_speed;
+ }
+ else if (streq(parameter_set, "x9_98_bandwidth"))
+ {
+ param_sets = param_sets_x9_98_bandwidth;
+ }
+ else if (streq(parameter_set, "x9_98_balance"))
+ {
+ param_sets = param_sets_x9_98_balance;
+ }
+ else
+ {
+ param_sets = param_sets_optimum;
+ }
+
+ switch (group)
+ {
+ case NTRU_112_BIT:
+ strength = 112;
+ param_set = &param_sets[0];
+ break;
+ case NTRU_128_BIT:
+ strength = 128;
+ param_set = &param_sets[1];
+ break;
+ case NTRU_192_BIT:
+ strength = 192;
+ param_set = &param_sets[2];
+ break;
+ case NTRU_256_BIT:
+ strength = 256;
+ param_set = &param_sets[3];
+ break;
+ default:
+ return NULL;
+ }
+ DBG1(DBG_LIB, "%u bit %s NTRU parameter set %s selected", strength,
+ parameter_set, param_set->name);
+
+ entropy = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
+ if (!entropy)
+ {
+ DBG1(DBG_LIB, "could not attach entropy source for DRBG");
+ return NULL;
+ }
+
+ drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy);
+ if (!drbg)
+ {
+ DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
+ entropy->destroy(entropy);
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .dh = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ },
+ },
+ .group = group,
+ .param_set = param_set,
+ .strength = strength,
+ .entropy = entropy,
+ .drbg = drbg,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.h b/src/libstrongswan/plugins/ntru/ntru_ke.h
new file mode 100644
index 000000000..b8bbf5e54
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_ke.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_ke ntru_ke
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_KE_H_
+#define NTRU_KE_H_
+
+typedef struct ntru_ke_t ntru_ke_t;
+
+#include <library.h>
+
+/**
+ * Implementation of a key exchange algorithm using NTRU encryption
+ */
+struct ntru_ke_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new ntru_ke_t object.
+ *
+ * @param group NTRU group number to use
+ * @param g not used
+ * @param p not used
+ * @return ntru_ke_t object, NULL if not supported
+ */
+ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p);
+
+#endif /** NTRU_KE_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.c b/src/libstrongswan/plugins/ntru/ntru_mgf1.c
new file mode 100644
index 000000000..2338db208
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_mgf1.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_mgf1.h"
+
+#include <crypto/hashers/hasher.h>
+#include <utils/debug.h>
+#include <utils/test.h>
+
+typedef struct private_ntru_mgf1_t private_ntru_mgf1_t;
+
+/**
+ * Private data of an ntru_mgf1_t object.
+ */
+struct private_ntru_mgf1_t {
+
+ /**
+ * Public ntru_mgf1_t interface.
+ */
+ ntru_mgf1_t public;
+
+ /**
+ * Hasher the MGF1 Mask Generation Function is based on
+ */
+ hasher_t *hasher;
+
+ /**
+ * Counter
+ */
+ u_int32_t counter;
+
+ /**
+ * Set if counter has reached 2^32
+ */
+ bool overflow;
+
+ /**
+ * Current state to be hashed
+ */
+ chunk_t state;
+
+ /**
+ * Position of the 4 octet counter string
+ */
+ u_char *ctr_str;
+
+};
+
+METHOD(ntru_mgf1_t, get_hash_size, size_t,
+ private_ntru_mgf1_t *this)
+{
+ return this->hasher->get_hash_size(this->hasher);
+}
+
+METHOD(ntru_mgf1_t, get_mask, bool,
+ private_ntru_mgf1_t *this, size_t mask_len, u_char *mask)
+{
+ u_char buf[HASH_SIZE_SHA512];
+ size_t hash_len;
+
+ hash_len = this->hasher->get_hash_size(this->hasher);
+
+ while (mask_len > 0)
+ {
+ /* detect overflow, set counter string and increment counter */
+ if (this->overflow)
+ {
+ return FALSE;
+ }
+ htoun32(this->ctr_str, this->counter++);
+ if (this->counter == 0)
+ {
+ this->overflow = TRUE;
+ }
+
+ /* get the next or final mask block from the hash function */
+ if (!this->hasher->get_hash(this->hasher, this->state,
+ (mask_len < hash_len) ? buf : mask))
+ {
+ return FALSE;
+ }
+ if (mask_len < hash_len)
+ {
+ memcpy(mask, buf, mask_len);
+ return TRUE;
+ }
+ mask_len -= hash_len;
+ mask += hash_len;
+ }
+ return TRUE;
+}
+
+METHOD(ntru_mgf1_t, allocate_mask, bool,
+ private_ntru_mgf1_t *this, size_t mask_len, chunk_t *mask)
+{
+ if (mask_len == 0)
+ {
+ *mask = chunk_empty;
+ return TRUE;
+ }
+ *mask = chunk_alloc(mask_len);
+
+ return get_mask(this, mask_len, mask->ptr);
+}
+
+METHOD(ntru_mgf1_t, destroy, void,
+ private_ntru_mgf1_t *this)
+{
+ this->hasher->destroy(this->hasher);
+ chunk_clear(&this->state);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
+ bool hash_seed)
+{
+ private_ntru_mgf1_t *this;
+ hasher_t *hasher;
+ size_t state_len;
+
+ if (seed.len == 0)
+ {
+ DBG1(DBG_LIB, "empty seed for MGF1");
+ return NULL;
+ }
+
+ hasher = lib->crypto->create_hasher(lib->crypto, alg);
+ if (!hasher)
+ {
+ DBG1(DBG_LIB, "failed to create %N hasher for MGF1",
+ hash_algorithm_names, alg);
+ return NULL;
+ }
+ state_len = (hash_seed ? hasher->get_hash_size(hasher) : seed.len) + 4;
+
+ INIT(this,
+ .public = {
+ .get_hash_size = _get_hash_size,
+ .allocate_mask = _allocate_mask,
+ .get_mask = _get_mask,
+ .destroy = _destroy,
+ },
+ .hasher = hasher,
+ .state = chunk_alloc(state_len),
+ );
+
+ /* determine position of the 4 octet counter string */
+ this->ctr_str = this->state.ptr + state_len - 4;
+
+ if (hash_seed)
+ {
+ if (!hasher->get_hash(hasher, seed, this->state.ptr))
+ {
+ DBG1(DBG_LIB, "failed to hash seed for MGF1");
+ destroy(this);
+ return NULL;
+ }
+ }
+ else
+ {
+ memcpy(this->state.ptr, seed.ptr, seed.len);
+ }
+
+ return &this->public;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create);
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.h b/src/libstrongswan/plugins/ntru/ntru_mgf1.h
new file mode 100644
index 000000000..53e90412a
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_mgf1.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_mgf1 ntru_mgf1
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_MGF1_H_
+#define NTRU_MGF1_H_
+
+typedef struct ntru_mgf1_t ntru_mgf1_t;
+
+#include <library.h>
+
+/**
+ * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function
+ * defined in section 10.2.1 of RFC 2437
+ */
+struct ntru_mgf1_t {
+
+ /**
+ * Get the hash size of the underlying hash function
+ *
+ * @return hash size in bytes
+ */
+ size_t (*get_hash_size)(ntru_mgf1_t *this);
+
+ /**
+ * Generate a mask pattern and copy it to an output buffer
+ * If the maximum number of requests has been reached, reseeding occurs
+ *
+ * @param mask_len number of mask bytes to generate
+ * @param mask output buffer of minimum size mask_len
+ * @return TRUE if successful
+ */
+ bool (*get_mask)(ntru_mgf1_t *this, size_t mask_len, u_char *mask);
+
+ /**
+ * Generate a mask pattern and return it in an allocated chunk
+ *
+ * @param mask_len number of mask bytes to generate
+ * @param mask chunk containing generated mask
+ * @return TRUE if successful
+ */
+ bool (*allocate_mask)(ntru_mgf1_t *this, size_t mask_len, chunk_t *mask);
+
+ /**
+ * Destroy the MGF1 object
+ */
+ void (*destroy)(ntru_mgf1_t *this);
+};
+
+/**
+ * Create an MGF1 object
+ *
+ * @param alg hash algorithm to be used by MGF1
+ * @param seed seed used by MGF1 to generate mask from
+ * @param hash_seed hash seed before using it as a seed from MGF1
+ */
+ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
+ bool hash_seed);
+
+#endif /** NTRU_MGF1_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_plugin.c b/src/libstrongswan/plugins/ntru/ntru_plugin.c
new file mode 100644
index 000000000..66be7c75b
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_plugin.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_plugin.h"
+#include "ntru_ke.h"
+
+#include <library.h>
+
+typedef struct private_ntru_plugin_t private_ntru_plugin_t;
+
+/**
+ * private data of ntru_plugin
+ */
+struct private_ntru_plugin_t {
+
+ /**
+ * public functions
+ */
+ ntru_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_ntru_plugin_t *this)
+{
+ return "ntru";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_ntru_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(DH, ntru_ke_create),
+ PLUGIN_PROVIDE(DH, NTRU_112_BIT),
+ PLUGIN_PROVIDE(DH, NTRU_128_BIT),
+ PLUGIN_PROVIDE(DH, NTRU_192_BIT),
+ PLUGIN_PROVIDE(DH, NTRU_256_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_TRUE),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA1)
+ };
+ *features = f;
+
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_ntru_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *ntru_plugin_create()
+{
+ private_ntru_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/ntru/ntru_plugin.h b/src/libstrongswan/plugins/ntru/ntru_plugin.h
new file mode 100644
index 000000000..187b83445
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_p ntru
+ * @ingroup plugins
+ *
+ * @defgroup ntru_plugin ntru_plugin
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_PLUGIN_H_
+#define NTRU_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct ntru_plugin_t ntru_plugin_t;
+
+/**
+ * Plugin implementing NTRU-base key exchange
+ */
+struct ntru_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** NTRU_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c
new file mode 100644
index 000000000..3f754f2a0
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_poly.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Copyright (C) 2009-2013 Security Innovation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_poly.h"
+#include "ntru_mgf1.h"
+
+#include <utils/debug.h>
+#include <utils/test.h>
+
+typedef struct private_ntru_poly_t private_ntru_poly_t;
+typedef struct indices_len_t indices_len_t;
+
+/**
+ * Stores number of +1 and -1 coefficients
+ */
+struct indices_len_t {
+ int p;
+ int m;
+};
+
+/**
+ * Private data of an ntru_poly_t object.
+ */
+struct private_ntru_poly_t {
+
+ /**
+ * Public ntru_poly_t interface.
+ */
+ ntru_poly_t public;
+
+ /**
+ * Ring dimension equal to the number of polynomial coefficients
+ */
+ uint16_t N;
+
+ /**
+ * Large modulus
+ */
+ uint16_t q;
+
+ /**
+ * Array containing the indices of the non-zero coefficients
+ */
+ uint16_t *indices;
+
+ /**
+ * Number of indices of the non-zero coefficients
+ */
+ size_t num_indices;
+
+ /**
+ * Number of sparse polynomials
+ */
+ int num_polynomials;
+
+ /**
+ * Number of nonzero coefficients for up to 3 sparse polynomials
+ */
+ indices_len_t indices_len[3];
+
+};
+
+METHOD(ntru_poly_t, get_size, size_t,
+ private_ntru_poly_t *this)
+{
+ return this->num_indices;
+}
+
+METHOD(ntru_poly_t, get_indices, uint16_t*,
+ private_ntru_poly_t *this)
+{
+ return this->indices;
+}
+
+/**
+ * Multiplication of polynomial a with a sparse polynomial b given by
+ * the indices of its +1 and -1 coefficients results in polynomial c.
+ * This is a convolution operation
+ */
+static void ring_mult_i(uint16_t *a, indices_len_t len, uint16_t *indices,
+ uint16_t N, uint16_t mod_q_mask, uint16_t *t,
+ uint16_t *c)
+{
+ int i, j, k;
+
+ /* initialize temporary array t */
+ for (k = 0; k < N; k++)
+ {
+ t[k] = 0;
+ }
+
+ /* t[(i+k)%N] = sum i=0 through N-1 of a[i], for b[k] = -1 */
+ for (j = len.p; j < len.p + len.m; j++)
+ {
+ k = indices[j];
+ for (i = 0; k < N; ++i, ++k)
+ {
+ t[k] += a[i];
+ }
+ for (k = 0; i < N; ++i, ++k)
+ {
+ t[k] += a[i];
+ }
+ }
+
+ /* t[(i+k)%N] = -(sum i=0 through N-1 of a[i] for b[k] = -1) */
+ for (k = 0; k < N; k++)
+ {
+ t[k] = -t[k];
+ }
+
+ /* t[(i+k)%N] += sum i=0 through N-1 of a[i] for b[k] = +1 */
+ for (j = 0; j < len.p; j++)
+ {
+ k = indices[j];
+ for (i = 0; k < N; ++i, ++k)
+ {
+ t[k] += a[i];
+ }
+ for (k = 0; i < N; ++i, ++k)
+ {
+ t[k] += a[i];
+ }
+ }
+
+ /* c = (a * b) mod q */
+ for (k = 0; k < N; k++)
+ {
+ c[k] = t[k] & mod_q_mask;
+ }
+}
+
+METHOD(ntru_poly_t, get_array, void,
+ private_ntru_poly_t *this, uint16_t *array)
+{
+ uint16_t *t, *bi;
+ uint16_t mod_q_mask = this->q - 1;
+ indices_len_t len;
+ int i;
+
+ /* form polynomial F or F1 */
+ memset(array, 0x00, this->N * sizeof(uint16_t));
+ bi = this->indices;
+ len = this->indices_len[0];
+ for (i = 0; i < len.p + len.m; i++)
+ {
+ array[bi[i]] = (i < len.p) ? 1 : mod_q_mask;
+ }
+
+ if (this->num_polynomials == 3)
+ {
+ /* allocate temporary array t */
+ t = malloc(this->N * sizeof(uint16_t));
+
+ /* form F1 * F2 */
+ bi += len.p + len.m;
+ len = this->indices_len[1];
+ ring_mult_i(array, len, bi, this->N, mod_q_mask, t, array);
+
+ /* form (F1 * F2) + F3 */
+ bi += len.p + len.m;
+ len = this->indices_len[2];
+ for (i = 0; i < len.p + len.m; i++)
+ {
+ if (i < len.p)
+ {
+ array[bi[i]] += 1;
+ }
+ else
+ {
+ array[bi[i]] -= 1;
+ }
+ array[bi[i]] &= mod_q_mask;
+ }
+ free(t);
+ }
+}
+
+METHOD(ntru_poly_t, ring_mult, void,
+ private_ntru_poly_t *this, uint16_t *a, uint16_t *c)
+{
+ uint16_t *t1, *t2;
+ uint16_t *bi = this->indices;
+ uint16_t mod_q_mask = this->q - 1;
+ int i;
+
+ /* allocate temporary array t1 */
+ t1 = malloc(this->N * sizeof(uint16_t));
+
+ if (this->num_polynomials == 1)
+ {
+ ring_mult_i(a, this->indices_len[0], bi, this->N, mod_q_mask, t1, c);
+ }
+ else
+ {
+ /* allocate temporary array t2 */
+ t2 = malloc(this->N * sizeof(uint16_t));
+
+ /* t1 = a * b1 */
+ ring_mult_i(a, this->indices_len[0], bi, this->N, mod_q_mask, t1, t1);
+
+ /* t1 = (a * b1) * b2 */
+ bi += this->indices_len[0].p + this->indices_len[0].m;
+ ring_mult_i(t1, this->indices_len[1], bi, this->N, mod_q_mask, t2, t1);
+
+ /* t2 = a * b3 */
+ bi += this->indices_len[1].p + this->indices_len[1].m;
+ ring_mult_i(a, this->indices_len[2], bi, this->N, mod_q_mask, t2, t2);
+
+ /* c = (a * b1 * b2) + (a * b3) */
+ for (i = 0; i < this->N; i++)
+ {
+ c[i] = (t1[i] + t2[i]) & mod_q_mask;
+ }
+ free(t2);
+ }
+ free(t1);
+}
+
+METHOD(ntru_poly_t, destroy, void,
+ private_ntru_poly_t *this)
+{
+ memwipe(this->indices, sizeof(uint16_t) * get_size(this));
+ free(this->indices);
+ free(this);
+}
+
+static void init_indices(private_ntru_poly_t *this, bool is_product_form,
+ uint32_t indices_len_p, uint32_t indices_len_m)
+{
+ int n;
+
+ if (is_product_form)
+ {
+ this->num_polynomials = 3;
+ for (n = 0; n < 3; n++)
+ {
+ this->indices_len[n].p = 0xff & indices_len_p;
+ this->indices_len[n].m = 0xff & indices_len_m;
+ this->num_indices += this->indices_len[n].p +
+ this->indices_len[n].m;
+ indices_len_p >>= 8;
+ indices_len_m >>= 8;
+ }
+ }
+ else
+ {
+ this->num_polynomials = 1;
+ this->indices_len[0].p = indices_len_p;
+ this->indices_len[0].m = indices_len_m;
+ this->num_indices = indices_len_p + indices_len_m;
+ }
+ this->indices = malloc(sizeof(uint16_t) * this->num_indices);
+}
+
+/*
+ * Described in header.
+ */
+ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
+ uint8_t c_bits, uint16_t N, uint16_t q,
+ uint32_t indices_len_p,
+ uint32_t indices_len_m,
+ bool is_product_form)
+{
+ private_ntru_poly_t *this;
+ size_t hash_len, octet_count = 0, i;
+ uint8_t octets[HASH_SIZE_SHA512], *used, num_left = 0, num_needed;
+ uint16_t index, limit, left = 0;
+ int n, num_indices, index_i = 0;
+ ntru_mgf1_t *mgf1;
+
+ DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
+ mgf1 = ntru_mgf1_create(alg, seed, TRUE);
+ if (!mgf1)
+ {
+ return NULL;
+ }
+ i = hash_len = mgf1->get_hash_size(mgf1);
+
+ INIT(this,
+ .public = {
+ .get_size = _get_size,
+ .get_indices = _get_indices,
+ .get_array = _get_array,
+ .ring_mult = _ring_mult,
+ .destroy = _destroy,
+ },
+ .N = N,
+ .q = q,
+ );
+
+ init_indices(this, is_product_form, indices_len_p, indices_len_m);
+ used = malloc(N);
+ limit = N * ((1 << c_bits) / N);
+
+ /* generate indices for all polynomials */
+ for (n = 0; n < this->num_polynomials; n++)
+ {
+ memset(used, 0, N);
+ num_indices = this->indices_len[n].p + this->indices_len[n].m;
+
+ /* generate indices for a single polynomial */
+ while (num_indices)
+ {
+ /* generate a random candidate index with a size of c_bits */
+ do
+ {
+ /* use any leftover bits first */
+ index = num_left ? left << (c_bits - num_left) : 0;
+
+ /* get the rest of the bits needed from new octets */
+ num_needed = c_bits - num_left;
+
+ while (num_needed)
+ {
+ if (i == hash_len)
+ {
+ /* get another block from MGF1 */
+ if (!mgf1->get_mask(mgf1, hash_len, octets))
+ {
+ mgf1->destroy(mgf1);
+ destroy(this);
+ free(used);
+ return NULL;
+ }
+ octet_count += hash_len;
+ i = 0;
+ }
+ left = octets[i++];
+
+ if (num_needed <= 8)
+ {
+ /* all bits needed to fill the index are in this octet */
+ index |= left >> (8 - num_needed);
+ num_left = 8 - num_needed;
+ num_needed = 0;
+ left &= 0xff >> (8 - num_left);
+ }
+ else
+ {
+ /* more than one octet will be needed */
+ index |= left << (num_needed - 8);
+ num_needed -= 8;
+ }
+ }
+ }
+ while (index >= limit);
+
+ /* form index and check if unique */
+ index %= N;
+ if (!used[index])
+ {
+ used[index] = 1;
+ this->indices[index_i++] = index;
+ num_indices--;
+ }
+ }
+ }
+
+ DBG2(DBG_LIB, "MGF1 generates %u octets to derive %u indices",
+ octet_count, this->num_indices);
+ mgf1->destroy(mgf1);
+ free(used);
+
+ return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+ntru_poly_t *ntru_poly_create_from_data(uint16_t *data, uint16_t N, uint16_t q,
+ uint32_t indices_len_p,
+ uint32_t indices_len_m,
+ bool is_product_form)
+{
+ private_ntru_poly_t *this;
+ int i;
+
+ INIT(this,
+ .public = {
+ .get_size = _get_size,
+ .get_indices = _get_indices,
+ .get_array = _get_array,
+ .ring_mult = _ring_mult,
+ .destroy = _destroy,
+ },
+ .N = N,
+ .q = q,
+ );
+
+ init_indices(this, is_product_form, indices_len_p, indices_len_m);
+ for (i = 0; i < this->num_indices; i++)
+ {
+ this->indices[i] = data[i];
+ }
+
+ return &this->public;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_seed);
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_data);
diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.h b/src/libstrongswan/plugins/ntru/ntru_poly.h
new file mode 100644
index 000000000..87c77103c
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_poly.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_poly ntru_poly
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_POLY_H_
+#define NTRU_POLY_H_
+
+typedef struct ntru_poly_t ntru_poly_t;
+
+#include <library.h>
+
+/**
+ * Implements a trinary polynomial storing the indices of non-zero coefficients
+ */
+struct ntru_poly_t {
+
+ /**
+ * Get the size of the indices array
+ *
+ * @return number of indices
+ */
+ size_t (*get_size)(ntru_poly_t *this);
+
+ /**
+ * @return array containing the indices of the non-zero coefficients
+ */
+ uint16_t* (*get_indices)(ntru_poly_t *this);
+
+ /**
+ * @param array array containing all N coefficients of the polynomial
+ */
+ void (*get_array)(ntru_poly_t *this, uint16_t *array);
+
+ /**
+ * Multiply polynomial a with ntru_poly_t object b having sparse coeffients
+ * to form result polynomial c = a * b
+ *
+ * @param a input polynomial a
+ * @param b output polynomial c
+ */
+ void (*ring_mult)(ntru_poly_t *this, uint16_t *a, uint16_t *c);
+
+ /**
+ * Destroy ntru_poly_t object
+ */
+ void (*destroy)(ntru_poly_t *this);
+};
+
+/**
+ * Create a trits polynomial from a seed using MGF1 with a base hash function
+ *
+ * @param alg hash algorithm to be used by MGF1
+ * @param seed seed used by MGF1 to generate trits from
+ * @param N ring dimension, number of polynomial coefficients
+ * @param q large modulus
+ * @param c_bits number of bits for candidate index
+ * @param indices_len_p number of indices for +1 coefficients
+ * @param indices_len_m number of indices for -1 coefficients
+ * @param is_product_form generate multiple polynomials
+ */
+ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
+ uint8_t c_bits, uint16_t N, uint16_t q,
+ uint32_t indices_len_p,
+ uint32_t indices_len_m,
+ bool is_product_form);
+
+/**
+ * Create a trits polynomial from an array of indices of non-zero coefficients
+ *
+ * @param data array of indices of non-zero coefficients
+ * @param N ring dimension, number of polynomial coefficients
+ * @param q large modulus
+ * @param indices_len_p number of indices for +1 coefficients
+ * @param indices_len_m number of indices for -1 coefficients
+ * @param is_product_form generate multiple polynomials
+ */
+ntru_poly_t *ntru_poly_create_from_data(uint16_t *data, uint16_t N, uint16_t q,
+ uint32_t indices_len_p,
+ uint32_t indices_len_m,
+ bool is_product_form);
+
+#endif /** NTRU_POLY_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c
new file mode 100644
index 000000000..f82501629
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_trits.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ntru_trits.h"
+#include "ntru_mgf1.h"
+
+#include "ntru_crypto/ntru_crypto_ntru_convert.h"
+
+#include <utils/debug.h>
+#include <utils/test.h>
+
+typedef struct private_ntru_trits_t private_ntru_trits_t;
+
+/**
+ * Private data of an ntru_trits_t object.
+ */
+struct private_ntru_trits_t {
+
+ /**
+ * Public ntru_trits_t interface.
+ */
+ ntru_trits_t public;
+
+ /**
+ * Size of the trits array
+ */
+ size_t trits_len;
+
+ /**
+ * Array containing a trit per octet
+ */
+ uint8_t *trits;
+
+};
+
+METHOD(ntru_trits_t, get_size, size_t,
+ private_ntru_trits_t *this)
+{
+ return this->trits_len;
+}
+
+METHOD(ntru_trits_t, get_trits, uint8_t*,
+ private_ntru_trits_t *this)
+{
+ return this->trits;
+}
+
+METHOD(ntru_trits_t, destroy, void,
+ private_ntru_trits_t *this)
+{
+ memwipe(this->trits, this->trits_len);
+ free(this->trits);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
+{
+ private_ntru_trits_t *this;
+ uint8_t octets[HASH_SIZE_SHA512], buf[5], *trits;
+ size_t hash_len, octet_count = 0, trits_needed, i;
+ ntru_mgf1_t *mgf1;
+
+ DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
+ mgf1 = ntru_mgf1_create(alg, seed, TRUE);
+ if (!mgf1)
+ {
+ return NULL;
+ }
+ i = hash_len = mgf1->get_hash_size(mgf1);
+
+ INIT(this,
+ .public = {
+ .get_size = _get_size,
+ .get_trits = _get_trits,
+ .destroy = _destroy,
+ },
+ .trits_len = len,
+ .trits = malloc(len),
+ );
+
+ trits = this->trits;
+ trits_needed = this->trits_len;
+
+ while (trits_needed > 0)
+ {
+ if (i == hash_len)
+ {
+ /* get another block from MGF1 */
+ if (!mgf1->get_mask(mgf1, hash_len, octets))
+ {
+ mgf1->destroy(mgf1);
+ destroy(this);
+ return NULL;
+ }
+ octet_count += hash_len;
+ i = 0;
+ }
+ if (octets[i] < 243) /* 243 = 3^5 */
+ {
+ ntru_octet_2_trits(octets[i], (trits_needed < 5) ? buf : trits);
+ if (trits_needed < 5)
+ {
+ memcpy(trits, buf, trits_needed);
+ break;
+ }
+ trits += 5;
+ trits_needed -= 5;
+ }
+ i++;
+ }
+ DBG2(DBG_LIB, "MGF1 generates %u octets to extract %u trits",
+ octet_count, len);
+ mgf1->destroy(mgf1);
+
+ return &this->public;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create);
diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.h b/src/libstrongswan/plugins/ntru/ntru_trits.h
new file mode 100644
index 000000000..524c51bac
--- /dev/null
+++ b/src/libstrongswan/plugins/ntru/ntru_trits.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ntru_trits ntru_trits
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_TRITS_H_
+#define NTRU_TRITS_H_
+
+typedef struct ntru_trits_t ntru_trits_t;
+
+#include <library.h>
+
+/**
+ * Implements an array of trinary elements (trits)
+ */
+struct ntru_trits_t {
+
+ /**
+ * Get the size of the trits array
+ *
+ * @return number of trinary elements
+ */
+ size_t (*get_size)(ntru_trits_t *this);
+
+ /**
+ * @return octet array containing a trit per octet
+ */
+ uint8_t* (*get_trits)(ntru_trits_t *this);
+
+ /**
+ * Destroy ntru_trits_t object
+ */
+ void (*destroy)(ntru_trits_t *this);
+};
+
+/**
+ * Create a trits array from a seed using MGF1 with a base hash function
+ *
+ * @param size size of the trits array
+ * @param alg hash algorithm to be used by MGF1
+ * @param seed seed used by MGF1 to generate trits from
+ */
+ntru_trits_t *ntru_trits_create(size_t size, hash_algorithm_t alg, chunk_t seed);
+
+#endif /** NTRU_TRITS_H_ @}*/
+