From 5ac03256db0fe4ca7e3ad1117d096c3a76368b76 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 9 Jan 2015 09:46:07 +0100 Subject: backported CyaSSL/OpenSSL support for internal webserver instead of MatrixSSL --- release/src/router/cyassl/ctaocrypt/Makefile.am | 3 + release/src/router/cyassl/ctaocrypt/Makefile.in | 503 +++ .../router/cyassl/ctaocrypt/benchmark/Makefile.am | 7 + .../router/cyassl/ctaocrypt/benchmark/Makefile.in | 485 +++ .../router/cyassl/ctaocrypt/benchmark/benchmark.c | 538 +++ .../cyassl/ctaocrypt/benchmark/benchmark.sln | 20 + .../cyassl/ctaocrypt/benchmark/benchmark.vcproj | 195 + .../router/cyassl/ctaocrypt/benchmark/dh1024.der | Bin 0 -> 138 bytes .../router/cyassl/ctaocrypt/benchmark/rsa1024.der | Bin 0 -> 608 bytes release/src/router/cyassl/ctaocrypt/ctaocrypt.sln | 38 + .../src/router/cyassl/ctaocrypt/ctaocrypt.vcproj | 323 ++ release/src/router/cyassl/ctaocrypt/include/arc4.h | 56 + release/src/router/cyassl/ctaocrypt/include/asn.h | 319 ++ .../src/router/cyassl/ctaocrypt/include/coding.h | 47 + .../router/cyassl/ctaocrypt/include/config.h.in | 85 + .../src/router/cyassl/ctaocrypt/include/ctc_aes.h | 84 + .../src/router/cyassl/ctaocrypt/include/ctc_dh.h | 59 + .../src/router/cyassl/ctaocrypt/include/ctc_dsa.h | 61 + .../src/router/cyassl/ctaocrypt/include/ctc_ecc.h | 119 + .../src/router/cyassl/ctaocrypt/include/ctc_hmac.h | 85 + .../src/router/cyassl/ctaocrypt/include/ctc_md4.h | 65 + .../src/router/cyassl/ctaocrypt/include/ctc_md5.h | 62 + .../router/cyassl/ctaocrypt/include/ctc_ripemd.h | 65 + .../src/router/cyassl/ctaocrypt/include/ctc_rsa.h | 74 + .../src/router/cyassl/ctaocrypt/include/ctc_sha.h | 63 + release/src/router/cyassl/ctaocrypt/include/des3.h | 75 + .../src/router/cyassl/ctaocrypt/include/error.h | 106 + .../src/router/cyassl/ctaocrypt/include/hc128.h | 57 + .../src/router/cyassl/ctaocrypt/include/integer.h | 329 ++ release/src/router/cyassl/ctaocrypt/include/misc.h | 55 + .../router/cyassl/ctaocrypt/include/mpi_class.h | 996 +++++ .../cyassl/ctaocrypt/include/mpi_superclass.h | 73 + .../router/cyassl/ctaocrypt/include/os_settings.h | 269 ++ .../src/router/cyassl/ctaocrypt/include/pwdbased.h | 47 + .../src/router/cyassl/ctaocrypt/include/rabbit.h | 60 + .../src/router/cyassl/ctaocrypt/include/random.h | 72 + .../src/router/cyassl/ctaocrypt/include/sha256.h | 69 + .../src/router/cyassl/ctaocrypt/include/sha512.h | 65 + release/src/router/cyassl/ctaocrypt/include/tfm.h | 667 +++ .../src/router/cyassl/ctaocrypt/include/types.h | 198 + .../src/router/cyassl/ctaocrypt/src/Makefile.am | 2 + .../src/router/cyassl/ctaocrypt/src/Makefile.in | 343 ++ release/src/router/cyassl/ctaocrypt/src/aes.c | 1312 ++++++ release/src/router/cyassl/ctaocrypt/src/aes_asm.s | 484 +++ release/src/router/cyassl/ctaocrypt/src/arc4.c | 76 + release/src/router/cyassl/ctaocrypt/src/asm.c | 1302 ++++++ release/src/router/cyassl/ctaocrypt/src/asn.c | 2866 +++++++++++++ release/src/router/cyassl/ctaocrypt/src/coding.c | 229 + release/src/router/cyassl/ctaocrypt/src/des3.c | 493 +++ release/src/router/cyassl/ctaocrypt/src/dh.c | 165 + release/src/router/cyassl/ctaocrypt/src/dsa.c | 216 + release/src/router/cyassl/ctaocrypt/src/ecc.c | 1 + release/src/router/cyassl/ctaocrypt/src/ecc_fp.c | 1 + .../router/cyassl/ctaocrypt/src/fp_mont_small.i | 3838 +++++++++++++++++ .../router/cyassl/ctaocrypt/src/fp_mul_comba_12.i | 108 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_17.i | 148 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_20.i | 172 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_24.i | 204 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_28.i | 236 ++ .../router/cyassl/ctaocrypt/src/fp_mul_comba_3.i | 36 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_32.i | 282 ++ .../router/cyassl/ctaocrypt/src/fp_mul_comba_4.i | 44 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_48.i | 396 ++ .../router/cyassl/ctaocrypt/src/fp_mul_comba_6.i | 60 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_64.i | 524 +++ .../router/cyassl/ctaocrypt/src/fp_mul_comba_7.i | 68 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_8.i | 76 + .../router/cyassl/ctaocrypt/src/fp_mul_comba_9.i | 84 + .../cyassl/ctaocrypt/src/fp_mul_comba_small_set.i | 1225 ++++++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_12.i | 135 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_17.i | 185 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_20.i | 218 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_24.i | 258 ++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_28.i | 298 ++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_3.i | 45 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_32.i | 338 ++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_4.i | 55 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_48.i | 498 +++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_6.i | 75 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_64.i | 658 +++ .../router/cyassl/ctaocrypt/src/fp_sqr_comba_7.i | 85 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_8.i | 95 + .../router/cyassl/ctaocrypt/src/fp_sqr_comba_9.i | 105 + .../cyassl/ctaocrypt/src/fp_sqr_comba_small_set.i | 1515 +++++++ release/src/router/cyassl/ctaocrypt/src/hc128.c | 317 ++ release/src/router/cyassl/ctaocrypt/src/hmac.c | 158 + release/src/router/cyassl/ctaocrypt/src/integer.c | 4359 ++++++++++++++++++++ release/src/router/cyassl/ctaocrypt/src/md4.c | 215 + release/src/router/cyassl/ctaocrypt/src/md5.c | 222 + release/src/router/cyassl/ctaocrypt/src/misc.c | 171 + release/src/router/cyassl/ctaocrypt/src/pwdbased.c | 76 + release/src/router/cyassl/ctaocrypt/src/rabbit.c | 239 ++ release/src/router/cyassl/ctaocrypt/src/random.c | 182 + release/src/router/cyassl/ctaocrypt/src/ripemd.c | 347 ++ release/src/router/cyassl/ctaocrypt/src/rsa.c | 536 +++ release/src/router/cyassl/ctaocrypt/src/sha.c | 198 + release/src/router/cyassl/ctaocrypt/src/sha256.c | 206 + release/src/router/cyassl/ctaocrypt/src/sha512.c | 242 ++ release/src/router/cyassl/ctaocrypt/src/tfm.c | 2430 +++++++++++ .../src/router/cyassl/ctaocrypt/test/Makefile.am | 7 + .../src/router/cyassl/ctaocrypt/test/Makefile.in | 485 +++ release/src/router/cyassl/ctaocrypt/test/test.c | 1783 ++++++++ release/src/router/cyassl/ctaocrypt/test/test.sln | 20 + .../src/router/cyassl/ctaocrypt/test/test.vcproj | 195 + 104 files changed, 38436 insertions(+) create mode 100644 release/src/router/cyassl/ctaocrypt/Makefile.am create mode 100644 release/src/router/cyassl/ctaocrypt/Makefile.in create mode 100644 release/src/router/cyassl/ctaocrypt/benchmark/Makefile.am create mode 100644 release/src/router/cyassl/ctaocrypt/benchmark/Makefile.in create mode 100644 release/src/router/cyassl/ctaocrypt/benchmark/benchmark.c create mode 100755 release/src/router/cyassl/ctaocrypt/benchmark/benchmark.sln create mode 100755 release/src/router/cyassl/ctaocrypt/benchmark/benchmark.vcproj create mode 100644 release/src/router/cyassl/ctaocrypt/benchmark/dh1024.der create mode 100644 release/src/router/cyassl/ctaocrypt/benchmark/rsa1024.der create mode 100755 release/src/router/cyassl/ctaocrypt/ctaocrypt.sln create mode 100755 release/src/router/cyassl/ctaocrypt/ctaocrypt.vcproj create mode 100644 release/src/router/cyassl/ctaocrypt/include/arc4.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/asn.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/coding.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/config.h.in create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_aes.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_dh.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_dsa.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_ecc.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_hmac.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_md4.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_md5.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_ripemd.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_rsa.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/ctc_sha.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/des3.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/error.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/hc128.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/integer.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/misc.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/mpi_class.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/mpi_superclass.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/os_settings.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/pwdbased.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/rabbit.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/random.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/sha256.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/sha512.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/tfm.h create mode 100644 release/src/router/cyassl/ctaocrypt/include/types.h create mode 100644 release/src/router/cyassl/ctaocrypt/src/Makefile.am create mode 100644 release/src/router/cyassl/ctaocrypt/src/Makefile.in create mode 100644 release/src/router/cyassl/ctaocrypt/src/aes.c create mode 100755 release/src/router/cyassl/ctaocrypt/src/aes_asm.s create mode 100644 release/src/router/cyassl/ctaocrypt/src/arc4.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/asm.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/asn.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/coding.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/des3.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/dh.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/dsa.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/ecc.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/ecc_fp.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mont_small.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_12.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_17.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_20.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_24.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_28.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_3.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_32.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_4.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_48.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_6.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_64.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_7.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_8.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_9.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_small_set.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_12.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_17.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_20.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_24.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_28.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_3.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_32.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_4.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_48.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_6.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_64.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_7.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_8.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_9.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_small_set.i create mode 100644 release/src/router/cyassl/ctaocrypt/src/hc128.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/hmac.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/integer.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/md4.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/md5.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/misc.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/pwdbased.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/rabbit.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/random.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/ripemd.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/rsa.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/sha.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/sha256.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/sha512.c create mode 100644 release/src/router/cyassl/ctaocrypt/src/tfm.c create mode 100644 release/src/router/cyassl/ctaocrypt/test/Makefile.am create mode 100644 release/src/router/cyassl/ctaocrypt/test/Makefile.in create mode 100644 release/src/router/cyassl/ctaocrypt/test/test.c create mode 100755 release/src/router/cyassl/ctaocrypt/test/test.sln create mode 100755 release/src/router/cyassl/ctaocrypt/test/test.vcproj (limited to 'release/src/router/cyassl/ctaocrypt') diff --git a/release/src/router/cyassl/ctaocrypt/Makefile.am b/release/src/router/cyassl/ctaocrypt/Makefile.am new file mode 100644 index 00000000..e36e5bc8 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src test benchmark +EXTRA_DIST = ctaocrypt.sln ctaocrypt.vcproj + diff --git a/release/src/router/cyassl/ctaocrypt/Makefile.in b/release/src/router/cyassl/ctaocrypt/Makefile.in new file mode 100644 index 00000000..e5eea822 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/Makefile.in @@ -0,0 +1,503 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@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@ +target_triplet = @target@ +subdir = ctaocrypt +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/lib_socket_nsl.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ctaocrypt/include/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBM = @LIBM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +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_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src test benchmark +EXTRA_DIST = ctaocrypt.sln ctaocrypt.vcproj +all: all-recursive + +.SUFFIXES: +$(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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ctaocrypt/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ctaocrypt/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 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +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 $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +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-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean 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-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + +# 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/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.am b/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.am new file mode 100644 index 00000000..80f1c932 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I../include +bin_PROGRAMS = benchmark +benchmark_SOURCES = benchmark.c +benchmark_LDFLAGS = -L../src +benchmark_LDADD = ../../src/libcyassl.la +benchmark_DEPENDENCIES = ../../src/libcyassl.la +EXTRA_DIST = *.der benchmark.sln benchmark.vcproj diff --git a/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.in b/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.in new file mode 100644 index 00000000..fb004f36 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/benchmark/Makefile.in @@ -0,0 +1,485 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@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@ +target_triplet = @target@ +bin_PROGRAMS = benchmark$(EXEEXT) +subdir = ctaocrypt/benchmark +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/lib_socket_nsl.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ctaocrypt/include/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_benchmark_OBJECTS = benchmark.$(OBJEXT) +benchmark_OBJECTS = $(am_benchmark_OBJECTS) +benchmark_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(benchmark_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)/ctaocrypt/include@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(benchmark_SOURCES) +DIST_SOURCES = $(benchmark_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBM = @LIBM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +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_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I../include +benchmark_SOURCES = benchmark.c +benchmark_LDFLAGS = -L../src +benchmark_LDADD = ../../src/libcyassl.la +benchmark_DEPENDENCIES = ../../src/libcyassl.la +EXTRA_DIST = *.der benchmark.sln benchmark.vcproj +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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ctaocrypt/benchmark/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ctaocrypt/benchmark/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 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) + @rm -f benchmark$(EXEEXT) + $(benchmark_LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +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 $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$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 $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +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-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(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-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS 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-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 uninstall uninstall-am \ + uninstall-binPROGRAMS + +# 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/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.c b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.c new file mode 100644 index 00000000..9e0170ab --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.c @@ -0,0 +1,538 @@ +/* benchmark.c */ +/* CTaoCrypt benchmark */ + +#include +#include + +#include "des3.h" +#include "arc4.h" +#include "hc128.h" +#include "rabbit.h" +#include "ctc_aes.h" +#include "ctc_md5.h" +#include "ctc_sha.h" +#include "sha256.h" +#include "sha512.h" +#include "ctc_rsa.h" +#include "asn.h" +#include "ctc_ripemd.h" + +#include "ctc_dh.h" + + +#ifdef _MSC_VER + /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ + #pragma warning(disable: 4996) +#endif + +void bench_des(); +void bench_arc4(); +void bench_hc128(); +void bench_rabbit(); +void bench_aes(int); + +void bench_md5(); +void bench_sha(); +void bench_sha256(); +void bench_sha512(); +void bench_ripemd(); + +void bench_rsa(); +void bench_rsaKeyGen(); +void bench_dh(); + +double current_time(); + + + +int main(int argc, char** argv) +{ +#ifndef NO_AES + bench_aes(0); + bench_aes(1); +#endif + bench_arc4(); +#ifndef NO_HC128 + bench_hc128(); +#endif +#ifndef NO_RABBIT + bench_rabbit(); +#endif +#ifndef NO_DES3 + bench_des(); +#endif + + printf("\n"); + + bench_md5(); + bench_sha(); +#ifndef NO_SHA256 + bench_sha256(); +#endif +#ifdef CYASSL_SHA512 + bench_sha512(); +#endif +#ifdef CYASSL_RIPEMD + bench_ripemd(); +#endif + + printf("\n"); + + bench_rsa(); + +#ifndef NO_DH + bench_dh(); +#endif + +#ifdef CYASSL_KEY_GEN + bench_rsaKeyGen(); +#endif + + return 0; +} + +const int megs = 5; /* how many megs to test (en/de)cryption */ +const int times = 100; /* public key iterations */ + +const byte key[] = +{ + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 +}; + +const byte iv[] = +{ + 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81 + +}; + + +byte plain [1024*1024]; +byte cipher[1024*1024]; + + +#ifndef NO_AES +void bench_aes(int show) +{ + Aes enc; + double start, total, persec; + int i; + + AesSetKey(&enc, key, 16, iv, AES_ENCRYPTION); + start = current_time(); + + for(i = 0; i < megs; i++) + AesCbcEncrypt(&enc, plain, cipher, sizeof(plain)); + + total = current_time() - start; + + persec = 1 / total * megs; + + if (show) + printf("AES %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif + + +#ifndef NO_DES3 +void bench_des() +{ + Des3 enc; + double start, total, persec; + int i; + + Des3_SetKey(&enc, key, iv, DES_ENCRYPTION); + start = current_time(); + + for(i = 0; i < megs; i++) + Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain)); + + total = current_time() - start; + + persec = 1 / total * megs; + + printf("3DES %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif + + +void bench_arc4() +{ + Arc4 enc; + double start, total, persec; + int i; + + Arc4SetKey(&enc, key, 16); + start = current_time(); + + for(i = 0; i < megs; i++) + Arc4Process(&enc, cipher, plain, sizeof(plain)); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("ARC4 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} + + +#ifndef NO_HC128 +void bench_hc128() +{ + HC128 enc; + double start, total, persec; + int i; + + Hc128_SetKey(&enc, key, iv); + start = current_time(); + + for(i = 0; i < megs; i++) + Hc128_Process(&enc, cipher, plain, sizeof(plain)); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("HC128 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif /* NO_HC128 */ + + +#ifndef NO_RABBIT +void bench_rabbit() +{ + Rabbit enc; + double start, total, persec; + int i; + + RabbitSetKey(&enc, key, iv); + start = current_time(); + + for(i = 0; i < megs; i++) + RabbitProcess(&enc, cipher, plain, sizeof(plain)); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("RABBIT %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif /* NO_RABBIT */ + + +void bench_md5() +{ + Md5 hash; + byte digest[MD5_DIGEST_SIZE]; + double start, total, persec; + int i; + + InitMd5(&hash); + start = current_time(); + + for(i = 0; i < megs; i++) + Md5Update(&hash, plain, sizeof(plain)); + + Md5Final(&hash, digest); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("MD5 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} + + +void bench_sha() +{ + Sha hash; + byte digest[SHA_DIGEST_SIZE]; + double start, total, persec; + int i; + + InitSha(&hash); + start = current_time(); + + for(i = 0; i < megs; i++) + ShaUpdate(&hash, plain, sizeof(plain)); + + ShaFinal(&hash, digest); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("SHA %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} + + +#ifndef NO_SHA256 +void bench_sha256() +{ + Sha256 hash; + byte digest[SHA256_DIGEST_SIZE]; + double start, total, persec; + int i; + + InitSha256(&hash); + start = current_time(); + + for(i = 0; i < megs; i++) + Sha256Update(&hash, plain, sizeof(plain)); + + Sha256Final(&hash, digest); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("SHA-256 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif + +#ifdef CYASSL_SHA512 +void bench_sha512() +{ + Sha512 hash; + byte digest[SHA512_DIGEST_SIZE]; + double start, total, persec; + int i; + + InitSha512(&hash); + start = current_time(); + + for(i = 0; i < megs; i++) + Sha512Update(&hash, plain, sizeof(plain)); + + Sha512Final(&hash, digest); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("SHA-512 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif + +#ifdef CYASSL_RIPEMD +void bench_ripemd() +{ + RipeMd hash; + byte digest[RIPEMD_DIGEST_SIZE]; + double start, total, persec; + int i; + + InitRipeMd(&hash); + start = current_time(); + + for(i = 0; i < megs; i++) + RipeMdUpdate(&hash, plain, sizeof(plain)); + + RipeMdFinal(&hash, digest); + + total = current_time() - start; + persec = 1 / total * megs; + + printf("RIPEMD %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, + persec); +} +#endif + + +RNG rng; + +void bench_rsa() +{ + int i; + byte tmp[4096]; + size_t bytes; + word32 idx = 0; + + byte message[] = "Everyone gets Friday off."; + byte cipher[512]; /* for up to 4096 bit */ + byte* output; + const int len = (int)strlen((char*)message); + double start, total, each, milliEach; + + RsaKey key; + FILE* file = fopen("./rsa1024.der", "rb"); + + if (!file) { + printf("can't find ./rsa1024.der\n"); + return; + } + + InitRng(&rng); + bytes = fread(tmp, 1, sizeof(tmp), file); + InitRsaKey(&key, 0); + bytes = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); + + start = current_time(); + + for (i = 0; i < times; i++) + bytes = RsaPublicEncrypt(message,len,cipher,sizeof(cipher), &key, &rng); + + total = current_time() - start; + each = total / times; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("RSA 1024 encryption took %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, times); + + start = current_time(); + + for (i = 0; i < times; i++) + RsaPrivateDecryptInline(cipher, (word32)bytes, &output, &key); + + total = current_time() - start; + each = total / times; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("RSA 1024 decryption took %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, times); + + fclose(file); + FreeRsaKey(&key); +} + + +#ifndef NO_DH +void bench_dh() +{ + int i; + byte tmp[1024]; + size_t bytes; + word32 idx = 0, pubSz, privSz, pubSz2, privSz2, agreeSz; + + byte pub[128]; /* for 1024 bit */ + byte priv[128]; /* for 1024 bit */ + byte pub2[128]; /* for 1024 bit */ + byte priv2[128]; /* for 1024 bit */ + byte agree[128]; /* for 1024 bit */ + + double start, total, each, milliEach; + DhKey key; + FILE* file = fopen("./dh1024.der", "rb"); + + if (!file) { + printf("can't find ./dh1024.der\n"); + return; + } + + bytes = fread(tmp, 1, 1024, file); + InitDhKey(&key); + bytes = DhKeyDecode(tmp, &idx, &key, (word32)bytes); + + start = current_time(); + + for (i = 0; i < times; i++) + DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz); + + total = current_time() - start; + each = total / times; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("DH 1024 key generation %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, times); + + DhGenerateKeyPair(&key, &rng, priv2, &privSz2, pub2, &pubSz2); + start = current_time(); + + for (i = 0; i < times; i++) + DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); + + total = current_time() - start; + each = total / times; /* per second */ + milliEach = each * 1000; /* milliseconds */ + + printf("DH 1024 key agreement %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, times); + + fclose(file); + FreeDhKey(&key); +} +#endif + +#ifdef CYASSL_KEY_GEN +void bench_rsaKeyGen() +{ + RsaKey genKey; + double start, total, each, milliEach; + int i; + const int genTimes = 5; + + /* 1024 bit */ + start = current_time(); + + for(i = 0; i < genTimes; i++) { + InitRsaKey(&genKey, 0); + MakeRsaKey(&genKey, 1024, 65537, &rng); + FreeRsaKey(&genKey); + } + + total = current_time() - start; + each = total / genTimes; /* per second */ + milliEach = each * 1000; /* millisconds */ + printf("\n"); + printf("RSA 1024 key generation %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, genTimes); + + /* 2048 bit */ + start = current_time(); + + for(i = 0; i < genTimes; i++) { + InitRsaKey(&genKey, 0); + MakeRsaKey(&genKey, 2048, 65537, &rng); + FreeRsaKey(&genKey); + } + + total = current_time() - start; + each = total / genTimes; /* per second */ + milliEach = each * 1000; /* millisconds */ + printf("RSA 2048 key generation %6.2f milliseconds, avg over %d" + " iterations\n", milliEach, genTimes); +} +#endif /* CYASSL_KEY_GEN */ + + +#ifdef _WIN32 + + #define WIN32_LEAN_AND_MEAN + #include + + double current_time() + { + static int init = 0; + static LARGE_INTEGER freq; + + LARGE_INTEGER count; + + if (!init) { + QueryPerformanceFrequency(&freq); + init = 1; + } + + QueryPerformanceCounter(&count); + + return (double)count.QuadPart / freq.QuadPart; + } + +#else + + #include + + double current_time() + { + struct timeval tv; + gettimeofday(&tv, 0); + + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; + } + +#endif /* _WIN32 */ + diff --git a/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.sln b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.sln new file mode 100755 index 00000000..e3e9483b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchmark", "benchmark.vcproj", "{615AEC46-5595-4DEA-9490-DBD5DE0F8772}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Debug|Win32.ActiveCfg = Debug|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Debug|Win32.Build.0 = Debug|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Release|Win32.ActiveCfg = Release|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.vcproj b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.vcproj new file mode 100755 index 00000000..5db23c37 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/benchmark/benchmark.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/release/src/router/cyassl/ctaocrypt/benchmark/dh1024.der b/release/src/router/cyassl/ctaocrypt/benchmark/dh1024.der new file mode 100644 index 00000000..09f81ee1 Binary files /dev/null and b/release/src/router/cyassl/ctaocrypt/benchmark/dh1024.der differ diff --git a/release/src/router/cyassl/ctaocrypt/benchmark/rsa1024.der b/release/src/router/cyassl/ctaocrypt/benchmark/rsa1024.der new file mode 100644 index 00000000..a69c5e33 Binary files /dev/null and b/release/src/router/cyassl/ctaocrypt/benchmark/rsa1024.der differ diff --git a/release/src/router/cyassl/ctaocrypt/ctaocrypt.sln b/release/src/router/cyassl/ctaocrypt/ctaocrypt.sln new file mode 100755 index 00000000..f2154d0d --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/ctaocrypt.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctaocrypt", "ctaocrypt.vcproj", "{BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcproj", "{D04BDF66-664A-4D59-BEAC-8AB2D5809C21}" + ProjectSection(ProjectDependencies) = postProject + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62} = {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchmark", "benchmark\benchmark.vcproj", "{615AEC46-5595-4DEA-9490-DBD5DE0F8772}" + ProjectSection(ProjectDependencies) = postProject + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62} = {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62}.Debug|Win32.ActiveCfg = Debug|Win32 + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62}.Debug|Win32.Build.0 = Debug|Win32 + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62}.Release|Win32.ActiveCfg = Release|Win32 + {BF0EA0C1-3F4C-4767-B79E-7B2A391F7D62}.Release|Win32.Build.0 = Release|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Debug|Win32.ActiveCfg = Debug|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Debug|Win32.Build.0 = Debug|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Release|Win32.ActiveCfg = Release|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Release|Win32.Build.0 = Release|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Debug|Win32.ActiveCfg = Debug|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Debug|Win32.Build.0 = Debug|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Release|Win32.ActiveCfg = Release|Win32 + {615AEC46-5595-4DEA-9490-DBD5DE0F8772}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/release/src/router/cyassl/ctaocrypt/ctaocrypt.vcproj b/release/src/router/cyassl/ctaocrypt/ctaocrypt.vcproj new file mode 100755 index 00000000..26ba6966 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/ctaocrypt.vcproj @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/release/src/router/cyassl/ctaocrypt/include/arc4.h b/release/src/router/cyassl/ctaocrypt/include/arc4.h new file mode 100644 index 00000000..1ffff6f3 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/arc4.h @@ -0,0 +1,56 @@ +/* arc4.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_ARC4_H +#define CTAO_CRYPT_ARC4_H + + +#include "types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + ARC4_STATE_SIZE = 256 +}; + +/* ARC4 encryption and decryption */ +typedef struct Arc4 { + byte x; + byte y; + byte state[ARC4_STATE_SIZE]; +} Arc4; + +void Arc4Process(Arc4*, byte*, const byte*, word32); +void Arc4SetKey(Arc4*, const byte*, word32); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CTAO_CRYPT_ARC4_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/asn.h b/release/src/router/cyassl/ctaocrypt/include/asn.h new file mode 100644 index 00000000..4623da95 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/asn.h @@ -0,0 +1,319 @@ +/* asn.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_ASN_H +#define CTAO_CRYPT_ASN_H + +#include "types.h" +#include "ctc_rsa.h" +#include "ctc_dh.h" +#include "ctc_dsa.h" +#include "ctc_sha.h" +#ifdef HAVE_ECC + #include "ctc_ecc.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + ISSUER = 0, + SUBJECT = 1, + + BEFORE = 0, + AFTER = 1 +}; + +/* ASN Tags */ +enum ASN_Tags { + ASN_INTEGER = 0x02, + ASN_BIT_STRING = 0x03, + ASN_OCTET_STRING = 0x04, + ASN_TAG_NULL = 0x05, + ASN_OBJECT_ID = 0x06, + ASN_SEQUENCE = 0x10, + ASN_SET = 0x11, + ASN_UTC_TIME = 0x17, + ASN_GENERALIZED_TIME = 0x18, + ASN_LONG_LENGTH = 0x80 +}; + + +enum ASN_Flags{ + ASN_CONSTRUCTED = 0x20, + ASN_CONTEXT_SPECIFIC = 0x80 +}; + +enum DN_Tags { + ASN_COMMON_NAME = 0x03, /* CN */ + ASN_SUR_NAME = 0x04, /* SN */ + ASN_COUNTRY_NAME = 0x06, /* C */ + ASN_LOCALITY_NAME = 0x07, /* L */ + ASN_STATE_NAME = 0x08, /* ST */ + ASN_ORG_NAME = 0x0a, /* O */ + ASN_ORGUNIT_NAME = 0x0b /* OU */ +}; + +enum Misc_ASN { + ASN_NAME_MAX = 256, + SHA_SIZE = 20, + RSA_INTS = 8, /* RSA ints in private key */ + MIN_DATE_SIZE = 13, + MAX_DATE_SIZE = 32, + ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */ + MAX_ENCODED_SIG_SZ = 512, + MAX_SIG_SZ = 256, + MAX_ALGO_SZ = 20, + MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */ + MAX_SET_SZ = 5, /* enum(set | con) + length(4) */ + MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/ + MAX_ENCODED_DIG_SZ = 25, /* sha + enum(bit or octet) + legnth(4) */ + MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */ + MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */ + MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */ + MAX_RSA_E_SZ = 16, /* Max RSA public e size */ + MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, + /* use bigger NTRU size */ + MAX_LENGTH_SZ = 4 +}; + + +enum Oid_Types { + hashType = 0, + sigType = 1, + keyType = 2 +}; + + +enum Sig_Sum { + SHAwDSA = 517, + MD2wRSA = 646, + MD5wRSA = 648, + SHAwRSA = 649, + SHAwECDSA = 520 +}; + +enum Hash_Sum { + MD2h = 646, + MD5h = 649, + SHAh = 88 +}; + +enum Key_Sum { + DSAk = 515, + RSAk = 645, + NTRUk = 364, + ECDSAk = 518 +}; + +enum Ecc_Sum { + ECC_256R1 = 526, + ECC_384R1 = 210, + ECC_521R1 = 211, + ECC_160R1 = 184, + ECC_192R1 = 520, + ECC_224R1 = 209 +}; + + +/* Certificate file Type */ +enum CertType { + CERT_TYPE = 0, + PRIVATEKEY_TYPE, + CA_TYPE +}; + + +enum VerifyType { + NO_VERIFY = 0, + VERIFY = 1 +}; + + +typedef struct DecodedCert { + byte* publicKey; + word32 pubKeySize; + int pubKeyStored; + word32 certBegin; /* offset to start of cert */ + word32 sigIndex; /* offset to start of signature */ + word32 sigLength; /* length of signature */ + word32 signatureOID; /* sum of algorithm object id */ + word32 keyOID; /* sum of key algo object id */ + byte subjectHash[SHA_SIZE]; /* hash of all Names */ + byte issuerHash[SHA_SIZE]; /* hash of all Names */ + byte* signature; /* not owned, points into raw cert */ + char* subjectCN; /* CommonName */ + int subjectCNLen; + char issuer[ASN_NAME_MAX]; /* full name including common name */ + char subject[ASN_NAME_MAX]; /* full name including common name */ + int verify; /* Default to yes, but could be off */ + byte* source; /* byte buffer holder cert, NOT owner */ + word32 srcIdx; /* current offset into buffer */ + void* heap; /* for user memory overrides */ +#ifdef CYASSL_CERT_GEN + /* easy access to sujbect info for other sign */ + char* subjectSN; + int subjectSNLen; + char* subjectC; + int subjectCLen; + char* subjectL; + int subjectLLen; + char* subjectST; + int subjectSTLen; + char* subjectO; + int subjectOLen; + char* subjectOU; + int subjectOULen; + char* subjectEmail; + int subjectEmailLen; +#endif /* CYASSL_CERT_GEN */ +} DecodedCert; + + +typedef struct Signer Signer; + +/* CA Signers */ +struct Signer { + byte* publicKey; + word32 pubKeySize; + word32 keyOID; /* key type */ + char* name; /* common name */ + byte hash[SHA_DIGEST_SIZE]; /* sha hash of names in certificate */ + Signer* next; +}; + + +void InitDecodedCert(DecodedCert*, byte*, void*); +void FreeDecodedCert(DecodedCert*); +int ParseCert(DecodedCert*, word32, int type, int verify, Signer* signer); +int ParseCertRelative(DecodedCert*, word32, int type, int verify, + Signer* signer); + +word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,int hashOID); + +Signer* MakeSigner(void*); +void FreeSigners(Signer*, void*); + + +int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32); +int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32); +int ToTraditional(byte* buffer, word32 length); + +#ifndef NO_DH +int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32); +int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz); +#endif + +#ifndef NO_DSA +int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey*, word32); +int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey*, word32); +#endif + +#ifdef CYASSL_KEY_GEN +int RsaKeyToDer(RsaKey*, byte* output, word32 inLen); +#endif + +#ifdef HAVE_ECC + /* ASN sig helpers */ + int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s); + int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s); + /* private key helpers */ + int EccPrivateKeyDecode(const byte* input,word32* inOutIdx,ecc_key*,word32); +#endif + +#if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) +int DerToPem(const byte* der, word32 derSz, byte* output, word32 outputSz, + int type); +#endif + +#ifdef CYASSL_CERT_GEN + +enum cert_enums { + SERIAL_SIZE = 8, + NAME_SIZE = 64, + NAME_ENTRIES = 8, + JOINT_LEN = 2, + EMAIL_JOINT_LEN = 9, + RSA_KEY = 10, + NTRU_KEY = 11 +}; + + +typedef struct CertName { + char country[NAME_SIZE]; + char state[NAME_SIZE]; + char locality[NAME_SIZE]; + char sur[NAME_SIZE]; + char org[NAME_SIZE]; + char unit[NAME_SIZE]; + char commonName[NAME_SIZE]; + char email[NAME_SIZE]; /* !!!! email has to be last !!!! */ +} CertName; + + +/* for user to fill for certificate generation */ +typedef struct Cert { + int version; /* x509 version */ + byte serial[SERIAL_SIZE]; /* serial number */ + int sigType; /* signature algo type */ + CertName issuer; /* issuer info */ + int daysValid; /* validity days */ + int selfSigned; /* self signed flag */ + CertName subject; /* subject info */ + /* internal use only */ + int bodySz; /* pre sign total size */ + int keyType; /* public key type of subject */ +} Cert; + + +/* Initialize and Set Certficate defaults: + version = 3 (0x2) + serial = 0 (Will be randomly generated) + sigType = MD5_WITH_RSA + issuer = blank + daysValid = 500 + selfSigned = 1 (true) use subject as issuer + subject = blank + keyType = RSA_KEY (default) +*/ +void InitCert(Cert*); +int MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); +int SignCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); +int MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); +int SetIssuer(Cert*, const char*); +#ifdef HAVE_NTRU +int MakeNtruCert(Cert*, byte* derBuffer, word32 derSz, const byte* ntruKey, + word16 keySz, RNG*); +#endif + + +#endif /* CYASSL_CERT_GEN */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_ASN_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/coding.h b/release/src/router/cyassl/ctaocrypt/include/coding.h new file mode 100644 index 00000000..2ece68f5 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/coding.h @@ -0,0 +1,47 @@ +/* coding.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_CODING_H +#define CTAO_CRYPT_CODING_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* decode needed by CyaSSL */ +int Base64Decode(const byte* in, word32 inLen, byte* out, word32* outLen); + +#if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) + /* encode isn't */ + int Base64Encode(const byte* in, word32 inLen, byte* out, word32* outLen); + int Base16Decode(const byte* in, word32 inLen, byte* out, word32* outLen); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_CODING_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/config.h.in b/release/src/router/cyassl/ctaocrypt/include/config.h.in new file mode 100644 index 00000000..4a360135 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/config.h.in @@ -0,0 +1,85 @@ +/* ctaocrypt/include/config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `network' library (-lnetwork). */ +#undef HAVE_LIBNETWORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_aes.h b/release/src/router/cyassl/ctaocrypt/include/ctc_aes.h new file mode 100644 index 00000000..64fc7426 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_aes.h @@ -0,0 +1,84 @@ +/* ctc_aes.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_AES + +#ifndef CTAO_CRYPT_AES_H +#define CTAO_CRYPT_AES_H + + +#include "types.h" + +#ifdef CYASSL_AESNI + +#include + +#if !defined (ALIGN16) + #if defined (__GNUC__) + #define ALIGN16 __attribute__ ( (aligned (16))) + #elif defined(_MSC_VER) + #define ALIGN16 __declspec (align (16)) + #else + #define ALIGN16 + #endif +#endif + +#endif /* CYASSL_AESNI */ + +#if !defined (ALIGN16) + #define ALIGN16 +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + AES_ENCRYPTION = 0, + AES_DECRYPTION = 1, + AES_BLOCK_SIZE = 16 +}; + + +typedef struct Aes { + /* AESNI needs key first, rounds 2nd, not sure why yet */ + ALIGN16 word32 key[60]; + word32 rounds; + + ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */ +} Aes; + + +int AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, int dir); +void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); +void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CTAO_CRYPT_AES_H */ +#endif /* NO_AES */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_dh.h b/release/src/router/cyassl/ctaocrypt/include/ctc_dh.h new file mode 100644 index 00000000..f94b6d72 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_dh.h @@ -0,0 +1,59 @@ +/* ctc_dh.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_DH + +#ifndef CTAO_CRYPT_DH_H +#define CTAO_CRYPT_DH_H + +#include "types.h" +#include "integer.h" +#include "random.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* Diffie-Hellman Key */ +typedef struct DhKey { + mp_int p, g; /* group parameters */ +} DhKey; + + +void InitDhKey(DhKey* key); +void FreeDhKey(DhKey* key); + +int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz, + byte* pub, word32* pubSz); +int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, + word32 privSz, const byte* otherPub, word32 pubSz); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_DH_H */ + +#endif /* NO_DH */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_dsa.h b/release/src/router/cyassl/ctaocrypt/include/ctc_dsa.h new file mode 100644 index 00000000..1779e209 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_dsa.h @@ -0,0 +1,61 @@ +/* ctc_dsa.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_DSA + +#ifndef CTAO_CRYPT_DSA_H +#define CTAO_CRYPT_DSA_H + +#include "types.h" +#include "integer.h" +#include "random.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + DSA_PUBLIC = 0, + DSA_PRIVATE = 1 +}; + +/* DSA */ +typedef struct DsaKey { + mp_int p, q, g, y, x; + int type; /* public or private */ +} DsaKey; + + +void InitDsaKey(DsaKey* key); +void FreeDsaKey(DsaKey* key); + +int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng); +int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_DSA_H */ +#endif /* NO_DSA */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_ecc.h b/release/src/router/cyassl/ctaocrypt/include/ctc_ecc.h new file mode 100644 index 00000000..207a96c4 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_ecc.h @@ -0,0 +1,119 @@ +/* ctc_ecc.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_ECC + +#ifndef CTAO_CRYPT_ECC_H +#define CTAO_CRYPT_ECC_H + +#include "types.h" +#include "integer.h" +#include "random.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + ECC_PUBLICKEY = 1, + ECC_PRIVATEKEY = 2, + ECC_MAXNAME = 16, /* MAX CURVE NAME LENGTH */ + SIG_HEADER_SZ = 6, /* ECC signature header size */ + ECC_BUFSIZE = 256, /* for exported keys temp buffer */ + ECC_MAXSIZE = 66 /* MAX Private Key size */ +}; + + +/* ECC set type defined a NIST GF(p) curve */ +typedef struct { + int size; /* The size of the curve in octets */ + char* name; /* name of this curve */ + char* prime; /* prime that defines the field the curve is in (hex) */ + char* B; /* fields B param (hex) */ + char* order; /* order of the curve (hex) */ + char* Gx; /* x coordinate of the base point on curve (hex) */ + char* Gy; /* y coordinate of the base point on curve (hex) */ +} ecc_set_type; + + +/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) => + (x/z^2, y/z^3, 1) when interpreted as affine */ +typedef struct { + mp_int x; /* The x coordinate */ + mp_int y; /* The y coordinate */ + mp_int z; /* The z coordinate */ +} ecc_point; + +/* An ECC Key */ +typedef struct { + int type; /* Public or Private */ + int idx; /* Index into the ecc_sets[] for the parameters of + this curve if -1, this key is using user supplied + curve in dp */ + const ecc_set_type* dp; /* domain parameters, either points to NIST + curves (idx >= 0) or user supplied */ + ecc_point pubkey; /* public key */ + mp_int k; /* private key */ +} ecc_key; + + +/* ECC predefined curve sets */ +extern const ecc_set_type ecc_sets[]; + + +int ecc_make_key(RNG* rng, int keysize, ecc_key* key); +int ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, + word32* outlen); + +int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, + RNG* rng, ecc_key* key); +int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen, + int* stat, ecc_key* key); + +void ecc_init(ecc_key* key); +void ecc_free(ecc_key* key); + + +/* ASN key helpers */ +int ecc_export_x963(ecc_key*, byte* out, word32* outLen); +int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key); + +int ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, + word32 pubSz, ecc_key* key); + +/* size helper */ +int ecc_size(ecc_key* key); +int ecc_sig_size(ecc_key* key); + +/* TODO: fix mutex types */ +#define MUTEX_GLOBAL(x) int (x); +#define MUTEX_LOCK(x) +#define MUTEX_UNLOCK(x) + + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_ECC_H */ +#endif /* HAVE_ECC */ diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_hmac.h b/release/src/router/cyassl/ctaocrypt/include/ctc_hmac.h new file mode 100644 index 00000000..27ecb605 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_hmac.h @@ -0,0 +1,85 @@ +/* ctc_hmac.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_HMAC + +#ifndef CTAO_CRYPT_HMAC_H +#define CTAO_CRYPT_HMAC_H + +#include "ctc_md5.h" +#include "ctc_sha.h" + +#ifndef NO_SHA256 + #include "sha256.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + + +enum { + IPAD = 0x36, + OPAD = 0x5C, +#ifndef NO_SHA256 + INNER_HASH_SIZE = SHA256_DIGEST_SIZE, +#else + INNER_HASH_SIZE = SHA_DIGEST_SIZE, + SHA256 = 2, /* hash type unique */ +#endif + HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE +}; + + +/* hash union */ +typedef union { + Md5 md5; + Sha sha; + #ifndef NO_SHA256 + Sha256 sha256; + #endif +} Hash; + +/* Hmac digest */ +typedef struct Hmac { + Hash hash; + word32 ipad[HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ + word32 opad[HMAC_BLOCK_SIZE / sizeof(word32)]; + word32 innerHash[INNER_HASH_SIZE / sizeof(word32)]; /* max size */ + byte macType; /* md5 sha or sha256 */ + byte innerHashKeyed; /* keyed flag */ +} Hmac; + + +void HmacSetKey(Hmac*, int type, const byte* key, word32 keySz); /* does init */ +void HmacUpdate(Hmac*, const byte*, word32); +void HmacFinal(Hmac*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_HMAC_H */ + +#endif /* NO_HMAC */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_md4.h b/release/src/router/cyassl/ctaocrypt/include/ctc_md4.h new file mode 100644 index 00000000..2bb389d2 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_md4.h @@ -0,0 +1,65 @@ +/* ctc_md4.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_MD4 + +#ifndef CTAO_CRYPT_MD4_H +#define CTAO_CRYPT_MD4_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* in bytes */ +enum { + MD4_BLOCK_SIZE = 64, + MD4_DIGEST_SIZE = 16, + MD4_PAD_SIZE = 56 +}; + + +/* MD4 digest */ +typedef struct Md4 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[MD4_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[MD4_BLOCK_SIZE / sizeof(word32)]; +} Md4; + + +void InitMd4(Md4*); +void Md4Update(Md4*, const byte*, word32); +void Md4Final(Md4*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_MD4_H */ + +#endif /* NO_MD4 */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_md5.h b/release/src/router/cyassl/ctaocrypt/include/ctc_md5.h new file mode 100644 index 00000000..058f3ed2 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_md5.h @@ -0,0 +1,62 @@ +/* ctc_md5.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_MD5_H +#define CTAO_CRYPT_MD5_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* in bytes */ +enum { + MD5 = 0, /* hash type unique */ + MD5_BLOCK_SIZE = 64, + MD5_DIGEST_SIZE = 16, + MD5_PAD_SIZE = 56 +}; + + +/* MD5 digest */ +typedef struct Md5 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[MD5_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[MD5_BLOCK_SIZE / sizeof(word32)]; +} Md5; + + +void InitMd5(Md5*); +void Md5Update(Md5*, const byte*, word32); +void Md5Final(Md5*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_MD5_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_ripemd.h b/release/src/router/cyassl/ctaocrypt/include/ctc_ripemd.h new file mode 100644 index 00000000..dff20719 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_ripemd.h @@ -0,0 +1,65 @@ +/* ctc_ripemd.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef CYASSL_RIPEMD + +#ifndef CTAO_CRYPT_RIPEMD_H +#define CTAO_CRYPT_RIPEME_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* in bytes */ +enum { + RIPEMD = 3, /* hash type unique */ + RIPEMD_BLOCK_SIZE = 64, + RIPEMD_DIGEST_SIZE = 20, + RIPEMD_PAD_SIZE = 56 +}; + + +/* RipeMd 160 digest */ +typedef struct RipeMd { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[RIPEMD_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[RIPEMD_BLOCK_SIZE / sizeof(word32)]; +} RipeMd; + + +void InitRipeMd(RipeMd*); +void RipeMdUpdate(RipeMd*, const byte*, word32); +void RipeMdFinal(RipeMd*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_RIPEMD_H */ +#endif /* CYASSL_RIPEMD */ diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_rsa.h b/release/src/router/cyassl/ctaocrypt/include/ctc_rsa.h new file mode 100644 index 00000000..f47bbe29 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_rsa.h @@ -0,0 +1,74 @@ +/* ctc_rsa.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_RSA_H +#define CTAO_CRYPT_RSA_H + +#include "types.h" +#include "integer.h" +#include "random.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +enum { + RSA_PUBLIC = 0, + RSA_PRIVATE = 1 +}; + +/* RSA */ +typedef struct RsaKey { + mp_int n, e, d, p, q, dP, dQ, u; + int type; /* public or private */ + void* heap; /* for user memory overrides */ +} RsaKey; + + +void InitRsaKey(RsaKey* key, void*); +void FreeRsaKey(RsaKey* key); + +int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key, RNG* rng); +int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key); +int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key); +int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key, RNG* rng); +int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key); +int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key); + +int RsaEncryptSize(RsaKey* key); + +#ifdef CYASSL_KEY_GEN + int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng); +#endif + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_RSA_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/ctc_sha.h b/release/src/router/cyassl/ctaocrypt/include/ctc_sha.h new file mode 100644 index 00000000..ab7f6cb1 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/ctc_sha.h @@ -0,0 +1,63 @@ +/* ctc_sha.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_SHA_H +#define CTAO_CRYPT_SHA_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* in bytes */ +enum { + SHA = 1, /* hash type unique */ + SHA_BLOCK_SIZE = 64, + SHA_DIGEST_SIZE = 20, + SHA_PAD_SIZE = 56 +}; + + +/* Sha digest */ +typedef struct Sha { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[SHA_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)]; +} Sha; + + +void InitSha(Sha*); +void ShaUpdate(Sha*, const byte*, word32); +void ShaFinal(Sha*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_SHA_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/des3.h b/release/src/router/cyassl/ctaocrypt/include/des3.h new file mode 100644 index 00000000..3af40fb3 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/des3.h @@ -0,0 +1,75 @@ +/* des3.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_DES3 + +#ifndef CTAO_CRYPT_DES3_H +#define CTAO_CRYPT_DES3_H + + +#include "types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +enum { + DES_BLOCK_SIZE = 8, + DES_KS_SIZE = 32, + + DES_ENCRYPTION = 0, + DES_DECRYPTION = 1, +}; + + +/* DES encryption and decryption */ +typedef struct Des { + word32 key[DES_KS_SIZE]; + word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */ +} Des; + + +/* DES3 encryption and decryption */ +typedef struct Des3 { + word32 key[3][DES_KS_SIZE]; + word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ + word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */ +} Des3; + + +void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir); +void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz); +void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); + +void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir); +void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz); +void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* NO_DES3 */ +#endif /* CTAO_CRYPT_DES3_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/error.h b/release/src/router/cyassl/ctaocrypt/include/error.h new file mode 100644 index 00000000..5dd6508b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/error.h @@ -0,0 +1,106 @@ +/* error.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_ERROR_H +#define CTAO_CRYPT_ERROR_H + +#include "types.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +/* error codes */ +enum { + MAX_ERROR_SZ = 80, /* max size of error string */ + MAX_CODE_E = -100, /* errors -101 - -199 */ + OPEN_RAN_E = -101, /* opening random device error */ + READ_RAN_E = -102, /* reading random device error */ + WINCRYPT_E = -103, /* windows crypt init error */ + CRYPTGEN_E = -104, /* windows crypt generation error */ + RAN_BLOCK_E = -105, /* reading random device would block */ + + MP_INIT_E = -110, /* mp_init error state */ + MP_READ_E = -111, /* mp_read error state */ + MP_EXPTMOD_E = -112, /* mp_exptmod error state */ + MP_TO_E = -113, /* mp_to_xxx error state, can't convert */ + MP_SUB_E = -114, /* mp_sub error state, can't subtract */ + MP_ADD_E = -115, /* mp_add error state, can't add */ + MP_MUL_E = -116, /* mp_mul error state, can't multiply */ + MP_MULMOD_E = -117, /* mp_mulmod error state, can't multiply mod */ + MP_MOD_E = -118, /* mp_mod error state, can't mod */ + MP_INVMOD_E = -119, /* mp_invmod error state, can't inv mod */ + MP_CMP_E = -120, /* mp_cmp error state */ + + MEMORY_E = -125, /* out of memory error */ + + RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */ + RSA_BUFFER_E = -131, /* RSA buffer error, output too small or + input too large */ + BUFFER_E = -132, /* output buffer too small or input too large */ + ALGO_ID_E = -133, /* setting algo id error */ + PUBLIC_KEY_E = -134, /* setting public key error */ + DATE_E = -135, /* setting date validity error */ + SUBJECT_E = -136, /* setting subject name error */ + ISSUER_E = -137, /* setting issuer name error */ + + ASN_PARSE_E = -140, /* ASN parsing error, invalid input */ + ASN_VERSION_E = -141, /* ASN version error, invalid number */ + ASN_GETINT_E = -142, /* ASN get big int error, invalid data */ + ASN_RSA_KEY_E = -143, /* ASN key init error, invalid input */ + ASN_OBJECT_ID_E = -144, /* ASN object id error, invalid id */ + ASN_TAG_NULL_E = -145, /* ASN tag error, not null */ + ASN_EXPECT_0_E = -146, /* ASN expect error, not zero */ + ASN_BITSTR_E = -147, /* ASN bit string error, wrong id */ + ASN_UNKNOWN_OID_E = -148, /* ASN oid error, unknown sum id */ + ASN_DATE_SZ_E = -149, /* ASN date error, bad size */ + ASN_BEFORE_DATE_E = -150, /* ASN date error, current date before */ + ASN_AFTER_DATE_E = -151, /* ASN date error, current date after */ + ASN_SIG_OID_E = -152, /* ASN signature error, mismatched oid */ + ASN_TIME_E = -153, /* ASN time error, unkown time type */ + ASN_INPUT_E = -154, /* ASN input error, not enough data */ + ASN_SIG_CONFIRM_E = -155, /* ASN sig error, confirm failure */ + ASN_SIG_HASH_E = -156, /* ASN sig error, unsupported hash type */ + ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */ + ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */ + ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */ + + /* TODO: TAO add ECC error strings to ErrorString() */ + ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */ + ASN_ECC_KEY_E = -171, /* ASN ECC bad input */ + ECC_CURVE_OID_E = -172, /* Unsupported ECC OID curve type */ + + MIN_CODE_E = -200 /* errors -101 - -199 */ +}; + + +void CTaoCryptErrorString(int error, char* buffer); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_ERROR_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/hc128.h b/release/src/router/cyassl/ctaocrypt/include/hc128.h new file mode 100644 index 00000000..aa58304d --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/hc128.h @@ -0,0 +1,57 @@ +/* hc128.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_HC128 + +#ifndef CTAO_CRYPT_HC128_H +#define CTAO_CRYPT_HC128_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* HC-128 stream cipher */ +typedef struct HC128 { + word32 T[1024]; /* P[i] = T[i]; Q[i] = T[1024 + i ]; */ + word32 X[16]; + word32 Y[16]; + word32 counter1024; /* counter1024 = i mod 1024 at the ith step */ + word32 key[8]; + word32 iv[8]; +} HC128; + + +void Hc128_Process(HC128*, byte*, const byte*, word32); +void Hc128_SetKey(HC128*, const byte* key, const byte* iv); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_HC128_H */ + +#endif /* NO_HC128 */ diff --git a/release/src/router/cyassl/ctaocrypt/include/integer.h b/release/src/router/cyassl/ctaocrypt/include/integer.h new file mode 100644 index 00000000..aaa2c7b1 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/integer.h @@ -0,0 +1,329 @@ +/* integer.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + + +/* + * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + +#ifndef CTAO_CRYPT_INTEGER_H +#define CTAO_CRYPT_INTEGER_H + +/* may optionally use fast math instead, not yet supported on all platforms and + may not be faster on all +*/ +#include "types.h" /* will set MP_xxBIT if not default */ +#ifdef USE_FAST_MATH + #include "tfm.h" +#else + +#ifndef CHAR_BIT + #include +#endif + +#include "mpi_class.h" + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif + + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) + #define MP_64BIT + #endif +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef unsigned char mp_digit; + typedef unsigned short mp_word; +#elif defined(MP_16BIT) + typedef unsigned short mp_digit; + typedef unsigned long mp_word; +#elif defined(MP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long long ulong64; + typedef signed long long long64; +#endif + + typedef unsigned long mp_digit; + typedef unsigned long mp_word __attribute__ ((mode(TI))); + + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + + typedef unsigned long mp_digit; + typedef ulong64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + + +/* otherwise the bits per digit is calculated automatically from the size of + a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) + /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* define this to use lower memory usage routines (exptmods mostly) */ +#define MP_LOW_MEM + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 1 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - + BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return + how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) \ + (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) \ + (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +#define mp_prime_random(a, t, size, bbs, cb, dat) \ + mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) + +extern const char *mp_s_rmap; + +/* 6 functions needed by Rsa */ +int mp_init (mp_int * a); +void mp_clear (mp_int * a); +int mp_unsigned_bin_size(mp_int * a); +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); +int mp_to_unsigned_bin (mp_int * a, unsigned char *b); +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +/* end functions needed by Rsa */ + +/* functions added to support above needed, removed TOOM and KARATSUBA */ +int mp_count_bits (mp_int * a); +int mp_init_copy (mp_int * a, mp_int * b); +int mp_copy (mp_int * a, mp_int * b); +int mp_grow (mp_int * a, int size); +void bn_reverse (unsigned char *s, int len); +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); +void mp_zero (mp_int * a); +void mp_clamp (mp_int * a); +void mp_exch (mp_int * a, mp_int * b); +void mp_rshd (mp_int * a, int b); +int mp_mod_2d (mp_int * a, int b, mp_int * c); +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); +int mp_mul_2d (mp_int * a, int b, mp_int * c); +int mp_lshd (mp_int * a, int b); +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +int mp_abs (mp_int * a, mp_int * b); +int mp_invmod (mp_int * a, mp_int * b, mp_int * c); +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c); +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); +int mp_cmp_mag (mp_int * a, mp_int * b); +int mp_cmp (mp_int * a, mp_int * b); +int mp_cmp_d(mp_int * a, mp_digit b); +void mp_set (mp_int * a, mp_digit b); +int mp_mod (mp_int * a, mp_int * b, mp_int * c); +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); +int mp_div_2(mp_int * a, mp_int * b); +int mp_add (mp_int * a, mp_int * b, mp_int * c); +int s_mp_add (mp_int * a, mp_int * b, mp_int * c); +int s_mp_sub (mp_int * a, mp_int * b, mp_int * c); +int mp_sub (mp_int * a, mp_int * b, mp_int * c); +int mp_init (mp_int * a); +int mp_reduce_is_2k_l(mp_int *a); +int mp_reduce_is_2k(mp_int *a); +int mp_dr_is_modulus(mp_int *a); +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int); +int mp_montgomery_setup (mp_int * n, mp_digit * rho); +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); +int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); +void mp_dr_setup(mp_int *a, mp_digit *d); +int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k); +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu); +int mp_reduce_setup (mp_int * a, mp_int * b); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b); +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int s_mp_sqr (mp_int * a, mp_int * b); +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +int fast_s_mp_sqr (mp_int * a, mp_int * b); +int mp_init_size (mp_int * a, int size); +int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d); +int mp_mul_2(mp_int * a, mp_int * b); +int mp_mul (mp_int * a, mp_int * b, mp_int * c); +int mp_sqr (mp_int * a, mp_int * b); +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); +int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); +int mp_2expt (mp_int * a, int b); +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); +/* end support added functions */ + +/* added */ +int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, + mp_int* f); + +#ifdef HAVE_ECC + int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); + int mp_read_radix(mp_int* a, const char* str, int radix); +#endif + +#ifdef CYASSL_KEY_GEN + int mp_prime_is_prime (mp_int * a, int t, int *result); + int mp_set_int (mp_int * a, unsigned long b); + int mp_gcd (mp_int * a, mp_int * b, mp_int * c); + int mp_lcm (mp_int * a, mp_int * b, mp_int * c); + int mp_sub_d (mp_int * a, mp_digit b, mp_int * c); +#endif + + +#ifdef __cplusplus + } +#endif + + +#endif /* USE_FAST_MATH */ + +#endif /* CTAO_CRYPT_INTEGER_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/misc.h b/release/src/router/cyassl/ctaocrypt/include/misc.h new file mode 100644 index 00000000..63ab1068 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/misc.h @@ -0,0 +1,55 @@ +/* misc.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_MISC_H +#define CTAO_CRYPT_MISC_H + + +#include "types.h" + + + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef NO_INLINE +word32 rotlFixed(word32, word32); +word32 rotrFixed(word32, word32); + +word32 ByteReverseWord32(word32); +void ByteReverseWords(word32*, const word32*, word32); +void ByteReverseBytes(byte*, const byte*, word32); + +void XorWords(word*, const word*, word32); +void xorbuf(byte*, const byte*, word32); +#endif /* NO_INLINE */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CTAO_CRYPT_MISC_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/mpi_class.h b/release/src/router/cyassl/ctaocrypt/include/mpi_class.h new file mode 100644 index 00000000..e2b20bf9 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/mpi_class.h @@ -0,0 +1,996 @@ +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GROW_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_L_C +#define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_2K_SETUP_L_C +#define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_IS_2K_L_C +#define BN_MP_REDUCE_SETUP_C +#define BN_MP_RSHD_C +#define BN_MP_SET_C +#define BN_MP_SET_INT_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_SIGNED_BIN_N_C +#define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_N_C +#define BN_MP_TOOM_MUL_C +#define BN_MP_TOOM_SQR_C +#define BN_MP_TORADIX_C +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_MOD_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_ABS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MUL_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_REDUCE_IS_2K_L_C + #define BN_S_MP_EXPTMOD_C + #define BN_MP_DR_IS_MODULUS_C + #define BN_MP_REDUCE_IS_2K_C + #define BN_MP_ISODD_C + #define BN_MP_EXPTMOD_FAST_C +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_NEG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_MP_SUB_C + #define BN_S_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_RADIX_SMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_MOD_2D_C + #define BN_S_MP_MUL_DIGS_C + #define BN_MP_SUB_C + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_L_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_L_C) + #define BN_MP_INIT_C + #define BN_MP_2EXPT_C + #define BN_MP_COUNT_BITS_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_C) + #define BN_MP_REDUCE_2K_C + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_L_C) +#endif + +#if defined(BN_MP_REDUCE_SETUP_C) + #define BN_MP_2EXPT_C + #define BN_MP_DIV_C +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_N_C) + #define BN_MP_SIGNED_BIN_SIZE_C + #define BN_MP_TO_SIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_L_C + #define BN_MP_REDUCE_2K_L_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include "mpi_superclass.h" +#include "mpi_class.h" +#else +#define LTM_LAST +#endif + diff --git a/release/src/router/cyassl/ctaocrypt/include/mpi_superclass.h b/release/src/router/cyassl/ctaocrypt/include/mpi_superclass.h new file mode 100644 index 00000000..a7d16f01 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/mpi_superclass.h @@ -0,0 +1,73 @@ +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +/* #define SC_RSA_1 */ + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif + diff --git a/release/src/router/cyassl/ctaocrypt/include/os_settings.h b/release/src/router/cyassl/ctaocrypt/include/os_settings.h new file mode 100644 index 00000000..9fbd8f8b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/os_settings.h @@ -0,0 +1,269 @@ +/* os_settings.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* Place OS specific preprocessor flags, defines, includes here, will be + included into every file because types.h includes it */ + +#ifndef CTAO_CRYPT_OS_SETTINGS_H +#define CTAO_CRYPT_OS_SETTINGS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Uncomment next line if using IPHONE */ +/* #define IPHONE */ + +/* Uncomment next line if using ThreadX */ +/* #define THREADX */ + +/* Uncomment next line if using Micrium ucOS */ +/* #define MICRIUM */ + +/* Uncomment next line if using Mbed */ +/* #define MBED */ + + +#ifdef IPHONE + #define SIZEOF_LONG_LONG 8 +#endif + +#ifdef THREADX + #define SIZEOF_LONG_LONG 8 +#endif + +#ifdef MBED + #define SINGLE_THREADED + #define CYASSL_USER_IO + #define NO_WRITEV + #define NO_DEV_RANDOM + #define NO_SHA512 + #define NO_DH + #define NO_DSA + #define NO_HC128 +#endif /* MBED */ + + +#ifdef MICRIUM + + #include "stdlib.h" + #include "net_cfg.h" + #include "ssl_cfg.h" + #include "net_secure_os.h" + + #define CYASSL_TYPES + + typedef CPU_INT08U byte; + typedef CPU_INT16U word16; + typedef CPU_INT32U word32; + + #if (NET_SECURE_MGR_CFG_WORD_SIZE == CPU_WORD_SIZE_32) + #define SIZEOF_LONG 4 + #undef SIZEOF_LONG_LONG + #else + #undef SIZEOF_LONG + #define SIZEOF_LONG_LONG 8 + #endif + + #define STRING_USER + + #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr))) + #define XSTRNCPY(pstr_dest, pstr_src, len_max) \ + ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \ + (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max))) + #define XSTRNCMP(pstr_1, pstr_2, len_max) \ + ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \ + (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max))) + #define XSTRSTR(pstr, pstr_srch) \ + ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \ + (CPU_CHAR *)(pstr_srch))) + #define XMEMSET(pmem, data_val, size) \ + ((void)Mem_Set((void *)(pmem), (CPU_INT08U) (data_val), \ + (CPU_SIZE_T)(size))) + #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \ + (void *)(psrc), (CPU_SIZE_T)(size))) + #define XMEMCMP(pmem_1, pmem_2, size) \ + (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), (void *)(pmem_2), \ + (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES) + #define XMEMMOVE XMEMCPY + +#if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) + #define MICRIUM_MALLOC + #define XMALLOC(s, h, type) ((void *)NetSecure_BlkGet((CPU_INT08U)(type), \ + (CPU_SIZE_T)(s), (void *)0)) + #define XFREE(p, h, type) (NetSecure_BlkFree((CPU_INT08U)(type), \ + (p), (void *)0)) + #define XREALLOC(p, n, h, t) realloc((p), (n)) +#endif + + #if (NET_SECURE_MGR_CFG_FS_EN == DEF_ENABLED) + #undef NO_FILESYSTEM + #else + #define NO_FILESYSTEM + #endif + + #if (SSL_CFG_TRACE_LEVEL == CYASSL_TRACE_LEVEL_DBG) + #define DEBUG_CYASSL + #else + #undef DEBUG_CYASSL + #endif + + #if (SSL_CFG_OPENSSL_EN == DEF_ENABLED) + #define OPENSSL_EXTRA + #else + #undef OPENSSL_EXTRA + #endif + + #if (SSL_CFG_MULTI_THREAD_EN == DEF_ENABLED) + #undef SINGLE_THREADED + #else + #define SINGLE_THREADED + #endif + + #if (SSL_CFG_DH_EN == DEF_ENABLED) + #undef NO_DH + #else + #define NO_DH + #endif + + #if (SSL_CFG_DSA_EN == DEF_ENABLED) + #undef NO_DSA + #else + #define NO_DSA + #endif + + #if (SSL_CFG_PSK_EN == DEF_ENABLED) + #undef NO_PSK + #else + #define NO_PSK + #endif + + #if (SSL_CFG_3DES_EN == DEF_ENABLED) + #undef NO_DES + #else + #define NO_DES + #endif + + #if (SSL_CFG_AES_EN == DEF_ENABLED) + #undef NO_AES + #else + #define NO_AES + #endif + + #if (SSL_CFG_RC4_EN == DEF_ENABLED) + #undef NO_RC4 + #else + #define NO_RC4 + #endif + + #if (SSL_CFG_RABBIT_EN == DEF_ENABLED) + #undef NO_RABBIT + #else + #define NO_RABBIT + #endif + + #if (SSL_CFG_HC128_EN == DEF_ENABLED) + #undef NO_HC128 + #else + #define NO_HC128 + #endif + + #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + #define BIG_ENDIAN_ORDER + #else + #undef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER + #endif + + #if (SSL_CFG_MD4_EN == DEF_ENABLED) + #undef NO_MD4 + #else + #define NO_MD4 + #endif + + #if (SSL_CFG_WRITEV_EN == DEF_ENABLED) + #undef NO_WRITEV + #else + #define NO_WRITEV + #endif + + #if (SSL_CFG_USER_RNG_SEED_EN == DEF_ENABLED) + #define NO_DEV_RANDOM + #else + #undef NO_DEV_RANDOM + #endif + + #if (SSL_CFG_USER_IO_EN == DEF_ENABLED) + #define CYASSL_USER_IO + #else + #undef CYASSL_USER_IO + #endif + + #if (SSL_CFG_DYNAMIC_BUFFERS_EN == DEF_ENABLED) + #undef LARGE_STATIC_BUFFERS + #undef STATIC_CHUNKS_ONLY + #else + #define LARGE_STATIC_BUFFERS + #define STATIC_CHUNKS_ONLY + #endif + + #if (SSL_CFG_DER_LOAD_EN == DEF_ENABLED) + #define CYASSL_DER_LOAD + #else + #undef CYASSL_DER_LOAD + #endif + + #if (SSL_CFG_DTLS_EN == DEF_ENABLED) + #define CYASSL_DTLS + #else + #undef CYASSL_DTLS + #endif + + #if (SSL_CFG_CALLBACKS_EN == DEF_ENABLED) + #define CYASSL_CALLBACKS + #else + #undef CYASSL_CALLBACKS + #endif + + #if (SSL_CFG_FAST_MATH_EN == DEF_ENABLED) + #define USE_FAST_MATH + #else + #undef USE_FAST_MATH + #endif + + #if (SSL_CFG_TFM_TIMING_RESISTANT_EN == DEF_ENABLED) + #define TFM_TIMING_RESISTANT + #else + #undef TFM_TIMING_RESISTANT + #endif + +#endif /* MICRIUM */ + +/* Place any other flags or defines here */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CTAO_CRYPT_OS_SETTINGS_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/pwdbased.h b/release/src/router/cyassl/ctaocrypt/include/pwdbased.h new file mode 100644 index 00000000..43194897 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/pwdbased.h @@ -0,0 +1,47 @@ +/* pwdbased.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_PWDBASED + +#ifndef CTAO_CRYPT_PWDBASED_H +#define CTAO_CRYPT_PWDBASED_H + +#include "types.h" +#include "ctc_md5.h" /* for hash type */ +#include "ctc_sha.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, + int sLen, int iterations, int kLen, int hashType); + + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_PWDBASED_H */ +#endif /* NO_PWDBASED */ diff --git a/release/src/router/cyassl/ctaocrypt/include/rabbit.h b/release/src/router/cyassl/ctaocrypt/include/rabbit.h new file mode 100644 index 00000000..dd9165dd --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/rabbit.h @@ -0,0 +1,60 @@ +/* rabbit.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_RABBIT + +#ifndef CTAO_CRYPT_RABBIT_H +#define CTAO_CRYPT_RABBIT_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Rabbit Context */ +typedef struct RabbitCtx { + word32 x[8]; + word32 c[8]; + word32 carry; +} RabbitCtx; + + +/* Rabbit stream cipher */ +typedef struct Rabbit { + RabbitCtx masterCtx; + RabbitCtx workCtx; +} Rabbit; + + +void RabbitProcess(Rabbit*, byte*, const byte*, word32); +void RabbitSetKey(Rabbit*, const byte* key, const byte* iv); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_RABBIT_H */ + +#endif /* NO_RABBIT */ diff --git a/release/src/router/cyassl/ctaocrypt/include/random.h b/release/src/router/cyassl/ctaocrypt/include/random.h new file mode 100644 index 00000000..f153b1e8 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/random.h @@ -0,0 +1,72 @@ +/* random.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_RANDOM_H +#define CTAO_CRYPT_RANDOM_H + +#include "arc4.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +#if defined(USE_WINDOWS_API) + #if defined(_WIN64) + typedef unsigned __int64 ProviderHandle; + /* type HCRYPTPROV, avoid #include */ + #else + typedef unsigned long ProviderHandle; + #endif +#endif + + +/* OS specific seeder */ +typedef struct OS_Seed { + #if defined(USE_WINDOWS_API) + ProviderHandle handle; + #else + int fd; + #endif +} OS_Seed; + +int GenerateSeed(OS_Seed* os, byte* seed, word32 sz); + + +/* secure Random Nnumber Generator */ +typedef struct RNG { + OS_Seed seed; + Arc4 cipher; +} RNG; + + +int InitRng(RNG*); +void RNG_GenerateBlock(RNG*, byte*, word32 sz); +byte RNG_GenerateByte(RNG*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_RANDOM_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/sha256.h b/release/src/router/cyassl/ctaocrypt/include/sha256.h new file mode 100644 index 00000000..811b6f69 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/sha256.h @@ -0,0 +1,69 @@ +/* sha256.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +/* code submitted by raphael.huck@efixo.com */ + + +#ifndef NO_SHA256 + +#ifndef CTAO_CRYPT_SHA256_H +#define CTAO_CRYPT_SHA256_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* in bytes */ +enum { + SHA256 = 2, /* hash type unique */ + SHA256_BLOCK_SIZE = 64, + SHA256_DIGEST_SIZE = 32, + SHA256_PAD_SIZE = 56 +}; + + +/* Sha256 digest */ +typedef struct Sha256 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)]; + word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)]; +} Sha256; + + +void InitSha256(Sha256*); +void Sha256Update(Sha256*, const byte*, word32); +void Sha256Final(Sha256*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_SHA256_H */ +#endif /* NO_SHA256 */ + diff --git a/release/src/router/cyassl/ctaocrypt/include/sha512.h b/release/src/router/cyassl/ctaocrypt/include/sha512.h new file mode 100644 index 00000000..f892a4fb --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/sha512.h @@ -0,0 +1,65 @@ +/* sha512.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef CYASSL_SHA512 + +#ifndef CTAO_CRYPT_SHA512_H +#define CTAO_CRYPT_SHA512_H + +#include "types.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/* in bytes */ +enum { + SHA512 = 4, /* hash type unique */ + SHA512_BLOCK_SIZE = 128, + SHA512_DIGEST_SIZE = 64, + SHA512_PAD_SIZE = 112 +}; + + +/* Sha512 digest */ +typedef struct Sha512 { + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word64 digest[SHA512_DIGEST_SIZE / sizeof(word64)]; + word64 buffer[SHA512_BLOCK_SIZE / sizeof(word64)]; +} Sha512; + + +void InitSha512(Sha512*); +void Sha512Update(Sha512*, const byte*, word32); +void Sha512Final(Sha512*, byte*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CTAO_CRYPT_SHA512_H */ +#endif /* CYASSL_SHA512 */ diff --git a/release/src/router/cyassl/ctaocrypt/include/tfm.h b/release/src/router/cyassl/ctaocrypt/include/tfm.h new file mode 100644 index 00000000..75eb15c0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/tfm.h @@ -0,0 +1,667 @@ +/* tfm.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + + +/* + * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + +/** + * Edited by Moisés Guimarães (moises.guimaraes@phoebus.com.br) + * to fit CyaSSL's needs. + */ + + +#ifndef CTAO_CRYPT_TFM_H +#define CTAO_CRYPT_TFM_H + +#include "types.h" +#ifndef CHAR_BIT + #include +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */ +#ifndef TFM_ALREADY_SET + +/* do we want the large set of small multiplications ? + Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC + Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-) + */ +/* need to refactor the function */ +/*#define TFM_SMALL_SET */ + +/* do we want huge code + Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA) + Less important on 64-bit machines as 32 digits == 2048 bits + */ +#if 0 +#define TFM_MUL3 +#define TFM_MUL4 +#define TFM_MUL6 +#define TFM_MUL7 +#define TFM_MUL8 +#define TFM_MUL9 +#define TFM_MUL12 +#define TFM_MUL17 +#endif +#ifdef TFM_SMALL_SET +#define TFM_MUL20 +#define TFM_MUL24 +#define TFM_MUL28 +#define TFM_MUL32 +#define TFM_MUL48 +#define TFM_MUL64 +#endif + +#if 0 +#define TFM_SQR3 +#define TFM_SQR4 +#define TFM_SQR6 +#define TFM_SQR7 +#define TFM_SQR8 +#define TFM_SQR9 +#define TFM_SQR12 +#define TFM_SQR17 +#endif +#ifdef TFM_SMALL_SET +#define TFM_SQR20 +#define TFM_SQR24 +#define TFM_SQR28 +#define TFM_SQR32 +#define TFM_SQR48 +#define TFM_SQR64 +#endif + +/* do we want some overflow checks + Not required if you make sure your numbers are within range (e.g. by default a modulus for fp_exptmod() can only be upto 2048 bits long) + */ +/* #define TFM_CHECK */ + +/* Is the target a P4 Prescott + */ +/* #define TFM_PRESCOTT */ + +/* Do we want timing resistant fp_exptmod() ? + * This makes it slower but also timing invariant with respect to the exponent + */ +/* #define TFM_TIMING_RESISTANT */ + +#endif + +/* Max size of any number in bits. Basically the largest size you will be multiplying + * should be half [or smaller] of FP_MAX_SIZE-four_digit + * + * You can externally define this or it defaults to 4096-bits [allowing multiplications upto 2048x2048 bits ] + */ +#ifndef FP_MAX_SIZE + #define FP_MAX_SIZE (4096+(8*DIGIT_BIT)) +#endif + +/* will this lib work? */ +#if (CHAR_BIT & 7) + #error CHAR_BIT must be a multiple of eight. +#endif +#if FP_MAX_SIZE % CHAR_BIT + #error FP_MAX_SIZE must be a multiple of CHAR_BIT +#endif + +/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */ +#if defined(__x86_64__) + #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) + #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM) + #define TFM_X86_64 + #endif +#endif +#if defined(TFM_X86_64) + #if !defined(FP_64BIT) + #define FP_64BIT + #endif +#endif + +/* try to detect x86-32 */ +#if defined(__i386__) && !defined(TFM_SSE2) + #if defined(TFM_X86_64) || defined(TFM_ARM) + #error x86-32 detected, x86-64/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86) && !defined(TFM_NO_ASM) + #define TFM_X86 + #endif +#endif + +/* make sure we're 32-bit for x86-32/sse/arm/ppc32 */ +#if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT) + #warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining) + #undef FP_64BIT +#endif + +/* multi asms? */ +#ifdef TFM_X86 + #define TFM_ASM +#endif +#ifdef TFM_X86_64 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_SSE2 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_ARM + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_PPC32 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_PPC64 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_AVR32 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif + +/* we want no asm? */ +#ifdef TFM_NO_ASM + #undef TFM_X86 + #undef TFM_X86_64 + #undef TFM_SSE2 + #undef TFM_ARM + #undef TFM_PPC32 + #undef TFM_PPC64 + #undef TFM_AVR32 + #undef TFM_ASM +#endif + +/* ECC helpers */ +#ifdef TFM_ECC192 + #ifdef FP_64BIT + #define TFM_MUL3 + #define TFM_SQR3 + #else + #define TFM_MUL6 + #define TFM_SQR6 + #endif +#endif + +#ifdef TFM_ECC224 + #ifdef FP_64BIT + #define TFM_MUL4 + #define TFM_SQR4 + #else + #define TFM_MUL7 + #define TFM_SQR7 + #endif +#endif + +#ifdef TFM_ECC256 + #ifdef FP_64BIT + #define TFM_MUL4 + #define TFM_SQR4 + #else + #define TFM_MUL8 + #define TFM_SQR8 + #endif +#endif + +#ifdef TFM_ECC384 + #ifdef FP_64BIT + #define TFM_MUL6 + #define TFM_SQR6 + #else + #define TFM_MUL12 + #define TFM_SQR12 + #endif +#endif + +#ifdef TFM_ECC521 + #ifdef FP_64BIT + #define TFM_MUL9 + #define TFM_SQR9 + #else + #define TFM_MUL17 + #define TFM_SQR17 + #endif +#endif + + +/* some default configurations. + */ +#if defined(FP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long ulong64; +#endif + typedef ulong64 fp_digit; + typedef unsigned long fp_word __attribute__ ((mode(TI))); +#else + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + typedef unsigned long fp_digit; + typedef ulong64 fp_word; +#endif + +/* # of digits this is */ +#define DIGIT_BIT (int)((CHAR_BIT) * sizeof(fp_digit)) +#define FP_MASK (fp_digit)(-1) +#define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT) + +/* signs */ +#define FP_ZPOS 0 +#define FP_NEG 1 + +/* return codes */ +#define FP_OKAY 0 +#define FP_VAL 1 +#define FP_MEM 2 + +/* equalities */ +#define FP_LT -1 /* less than */ +#define FP_EQ 0 /* equal to */ +#define FP_GT 1 /* greater than */ + +/* replies */ +#define FP_YES 1 /* yes response */ +#define FP_NO 0 /* no response */ + +/* a FP type */ +typedef struct { + fp_digit dp[FP_SIZE]; + int used, + sign; +} fp_int; + +/* functions */ + +/* returns a TFM ident string useful for debugging... */ +/*const char *fp_ident(void);*/ + +/* initialize [or zero] an fp int */ +#define fp_init(a) (void)XMEMSET((a), 0, sizeof(fp_int)) +#define fp_zero(a) fp_init(a) + +/* zero/even/odd ? */ +#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO) +#define fp_iseven(a) (((a)->used >= 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO) +#define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO) + +/* set to a small digit */ +void fp_set(fp_int *a, fp_digit b); + +/* copy from a to b */ +#define fp_copy(a, b) (void)(((a) != (b)) ? (XMEMCPY((b), (a), sizeof(fp_int))) : (void)0) +#define fp_init_copy(a, b) fp_copy(b, a) + +/* clamp digits */ +#define fp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; } + +/* negate and absolute */ +#define fp_neg(a, b) { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); } +#define fp_abs(a, b) { fp_copy(a, b); (b)->sign = 0; } + +/* right shift x digits */ +void fp_rshd(fp_int *a, int x); + +/* left shift x digits */ +void fp_lshd(fp_int *a, int x); + +/* signed comparison */ +int fp_cmp(fp_int *a, fp_int *b); + +/* unsigned comparison */ +int fp_cmp_mag(fp_int *a, fp_int *b); + +/* power of 2 operations */ +void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); +void fp_mod_2d(fp_int *a, int b, fp_int *c); +void fp_mul_2d(fp_int *a, int b, fp_int *c); +void fp_2expt (fp_int *a, int b); +void fp_mul_2(fp_int *a, fp_int *c); +void fp_div_2(fp_int *a, fp_int *c); + +/* Counts the number of lsbs which are zero before the first zero bit */ +/*int fp_cnt_lsb(fp_int *a);*/ + +/* c = a + b */ +void fp_add(fp_int *a, fp_int *b, fp_int *c); + +/* c = a - b */ +void fp_sub(fp_int *a, fp_int *b, fp_int *c); + +/* c = a * b */ +void fp_mul(fp_int *a, fp_int *b, fp_int *c); + +/* b = a*a */ +void fp_sqr(fp_int *a, fp_int *b); + +/* a/b => cb + d == a */ +int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* c = a mod b, 0 <= c < b */ +int fp_mod(fp_int *a, fp_int *b, fp_int *c); + +/* compare against a single digit */ +int fp_cmp_d(fp_int *a, fp_digit b); + +/* c = a + b */ +/*void fp_add_d(fp_int *a, fp_digit b, fp_int *c);*/ + +/* c = a - b */ +/*void fp_sub_d(fp_int *a, fp_digit b, fp_int *c);*/ + +/* c = a * b */ +void fp_mul_d(fp_int *a, fp_digit b, fp_int *c); + +/* a/b => cb + d == a */ +/*int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d);*/ + +/* c = a mod b, 0 <= c < b */ +/*int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c);*/ + +/* ---> number theory <--- */ +/* d = a + b (mod c) */ +/*int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ + +/* d = a - b (mod c) */ +/*int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ + +/* d = a * b (mod c) */ +int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* c = a * a (mod b) */ +/*int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c);*/ + +/* c = 1/a (mod b) */ +int fp_invmod(fp_int *a, fp_int *b, fp_int *c); + +/* c = (a, b) */ +/*void fp_gcd(fp_int *a, fp_int *b, fp_int *c);*/ + +/* c = [a, b] */ +/*void fp_lcm(fp_int *a, fp_int *b, fp_int *c);*/ + +/* setups the montgomery reduction */ +int fp_montgomery_setup(fp_int *a, fp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +void fp_montgomery_calc_normalization(fp_int *a, fp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); + +/* d = a**b (mod c) */ +int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + +/* primality stuff */ + +/* perform a Miller-Rabin test of a to the base b and store result in "result" */ +/*void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);*/ + +/* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ +/*int fp_isprime(fp_int *a);*/ + +/* Primality generation flags */ +/*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ +/*#define TFM_PRIME_SAFE 0x0002 */ /* Safe prime (p-1)/2 == prime */ +/*#define TFM_PRIME_2MSB_OFF 0x0004 */ /* force 2nd MSB to 0 */ +/*#define TFM_PRIME_2MSB_ON 0x0008 */ /* force 2nd MSB to 1 */ + +/* callback for fp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +/*typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);*/ + +/*#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)*/ + +/*int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);*/ + +/* radix conersions */ +int fp_count_bits(fp_int *a); + +int fp_unsigned_bin_size(fp_int *a); +void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c); +void fp_to_unsigned_bin(fp_int *a, unsigned char *b); + +/*int fp_signed_bin_size(fp_int *a);*/ +/*void fp_read_signed_bin(fp_int *a, unsigned char *b, int c);*/ +/*void fp_to_signed_bin(fp_int *a, unsigned char *b);*/ + +/*int fp_read_radix(fp_int *a, char *str, int radix);*/ +/*int fp_toradix(fp_int *a, char *str, int radix);*/ +/*int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);*/ + + +/* VARIOUS LOW LEVEL STUFFS */ +void s_fp_add(fp_int *a, fp_int *b, fp_int *c); +void s_fp_sub(fp_int *a, fp_int *b, fp_int *c); +void fp_reverse(unsigned char *s, int len); + +void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C); + +#ifdef TFM_SMALL_SET +void fp_mul_comba_small(fp_int *A, fp_int *B, fp_int *C); +#endif + +#ifdef TFM_MUL3 +void fp_mul_comba3(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL4 +void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL6 +void fp_mul_comba6(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL7 +void fp_mul_comba7(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL8 +void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL9 +void fp_mul_comba9(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL12 +void fp_mul_comba12(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL17 +void fp_mul_comba17(fp_int *A, fp_int *B, fp_int *C); +#endif + +#ifdef TFM_MUL20 +void fp_mul_comba20(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL24 +void fp_mul_comba24(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL28 +void fp_mul_comba28(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL32 +void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL48 +void fp_mul_comba48(fp_int *A, fp_int *B, fp_int *C); +#endif +#ifdef TFM_MUL64 +void fp_mul_comba64(fp_int *A, fp_int *B, fp_int *C); +#endif + +void fp_sqr_comba(fp_int *A, fp_int *B); + +#ifdef TFM_SMALL_SET +void fp_sqr_comba_small(fp_int *A, fp_int *B); +#endif + +#ifdef TFM_SQR3 +void fp_sqr_comba3(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR4 +void fp_sqr_comba4(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR6 +void fp_sqr_comba6(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR7 +void fp_sqr_comba7(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR8 +void fp_sqr_comba8(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR9 +void fp_sqr_comba9(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR12 +void fp_sqr_comba12(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR17 +void fp_sqr_comba17(fp_int *A, fp_int *B); +#endif + +#ifdef TFM_SQR20 +void fp_sqr_comba20(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR24 +void fp_sqr_comba24(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR28 +void fp_sqr_comba28(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR32 +void fp_sqr_comba32(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR48 +void fp_sqr_comba48(fp_int *A, fp_int *B); +#endif +#ifdef TFM_SQR64 +void fp_sqr_comba64(fp_int *A, fp_int *B); +#endif +/*extern const char *fp_s_rmap;*/ + + +/** + * Used by CyaSSL + */ + +/* Types */ + typedef fp_digit mp_digit; + typedef fp_word mp_word; + typedef fp_int mp_int; + +/* Constants */ + #define MP_LT FP_LT /* less than */ + #define MP_EQ FP_EQ /* equal to */ + #define MP_GT FP_GT /* greater than */ + #define MP_OKAY FP_OKAY /* ok result */ + #define MP_NO FP_NO /* yes/no result */ + #define MP_YES FP_YES /* yes/no result */ + +/* Prototypes */ +int mp_init (mp_int * a); +void mp_clear (mp_int * a); +int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f); + +int mp_add (mp_int * a, mp_int * b, mp_int * c); +int mp_sub (mp_int * a, mp_int * b, mp_int * c); + +int mp_mul (mp_int * a, mp_int * b, mp_int * c); +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); +int mp_mod(mp_int *a, mp_int *b, mp_int *c); +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); + +int mp_cmp(mp_int *a, mp_int *b); +int mp_cmp_d(mp_int *a, mp_digit b); + +int mp_unsigned_bin_size(mp_int * a); +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); +int mp_to_unsigned_bin (mp_int * a, unsigned char *b); + +#ifdef HAVE_ECC + int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); + int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + int mp_read_radix(mp_int* a, const char* str, int radix); + int mp_iszero(mp_int* a); + int mp_set(fp_int *a, fp_digit b); + int mp_sqr(fp_int *A, fp_int *B); + int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); + int mp_montgomery_setup(fp_int *a, fp_digit *rho); + int mp_isodd(mp_int* a); + int mp_div_2(fp_int * a, fp_int * b); +#endif + +#if defined(HAVE_ECC) || defined(CYASSL_KEY_GEN) + int mp_copy(fp_int* a, fp_int* b); +#endif + +#ifdef CYASSL_KEY_GEN +int mp_set_int(fp_int *a, fp_digit b); +int mp_gcd(fp_int *a, fp_int *b, fp_int *c); +int mp_lcm(fp_int *a, fp_int *b, fp_int *c); +int mp_sub_d(fp_int *a, fp_digit b, fp_int *c); +int mp_prime_is_prime(mp_int* a, int t, int* result); +#endif /* CYASSL_KEY_GEN */ + +#ifdef __cplusplus + } +#endif + + +#endif /* CTAO_CRYPT_TFM_H */ diff --git a/release/src/router/cyassl/ctaocrypt/include/types.h b/release/src/router/cyassl/ctaocrypt/include/types.h new file mode 100644 index 00000000..fd8e5bca --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/include/types.h @@ -0,0 +1,198 @@ +/* types.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef CTAO_CRYPT_TYPES_H +#define CTAO_CRYPT_TYPES_H + +#include "os_settings.h" + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +#if defined(WORDS_BIGENDIAN) || (defined(__MWERKS__) && !defined(__INTEL__)) + #define BIG_ENDIAN_ORDER +#endif + +#ifndef BIG_ENDIAN_ORDER + #define LITTLE_ENDIAN_ORDER +#endif + +#ifndef CYASSL_TYPES + typedef unsigned char byte; + typedef unsigned short word16; + typedef unsigned int word32; +#endif + +#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) + #define WORD64_AVAILABLE + #define W64LIT(x) x##ui64 + typedef unsigned __int64 word64; +#elif SIZEOF_LONG == 8 + #define WORD64_AVAILABLE + #define W64LIT(x) x##LL + typedef unsigned long word64; +#elif SIZEOF_LONG_LONG == 8 + #define WORD64_AVAILABLE + #define W64LIT(x) x##LL + typedef unsigned long long word64; +#else + #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as + mp_digit, no 64 bit type so make mp_digit 16 bit */ +#endif + + +/* These platforms have 64-bit CPU registers. */ +#if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \ + defined(__mips64) || defined(__x86_64__)) + typedef word64 word; +#else + typedef word32 word; + #ifdef WORD64_AVAILABLE + #define CTAOCRYPT_SLOW_WORD64 + #endif +#endif + + +enum { + WORD_SIZE = sizeof(word), + BIT_SIZE = 8, + WORD_BITS = WORD_SIZE * BIT_SIZE +}; + + +/* use inlining if compiler allows */ +#ifndef INLINE +#ifndef NO_INLINE + #ifdef _MSC_VER + #define INLINE __inline + #elif defined(__GNUC__) + #define INLINE inline + #elif defined(THREADX) + #define INLINE _Inline + #else + #define INLINE + #endif +#else + #define INLINE +#endif +#endif + + +/* set up rotate style */ +#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) + #define INTEL_INTRINSICS + #define FAST_ROTATE +#elif defined(__MWERKS__) && TARGET_CPU_PPC + #define PPC_INTRINSICS + #define FAST_ROTATE +#elif defined(__GNUC__) && defined(__i386__) + /* GCC does peephole optimizations which should result in using rotate + instructions */ + #define FAST_ROTATE +#endif + + +/* Micrium will use Visual Studio for compilation but not the Win32 API */ +#if defined(_WIN32) && !defined(MICRIUM) + #define USE_WINDOWS_API +#endif + + +/* idea to add global alloc override by Moisés Guimarães */ +/* default to libc stuff */ +/* XREALLOC is used once in mormal math lib, not in fast math lib */ +/* XFREE on some embeded systems doesn't like free(0) so test */ +#ifdef XMALLOC_USER + /* prototypes for user heap override functions */ + #include /* for size_t */ + extern void *XMALLOC(size_t n, void* heap, int type); + extern void *XREALLOC(void *p, size_t n, void* heap, int type); + extern void XFREE(void *p, void* heap, int type); +#elif !defined(MICRIUM_MALLOC) + /* defaults to C runtime if user doesn't override and not Micrium */ + #include + #define XMALLOC(s, h, t) malloc((s)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} + #define XREALLOC(p, n, h, t) realloc((p), (n)) +#endif + +#ifndef STRING_USER + #include + #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) + #define XMEMSET(b,c,l) memset((b),(c),(l)) + #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) + #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) + + #define XSTRLEN(s1) strlen((s1)) + #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) + /* strstr and strncmp only used by CyaSSL proper, not required for + CTaoCrypt only */ + #define XSTRSTR(s1,s2) strstr((s1),(s2)) + #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) +#endif + +#ifdef HAVE_ECC + #ifndef CTYPE_USER + #include + #define XTOUPPER(c) toupper((c)) + #endif +#endif + + +/* memory allocation types for user hints */ +enum { + DYNAMIC_TYPE_CA = 1, + DYNAMIC_TYPE_CERT = 2, + DYNAMIC_TYPE_KEY = 3, + DYNAMIC_TYPE_FILE = 4, + DYNAMIC_TYPE_ISSUER_CN = 5, + DYNAMIC_TYPE_PUBLIC_KEY = 6, + DYNAMIC_TYPE_SIGNER = 7, + DYNAMIC_TYPE_NONE = 8, + DYNAMIC_TYPE_BIGINT = 9, + DYNAMIC_TYPE_RSA = 10, + DYNAMIC_TYPE_METHOD = 11, + DYNAMIC_TYPE_OUT_BUFFER = 12, + DYNAMIC_TYPE_IN_BUFFER = 13, + DYNAMIC_TYPE_INFO = 14, + DYNAMIC_TYPE_DH = 15, + DYNAMIC_TYPE_DOMAIN = 16, + DYNAMIC_TYPE_SSL = 17, + DYNAMIC_TYPE_CTX = 18, + DYNAMIC_TYPE_WRITEV = 19, + DYNAMIC_TYPE_OPENSSL = 20 +}; + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CTAO_CRYPT_TYPES_H */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/Makefile.am b/release/src/router/cyassl/ctaocrypt/src/Makefile.am new file mode 100644 index 00000000..357c2ed2 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = ../include/*.h *.c *.i + diff --git a/release/src/router/cyassl/ctaocrypt/src/Makefile.in b/release/src/router/cyassl/ctaocrypt/src/Makefile.in new file mode 100644 index 00000000..fbdad9c4 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/Makefile.in @@ -0,0 +1,343 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@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@ +target_triplet = @target@ +subdir = ctaocrypt/src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/lib_socket_nsl.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ctaocrypt/include/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBM = @LIBM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +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_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = ../include/*.h *.c *.i +all: all-am + +.SUFFIXES: +$(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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ctaocrypt/src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ctaocrypt/src/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 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +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 $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$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 +installdirs: +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +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 mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool 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-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + +# 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/release/src/router/cyassl/ctaocrypt/src/aes.c b/release/src/router/cyassl/ctaocrypt/src/aes.c new file mode 100644 index 00000000..841c1e4e --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/aes.c @@ -0,0 +1,1312 @@ +/* aes.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_AES + +#include "ctc_aes.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +static const word32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + + +static const word32 Te[5][256] = { +{ + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}, +{ + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}, +{ + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}, +{ + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}, +{ + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +} +}; + + +static const word32 Td[5][256] = { +{ + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}, +{ + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}, +{ + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}, +{ + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}, +{ + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +} +}; + + + +#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) + + +#ifdef CYASSL_AESNI + +#define cpuid(func,ax,bx,cx,dx)\ + __asm__ __volatile__ ("cpuid":\ + "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); + +static int Check_CPU_support_AES() +{ + unsigned int a,b,c,d; + cpuid(1,a,b,c,d); + + if (c & 0x2000000) + return 1; + + return 0; +} + +static int checkAESNI = 0; +static int haveAESNI = 0; + + +void AES_CBC_encrypt(const unsigned char* in, unsigned char* out, + unsigned char* ivec, unsigned long length, + const unsigned char* KS, int nr); + + +void AES_CBC_decrypt(const unsigned char* in, unsigned char* out, + unsigned char* ivec, unsigned long length, + const unsigned char* KS, int nr); + +void AES_128_Key_Expansion(const unsigned char* userkey, + unsigned char* key_schedule); + +void AES_192_Key_Expansion(const unsigned char* userkey, + unsigned char* key_schedule); + +void AES_256_Key_Expansion(const unsigned char* userkey, + unsigned char* key_schedule); + + +int AES_set_encrypt_key (const unsigned char *userKey, const int bits, + Aes* aes) +{ + if (!userKey || !aes) + return -1; + + if (bits == 128) { + AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10; + return 0; + } + else if (bits == 192) { + AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12; + return 0; + } + else if (bits == 256) { + AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14; + return 0; + } + return -1; +} + + +int AES_set_decrypt_key (const unsigned char* userKey, const int bits, + Aes* aes) +{ + int nr; + Aes temp_key; + __m128i *Key_Schedule = (__m128i*)aes->key; + __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key; + + if (!userKey || !aes) + return -1; + + if (AES_set_encrypt_key(userKey,bits,&temp_key) == -1) + return -1; + + nr = temp_key.rounds; + aes->rounds = nr; + + Key_Schedule[nr] = Temp_Key_Schedule[0]; + Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]); + Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]); + Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]); + Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]); + Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]); + Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]); + Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]); + Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]); + Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]); + + if(nr>10) { + Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]); + Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]); + } + + if(nr>12) { + Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]); + Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]); + } + + Key_Schedule[0] = Temp_Key_Schedule[nr]; + + return 0; +} + + + +#endif /* CYASSL_AESNI */ + + +int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) +{ + word32 temp, *rk = aes->key; + unsigned int i = 0; + + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return -1; + +#ifdef CYASSL_AESNI + if (checkAESNI == 0) { + haveAESNI = Check_CPU_support_AES(); + checkAESNI = 1; + } + if (haveAESNI) { + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + if (dir == AES_ENCRYPTION) + return AES_set_encrypt_key(userKey, keylen * 8, aes); + else + return AES_set_decrypt_key(userKey, keylen * 8, aes); + } +#endif /* CYASSL_AESNI */ + + aes->rounds = keylen/4 + 6; + + XMEMCPY(rk, userKey, keylen); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords(rk, rk, keylen); + #endif + + switch(keylen) + { + case 16: + while (1) + { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) + break; + rk += 4; + } + break; + + case 24: + while (1) /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ + { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) + break; + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + break; + + case 32: + while (1) + { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) + break; + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 0)] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + break; + } + + if (dir == AES_DECRYPTION) + { + unsigned int i, j; + rk = aes->key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the + first and the last: */ + for (i = 1; i < aes->rounds; i++) { + rk += 4; + rk[0] = + Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff]; + rk[1] = + Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff]; + rk[2] = + Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff]; + rk[3] = + Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; + } + } + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + + return 0; +} + + +void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) +{ + word32 s0, s1, s2, s3; + word32 t0, t1, t2, t3; + word32 r = aes->rounds >> 1; + + const word32* rk = aes->key; + if (r > 7) + return; /* stop instead of segfaulting, set up your keys! */ + /* + * map byte array block to cipher state + * and add initial round key: + */ + XMEMCPY(&s0, inBlock, sizeof(s0)); + XMEMCPY(&s1, inBlock + sizeof(s0), sizeof(s1)); + XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2)); + XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3)); + + #ifdef LITTLE_ENDIAN_ORDER + s0 = ByteReverseWord32(s0); + s1 = ByteReverseWord32(s1); + s2 = ByteReverseWord32(s2); + s3 = ByteReverseWord32(s3); + #endif + + s0 ^= rk[0]; + s1 ^= rk[1]; + s2 ^= rk[2]; + s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + + for (;;) { + t0 = + Te[0][GETBYTE(s0, 3)] ^ + Te[1][GETBYTE(s1, 2)] ^ + Te[2][GETBYTE(s2, 1)] ^ + Te[3][GETBYTE(s3, 0)] ^ + rk[4]; + t1 = + Te[0][GETBYTE(s1, 3)] ^ + Te[1][GETBYTE(s2, 2)] ^ + Te[2][GETBYTE(s3, 1)] ^ + Te[3][GETBYTE(s0, 0)] ^ + rk[5]; + t2 = + Te[0][GETBYTE(s2, 3)] ^ + Te[1][GETBYTE(s3, 2)] ^ + Te[2][GETBYTE(s0, 1)] ^ + Te[3][GETBYTE(s1, 0)] ^ + rk[6]; + t3 = + Te[0][GETBYTE(s3, 3)] ^ + Te[1][GETBYTE(s0, 2)] ^ + Te[2][GETBYTE(s1, 1)] ^ + Te[3][GETBYTE(s2, 0)] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te[0][GETBYTE(t0, 3)] ^ + Te[1][GETBYTE(t1, 2)] ^ + Te[2][GETBYTE(t2, 1)] ^ + Te[3][GETBYTE(t3, 0)] ^ + rk[0]; + s1 = + Te[0][GETBYTE(t1, 3)] ^ + Te[1][GETBYTE(t2, 2)] ^ + Te[2][GETBYTE(t3, 1)] ^ + Te[3][GETBYTE(t0, 0)] ^ + rk[1]; + s2 = + Te[0][GETBYTE(t2, 3)] ^ + Te[1][GETBYTE(t3, 2)] ^ + Te[2][GETBYTE(t0, 1)] ^ + Te[3][GETBYTE(t1, 0)] ^ + rk[2]; + s3 = + Te[0][GETBYTE(t3, 3)] ^ + Te[1][GETBYTE(t0, 2)] ^ + Te[2][GETBYTE(t1, 1)] ^ + Te[3][GETBYTE(t2, 0)] ^ + rk[3]; + } + + /* + * apply last round and + * map cipher state to byte array block: + */ + + s0 = + (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^ + rk[0]; + s1 = + (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^ + rk[1]; + s2 = + (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^ + rk[2]; + s3 = + (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^ + rk[3]; + + /* write out */ + #ifdef LITTLE_ENDIAN_ORDER + s0 = ByteReverseWord32(s0); + s1 = ByteReverseWord32(s1); + s2 = ByteReverseWord32(s2); + s3 = ByteReverseWord32(s3); + #endif + + XMEMCPY(outBlock, &s0, sizeof(s0)); + XMEMCPY(outBlock + sizeof(s0), &s1, sizeof(s1)); + XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2)); + XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); +} + + +void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) +{ + word32 s0, s1, s2, s3; + word32 t0, t1, t2, t3; + word32 r = aes->rounds >> 1; + + const word32* rk = aes->key; + if (r > 7) + return; /* stop instead of segfaulting, set up your keys! */ + /* + * map byte array block to cipher state + * and add initial round key: + */ + XMEMCPY(&s0, inBlock, sizeof(s0)); + XMEMCPY(&s1, inBlock + sizeof(s0), sizeof(s1)); + XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2)); + XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3)); + + #ifdef LITTLE_ENDIAN_ORDER + s0 = ByteReverseWord32(s0); + s1 = ByteReverseWord32(s1); + s2 = ByteReverseWord32(s2); + s3 = ByteReverseWord32(s3); + #endif + + s0 ^= rk[0]; + s1 ^= rk[1]; + s2 ^= rk[2]; + s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + + for (;;) { + t0 = + Td[0][GETBYTE(s0, 3)] ^ + Td[1][GETBYTE(s3, 2)] ^ + Td[2][GETBYTE(s2, 1)] ^ + Td[3][GETBYTE(s1, 0)] ^ + rk[4]; + t1 = + Td[0][GETBYTE(s1, 3)] ^ + Td[1][GETBYTE(s0, 2)] ^ + Td[2][GETBYTE(s3, 1)] ^ + Td[3][GETBYTE(s2, 0)] ^ + rk[5]; + t2 = + Td[0][GETBYTE(s2, 3)] ^ + Td[1][GETBYTE(s1, 2)] ^ + Td[2][GETBYTE(s0, 1)] ^ + Td[3][GETBYTE(s3, 0)] ^ + rk[6]; + t3 = + Td[0][GETBYTE(s3, 3)] ^ + Td[1][GETBYTE(s2, 2)] ^ + Td[2][GETBYTE(s1, 1)] ^ + Td[3][GETBYTE(s0, 0)] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td[0][GETBYTE(t0, 3)] ^ + Td[1][GETBYTE(t3, 2)] ^ + Td[2][GETBYTE(t2, 1)] ^ + Td[3][GETBYTE(t1, 0)] ^ + rk[0]; + s1 = + Td[0][GETBYTE(t1, 3)] ^ + Td[1][GETBYTE(t0, 2)] ^ + Td[2][GETBYTE(t3, 1)] ^ + Td[3][GETBYTE(t2, 0)] ^ + rk[1]; + s2 = + Td[0][GETBYTE(t2, 3)] ^ + Td[1][GETBYTE(t1, 2)] ^ + Td[2][GETBYTE(t0, 1)] ^ + Td[3][GETBYTE(t3, 0)] ^ + rk[2]; + s3 = + Td[0][GETBYTE(t3, 3)] ^ + Td[1][GETBYTE(t2, 2)] ^ + Td[2][GETBYTE(t1, 1)] ^ + Td[3][GETBYTE(t0, 0)] ^ + rk[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^ + (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ + (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ + (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^ + rk[0]; + s1 = + (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^ + (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ + (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ + (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^ + rk[1]; + s2 = + (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^ + (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ + (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ + (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^ + rk[2]; + s3 = + (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^ + (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ + (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ + (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^ + rk[3]; + + /* write out */ + #ifdef LITTLE_ENDIAN_ORDER + s0 = ByteReverseWord32(s0); + s1 = ByteReverseWord32(s1); + s2 = ByteReverseWord32(s2); + s3 = ByteReverseWord32(s3); + #endif + + XMEMCPY(outBlock, &s0, sizeof(s0)); + XMEMCPY(outBlock + sizeof(s0), &s1, sizeof(s1)); + XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2)); + XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); +} + + +void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / AES_BLOCK_SIZE; + +#ifdef CYASSL_AESNI + if (haveAESNI) { + #ifdef DEBUG_AESNI + printf("about to aes cbc encrypt\n"); + printf("in = %p\n", in); + printf("out = %p\n", out); + printf("aes->key = %p\n", aes->key); + printf("aes->reg = %p\n", aes->reg); + printf("aes->rounds = %d\n", aes->rounds); + printf("sz = %d\n", sz); + #endif + AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, + aes->rounds); + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + return; + } +#endif + + while (blocks--) { + xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE); + AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg); + XMEMCPY(out, aes->reg, AES_BLOCK_SIZE); + + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } +} + + +void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / AES_BLOCK_SIZE; + +#ifdef CYASSL_AESNI + if (haveAESNI) { + #ifdef DEBUG_AESNI + printf("about to aes cbc decrypt\n"); + printf("in = %p\n", in); + printf("out = %p\n", out); + printf("aes->key = %p\n", aes->key); + printf("aes->reg = %p\n", aes->reg); + printf("aes->rounds = %d\n", aes->rounds); + printf("sz = %d\n", sz); + #endif + + /* if input and output same will overwirte input iv */ + XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, + aes->rounds); + /* store iv for next call */ + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + return; + } +#endif + + while (blocks--) { + XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE); + AesDecrypt(aes, (byte*)aes->tmp, out); + xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE); + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } +} + + +#endif /* NO_AES */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/aes_asm.s b/release/src/router/cyassl/ctaocrypt/src/aes_asm.s new file mode 100755 index 00000000..4aa35861 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/aes_asm.s @@ -0,0 +1,484 @@ +/* aes_asm.s + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +/* See Intel® Advanced Encryption Standard (AES) Instructions Set White Paper + * by Intel Mobility Group, Israel Development Center, Israel Shay Gueron + */ + + +//AES_CBC_encrypt (const unsigned char *in, +// unsigned char *out, +// unsigned char ivec[16], +// unsigned long length, +// const unsigned char *KS, +// int nr) +.globl AES_CBC_encrypt +AES_CBC_encrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8 +# parameter 6: %r9d +movq %rcx, %r10 +shrq $4, %rcx +shlq $60, %r10 +je NO_PARTS +addq $1, %rcx +NO_PARTS: +subq $16, %rsi +movdqa (%rdx), %xmm1 +LOOP: +pxor (%rdi), %xmm1 +pxor (%r8), %xmm1 +addq $16,%rsi +addq $16,%rdi +cmpl $12, %r9d +aesenc 16(%r8),%xmm1 +aesenc 32(%r8),%xmm1 +aesenc 48(%r8),%xmm1 +aesenc 64(%r8),%xmm1 +aesenc 80(%r8),%xmm1 +aesenc 96(%r8),%xmm1 +aesenc 112(%r8),%xmm1 +aesenc 128(%r8),%xmm1 +aesenc 144(%r8),%xmm1 +movdqa 160(%r8),%xmm2 +jb LAST +cmpl $14, %r9d + +aesenc 160(%r8),%xmm1 +aesenc 176(%r8),%xmm1 +movdqa 192(%r8),%xmm2 +jb LAST +aesenc 192(%r8),%xmm1 +aesenc 208(%r8),%xmm1 +movdqa 224(%r8),%xmm2 +LAST: +decq %rcx +aesenclast %xmm2,%xmm1 +movdqu %xmm1,(%rsi) +jne LOOP +ret + + + +//AES_CBC_decrypt (const unsigned char *in, +// unsigned char *out, +// unsigned char ivec[16], +// unsigned long length, +// const unsigned char *KS, +// int nr) +.globl AES_CBC_decrypt +AES_CBC_decrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8 +# parameter 6: %r9d + +movq %rcx, %r10 +shrq $4, %rcx +shlq $60, %r10 +je DNO_PARTS_4 +addq $1, %rcx +DNO_PARTS_4: +movq %rcx, %r10 +shlq $62, %r10 +shrq $62, %r10 +shrq $2, %rcx +movdqu (%rdx),%xmm5 +je DREMAINDER_4 +subq $64, %rsi +DLOOP_4: +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm2 +movdqu 32(%rdi), %xmm3 +movdqu 48(%rdi), %xmm4 +movdqa %xmm1, %xmm6 +movdqa %xmm2, %xmm7 +movdqa %xmm3, %xmm8 +movdqa %xmm4, %xmm15 +movdqa (%r8), %xmm9 +movdqa 16(%r8), %xmm10 +movdqa 32(%r8), %xmm11 +movdqa 48(%r8), %xmm12 +pxor %xmm9, %xmm1 +pxor %xmm9, %xmm2 +pxor %xmm9, %xmm3 + +pxor %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +aesdec %xmm11, %xmm1 +aesdec %xmm11, %xmm2 +aesdec %xmm11, %xmm3 +aesdec %xmm11, %xmm4 +aesdec %xmm12, %xmm1 +aesdec %xmm12, %xmm2 +aesdec %xmm12, %xmm3 +aesdec %xmm12, %xmm4 +movdqa 64(%r8), %xmm9 +movdqa 80(%r8), %xmm10 +movdqa 96(%r8), %xmm11 +movdqa 112(%r8), %xmm12 +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +aesdec %xmm11, %xmm1 +aesdec %xmm11, %xmm2 +aesdec %xmm11, %xmm3 +aesdec %xmm11, %xmm4 +aesdec %xmm12, %xmm1 +aesdec %xmm12, %xmm2 +aesdec %xmm12, %xmm3 +aesdec %xmm12, %xmm4 +movdqa 128(%r8), %xmm9 +movdqa 144(%r8), %xmm10 +movdqa 160(%r8), %xmm11 +cmpl $12, %r9d +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +jb DLAST_4 +movdqa 160(%r8), %xmm9 +movdqa 176(%r8), %xmm10 +movdqa 192(%r8), %xmm11 +cmpl $14, %r9d +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +jb DLAST_4 + +movdqa 192(%r8), %xmm9 +movdqa 208(%r8), %xmm10 +movdqa 224(%r8), %xmm11 +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +DLAST_4: +addq $64, %rdi +addq $64, %rsi +decq %rcx +aesdeclast %xmm11, %xmm1 +aesdeclast %xmm11, %xmm2 +aesdeclast %xmm11, %xmm3 +aesdeclast %xmm11, %xmm4 +pxor %xmm5 ,%xmm1 +pxor %xmm6 ,%xmm2 +pxor %xmm7 ,%xmm3 +pxor %xmm8 ,%xmm4 +movdqu %xmm1, (%rsi) +movdqu %xmm2, 16(%rsi) +movdqu %xmm3, 32(%rsi) +movdqu %xmm4, 48(%rsi) +movdqa %xmm15,%xmm5 +jne DLOOP_4 +addq $64, %rsi +DREMAINDER_4: +cmpq $0, %r10 +je DEND_4 +DLOOP_4_2: +movdqu (%rdi), %xmm1 +movdqa %xmm1 ,%xmm15 +addq $16, %rdi +pxor (%r8), %xmm1 +movdqu 160(%r8), %xmm2 +cmpl $12, %r9d +aesdec 16(%r8), %xmm1 +aesdec 32(%r8), %xmm1 +aesdec 48(%r8), %xmm1 +aesdec 64(%r8), %xmm1 +aesdec 80(%r8), %xmm1 +aesdec 96(%r8), %xmm1 +aesdec 112(%r8), %xmm1 +aesdec 128(%r8), %xmm1 +aesdec 144(%r8), %xmm1 +jb DLAST_4_2 +movdqu 192(%r8), %xmm2 +cmpl $14, %r9d +aesdec 160(%r8), %xmm1 +aesdec 176(%r8), %xmm1 +jb DLAST_4_2 +movdqu 224(%r8), %xmm2 +aesdec 192(%r8), %xmm1 +aesdec 208(%r8), %xmm1 +DLAST_4_2: +aesdeclast %xmm2, %xmm1 +pxor %xmm5, %xmm1 +movdqa %xmm15, %xmm5 +movdqu %xmm1, (%rsi) + +addq $16, %rsi +decq %r10 +jne DLOOP_4_2 +DEND_4: +ret + + + + +//void AES_128_Key_Expansion(const unsigned char* userkey, +// unsigned char* key_schedule); +.align 16,0x90 +.globl AES_128_Key_Expansion +AES_128_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi +movl $10, 240(%rsi) + +movdqu (%rdi), %xmm1 +movdqa %xmm1, (%rsi) + + +ASSISTS: +aeskeygenassist $1, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 16(%rsi) +aeskeygenassist $2, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 32(%rsi) +aeskeygenassist $4, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 48(%rsi) +aeskeygenassist $8, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 64(%rsi) +aeskeygenassist $16, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 80(%rsi) +aeskeygenassist $32, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 96(%rsi) +aeskeygenassist $64, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 112(%rsi) +aeskeygenassist $0x80, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 128(%rsi) +aeskeygenassist $0x1b, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 144(%rsi) +aeskeygenassist $0x36, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 160(%rsi) +ret + +PREPARE_ROUNDKEY_128: +pshufd $255, %xmm2, %xmm2 +movdqa %xmm1, %xmm3 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pxor %xmm2, %xmm1 +ret + + +//void AES_192_Key_Expansion (const unsigned char *userkey, +// unsigned char *key) +.globl AES_192_Key_Expansion +AES_192_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi + +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm3 +movdqa %xmm1, (%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x1, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 16(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 32(%rsi) + +aeskeygenassist $0x2, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 48(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x4, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 64(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 80(%rsi) + +aeskeygenassist $0x8, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 96(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x10, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 112(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 128(%rsi) + +aeskeygenassist $0x20, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 144(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x40, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 160(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 176(%rsi) + +aeskeygenassist $0x80, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 192(%rsi) +movdqa %xmm3, 208(%rsi) +ret + +PREPARE_ROUNDKEY_192: +pshufd $0x55, %xmm2, %xmm2 +movdqu %xmm1, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 + +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pxor %xmm2, %xmm1 +pshufd $0xff, %xmm1, %xmm2 +movdqu %xmm3, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pxor %xmm2, %xmm3 +ret + + +//void AES_256_Key_Expansion (const unsigned char *userkey, +// unsigned char *key) +.globl AES_256_Key_Expansion +AES_256_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi + +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm3 +movdqa %xmm1, (%rsi) +movdqa %xmm3, 16(%rsi) + +aeskeygenassist $0x1, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 32(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 48(%rsi) +aeskeygenassist $0x2, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 64(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 80(%rsi) +aeskeygenassist $0x4, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 96(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 112(%rsi) +aeskeygenassist $0x8, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 128(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 144(%rsi) +aeskeygenassist $0x10, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 160(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 176(%rsi) +aeskeygenassist $0x20, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 192(%rsi) + +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 208(%rsi) +aeskeygenassist $0x40, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 224(%rsi) + +ret + +MAKE_RK256_a: +pshufd $0xff, %xmm2, %xmm2 +movdqa %xmm1, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pxor %xmm2, %xmm1 +ret + +MAKE_RK256_b: +pshufd $0xaa, %xmm2, %xmm2 +movdqa %xmm3, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pxor %xmm2, %xmm3 +ret + diff --git a/release/src/router/cyassl/ctaocrypt/src/arc4.c b/release/src/router/cyassl/ctaocrypt/src/arc4.c new file mode 100644 index 00000000..a9b9729e --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/arc4.c @@ -0,0 +1,76 @@ +/* arc4.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "arc4.h" + + + +void Arc4SetKey(Arc4* arc4, const byte* key, word32 length) +{ + word32 i; + word32 keyIndex = 0, stateIndex = 0; + + arc4->x = 1; + arc4->y = 0; + + for (i = 0; i < ARC4_STATE_SIZE; i++) + arc4->state[i] = i; + + for (i = 0; i < ARC4_STATE_SIZE; i++) { + word32 a = arc4->state[i]; + stateIndex += key[keyIndex] + a; + stateIndex &= 0xFF; + arc4->state[i] = arc4->state[stateIndex]; + arc4->state[stateIndex] = a; + + if (++keyIndex >= length) + keyIndex = 0; + } +} + + +static INLINE word32 MakeByte(word32* x, word32* y, byte* s) +{ + word32 a = s[*x], b; + *y = (*y+a) & 0xff; + + b = s[*y]; + s[*x] = b; + s[*y] = a; + *x = (*x+1) & 0xff; + + return s[(a+b) & 0xff]; +} + + +void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) +{ + word32 x = arc4->x; + word32 y = arc4->y; + + while(length--) + *out++ = *in++ ^ MakeByte(&x, &y, arc4->state); + + arc4->x = x; + arc4->y = y; +} + diff --git a/release/src/router/cyassl/ctaocrypt/src/asm.c b/release/src/router/cyassl/ctaocrypt/src/asm.c new file mode 100644 index 00000000..0a5084e0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/asm.c @@ -0,0 +1,1302 @@ +/* asm.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + + +/******************************************************************/ +/* fp_montgomery_reduce.c asm or generic */ +#if defined(TFM_X86) && !defined(TFM_SSE2) +/* x86-32 code */ + +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + "movl %5,%%eax \n\t" \ + "mull %4 \n\t" \ + "addl %1,%%eax \n\t" \ + "adcl $0,%%edx \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl $0,%%edx \n\t" \ + "movl %%edx,%1 \n\t" \ +:"=g"(_c[LO]), "=r"(cy) \ +:"0"(_c[LO]), "1"(cy), "g"(mu), "g"(*tmpm++) \ +: "%eax", "%edx", "%cc") + +#define PROPCARRY \ +asm( \ + "addl %1,%0 \n\t" \ + "setb %%al \n\t" \ + "movzbl %%al,%1 \n\t" \ +:"=g"(_c[LO]), "=r"(cy) \ +:"0"(_c[LO]), "1"(cy) \ +: "%eax", "%cc") + +/******************************************************************/ +#elif defined(TFM_X86_64) +/* x86-64 code */ + +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + "movq %5,%%rax \n\t" \ + "mulq %4 \n\t" \ + "addq %1,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rdx,%1 \n\t" \ +:"=g"(_c[LO]), "=r"(cy) \ +:"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \ +: "%rax", "%rdx", "%cc") + +#define INNERMUL8 \ + asm( \ + "movq 0(%5),%%rax \n\t" \ + "movq 0(%2),%%r10 \n\t" \ + "movq 0x8(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x8(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x10(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x10(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x8(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x18(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x18(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x10(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x20(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x20(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x18(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x28(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x28(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x20(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x30(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x30(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x28(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "movq 0x38(%5),%%r11 \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq 0x38(%2),%%r10 \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x30(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ + "movq %%r11,%%rax \n\t" \ + "mulq %4 \n\t" \ + "addq %%r10,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "addq %3,%%rax \n\t" \ + "adcq $0,%%rdx \n\t" \ + "movq %%rax,0x38(%0) \n\t" \ + "movq %%rdx,%1 \n\t" \ + \ +:"=r"(_c), "=r"(cy) \ +: "0"(_c), "1"(cy), "g"(mu), "r"(tmpm)\ +: "%rax", "%rdx", "%r10", "%r11", "%cc") + + +#define PROPCARRY \ +asm( \ + "addq %1,%0 \n\t" \ + "setb %%al \n\t" \ + "movzbq %%al,%1 \n\t" \ +:"=g"(_c[LO]), "=r"(cy) \ +:"0"(_c[LO]), "1"(cy) \ +: "%rax", "%cc") + +/******************************************************************/ +#elif defined(TFM_SSE2) +/* SSE2 code (assumes 32-bit fp_digits) */ +/* XMM register assignments: + * xmm0 *tmpm++, then Mu * (*tmpm++) + * xmm1 c[x], then Mu + * xmm2 mp + * xmm3 cy + * xmm4 _c[LO] + */ + +#define MONT_START \ + asm("movd %0,%%mm2"::"g"(mp)) + +#define MONT_FINI \ + asm("emms") + +#define LOOP_START \ +asm( \ +"movd %0,%%mm1 \n\t" \ +"pxor %%mm3,%%mm3 \n\t" \ +"pmuludq %%mm2,%%mm1 \n\t" \ +:: "g"(c[x])) + +/* pmuludq on mmx registers does a 32x32->64 multiply. */ +#define INNERMUL \ +asm( \ + "movd %1,%%mm4 \n\t" \ + "movd %2,%%mm0 \n\t" \ + "paddq %%mm4,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm0 \n\t" \ + "paddq %%mm0,%%mm3 \n\t" \ + "movd %%mm3,%0 \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +:"=g"(_c[LO]) : "0"(_c[LO]), "g"(*tmpm++) ); + +#define INNERMUL8 \ +asm( \ + "movd 0(%1),%%mm4 \n\t" \ + "movd 0(%2),%%mm0 \n\t" \ + "paddq %%mm4,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm0 \n\t" \ + "movd 4(%2),%%mm5 \n\t" \ + "paddq %%mm0,%%mm3 \n\t" \ + "movd 4(%1),%%mm6 \n\t" \ + "movd %%mm3,0(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm6,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm5 \n\t" \ + "movd 8(%2),%%mm6 \n\t" \ + "paddq %%mm5,%%mm3 \n\t" \ + "movd 8(%1),%%mm7 \n\t" \ + "movd %%mm3,4(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm7,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm6 \n\t" \ + "movd 12(%2),%%mm7 \n\t" \ + "paddq %%mm6,%%mm3 \n\t" \ + "movd 12(%1),%%mm5 \n\t" \ + "movd %%mm3,8(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm5,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm7 \n\t" \ + "movd 16(%2),%%mm5 \n\t" \ + "paddq %%mm7,%%mm3 \n\t" \ + "movd 16(%1),%%mm6 \n\t" \ + "movd %%mm3,12(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm6,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm5 \n\t" \ + "movd 20(%2),%%mm6 \n\t" \ + "paddq %%mm5,%%mm3 \n\t" \ + "movd 20(%1),%%mm7 \n\t" \ + "movd %%mm3,16(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm7,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm6 \n\t" \ + "movd 24(%2),%%mm7 \n\t" \ + "paddq %%mm6,%%mm3 \n\t" \ + "movd 24(%1),%%mm5 \n\t" \ + "movd %%mm3,20(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm5,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm7 \n\t" \ + "movd 28(%2),%%mm5 \n\t" \ + "paddq %%mm7,%%mm3 \n\t" \ + "movd 28(%1),%%mm6 \n\t" \ + "movd %%mm3,24(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +\ + "paddq %%mm6,%%mm3 \n\t" \ + "pmuludq %%mm1,%%mm5 \n\t" \ + "paddq %%mm5,%%mm3 \n\t" \ + "movd %%mm3,28(%0) \n\t" \ + "psrlq $32, %%mm3 \n\t" \ +:"=r"(_c) : "0"(_c), "r"(tmpm) ); + +/* TAO switched tmpm from "g" to "r" after gcc tried to index the indexed stack + pointer */ + +#define LOOP_END \ +asm( "movd %%mm3,%0 \n" :"=r"(cy)) + +#define PROPCARRY \ +asm( \ + "addl %1,%0 \n\t" \ + "setb %%al \n\t" \ + "movzbl %%al,%1 \n\t" \ +:"=g"(_c[LO]), "=r"(cy) \ +:"0"(_c[LO]), "1"(cy) \ +: "%eax", "%cc") + +/******************************************************************/ +#elif defined(TFM_ARM) + /* ARMv4 code */ + +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + " LDR r0,%1 \n\t" \ + " ADDS r0,r0,%0 \n\t" \ + " MOVCS %0,#1 \n\t" \ + " MOVCC %0,#0 \n\t" \ + " UMLAL r0,%0,%3,%4 \n\t" \ + " STR r0,%1 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"r"(mu),"r"(*tmpm++),"1"(_c[0]):"r0","%cc"); + +#define PROPCARRY \ +asm( \ + " LDR r0,%1 \n\t" \ + " ADDS r0,r0,%0 \n\t" \ + " STR r0,%1 \n\t" \ + " MOVCS %0,#1 \n\t" \ + " MOVCC %0,#0 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"1"(_c[0]):"r0","%cc"); + +#elif defined(TFM_PPC32) + +/* PPC32 */ +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + " mullw 16,%3,%4 \n\t" \ + " mulhwu 17,%3,%4 \n\t" \ + " addc 16,16,%0 \n\t" \ + " addze 17,17 \n\t" \ + " lwz 18,%1 \n\t" \ + " addc 16,16,18 \n\t" \ + " addze %0,17 \n\t" \ + " stw 16,%1 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"r"(mu),"r"(tmpm[0]),"1"(_c[0]):"16", "17", "18","%cc"); ++tmpm; + +#define PROPCARRY \ +asm( \ + " lwz 16,%1 \n\t" \ + " addc 16,16,%0 \n\t" \ + " stw 16,%1 \n\t" \ + " xor %0,%0,%0 \n\t" \ + " addze %0,%0 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"1"(_c[0]):"16","%cc"); + +#elif defined(TFM_PPC64) + +/* PPC64 */ +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + " mulld 16,%3,%4 \n\t" \ + " mulhdu 17,%3,%4 \n\t" \ + " addc 16,16,%0 \n\t" \ + " addze 17,17 \n\t" \ + " ldx 18,0,%1 \n\t" \ + " addc 16,16,18 \n\t" \ + " addze %0,17 \n\t" \ + " sdx 16,0,%1 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"r"(mu),"r"(tmpm[0]),"1"(_c[0]):"16", "17", "18","%cc"); ++tmpm; + +#define PROPCARRY \ +asm( \ + " ldx 16,0,%1 \n\t" \ + " addc 16,16,%0 \n\t" \ + " sdx 16,0,%1 \n\t" \ + " xor %0,%0,%0 \n\t" \ + " addze %0,%0 \n\t" \ +:"=r"(cy),"=m"(_c[0]):"0"(cy),"1"(_c[0]):"16","%cc"); + +/******************************************************************/ + +#elif defined(TFM_AVR32) + +/* AVR32 */ +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ +asm( \ + " ld.w r2,%1 \n\t" \ + " add r2,%0 \n\t" \ + " eor r3,r3 \n\t" \ + " acr r3 \n\t" \ + " macu.d r2,%3,%4 \n\t" \ + " st.w %1,r2 \n\t" \ + " mov %0,r3 \n\t" \ +:"=r"(cy),"=r"(_c):"0"(cy),"r"(mu),"r"(*tmpm++),"1"(_c):"r2","r3"); + +#define PROPCARRY \ +asm( \ + " ld.w r2,%1 \n\t" \ + " add r2,%0 \n\t" \ + " st.w %1,r2 \n\t" \ + " eor %0,%0 \n\t" \ + " acr %0 \n\t" \ +:"=r"(cy),"=r"(&_c[0]):"0"(cy),"1"(&_c[0]):"r2","%cc"); + +#else + +/* ISO C code */ +#define MONT_START +#define MONT_FINI +#define LOOP_END +#define LOOP_START \ + mu = c[x] * mp + +#define INNERMUL \ + do { fp_word t; \ + _c[0] = t = ((fp_word)_c[0] + (fp_word)cy) + \ + (((fp_word)mu) * ((fp_word)*tmpm++)); \ + cy = (t >> DIGIT_BIT); \ + } while (0) + +#define PROPCARRY \ + do { fp_digit t = _c[0] += cy; cy = (t < cy); } while (0) + +#endif +/******************************************************************/ + + +#define LO 0 +/* end fp_montogomery_reduce.c asm */ + + +/* start fp_sqr_comba.c asm */ +#if defined(TFM_X86) + +/* x86-32 optimized */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +#define SQRADD(i, j) \ +asm( \ + "movl %6,%%eax \n\t" \ + "mull %%eax \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); + +#define SQRADD2(i, j) \ +asm( \ + "movl %6,%%eax \n\t" \ + "mull %7 \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx", "%cc"); + +#define SQRADDSC(i, j) \ +asm( \ + "movl %3,%%eax \n\t" \ + "mull %4 \n\t" \ + "movl %%eax,%0 \n\t" \ + "movl %%edx,%1 \n\t" \ + "xorl %2,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "g"(i), "g"(j) :"%eax","%edx","%cc"); + +/* TAO removed sc0,1,2 as input to remove warning so %6,%7 become %3,%4 */ + +#define SQRADDAC(i, j) \ +asm( \ + "movl %6,%%eax \n\t" \ + "mull %7 \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc"); + +#define SQRADDDB \ +asm( \ + "addl %6,%0 \n\t" \ + "adcl %7,%1 \n\t" \ + "adcl %8,%2 \n\t" \ + "addl %6,%0 \n\t" \ + "adcl %7,%1 \n\t" \ + "adcl %8,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "%cc"); + +#elif defined(TFM_X86_64) +/* x86-64 optimized */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +#define SQRADD(i, j) \ +asm( \ + "movq %6,%%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","%cc"); + +#define SQRADD2(i, j) \ +asm( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); + +#define SQRADDSC(i, j) \ +asm( \ + "movq %3,%%rax \n\t" \ + "mulq %4 \n\t" \ + "movq %%rax,%0 \n\t" \ + "movq %%rdx,%1 \n\t" \ + "xorq %2,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "g"(i), "g"(j) :"%rax","%rdx","%cc"); + +/* TAO removed sc0,1,2 as input to remove warning so %6,%7 become %3,%4 */ + +#define SQRADDAC(i, j) \ +asm( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); + +#define SQRADDDB \ +asm( \ + "addq %6,%0 \n\t" \ + "adcq %7,%1 \n\t" \ + "adcq %8,%2 \n\t" \ + "addq %6,%0 \n\t" \ + "adcq %7,%1 \n\t" \ + "adcq %8,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "%cc"); + +#elif defined(TFM_SSE2) + +/* SSE2 Optimized */ +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI \ + asm("emms"); + +#define SQRADD(i, j) \ +asm( \ + "movd %6,%%mm0 \n\t" \ + "pmuludq %%mm0,%%mm0\n\t" \ + "movd %%mm0,%%eax \n\t" \ + "psrlq $32,%%mm0 \n\t" \ + "addl %%eax,%0 \n\t" \ + "movd %%mm0,%%eax \n\t" \ + "adcl %%eax,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%cc"); + +#define SQRADD2(i, j) \ +asm( \ + "movd %6,%%mm0 \n\t" \ + "movd %7,%%mm1 \n\t" \ + "pmuludq %%mm1,%%mm0\n\t" \ + "movd %%mm0,%%eax \n\t" \ + "psrlq $32,%%mm0 \n\t" \ + "movd %%mm0,%%edx \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); + +#define SQRADDSC(i, j) \ +asm( \ + "movd %3,%%mm0 \n\t" \ + "movd %4,%%mm1 \n\t" \ + "pmuludq %%mm1,%%mm0\n\t" \ + "movd %%mm0,%0 \n\t" \ + "psrlq $32,%%mm0 \n\t" \ + "movd %%mm0,%1 \n\t" \ + "xorl %2,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "m"(i), "m"(j)); + +/* TAO removed sc0,1,2 as input to remove warning so %6,%7 become %3,%4 */ + +#define SQRADDAC(i, j) \ +asm( \ + "movd %6,%%mm0 \n\t" \ + "movd %7,%%mm1 \n\t" \ + "pmuludq %%mm1,%%mm0\n\t" \ + "movd %%mm0,%%eax \n\t" \ + "psrlq $32,%%mm0 \n\t" \ + "movd %%mm0,%%edx \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "m"(i), "m"(j) :"%eax","%edx","%cc"); + +#define SQRADDDB \ +asm( \ + "addl %6,%0 \n\t" \ + "adcl %7,%1 \n\t" \ + "adcl %8,%2 \n\t" \ + "addl %6,%0 \n\t" \ + "adcl %7,%1 \n\t" \ + "adcl %8,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "%cc"); + +#elif defined(TFM_ARM) + +/* ARM code */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +/* multiplies point i and j, updates carry "c1" and digit c2 */ +#define SQRADD(i, j) \ +asm( \ +" UMULL r0,r1,%6,%6 \n\t" \ +" ADDS %0,%0,r0 \n\t" \ +" ADCS %1,%1,r1 \n\t" \ +" ADC %2,%2,#0 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "%cc"); + +/* for squaring some of the terms are doubled... */ +#define SQRADD2(i, j) \ +asm( \ +" UMULL r0,r1,%6,%7 \n\t" \ +" ADDS %0,%0,r0 \n\t" \ +" ADCS %1,%1,r1 \n\t" \ +" ADC %2,%2,#0 \n\t" \ +" ADDS %0,%0,r0 \n\t" \ +" ADCS %1,%1,r1 \n\t" \ +" ADC %2,%2,#0 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); + +#define SQRADDSC(i, j) \ +asm( \ +" UMULL %0,%1,%6,%7 \n\t" \ +" SUB %2,%2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "%cc"); + +#define SQRADDAC(i, j) \ +asm( \ +" UMULL r0,r1,%6,%7 \n\t" \ +" ADDS %0,%0,r0 \n\t" \ +" ADCS %1,%1,r1 \n\t" \ +" ADC %2,%2,#0 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "%cc"); + +#define SQRADDDB \ +asm( \ +" ADDS %0,%0,%3 \n\t" \ +" ADCS %1,%1,%4 \n\t" \ +" ADC %2,%2,%5 \n\t" \ +" ADDS %0,%0,%3 \n\t" \ +" ADCS %1,%1,%4 \n\t" \ +" ADC %2,%2,%5 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); + +#elif defined(TFM_PPC32) + +/* PPC32 */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +/* multiplies point i and j, updates carry "c1" and digit c2 */ +#define SQRADD(i, j) \ +asm( \ + " mullw 16,%6,%6 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhwu 16,%6,%6 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i):"16","%cc"); + +/* for squaring some of the terms are doubled... */ +#define SQRADD2(i, j) \ +asm( \ + " mullw 16,%6,%7 \n\t" \ + " mulhwu 17,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " adde %1,%1,17 \n\t" \ + " addze %2,%2 \n\t" \ + " addc %0,%0,16 \n\t" \ + " adde %1,%1,17 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"16", "17","%cc"); + +#define SQRADDSC(i, j) \ +asm( \ + " mullw %0,%6,%7 \n\t" \ + " mulhwu %1,%6,%7 \n\t" \ + " xor %2,%2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "%cc"); + +#define SQRADDAC(i, j) \ +asm( \ + " mullw 16,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhwu 16,%6,%7 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j):"16", "%cc"); + +#define SQRADDDB \ +asm( \ + " addc %0,%0,%3 \n\t" \ + " adde %1,%1,%4 \n\t" \ + " adde %2,%2,%5 \n\t" \ + " addc %0,%0,%3 \n\t" \ + " adde %1,%1,%4 \n\t" \ + " adde %2,%2,%5 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); + +#elif defined(TFM_PPC64) +/* PPC64 */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +/* multiplies point i and j, updates carry "c1" and digit c2 */ +#define SQRADD(i, j) \ +asm( \ + " mulld 16,%6,%6 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhdu 16,%6,%6 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i):"16","%cc"); + +/* for squaring some of the terms are doubled... */ +#define SQRADD2(i, j) \ +asm( \ + " mulld 16,%6,%7 \n\t" \ + " mulhdu 17,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " adde %1,%1,17 \n\t" \ + " addze %2,%2 \n\t" \ + " addc %0,%0,16 \n\t" \ + " adde %1,%1,17 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"16", "17","%cc"); + +#define SQRADDSC(i, j) \ +asm( \ + " mulld %0,%6,%7 \n\t" \ + " mulhdu %1,%6,%7 \n\t" \ + " xor %2,%2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "%cc"); + +#define SQRADDAC(i, j) \ +asm( \ + " mulld 16,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhdu 16,%6,%7 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j):"16", "%cc"); + +#define SQRADDDB \ +asm( \ + " addc %0,%0,%3 \n\t" \ + " adde %1,%1,%4 \n\t" \ + " adde %2,%2,%5 \n\t" \ + " addc %0,%0,%3 \n\t" \ + " adde %1,%1,%4 \n\t" \ + " adde %2,%2,%5 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); + + +#elif defined(TFM_AVR32) + +/* AVR32 */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +/* multiplies point i and j, updates carry "c1" and digit c2 */ +#define SQRADD(i, j) \ +asm( \ + " mulu.d r2,%6,%6 \n\t" \ + " add %0,%0,r2 \n\t" \ + " adc %1,%1,r3 \n\t" \ + " acr %2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i):"r2","r3"); + +/* for squaring some of the terms are doubled... */ +#define SQRADD2(i, j) \ +asm( \ + " mulu.d r2,%6,%7 \n\t" \ + " add %0,%0,r2 \n\t" \ + " adc %1,%1,r3 \n\t" \ + " acr %2, \n\t" \ + " add %0,%0,r2 \n\t" \ + " adc %1,%1,r3 \n\t" \ + " acr %2, \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"r2", "r3"); + +#define SQRADDSC(i, j) \ +asm( \ + " mulu.d r2,%6,%7 \n\t" \ + " mov %0,r2 \n\t" \ + " mov %1,r3 \n\t" \ + " eor %2,%2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "r2", "r3"); + +#define SQRADDAC(i, j) \ +asm( \ + " mulu.d r2,%6,%7 \n\t" \ + " add %0,%0,r2 \n\t" \ + " adc %1,%1,r3 \n\t" \ + " acr %2 \n\t" \ +:"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j):"r2", "r3"); + +#define SQRADDDB \ +asm( \ + " add %0,%0,%3 \n\t" \ + " adc %1,%1,%4 \n\t" \ + " adc %2,%2,%5 \n\t" \ + " add %0,%0,%3 \n\t" \ + " adc %1,%1,%4 \n\t" \ + " adc %2,%2,%5 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); + + +#else + +#define TFM_ISO + +/* ISO C portable code */ + +#define COMBA_START + +#define CLEAR_CARRY \ + c0 = c1 = c2 = 0; + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define CARRY_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_FINI + +/* multiplies point i and j, updates carry "c1" and digit c2 */ +#define SQRADD(i, j) \ + do { fp_word t; \ + t = c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); + + +/* for squaring some of the terms are doubled... */ +#define SQRADD2(i, j) \ + do { fp_word t; \ + t = ((fp_word)i) * ((fp_word)j); \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + } while (0); + +#define SQRADDSC(i, j) \ + do { fp_word t; \ + t = ((fp_word)i) * ((fp_word)j); \ + sc0 = (fp_digit)t; sc1 = (t >> DIGIT_BIT); sc2 = 0; \ + } while (0); + +#define SQRADDAC(i, j) \ + do { fp_word t; \ + t = sc0 + ((fp_word)i) * ((fp_word)j); sc0 = t; \ + t = sc1 + (t >> DIGIT_BIT); sc1 = t; sc2 += t >> DIGIT_BIT; \ + } while (0); + +#define SQRADDDB \ + do { fp_word t; \ + t = ((fp_word)sc0) + ((fp_word)sc0) + c0; c0 = t; \ + t = ((fp_word)sc1) + ((fp_word)sc1) + c1 + (t >> DIGIT_BIT); c1 = t; \ + c2 = c2 + ((fp_word)sc2) + ((fp_word)sc2) + (t >> DIGIT_BIT); \ + } while (0); + +#endif + +#ifdef TFM_SMALL_SET +#include "fp_sqr_comba_small_set.i" +#include "fp_sqr_comba_3.i" +#include "fp_sqr_comba_4.i" +#include "fp_sqr_comba_6.i" +#include "fp_sqr_comba_7.i" +#include "fp_sqr_comba_8.i" +#include "fp_sqr_comba_9.i" +#include "fp_sqr_comba_12.i" +#include "fp_sqr_comba_17.i" +#include "fp_sqr_comba_20.i" +#include "fp_sqr_comba_24.i" +#include "fp_sqr_comba_28.i" +#include "fp_sqr_comba_32.i" +#include "fp_sqr_comba_48.i" +#include "fp_sqr_comba_64.i" +#endif +/* end fp_sqr_comba.c asm */ + +/* start fp_mul_comba.c asm */ +/* these are the combas. Worship them. */ +#if defined(TFM_X86) +/* Generic x86 optimized code */ + +/* anything you need at the start */ +#define COMBA_START + +/* clear the chaining variables */ +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +/* forward the carry to the next digit */ +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +/* store the first sum */ +#define COMBA_STORE(x) \ + x = c0; + +/* store the second sum [carry] */ +#define COMBA_STORE2(x) \ + x = c1; + +/* anything you need at the end */ +#define COMBA_FINI + +/* this should multiply i and j */ +#define MULADD(i, j) \ +asm( \ + "movl %6,%%eax \n\t" \ + "mull %7 \n\t" \ + "addl %%eax,%0 \n\t" \ + "adcl %%edx,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); + +#elif defined(TFM_X86_64) +/* x86-64 optimized */ + +/* anything you need at the start */ +#define COMBA_START + +/* clear the chaining variables */ +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +/* forward the carry to the next digit */ +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +/* store the first sum */ +#define COMBA_STORE(x) \ + x = c0; + +/* store the second sum [carry] */ +#define COMBA_STORE2(x) \ + x = c1; + +/* anything you need at the end */ +#define COMBA_FINI + +/* this should multiply i and j */ +#define MULADD(i, j) \ +asm ( \ + "movq %6,%%rax \n\t" \ + "mulq %7 \n\t" \ + "addq %%rax,%0 \n\t" \ + "adcq %%rdx,%1 \n\t" \ + "adcq $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); + +#elif defined(TFM_SSE2) +/* use SSE2 optimizations */ + +/* anything you need at the start */ +#define COMBA_START + +/* clear the chaining variables */ +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +/* forward the carry to the next digit */ +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +/* store the first sum */ +#define COMBA_STORE(x) \ + x = c0; + +/* store the second sum [carry] */ +#define COMBA_STORE2(x) \ + x = c1; + +/* anything you need at the end */ +#define COMBA_FINI \ + asm("emms"); + +/* this should multiply i and j */ +#define MULADD(i, j) \ +asm( \ + "movd %6,%%mm0 \n\t" \ + "movd %7,%%mm1 \n\t" \ + "pmuludq %%mm1,%%mm0\n\t" \ + "movd %%mm0,%%eax \n\t" \ + "psrlq $32,%%mm0 \n\t" \ + "addl %%eax,%0 \n\t" \ + "movd %%mm0,%%eax \n\t" \ + "adcl %%eax,%1 \n\t" \ + "adcl $0,%2 \n\t" \ + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%cc"); + +#elif defined(TFM_ARM) +/* ARM code */ + +#define COMBA_START + +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define COMBA_FINI + +#define MULADD(i, j) \ +asm( \ +" UMULL r0,r1,%6,%7 \n\t" \ +" ADDS %0,%0,r0 \n\t" \ +" ADCS %1,%1,r1 \n\t" \ +" ADC %2,%2,#0 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); + +#elif defined(TFM_PPC32) +/* For 32-bit PPC */ + +#define COMBA_START + +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define COMBA_FINI + +/* untested: will mulhwu change the flags? Docs say no */ +#define MULADD(i, j) \ +asm( \ + " mullw 16,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhwu 16,%6,%7 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"16"); + +#elif defined(TFM_PPC64) +/* For 64-bit PPC */ + +#define COMBA_START + +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define COMBA_FINI + +/* untested: will mulhwu change the flags? Docs say no */ +#define MULADD(i, j) \ +asm( \ + " mulld 16,%6,%7 \n\t" \ + " addc %0,%0,16 \n\t" \ + " mulhdu 16,%6,%7 \n\t" \ + " adde %1,%1,16 \n\t" \ + " addze %2,%2 \n\t" \ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"16"); + +#elif defined(TFM_AVR32) + +/* ISO C code */ + +#define COMBA_START + +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define COMBA_FINI + +#define MULADD(i, j) \ +asm( \ + " mulu.d r2,%6,%7 \n\t"\ + " add %0,r2 \n\t"\ + " adc %1,%1,r3 \n\t"\ + " acr %2 \n\t"\ +:"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"r2","r3"); + +#else +/* ISO C code */ + +#define COMBA_START + +#define COMBA_CLEAR \ + c0 = c1 = c2 = 0; + +#define COMBA_FORWARD \ + do { c0 = c1; c1 = c2; c2 = 0; } while (0); + +#define COMBA_STORE(x) \ + x = c0; + +#define COMBA_STORE2(x) \ + x = c1; + +#define COMBA_FINI + +#define MULADD(i, j) \ + do { fp_word t; \ + t = (fp_word)c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = (fp_word)c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); + +#endif + + +#ifdef TFM_SMALL_SET +#include "fp_mul_comba_small_set.i" +#include "fp_mul_comba_3.i" +#include "fp_mul_comba_4.i" +#include "fp_mul_comba_6.i" +#include "fp_mul_comba_7.i" +#include "fp_mul_comba_8.i" +#include "fp_mul_comba_9.i" +#include "fp_mul_comba_12.i" +#include "fp_mul_comba_17.i" +#include "fp_mul_comba_20.i" +#include "fp_mul_comba_24.i" +#include "fp_mul_comba_28.i" +#include "fp_mul_comba_32.i" +#include "fp_mul_comba_48.i" +#include "fp_mul_comba_64.i" +#endif + +/* end fp_mul_comba.c asm */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/asn.c b/release/src/router/cyassl/ctaocrypt/src/asn.c new file mode 100644 index 00000000..844ab71d --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/asn.c @@ -0,0 +1,2866 @@ +/* asn.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef THREADX + #include "os.h" /* dc_rtc_api needs */ + #include "dc_rtc_api.h" /* to get current time */ +#endif +#include "asn.h" +#include "coding.h" +#include "ctc_sha.h" +#include "ctc_md5.h" +#include "error.h" + +#ifdef HAVE_NTRU + #include "crypto_ntru.h" +#endif + +#ifdef HAVE_ECC + #include "ctc_ecc.h" +#endif + + +#ifdef _MSC_VER + /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */ + #pragma warning(disable: 4996) +#endif + + +#ifndef TRUE +enum { + FALSE = 0, + TRUE = 1 +}; +#endif + + +#ifdef THREADX + /* uses parital structures */ + #define XTIME(tl) (0) + #define XGMTIME(c) my_gmtime((c)) + #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) +#elif defined(MICRIUM) + #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) + #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t)) + #else + #define XVALIDATE_DATE(d, f, t) (0) + #endif + #define NO_TIME_H + /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */ +#elif defined(USER_TIME) + /* no strucutres used */ + #define NO_TIME_H + /* user time, and gmtime compatible functions, there is a gmtime + implementation here that WINCE uses, so really just need some ticks + since the EPOCH + */ +#else + /* default */ + /* uses complete facility */ + #include + #define XTIME(tl) time((tl)) + #define XGMTIME(c) gmtime((c)) + #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) +#endif + + +#ifdef _WIN32_WCE +/* no time() or gmtime() even though in time.h header?? */ + +#include + + +time_t time(time_t* timer) +{ + SYSTEMTIME sysTime; + FILETIME fTime; + ULARGE_INTEGER intTime; + time_t localTime; + + if (timer == NULL) + timer = &localTime; + + GetSystemTime(&sysTime); + SystemTimeToFileTime(&sysTime, &fTime); + + XMEMCPY(&intTime, &fTime, sizeof(FILETIME)); + /* subtract EPOCH */ + intTime.QuadPart -= 0x19db1ded53e8000; + /* to secs */ + intTime.QuadPart /= 10000000; + *timer = (time_t)intTime.QuadPart; + + return *timer; +} + + + +struct tm* gmtime(const time_t* timer) +{ + #define YEAR0 1900 + #define EPOCH_YEAR 1970 + #define SECS_DAY (24L * 60L * 60L) + #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400))) + #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) + + static const int _ytab[2][12] = + { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + + static struct tm st_time; + struct tm* ret = &st_time; + time_t time = *timer; + unsigned long dayclock, dayno; + int year = EPOCH_YEAR; + + dayclock = (unsigned long)time % SECS_DAY; + dayno = (unsigned long)time / SECS_DAY; + + ret->tm_sec = dayclock % 60; + ret->tm_min = (dayclock % 3600) / 60; + ret->tm_hour = dayclock / 3600; + ret->tm_wday = (dayno + 4) % 7; /* day 0 a Thursday */ + + while(dayno >= (unsigned long)YEARSIZE(year)) { + dayno -= YEARSIZE(year); + year++; + } + + ret->tm_year = year - YEAR0; + ret->tm_yday = dayno; + ret->tm_mon = 0; + + while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) { + dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon]; + ret->tm_mon++; + } + + ret->tm_mday = ++dayno; + ret->tm_isdst = 0; + + return ret; +} + +#endif /* _WIN32_WCE */ + + + +#ifdef THREADX + +#define YEAR0 1900 + +struct tm* my_gmtime(const time_t* timer) /* has a gmtime() but hangs */ +{ + static struct tm st_time; + struct tm* ret = &st_time; + + DC_RTC_CALENDAR cal; + dc_rtc_time_get(&cal, TRUE); + + ret->tm_year = cal.year - YEAR0; /* gm starts at 1900 */ + ret->tm_mon = cal.month - 1; /* gm starts at 0 */ + ret->tm_mday = cal.day; + ret->tm_hour = cal.hour; + ret->tm_min = cal.minute; + ret->tm_sec = cal.second; + + return ret; +} + +#endif /* THREADX */ + + +static INLINE word32 btoi(byte b) +{ + return b - 0x30; +} + + +/* two byte date/time, add to value */ +static INLINE void GetTime(int* value, const byte* date, int* idx) +{ + int i = *idx; + + *value += btoi(date[i++]) * 10; + *value += btoi(date[i++]); + + *idx = i; +} + + +#if defined(MICRIUM) + +CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format, + CPU_INT08U dateType) +{ + CPU_BOOLEAN rtn_code; + CPU_INT32S i; + CPU_INT32S val; + CPU_INT16U year; + CPU_INT08U month; + CPU_INT16U day; + CPU_INT08U hour; + CPU_INT08U min; + CPU_INT08U sec; + + i = 0; + year = 0u; + + if (format == ASN_UTC_TIME) { + if (btoi(date[0]) >= 5) + year = 1900; + else + year = 2000; + } + else { /* format == GENERALIZED_TIME */ + year += btoi(date[i++]) * 1000; + year += btoi(date[i++]) * 100; + } + + val = year; + GetTime(&val, date, &i); + year = (CPU_INT16U)val; + + val = 0; + GetTime(&val, date, &i); + month = (CPU_INT08U)val; + + val = 0; + GetTime(&val, date, &i); + day = (CPU_INT16U)val; + + val = 0; + GetTime(&val, date, &i); + hour = (CPU_INT08U)val; + + val = 0; + GetTime(&val, date, &i); + min = (CPU_INT08U)val; + + val = 0; + GetTime(&val, date, &i); + sec = (CPU_INT08U)val; + + return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); +} + +#endif /* MICRIUM */ + + +int GetLength(const byte* input, word32* inOutIdx, int* len) +{ + int length = 0; + word32 i = *inOutIdx; + + byte b = input[i++]; + if (b >= ASN_LONG_LENGTH) { + word32 bytes = b & 0x7F; + + while (bytes--) { + b = input[i++]; + length = (length << 8) | b; + } + } + else + length = b; + + *inOutIdx = i; + *len = length; + + return length; +} + + +int GetSequence(const byte* input, word32* inOutIdx, int* len) +{ + int length = -1; + word32 idx = *inOutIdx; + + if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) || + GetLength(input, &idx, &length) < 0) + return ASN_PARSE_E; + + *len = length; + *inOutIdx = idx; + + return length; +} + + +int GetSet(const byte* input, word32* inOutIdx, int* len) +{ + int length = -1; + word32 idx = *inOutIdx; + + if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) || + GetLength(input, &idx, &length) < 0) + return ASN_PARSE_E; + + *len = length; + *inOutIdx = idx; + + return length; +} + + +/* winodws header clash for WinCE using GetVersion */ +int GetMyVersion(const byte* input, word32* inOutIdx, int* version) +{ + word32 idx = *inOutIdx; + + if (input[idx++] != ASN_INTEGER) + return ASN_PARSE_E; + + if (input[idx++] != 0x01) + return ASN_VERSION_E; + + *version = input[idx++]; + *inOutIdx = idx; + + return *version; +} + + +/* May not have one, not an error */ +int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version) +{ + word32 idx = *inOutIdx; + + if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { + *inOutIdx = ++idx; /* eat header */ + return GetMyVersion(input, inOutIdx, version); + } + + /* go back as is */ + *version = 0; + + return 0; +} + + +int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx ) +{ + word32 i = *inOutIdx; + byte b = input[i++]; + int length; + + if (b != ASN_INTEGER) + return ASN_PARSE_E; + + if (GetLength(input, &i, &length) < 0) + return ASN_PARSE_E; + + if ( (b = input[i++]) == 0x00) + length--; + else + i--; + + mp_init(mpi); + if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) { + mp_clear(mpi); + return ASN_GETINT_E; + } + + *inOutIdx = i + length; + return 0; +} + + +static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid) +{ + int length; + word32 i = *inOutIdx; + byte b; + *oid = 0; + + if (GetSequence(input, &i, &length) < 0) + return ASN_PARSE_E; + + b = input[i++]; + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(input, &i, &length) < 0) + return ASN_PARSE_E; + + while(length--) + *oid += input[i++]; + /* just sum it up for now */ + + /* could have NULL tag and 0 terminator, but may not */ + b = input[i++]; + + if (b == ASN_TAG_NULL) { + b = input[i++]; + if (b != 0) + return ASN_EXPECT_0_E; + } + else + /* go back, didn't have it */ + i--; + + *inOutIdx = i; + + return 0; +} + + +int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, + word32 inSz) +{ + word32 begin = *inOutIdx; + int version, length; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + if (GetMyVersion(input, inOutIdx, &version) < 0) + return ASN_PARSE_E; + + key->type = RSA_PRIVATE; + + if (GetInt(&key->n, input, inOutIdx) < 0 || + GetInt(&key->e, input, inOutIdx) < 0 || + GetInt(&key->d, input, inOutIdx) < 0 || + GetInt(&key->p, input, inOutIdx) < 0 || + GetInt(&key->q, input, inOutIdx) < 0 || + GetInt(&key->dP, input, inOutIdx) < 0 || + GetInt(&key->dQ, input, inOutIdx) < 0 || + GetInt(&key->u, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E; + + return 0; +} + + +/* Remove PKCS8 header, move beginning of traditional to beginning of input */ +int ToTraditional(byte* input, word32 sz) +{ + word32 inOutIdx = 0, oid; + int version, length; + + if (GetSequence(input, &inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (sz - inOutIdx)) + return ASN_INPUT_E; + + if (GetMyVersion(input, &inOutIdx, &version) < 0) + return ASN_PARSE_E; + + if (GetAlgoId(input, &inOutIdx, &oid) < 0) + return ASN_PARSE_E; + + if (input[inOutIdx++] != ASN_OCTET_STRING) + return ASN_PARSE_E; + + if (GetLength(input, &inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (sz - inOutIdx)) + return ASN_INPUT_E; + + XMEMMOVE(input, input + inOutIdx, length); + + return 0; +} + + +int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, + word32 inSz) +{ + word32 begin = *inOutIdx; + int length; + byte b; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + key->type = RSA_PUBLIC; + b = input[*inOutIdx]; + +#ifdef OPENSSL_EXTRA + if (b != ASN_INTEGER) { + /* not from decoded cert, will have algo id, skip past */ + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + b = input[(*inOutIdx)++]; + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + *inOutIdx += length; /* skip past */ + + /* could have NULL tag and 0 terminator, but may not */ + b = input[(*inOutIdx)++]; + + if (b == ASN_TAG_NULL) { + b = input[(*inOutIdx)++]; + if (b != 0) + return ASN_EXPECT_0_E; + } + else + /* go back, didn't have it */ + (*inOutIdx)--; + + /* should have bit tag length and seq next */ + b = input[(*inOutIdx)++]; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + /* could have 0 */ + b = input[(*inOutIdx)++]; + if (b != 0) + (*inOutIdx)--; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + } +#endif /* OPENSSL_EXTRA */ + + if (GetInt(&key->n, input, inOutIdx) < 0 || + GetInt(&key->e, input, inOutIdx) < 0 ) return ASN_RSA_KEY_E; + + return 0; +} + + +#ifndef NO_DH + +int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz) +{ + word32 begin = *inOutIdx; + int length; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + if (GetInt(&key->p, input, inOutIdx) < 0 || + GetInt(&key->g, input, inOutIdx) < 0 ) return ASN_DH_KEY_E; + + return 0; +} + +int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) +{ + /* may have leading 0 */ + if (p[0] == 0) { + pSz--; p++; + } + + if (g[0] == 0) { + gSz--; g++; + } + + mp_init(&key->p); + if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) { + mp_clear(&key->p); + return ASN_DH_KEY_E; + } + + mp_init(&key->g); + if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) { + mp_clear(&key->p); + return ASN_DH_KEY_E; + } + + return 0; +} + + +#endif /* NO_DH */ + + +#ifndef NO_DSA + +int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, + word32 inSz) +{ + word32 begin = *inOutIdx; + int length; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + if (GetInt(&key->p, input, inOutIdx) < 0 || + GetInt(&key->q, input, inOutIdx) < 0 || + GetInt(&key->g, input, inOutIdx) < 0 || + GetInt(&key->y, input, inOutIdx) < 0 ) return ASN_DH_KEY_E; + + key->type = DSA_PUBLIC; + return 0; +} + + +int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, + word32 inSz) +{ + word32 begin = *inOutIdx; + int length, version; + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + if (GetMyVersion(input, inOutIdx, &version) < 0) + return ASN_PARSE_E; + + if (GetInt(&key->p, input, inOutIdx) < 0 || + GetInt(&key->q, input, inOutIdx) < 0 || + GetInt(&key->g, input, inOutIdx) < 0 || + GetInt(&key->y, input, inOutIdx) < 0 || + GetInt(&key->x, input, inOutIdx) < 0 ) return ASN_DH_KEY_E; + + key->type = DSA_PRIVATE; + return 0; +} + +#endif /* NO_DSA */ + + +void InitDecodedCert(DecodedCert* cert, byte* source, void* heap) +{ + cert->publicKey = 0; + cert->pubKeyStored = 0; + cert->signature = 0; + cert->subjectCN = 0; + cert->subjectCNLen = 0; + cert->source = source; /* don't own */ + cert->srcIdx = 0; + cert->heap = heap; +#ifdef CYASSL_CERT_GEN + cert->subjectSN = 0; + cert->subjectSNLen = 0; + cert->subjectC = 0; + cert->subjectCLen = 0; + cert->subjectL = 0; + cert->subjectLLen = 0; + cert->subjectST = 0; + cert->subjectSTLen = 0; + cert->subjectO = 0; + cert->subjectOLen = 0; + cert->subjectOU = 0; + cert->subjectOULen = 0; + cert->subjectEmail = 0; + cert->subjectEmailLen = 0; +#endif /* CYASSL_CERT_GEN */ +} + + +void FreeDecodedCert(DecodedCert* cert) +{ + if (cert->subjectCNLen == 0) /* 0 means no longer pointer to raw, we own */ + XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN); + if (cert->pubKeyStored == 1) + XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); +} + + +static int GetCertHeader(DecodedCert* cert, word32 inSz) +{ + int ret = 0, version, len; + word32 begin = cert->srcIdx; + mp_int mpi; + + if (GetSequence(cert->source, &cert->srcIdx, &len) < 0) + return ASN_PARSE_E; + + if ((word32)len > (inSz - (cert->srcIdx - begin))) return ASN_INPUT_E; + + cert->certBegin = cert->srcIdx; + + GetSequence(cert->source, &cert->srcIdx, &len); + cert->sigIndex = len + cert->srcIdx; + + if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0) + return ASN_PARSE_E; + + if (GetInt(&mpi, cert->source, &cert->srcIdx) < 0) + ret = ASN_PARSE_E; + + mp_clear(&mpi); + return ret; +} + + +/* Store Rsa Key, may save later, Dsa could use in future */ +static int StoreRsaKey(DecodedCert* cert) +{ + int length; + word32 read = cert->srcIdx; + + if (GetSequence(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + read = cert->srcIdx - read; + length += read; + + while (read--) + cert->srcIdx--; + + cert->pubKeySize = length; + cert->publicKey = cert->source + cert->srcIdx; + cert->srcIdx += length; + + return 0; +} + + +#ifdef HAVE_ECC + + /* return 0 on sucess if the ECC curve oid sum is supported */ + static int CheckCurve(word32 oid) + { + if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid != + ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1) + return -1; + + return 0; + } + +#endif /* HAVE_ECC */ + + +static int GetKey(DecodedCert* cert) +{ + int length; +#ifdef HAVE_NTRU + int tmpIdx = cert->srcIdx; +#endif + + if (GetSequence(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID) < 0) + return ASN_PARSE_E; + + if (cert->keyOID == RSAk) { + byte b = cert->source[cert->srcIdx++]; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + b = cert->source[cert->srcIdx++]; + if (b != 0x00) + return ASN_EXPECT_0_E; + } + else if (cert->keyOID == DSAk ) + ; /* do nothing */ +#ifdef HAVE_NTRU + else if (cert->keyOID == NTRUk ) { + const byte* key = &cert->source[tmpIdx]; + byte* next = (byte*)key; + word16 keyLen; + byte keyBlob[MAX_NTRU_KEY_SZ]; + + word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, + &keyLen, NULL, &next); + + if (rc != NTRU_OK) + return ASN_NTRU_KEY_E; + if (keyLen > sizeof(keyBlob)) + return ASN_NTRU_KEY_E; + + rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, &keyLen, + keyBlob, &next); + if (rc != NTRU_OK) + return ASN_NTRU_KEY_E; + + if ( (next - key) < 0) + return ASN_NTRU_KEY_E; + + cert->srcIdx = tmpIdx + (next - key); + + cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (cert->publicKey == NULL) + return MEMORY_E; + memcpy(cert->publicKey, keyBlob, keyLen); + cert->pubKeyStored = 1; + cert->pubKeySize = keyLen; + } +#endif /* HAVE_NTRU */ +#ifdef HAVE_ECC + else if (cert->keyOID == ECDSAk ) { + word32 oid = 0; + int oidSz = 0; + byte b = cert->source[cert->srcIdx++]; + + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(cert->source, &cert->srcIdx, &oidSz) < 0) + return ASN_PARSE_E; + + while(oidSz--) + oid += cert->source[cert->srcIdx++]; + if (CheckCurve(oid) < 0) + return ECC_CURVE_OID_E; + + /* key header */ + b = cert->source[cert->srcIdx++]; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + b = cert->source[cert->srcIdx++]; + if (b != 0x00) + return ASN_EXPECT_0_E; + + /* actual key, use length - 1 since preceding 0 */ + cert->publicKey = (byte*) XMALLOC(length - 1, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (cert->publicKey == NULL) + return MEMORY_E; + memcpy(cert->publicKey, &cert->source[cert->srcIdx], length - 1); + cert->pubKeyStored = 1; + cert->pubKeySize = length - 1; + + cert->srcIdx += length; + } +#endif /* HAVE_ECC */ + else + return ASN_UNKNOWN_OID_E; + + if (cert->keyOID == RSAk) + return StoreRsaKey(cert); + return 0; +} + + +/* process NAME, either issuer or subject */ +static int GetName(DecodedCert* cert, int nameType) +{ + Sha sha; + int length; /* length of all distinguished names */ + int dummy; + char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; + word32 idx = 0; + + InitSha(&sha); + + if (GetSequence(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + length += cert->srcIdx; + + while (cert->srcIdx < (word32)length) { + byte b; + byte joint[2]; + int oidSz; + + if (GetSet(cert->source, &cert->srcIdx, &dummy) < 0) + return ASN_PARSE_E; + + if (GetSequence(cert->source, &cert->srcIdx, &dummy) < 0) + return ASN_PARSE_E; + + b = cert->source[cert->srcIdx++]; + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(cert->source, &cert->srcIdx, &oidSz) < 0) + return ASN_PARSE_E; + + XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint)); + + /* v1 name types */ + if (joint[0] == 0x55 && joint[1] == 0x04) { + byte id; + byte copy = FALSE; + int strLen; + + cert->srcIdx += 2; + id = cert->source[cert->srcIdx++]; + b = cert->source[cert->srcIdx++]; /* strType */ + + if (GetLength(cert->source, &cert->srcIdx, &strLen) < 0) + return ASN_PARSE_E; + + if (strLen > (int)(ASN_NAME_MAX - idx)) + return ASN_PARSE_E; + + if (4 > (ASN_NAME_MAX - idx)) /* make sure room for biggest */ + return ASN_PARSE_E; /* pre fix header too "/CN=" */ + + if (id == ASN_COMMON_NAME) { + if (nameType == SUBJECT) { + cert->subjectCN = (char *)&cert->source[cert->srcIdx]; + cert->subjectCNLen = strLen; + } + + XMEMCPY(&full[idx], "/CN=", 4); + idx += 4; + copy = TRUE; + } + else if (id == ASN_SUR_NAME) { + XMEMCPY(&full[idx], "/SN=", 4); + idx += 4; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectSN = (char*)&cert->source[cert->srcIdx]; + cert->subjectSNLen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + else if (id == ASN_COUNTRY_NAME) { + XMEMCPY(&full[idx], "/C=", 3); + idx += 3; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectC = (char*)&cert->source[cert->srcIdx]; + cert->subjectCLen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + else if (id == ASN_LOCALITY_NAME) { + XMEMCPY(&full[idx], "/L=", 3); + idx += 3; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectL = (char*)&cert->source[cert->srcIdx]; + cert->subjectLLen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + else if (id == ASN_STATE_NAME) { + XMEMCPY(&full[idx], "/ST=", 4); + idx += 4; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectST = (char*)&cert->source[cert->srcIdx]; + cert->subjectSTLen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + else if (id == ASN_ORG_NAME) { + XMEMCPY(&full[idx], "/O=", 3); + idx += 3; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectO = (char*)&cert->source[cert->srcIdx]; + cert->subjectOLen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + else if (id == ASN_ORGUNIT_NAME) { + XMEMCPY(&full[idx], "/OU=", 4); + idx += 4; + copy = TRUE; +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectOU = (char*)&cert->source[cert->srcIdx]; + cert->subjectOULen = strLen; + } +#endif /* CYASSL_CERT_GEN */ + } + + if (copy) { + XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen); + idx += strLen; + } + + ShaUpdate(&sha, &cert->source[cert->srcIdx], strLen); + cert->srcIdx += strLen; + } + else { + /* skip */ + byte email = FALSE; + int adv; + + if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */ + email = TRUE; + + cert->srcIdx += oidSz + 1; + + if (GetLength(cert->source, &cert->srcIdx, &adv) < 0) + return ASN_PARSE_E; + + if (adv > (int)(ASN_NAME_MAX - idx)) + return ASN_PARSE_E; + + if (email) { + if (14 > (ASN_NAME_MAX - idx)) + return ASN_PARSE_E; + XMEMCPY(&full[idx], "/emailAddress=", 14); + idx += 14; + +#ifdef CYASSL_CERT_GEN + if (nameType == SUBJECT) { + cert->subjectEmail = (char*)&cert->source[cert->srcIdx]; + cert->subjectEmailLen = adv; + } +#endif /* CYASSL_CERT_GEN */ + + XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); + idx += adv; + } + + cert->srcIdx += adv; + } + } + full[idx++] = 0; + + if (nameType == ISSUER) + ShaFinal(&sha, cert->issuerHash); + else + ShaFinal(&sha, cert->subjectHash); + + return 0; +} + + +#ifndef NO_TIME_H + +/* to the second */ +static int DateGreaterThan(const struct tm* a, const struct tm* b) +{ + if (a->tm_year > b->tm_year) + return 1; + + if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon) + return 1; + + if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && + a->tm_mday > b->tm_mday) + return 1; + + if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && + a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour) + return 1; + + if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && + a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && + a->tm_min > b->tm_min) + return 1; + + if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && + a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && + a->tm_min == b->tm_min && a->tm_sec > b->tm_sec) + return 1; + + return 0; /* false */ +} + + +static INLINE int DateLessThan(const struct tm* a, const struct tm* b) +{ + return !DateGreaterThan(a,b); +} + + +/* like atoi but only use first byte */ +/* Make sure before and after dates are valid */ +static int ValidateDate(const byte* date, byte format, int dateType) +{ + time_t ltime; + struct tm certTime; + struct tm* localTime; + int i = 0; + + ltime = XTIME(0); + XMEMSET(&certTime, 0, sizeof(certTime)); + + if (format == ASN_UTC_TIME) { + if (btoi(date[0]) >= 5) + certTime.tm_year = 1900; + else + certTime.tm_year = 2000; + } + else { /* format == GENERALIZED_TIME */ + certTime.tm_year += btoi(date[i++]) * 1000; + certTime.tm_year += btoi(date[i++]) * 100; + } + + GetTime(&certTime.tm_year, date, &i); certTime.tm_year -= 1900; /* adjust */ + GetTime(&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; /* adjust */ + GetTime(&certTime.tm_mday, date, &i); + GetTime(&certTime.tm_hour, date, &i); + GetTime(&certTime.tm_min, date, &i); + GetTime(&certTime.tm_sec, date, &i); + + if (date[i] != 'Z') /* only Zulu supported for this profile */ + return 0; + + localTime = XGMTIME(<ime); + + if (dateType == BEFORE) { + if (DateLessThan(localTime, &certTime)) + return 0; + } + else + if (DateGreaterThan(localTime, &certTime)) + return 0; + + return 1; +} + +#endif /* NO_TIME_H */ + + +static int GetDate(DecodedCert* cert, int dateType) +{ + int length; + byte date[MAX_DATE_SIZE]; + byte b = cert->source[cert->srcIdx++]; + + if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) + return ASN_TIME_E; + + if (GetLength(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) + return ASN_DATE_SZ_E; + + XMEMCPY(date, &cert->source[cert->srcIdx], length); + cert->srcIdx += length; + + if (!XVALIDATE_DATE(date, b, dateType)) { + if (dateType == BEFORE) + return ASN_BEFORE_DATE_E; + else + return ASN_AFTER_DATE_E; + } + + return 0; +} + + +static int GetValidity(DecodedCert* cert, int verify) +{ + int length; + int badDate = 0; + + if (GetSequence(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + if (GetDate(cert, BEFORE) < 0 && verify) + badDate = ASN_BEFORE_DATE_E; /* continue parsing */ + + if (GetDate(cert, AFTER) < 0 && verify) + return ASN_AFTER_DATE_E; + + if (badDate != 0) + return badDate; + + return 0; +} + + +static int DecodeToKey(DecodedCert* cert, word32 inSz, int verify) +{ + int badDate = 0; + int ret; + + if ( (ret = GetCertHeader(cert, inSz)) < 0) + return ret; + + if ( (ret = GetAlgoId(cert->source, &cert->srcIdx,&cert->signatureOID)) < 0) + return ret; + + if ( (ret = GetName(cert, ISSUER)) < 0) + return ret; + + if ( (ret = GetValidity(cert, verify)) < 0) + badDate = ret; + + if ( (ret = GetName(cert, SUBJECT)) < 0) + return ret; + + if ( (ret = GetKey(cert)) < 0) + return ret; + + if (badDate != 0) + return badDate; + + return ret; +} + + +static int GetSignature(DecodedCert* cert) +{ + int length; + byte b = cert->source[cert->srcIdx++]; + + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(cert->source, &cert->srcIdx, &length) < 0) + return ASN_PARSE_E; + + cert->sigLength = length; + + b = cert->source[cert->srcIdx++]; + if (b != 0x00) + return ASN_EXPECT_0_E; + + cert->sigLength--; + cert->signature = &cert->source[cert->srcIdx]; + cert->srcIdx += cert->sigLength; + + return 0; +} + + +static word32 SetDigest(const byte* digest, word32 digSz, byte* output) +{ + output[0] = ASN_OCTET_STRING; + output[1] = digSz; + XMEMCPY(&output[2], digest, digSz); + + return digSz + 2; +} + + +static word32 BytePrecision(word32 value) +{ + word32 i; + for (i = sizeof(value); i; --i) + if (value >> (i - 1) * 8) + break; + + return i; +} + + +static word32 SetLength(word32 length, byte* output) +{ + word32 i = 0, j; + + if (length < ASN_LONG_LENGTH) + output[i++] = length; + else { + output[i++] = BytePrecision(length) | ASN_LONG_LENGTH; + + for (j = BytePrecision(length); j; --j) { + output[i] = length >> (j - 1) * 8; + i++; + } + } + + return i; +} + + +static word32 SetSequence(word32 len, byte* output) +{ + output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED; + return SetLength(len, output + 1) + 1; +} + + +static word32 SetAlgoID(int algoOID, byte* output, int type) +{ + /* adding TAG_NULL and 0 to end */ + + /* hashTypes */ + static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00 }; + static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x05, 0x05, 0x00 }; + static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x02, 0x05, 0x00}; + + /* sigTypes */ + static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x04, 0x05, 0x00}; + + /* keyTypes */ + static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00}; + + int algoSz = 0; + word32 idSz, seqSz; + const byte* algoName = 0; + byte ID_Length[MAX_LENGTH_SZ]; + byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */ + + if (type == hashType) { + switch (algoOID) { + case SHAh: + algoSz = sizeof(shaAlgoID); + algoName = shaAlgoID; + break; + + case MD2h: + algoSz = sizeof(md2AlgoID); + algoName = md2AlgoID; + break; + + case MD5h: + algoSz = sizeof(md5AlgoID); + algoName = md5AlgoID; + break; + + default: + return 0; /* UNKOWN_HASH_E; */ + } + } + else if (type == sigType) { /* sigType */ + switch (algoOID) { + case MD5wRSA: + algoSz = sizeof(md5wRSA_AlgoID); + algoName = md5wRSA_AlgoID; + break; + + default: + return 0; /* UNKOWN_HASH_E; */ + } + } + else if (type == keyType) { /* keyType */ + switch (algoOID) { + case RSAk: + algoSz = sizeof(RSA_AlgoID); + algoName = RSA_AlgoID; + break; + + default: + return 0; /* UNKOWN_HASH_E; */ + } + } + else + return 0; /* UNKNOWN_TYPE */ + + + idSz = SetLength(algoSz - 2, ID_Length); /* don't include TAG_NULL/0 */ + seqSz = SetSequence(idSz + algoSz + 1, seqArray); + seqArray[seqSz++] = ASN_OBJECT_ID; + + XMEMCPY(output, seqArray, seqSz); + XMEMCPY(output + seqSz, ID_Length, idSz); + XMEMCPY(output + seqSz + idSz, algoName, algoSz); + + return seqSz + idSz + algoSz; + +} + + +word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) +{ + byte digArray[MAX_ENCODED_DIG_SZ]; + byte algoArray[MAX_ALGO_SZ]; + byte seqArray[MAX_SEQ_SZ]; + word32 encDigSz, algoSz, seqSz; + + encDigSz = SetDigest(digest, digSz, digArray); + algoSz = SetAlgoID(hashOID, algoArray, hashType); + seqSz = SetSequence(encDigSz + algoSz, seqArray); + + XMEMCPY(out, seqArray, seqSz); + XMEMCPY(out + seqSz, algoArray, algoSz); + XMEMCPY(out + seqSz + algoSz, digArray, encDigSz); + + return encDigSz + algoSz + seqSz; +} + + +/* return true (1) for Confirmation */ +static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz, + word32 keyOID) +{ + byte digest[SHA_DIGEST_SIZE]; /* max size */ + int hashType, digestSz, ret; + + if (cert->signatureOID == MD5wRSA) { + Md5 md5; + InitMd5(&md5); + Md5Update(&md5, cert->source + cert->certBegin, + cert->sigIndex - cert->certBegin); + Md5Final(&md5, digest); + hashType = MD5h; + digestSz = MD5_DIGEST_SIZE; + } + else if (cert->signatureOID == SHAwRSA || cert->signatureOID == SHAwDSA || + cert->signatureOID == SHAwECDSA) { + Sha sha; + InitSha(&sha); + ShaUpdate(&sha, cert->source + cert->certBegin, + cert->sigIndex - cert->certBegin); + ShaFinal(&sha, digest); + hashType = SHAh; + digestSz = SHA_DIGEST_SIZE; + } + else + return 0; /* ASN_SIG_HASH_E; */ + + if (keyOID == RSAk) { + RsaKey pubKey; + byte encodedSig[MAX_ENCODED_SIG_SZ]; + byte plain[MAX_ENCODED_SIG_SZ]; + word32 idx = 0; + int sigSz, verifySz; + byte* out; + + if (cert->sigLength > MAX_ENCODED_SIG_SZ) + return 0; /* the key is too big */ + + InitRsaKey(&pubKey, cert->heap); + if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) + ret = 0; /* ASN_KEY_DECODE_E; */ + + else { + XMEMCPY(plain, cert->signature, cert->sigLength); + if ( (verifySz = RsaSSL_VerifyInline(plain, cert->sigLength, &out, + &pubKey)) < 0) + ret = 0; /* ASN_VERIFY_E; */ + else { + /* make sure we're right justified */ + sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType); + if (sigSz != verifySz || XMEMCMP(out, encodedSig, sigSz) != 0) + ret = 0; /* ASN_VERIFY_MATCH_E; */ + else + ret = 1; /* match */ + } + } + FreeRsaKey(&pubKey); + return ret; + } +#ifdef HAVE_ECC + else if (keyOID == ECDSAk) { + ecc_key pubKey; + int verify = 0; + + if (ecc_import_x963(key, keySz, &pubKey) < 0) + return 0; /* ASN_KEY_DECODE_E */ + + ret = ecc_verify_hash(cert->signature, cert->sigLength, digest, + digestSz, &verify, &pubKey); + ecc_free(&pubKey); + if (ret == 0 && verify == 1) + return 1; /* match */ + + return 0; /* ASN_VERIFY_E */ + } +#endif /* HAVE_ECC */ + else + return 0; /* ASN_SIG_KEY_E; */ +} + + +int ParseCert(DecodedCert* cert, word32 inSz, int type, int verify, + Signer* signers) +{ + int ret; + char* ptr; + + ret = ParseCertRelative(cert, inSz, type, verify, signers); + if (ret < 0) + return ret; + + if (cert->subjectCNLen > 0) { + ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap, + DYNAMIC_TYPE_SUBJECT_CN); + if (ptr == NULL) + return MEMORY_E; + XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen); + ptr[cert->subjectCNLen] = '\0'; + cert->subjectCN = ptr; + cert->subjectCNLen = 0; + } + + if (cert->keyOID == RSAk && cert->pubKeySize > 0) { + ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (ptr == NULL) + return MEMORY_E; + XMEMCPY(ptr, cert->publicKey, cert->pubKeySize); + cert->publicKey = (byte *)ptr; + cert->pubKeyStored = 1; + } + + return ret; +} + + +int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify, + Signer* signers) +{ + word32 confirmOID; + int ret; + int badDate = 0; + int confirm = 0; + + if ((ret = DecodeToKey(cert, inSz, verify)) < 0) { + if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) + badDate = ret; + else + return ret; + } + + if (cert->srcIdx != cert->sigIndex) + cert->srcIdx = cert->sigIndex; + + if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID)) < 0) + return ret; + + if ((ret = GetSignature(cert)) < 0) + return ret; + + if (confirmOID != cert->signatureOID) + return ASN_SIG_OID_E; + + if (verify && type != CA_TYPE) { + while (signers) { + if (XMEMCMP(cert->issuerHash, signers->hash, SHA_DIGEST_SIZE) + == 0) { + /* other confirm */ + if (!ConfirmSignature(cert, signers->publicKey, + signers->pubKeySize, signers->keyOID)) + return ASN_SIG_CONFIRM_E; + else { + confirm = 1; + break; + } + } + signers = signers->next; + } + if (!confirm) + return ASN_SIG_CONFIRM_E; + } + if (badDate != 0) + return badDate; + + return 0; +} + + +Signer* MakeSigner(void* heap) +{ + Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, + DYNAMIC_TYPE_SIGNER); + if (signer) { + signer->name = 0; + signer->publicKey = 0; + signer->next = 0; + } + + return signer; +} + + +void FreeSigners(Signer* signer, void* heap) +{ + Signer* next = signer; + + while( (signer = next) ) { + next = signer->next; + XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); + XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); + XFREE(signer, heap, DYNAMIC_TYPE_SIGNER); + } +} + + +void CTaoCryptErrorString(int error, char* buffer) +{ + const int max = MAX_ERROR_SZ; /* shorthand */ + +#ifdef NO_ERROR_STRINGS + + XSTRNCPY(buffer, "no support for error strings built in", max); + +#else + + switch (error) { + + case OPEN_RAN_E : + XSTRNCPY(buffer, "opening random device error", max); + break; + + case READ_RAN_E : + XSTRNCPY(buffer, "reading random device error", max); + break; + + case WINCRYPT_E : + XSTRNCPY(buffer, "windows crypt init error", max); + break; + + case CRYPTGEN_E : + XSTRNCPY(buffer, "windows crypt generation error", max); + break; + + case RAN_BLOCK_E : + XSTRNCPY(buffer, "random device read would block error", max); + break; + + case MP_INIT_E : + XSTRNCPY(buffer, "mp_init error state", max); + break; + + case MP_READ_E : + XSTRNCPY(buffer, "mp_read error state", max); + break; + + case MP_EXPTMOD_E : + XSTRNCPY(buffer, "mp_exptmod error state", max); + break; + + case MP_TO_E : + XSTRNCPY(buffer, "mp_to_xxx error state, can't convert", max); + break; + + case MP_SUB_E : + XSTRNCPY(buffer, "mp_sub error state, can't subtract", max); + break; + + case MP_ADD_E : + XSTRNCPY(buffer, "mp_add error state, can't add", max); + break; + + case MP_MUL_E : + XSTRNCPY(buffer, "mp_mul error state, can't multiply", max); + break; + + case MP_MULMOD_E : + XSTRNCPY(buffer, "mp_mulmod error state, can't multiply mod", max); + break; + + case MP_MOD_E : + XSTRNCPY(buffer, "mp_mod error state, can't mod", max); + break; + + case MP_INVMOD_E : + XSTRNCPY(buffer, "mp_invmod error state, can't inv mod", max); + break; + + case MP_CMP_E : + XSTRNCPY(buffer, "mp_cmp error state", max); + break; + + case MEMORY_E : + XSTRNCPY(buffer, "out of memory error", max); + break; + + case RSA_WRONG_TYPE_E : + XSTRNCPY(buffer, "RSA wrong block type for RSA function", max); + break; + + case RSA_BUFFER_E : + XSTRNCPY(buffer, "RSA buffer error, output too small or input too big", + max); + break; + + case BUFFER_E : + XSTRNCPY(buffer, "Buffer error, output too small or input too big", max); + break; + + case ALGO_ID_E : + XSTRNCPY(buffer, "Setting Cert AlogID error", max); + break; + + case PUBLIC_KEY_E : + XSTRNCPY(buffer, "Setting Cert Public Key error", max); + break; + + case DATE_E : + XSTRNCPY(buffer, "Setting Cert Date validity error", max); + break; + + case SUBJECT_E : + XSTRNCPY(buffer, "Setting Cert Subject name error", max); + break; + + case ISSUER_E : + XSTRNCPY(buffer, "Setting Cert Issuer name error", max); + break; + + case ASN_PARSE_E : + XSTRNCPY(buffer, "ASN parsing error, invalid input", max); + break; + + case ASN_VERSION_E : + XSTRNCPY(buffer, "ASN version error, invalid number", max); + break; + + case ASN_GETINT_E : + XSTRNCPY(buffer, "ASN get big int error, invalid data", max); + break; + + case ASN_RSA_KEY_E : + XSTRNCPY(buffer, "ASN key init error, invalid input", max); + break; + + case ASN_OBJECT_ID_E : + XSTRNCPY(buffer, "ASN object id error, invalid id", max); + break; + + case ASN_TAG_NULL_E : + XSTRNCPY(buffer, "ASN tag error, not null", max); + break; + + case ASN_EXPECT_0_E : + XSTRNCPY(buffer, "ASN expect error, not zero", max); + break; + + case ASN_BITSTR_E : + XSTRNCPY(buffer, "ASN bit string error, wrong id", max); + break; + + case ASN_UNKNOWN_OID_E : + XSTRNCPY(buffer, "ASN oid error, unknown sum id", max); + break; + + case ASN_DATE_SZ_E : + XSTRNCPY(buffer, "ASN date error, bad size", max); + break; + + case ASN_BEFORE_DATE_E : + XSTRNCPY(buffer, "ASN date error, current date before", max); + break; + + case ASN_AFTER_DATE_E : + XSTRNCPY(buffer, "ASN date error, current date after", max); + break; + + case ASN_SIG_OID_E : + XSTRNCPY(buffer, "ASN signature error, mismatched oid", max); + break; + + case ASN_TIME_E : + XSTRNCPY(buffer, "ASN time error, unkown time type", max); + break; + + case ASN_INPUT_E : + XSTRNCPY(buffer, "ASN input error, not enough data", max); + break; + + case ASN_SIG_CONFIRM_E : + XSTRNCPY(buffer, "ASN sig error, confirm failure", max); + break; + + case ASN_SIG_HASH_E : + XSTRNCPY(buffer, "ASN sig error, unsupported hash type", max); + break; + + case ASN_SIG_KEY_E : + XSTRNCPY(buffer, "ASN sig error, unsupported key type", max); + break; + + case ASN_DH_KEY_E : + XSTRNCPY(buffer, "ASN key init error, invalid input", max); + break; + + case ASN_NTRU_KEY_E : + XSTRNCPY(buffer, "ASN NTRU key decode error, invalid input", max); + break; + + case ECC_BAD_ARG_E : + XSTRNCPY(buffer, "ECC input argument wrong type, invalid input", max); + break; + + case ASN_ECC_KEY_E : + XSTRNCPY(buffer, "ECC ASN1 bad key data, invalid input", max); + break; + + case ECC_CURVE_OID_E : + XSTRNCPY(buffer, "ECC curve sum OID unsupported, invalid input", max); + break; + + default: + XSTRNCPY(buffer, "unknown error number", max); + + } + +#endif /* NO_ERROR_STRINGS */ + +} + + +#if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) + +static int SetMyVersion(word32 version, byte* output, int header) +{ + int i = 0; + + if (header) { + output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED; + output[i++] = ASN_BIT_STRING; + } + output[i++] = ASN_INTEGER; + output[i++] = 0x01; + output[i++] = version; + + return i; +} + + +int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, + int type) +{ + char header[80]; + char footer[80]; + + int headerLen; + int footerLen; + int i; + int outLen; /* return length or error */ + + if (type == CERT_TYPE) { + XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", sizeof(header)); + XSTRNCPY(footer, "-----END CERTIFICATE-----\n", sizeof(footer)); + } else { + XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", sizeof(header)); + XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", sizeof(footer)); + } + + headerLen = XSTRLEN(header); + footerLen = XSTRLEN(footer); + + if (!der || !output) + return -1; + + /* don't even try if outSz too short */ + if (outSz < headerLen + footerLen + derSz) + return -1; + + /* header */ + XMEMCPY(output, header, headerLen); + i = headerLen; + + /* body */ + outLen = outSz; /* input to Base64Encode */ + if (Base64Encode(der, derSz, output + i, (word32*)&outLen) < 0) + return -1; + i += outLen; + + /* footer */ + if ( (i + footerLen) > (int)outSz) + return -1; + XMEMCPY(output + i, footer, footerLen); + + return outLen + headerLen + footerLen; +} + + +#endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */ + + +#ifdef CYASSL_KEY_GEN + + +static mp_int* GetRsaInt(RsaKey* key, int index) +{ + if (index == 0) + return &key->n; + if (index == 1) + return &key->e; + if (index == 2) + return &key->d; + if (index == 3) + return &key->p; + if (index == 4) + return &key->q; + if (index == 5) + return &key->dP; + if (index == 6) + return &key->dQ; + if (index == 7) + return &key->u; + + return NULL; +} + + +/* Convert RsaKey key to DER format, write to output (inLen), return bytes + written */ +int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) +{ + word32 seqSz, verSz, rawLen, intTotalLen = 0; + word32 sizes[RSA_INTS]; + int i, j, outLen; + + byte seq[MAX_SEQ_SZ]; + byte ver[MAX_VERSION_SZ]; + byte tmps[RSA_INTS][MAX_RSA_INT_SZ]; + + if (!key || !output) + return -1; + + if (key->type != RSA_PRIVATE) + return -1; + + /* write all big ints from key to DER tmps */ + for (i = 0; i < RSA_INTS; i++) { + mp_int* keyInt = GetRsaInt(key, i); + rawLen = mp_unsigned_bin_size(keyInt); + + tmps[i][0] = ASN_INTEGER; + sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ + + if ( (sizes[i] + rawLen) < sizeof(tmps[i])) { + int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); + if (err == MP_OKAY) { + sizes[i] += rawLen; + intTotalLen += sizes[i]; + } + else + return err; + } + else + return -1; + } + + /* make headers */ + verSz = SetMyVersion(0, ver, FALSE); + seqSz = SetSequence(verSz + intTotalLen, seq); + + outLen = seqSz + verSz + intTotalLen; + if (outLen > (int)inLen) + return -1; + + /* write to output */ + XMEMCPY(output, seq, seqSz); + j = seqSz; + XMEMCPY(output + j, ver, verSz); + j += verSz; + + for (i = 0; i < RSA_INTS; i++) { + XMEMCPY(output + j, tmps[i], sizes[i]); + j += sizes[i]; + } + + return outLen; +} + +#endif /* CYASSL_KEY_GEN */ + + +#ifdef CYASSL_CERT_GEN + +/* Initialize and Set Certficate defaults: + version = 3 (0x2) + serial = 0 + sigType = MD5_WITH_RSA + issuer = blank + daysValid = 500 + selfSigned = 1 (true) use subject as issuer + subject = blank +*/ +void InitCert(Cert* cert) +{ + cert->version = 2; /* version 3 is hex 2 */ + cert->sigType = MD5wRSA; + cert->daysValid = 500; + cert->selfSigned = 1; + cert->bodySz = 0; + cert->keyType = RSA_KEY; + XMEMSET(cert->serial, 0, SERIAL_SIZE); + + cert->issuer.country[0] = '\0'; + cert->issuer.state[0] = '\0'; + cert->issuer.locality[0] = '\0'; + cert->issuer.sur[0] = '\0'; + cert->issuer.org[0] = '\0'; + cert->issuer.unit[0] = '\0'; + cert->issuer.commonName[0] = '\0'; + cert->issuer.email[0] = '\0'; + + cert->subject.country[0] = '\0'; + cert->subject.state[0] = '\0'; + cert->subject.locality[0] = '\0'; + cert->subject.sur[0] = '\0'; + cert->subject.org[0] = '\0'; + cert->subject.unit[0] = '\0'; + cert->subject.commonName[0] = '\0'; + cert->subject.email[0] = '\0'; +} + + +/* DER encoded x509 Certificate */ +typedef struct DerCert { + byte size[MAX_LENGTH_SZ]; /* length encoded */ + byte version[MAX_VERSION_SZ]; /* version encoded */ + byte serial[SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */ + byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */ + byte issuer[ASN_NAME_MAX]; /* issuer encoded */ + byte subject[ASN_NAME_MAX]; /* subject encoded */ + byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */ + byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */ + int sizeSz; /* encoded size length */ + int versionSz; /* encoded version length */ + int serialSz; /* encoded serial length */ + int sigAlgoSz; /* enocded sig alog length */ + int issuerSz; /* encoded issuer length */ + int subjectSz; /* encoded subject length */ + int validitySz; /* encoded validity length */ + int publicKeySz; /* encoded public key length */ + int total; /* total encoded lengths */ +} DerCert; + + +/* Write a set header to output */ +static word32 SetSet(word32 len, byte* output) +{ + output[0] = ASN_SET | ASN_CONSTRUCTED; + return SetLength(len, output + 1) + 1; +} + + +/* Write a serial number to output */ +static int SetSerial(const byte* serial, byte* output) +{ + int length = 0; + + output[length++] = ASN_INTEGER; + length += SetLength(SERIAL_SIZE, &output[length]); + XMEMCPY(&output[length], serial, SERIAL_SIZE); + + return length + SERIAL_SIZE; +} + + +/* Write a public RSA key to output */ +static int SetPublicKey(byte* output, RsaKey* key) +{ + byte n[MAX_RSA_INT_SZ]; + byte e[MAX_RSA_E_SZ]; + byte algo[MAX_ALGO_SZ]; + byte seq[MAX_SEQ_SZ]; + byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ + int nSz; + int eSz; + int algoSz; + int seqSz; + int lenSz; + int idx; + int rawLen; + + /* n */ + rawLen = mp_unsigned_bin_size(&key->n); + n[0] = ASN_INTEGER; + nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ + + if ( (nSz + rawLen) < sizeof(n)) { + int err = mp_to_unsigned_bin(&key->n, n + nSz); + if (err == MP_OKAY) + nSz += rawLen; + else + return MP_TO_E; + } + else + return BUFFER_E; + + /* e */ + rawLen = mp_unsigned_bin_size(&key->e); + e[0] = ASN_INTEGER; + eSz = SetLength(rawLen, e + 1) + 1; /* int tag */ + + if ( (eSz + rawLen) < sizeof(e)) { + int err = mp_to_unsigned_bin(&key->e, e + eSz); + if (err == MP_OKAY) + eSz += rawLen; + else + return MP_TO_E; + } + else + return BUFFER_E; + + /* headers */ + algoSz = SetAlgoID(RSAk, algo, keyType); + seqSz = SetSequence(nSz + eSz, seq); + lenSz = SetLength(seqSz + nSz + eSz + 1, len); + len[lenSz++] = 0; /* trailing 0 */ + + /* write */ + idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output); + /* 1 is for ASN_BIT_STRING */ + /* algo */ + XMEMCPY(output + idx, algo, algoSz); + idx += algoSz; + /* bit string */ + output[idx++] = ASN_BIT_STRING; + /* length */ + XMEMCPY(output + idx, len, lenSz); + idx += lenSz; + /* seq */ + XMEMCPY(output + idx, seq, seqSz); + idx += seqSz; + /* n */ + XMEMCPY(output + idx, n, nSz); + idx += nSz; + /* e */ + XMEMCPY(output + idx, e, eSz); + idx += eSz; + + return idx; +} + + +static INLINE byte itob(int number) +{ + return (byte)number + 0x30; +} + + +/* write time to output, format */ +static void SetTime(struct tm* date, byte* output) +{ + int i = 0; + + output[i++] = itob((date->tm_year % 10000) / 1000); + output[i++] = itob((date->tm_year % 1000) / 100); + output[i++] = itob((date->tm_year % 100) / 10); + output[i++] = itob( date->tm_year % 10); + + output[i++] = itob(date->tm_mon / 10); + output[i++] = itob(date->tm_mon % 10); + + output[i++] = itob(date->tm_mday / 10); + output[i++] = itob(date->tm_mday % 10); + + output[i++] = itob(date->tm_hour / 10); + output[i++] = itob(date->tm_hour % 10); + + output[i++] = itob(date->tm_min / 10); + output[i++] = itob(date->tm_min % 10); + + output[i++] = itob(date->tm_sec / 10); + output[i++] = itob(date->tm_sec % 10); + + output[i] = 'Z'; /* Zulu profiel */ +} + + +/* Set Date validity from now until now + daysValid */ +static int SetValidity(byte* output, int daysValid) +{ + byte before[MAX_DATE_SIZE]; + byte after[MAX_DATE_SIZE]; + + int beforeSz; + int afterSz; + int seqSz; + + time_t ticks; + struct tm* now; + struct tm local; + + ticks = XTIME(0); + now = XGMTIME(&ticks); + + /* before now */ + local = *now; + before[0] = ASN_GENERALIZED_TIME; + beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ + + /* adjust */ + local.tm_year += 1900; + local.tm_mon += 1; + + SetTime(&local, before + beforeSz); + beforeSz += ASN_GEN_TIME_SZ; + + /* after now + daysValid */ + local = *now; + after[0] = ASN_GENERALIZED_TIME; + afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ + + /* add daysValid */ + local.tm_mday += daysValid; + mktime(&local); + + /* adjust */ + local.tm_year += 1900; + local.tm_mon += 1; + + SetTime(&local, after + afterSz); + afterSz += ASN_GEN_TIME_SZ; + + /* headers and output */ + seqSz = SetSequence(beforeSz + afterSz, output); + XMEMCPY(output + seqSz, before, beforeSz); + XMEMCPY(output + seqSz + beforeSz, after, afterSz); + + return seqSz + beforeSz + afterSz; +} + + +/* ASN Encoded Name field */ +typedef struct EncodedName { + int nameLen; /* actual string value length */ + int totalLen; /* total encodeding length */ + int type; /* type of name */ + int used; /* are we actually using this one */ + byte encoded[NAME_SIZE * 2]; /* encoding */ +} EncodedName; + + +/* Get Which Name from index */ +static const char* GetOneName(CertName* name, int index) +{ + switch (index) { + case 0: + return name->country; + break; + case 1: + return name->state; + break; + case 2: + return name->locality; + break; + case 3: + return name->sur; + break; + case 4: + return name->org; + break; + case 5: + return name->unit; + break; + case 6: + return name->commonName; + break; + case 7: + return name->email; + break; + default: + return 0; + } + + return 0; +} + + +/* Get ASN Name from index */ +static byte GetNameId(int index) +{ + switch (index) { + case 0: + return ASN_COUNTRY_NAME; + break; + case 1: + return ASN_STATE_NAME; + break; + case 2: + return ASN_LOCALITY_NAME; + break; + case 3: + return ASN_SUR_NAME; + break; + case 4: + return ASN_ORG_NAME; + break; + case 5: + return ASN_ORGUNIT_NAME; + break; + case 6: + return ASN_COMMON_NAME; + break; + case 7: + /* email uses different id type */ + return 0; + break; + default: + return 0; + } + + return 0; +} + + +/* encode CertName into output, return total bytes written */ +static int SetName(byte* output, CertName* name) +{ + int totalBytes = 0, i, idx; + EncodedName names[NAME_ENTRIES]; + + for (i = 0; i < NAME_ENTRIES; i++) { + const char* nameStr = GetOneName(name, i); + if (nameStr) { + /* bottom up */ + byte firstLen[MAX_LENGTH_SZ]; + byte secondLen[MAX_LENGTH_SZ]; + byte sequence[MAX_SEQ_SZ]; + byte set[MAX_SET_SZ]; + + int email = i == (NAME_ENTRIES - 1) ? 1 : 0; + int strLen = XSTRLEN(nameStr); + int thisLen = strLen; + int firstSz, secondSz, seqSz, setSz; + + if (strLen == 0) { /* no user data for this item */ + names[i].used = 0; + continue; + } + + secondSz = SetLength(strLen, secondLen); + thisLen += secondSz; + if (email) { + thisLen += EMAIL_JOINT_LEN; + thisLen ++; /* id type */ + firstSz = SetLength(EMAIL_JOINT_LEN, firstLen); + } + else { + thisLen++; /* str type */ + thisLen++; /* id type */ + thisLen += JOINT_LEN; + firstSz = SetLength(JOINT_LEN + 1, firstLen); + } + thisLen += firstSz; + thisLen++; /* object id */ + + seqSz = SetSequence(thisLen, sequence); + thisLen += seqSz; + setSz = SetSet(thisLen, set); + thisLen += setSz; + + if (thisLen > sizeof(names[i].encoded)) + return BUFFER_E; + + /* store it */ + idx = 0; + /* set */ + XMEMCPY(names[i].encoded, set, setSz); + idx += setSz; + /* seq */ + XMEMCPY(names[i].encoded + idx, sequence, seqSz); + idx += seqSz; + /* asn object id */ + names[i].encoded[idx++] = ASN_OBJECT_ID; + /* first length */ + XMEMCPY(names[i].encoded + idx, firstLen, firstSz); + idx += firstSz; + if (email) { + const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16 }; + /* email joint id */ + XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); + idx += sizeof(EMAIL_OID); + } + else { + /* joint id */ + names[i].encoded[idx++] = 0x55; + names[i].encoded[idx++] = 0x04; + /* id type */ + names[i].encoded[idx++] = GetNameId(i); + /* str type */ + names[i].encoded[idx++] = 0x13; + } + /* second length */ + XMEMCPY(names[i].encoded + idx, secondLen, secondSz); + idx += secondSz; + /* str value */ + XMEMCPY(names[i].encoded + idx, nameStr, strLen); + idx += strLen; + + totalBytes += idx; + names[i].totalLen = idx; + names[i].used = 1; + } + else + names[i].used = 0; + } + + /* header */ + idx = SetSequence(totalBytes, output); + totalBytes += idx; + if (totalBytes > ASN_NAME_MAX) + return BUFFER_E; + + for (i = 0; i < NAME_ENTRIES; i++) { + if (names[i].used) { + XMEMCPY(output + idx, names[i].encoded, names[i].totalLen); + idx += names[i].totalLen; + } + } + return totalBytes; +} + + +/* encode info from cert into DER enocder format */ +static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng, + const byte* ntruKey, word16 ntruSz) +{ + /* version */ + der->versionSz = SetMyVersion(cert->version, der->version, TRUE); + + /* serial number */ + RNG_GenerateBlock(rng, cert->serial, SERIAL_SIZE); + cert->serial[0] = 0x01; /* ensure positive */ + der->serialSz = SetSerial(cert->serial, der->serial); + + /* signature algo */ + der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType); + if (der->sigAlgoSz == 0) + return ALGO_ID_E; + + /* public key */ + if (cert->keyType == RSA_KEY) { + der->publicKeySz = SetPublicKey(der->publicKey, rsaKey); + if (der->publicKeySz == 0) + return PUBLIC_KEY_E; + } + else { +#ifdef HAVE_NTRU + word32 rc; + word16 encodedSz; + + rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, + ntruKey, &encodedSz, NULL); + if (rc != NTRU_OK) + return PUBLIC_KEY_E; + if (encodedSz > MAX_PUBLIC_KEY_SZ) + return PUBLIC_KEY_E; + + rc = crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, + ntruKey, &encodedSz, der->publicKey); + if (rc != NTRU_OK) + return PUBLIC_KEY_E; + + der->publicKeySz = encodedSz; +#endif + } + + /* date validity */ + der->validitySz = SetValidity(der->validity, cert->daysValid); + if (der->validitySz == 0) + return DATE_E; + + /* subject name */ + der->subjectSz = SetName(der->subject, &cert->subject); + if (der->subjectSz == 0) + return SUBJECT_E; + + /* issuer name */ + der->issuerSz = SetName(der->issuer, cert->selfSigned ? + &cert->subject : &cert->issuer); + if (der->issuerSz == 0) + return ISSUER_E; + + der->total = der->versionSz + der->serialSz + der->sigAlgoSz + + der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz; + + return 0; +} + + +/* write DER encoded cert to buffer, size already checked */ +static int WriteCertBody(DerCert* der, byte* buffer) +{ + int idx; + + /* signed part header */ + idx = SetSequence(der->total, buffer); + /* version */ + XMEMCPY(buffer + idx, der->version, der->versionSz); + idx += der->versionSz; + /* serial */ + XMEMCPY(buffer + idx, der->serial, der->serialSz); + idx += der->serialSz; + /* sig algo */ + XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz); + idx += der->sigAlgoSz; + /* issuer */ + XMEMCPY(buffer + idx, der->issuer, der->issuerSz); + idx += der->issuerSz; + /* validity */ + XMEMCPY(buffer + idx, der->validity, der->validitySz); + idx += der->validitySz; + /* subject */ + XMEMCPY(buffer + idx, der->subject, der->subjectSz); + idx += der->subjectSz; + /* public key */ + XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); + idx += der->publicKeySz; + + return idx; +} + + +/* Make MD5wRSA signature from buffer (sz), write to sig (sigSz) */ +static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, + RsaKey* key, RNG* rng) +{ + byte digest[SHA_DIGEST_SIZE]; /* max size */ + byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; + int encSigSz, digestSz, hashType; + Md5 md5; /* md5 for now */ + + InitMd5(&md5); + Md5Update(&md5, buffer, sz); + Md5Final(&md5, digest); + digestSz = MD5_DIGEST_SIZE; + hashType = MD5h; + + /* signature */ + encSigSz = EncodeSignature(encSig, digest, digestSz, hashType); + return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng); +} + + +/* add signature to end of buffer, size of buffer assumed checked, return + new length */ +static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz) +{ + byte seq[MAX_SEQ_SZ]; + int idx = bodySz, seqSz; + + /* algo */ + idx += SetAlgoID(MD5wRSA, buffer + idx, sigType); + /* bit string */ + buffer[idx++] = ASN_BIT_STRING; + /* length */ + idx += SetLength(sigSz + 1, buffer + idx); + buffer[idx++] = 0; /* trailing 0 */ + /* signature */ + XMEMCPY(buffer + idx, sig, sigSz); + idx += sigSz; + + /* make room for overall header */ + seqSz = SetSequence(idx, seq); + XMEMMOVE(buffer + seqSz, buffer, idx); + XMEMCPY(buffer, seq, seqSz); + + return idx + seqSz; +} + + +/* Make an x509 Certificate v3 any key type from cert input, write to buffer */ +static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, + RsaKey* rsaKey, RNG* rng, const byte* ntruKey, word16 ntruSz) +{ + DerCert der; + int ret; + + cert->keyType = rsaKey ? RSA_KEY : NTRU_KEY; + ret = EncodeCert(cert, &der, rsaKey, rng, ntruKey, ntruSz); + if (ret != 0) + return ret; + + if (der.total + MAX_SEQ_SZ * 2 > (int)derSz) + return BUFFER_E; + + return cert->bodySz = WriteCertBody(&der, derBuffer); +} + + +/* Make an x509 Certificate v3 RSA from cert input, write to buffer */ +int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,RNG* rng) +{ + return MakeAnyCert(cert, derBuffer, derSz, rsaKey, rng, NULL, 0); +} + + +#ifdef HAVE_NTRU + +int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, + const byte* ntruKey, word16 keySz, RNG* rng) +{ + return MakeAnyCert(cert, derBuffer, derSz, NULL, rng, ntruKey, keySz); +} + +#endif /* HAVE_NTRU */ + + +int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) +{ + byte sig[MAX_ENCODED_SIG_SZ]; + int sigSz; + int bodySz = cert->bodySz; + + if (bodySz < 0) + return bodySz; + + sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng); + if (sigSz < 0) + return sigSz; + + if (bodySz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) + return BUFFER_E; + + return AddSignature(buffer, bodySz, sig, sigSz); +} + + +int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) +{ + int ret = MakeCert(cert, buffer, buffSz, key, rng); + + if (ret < 0) + return ret; + + return SignCert(cert, buffer, buffSz, key, rng); +} + + +/* forward from CyaSSL */ +int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz); + +#ifndef NO_FILESYSTEM + +int SetIssuer(Cert* cert, const char* issuerCertFile) +{ + DecodedCert decoded; + byte der[8192]; + int derSz = CyaSSL_PemCertToDer(issuerCertFile, der, sizeof(der)); + int ret; + int sz; + + if (derSz < 0) + return derSz; + + cert->selfSigned = 0; + + InitDecodedCert(&decoded, der, 0); + ret = ParseCertRelative(&decoded, derSz, CA_TYPE, NO_VERIFY, 0); + + if (ret < 0) + return ret; + + if (decoded.subjectCN) { + sz = (decoded.subjectCNLen < NAME_SIZE) ? decoded.subjectCNLen : + NAME_SIZE - 1; + strncpy(cert->issuer.commonName, decoded.subjectCN, NAME_SIZE); + cert->issuer.commonName[sz] = 0; + } + if (decoded.subjectC) { + sz = (decoded.subjectCLen < NAME_SIZE) ? decoded.subjectCLen : + NAME_SIZE - 1; + strncpy(cert->issuer.country, decoded.subjectC, NAME_SIZE); + cert->issuer.country[sz] = 0; + } + if (decoded.subjectST) { + sz = (decoded.subjectSTLen < NAME_SIZE) ? decoded.subjectSTLen : + NAME_SIZE - 1; + strncpy(cert->issuer.state, decoded.subjectST, NAME_SIZE); + cert->issuer.state[sz] = 0; + } + if (decoded.subjectL) { + sz = (decoded.subjectLLen < NAME_SIZE) ? decoded.subjectLLen : + NAME_SIZE - 1; + strncpy(cert->issuer.locality, decoded.subjectL, NAME_SIZE); + cert->issuer.locality[sz] = 0; + } + if (decoded.subjectO) { + sz = (decoded.subjectOLen < NAME_SIZE) ? decoded.subjectOLen : + NAME_SIZE - 1; + strncpy(cert->issuer.org, decoded.subjectO, NAME_SIZE); + cert->issuer.org[sz] = 0; + } + if (decoded.subjectOU) { + sz = (decoded.subjectOULen < NAME_SIZE) ? decoded.subjectOULen : + NAME_SIZE - 1; + strncpy(cert->issuer.unit, decoded.subjectOU, NAME_SIZE); + cert->issuer.unit[sz] = 0; + } + if (decoded.subjectSN) { + sz = (decoded.subjectSNLen < NAME_SIZE) ? decoded.subjectSNLen : + NAME_SIZE - 1; + strncpy(cert->issuer.sur, decoded.subjectSN, NAME_SIZE); + cert->issuer.sur[sz] = 0; + } + if (decoded.subjectEmail) { + sz = (decoded.subjectEmailLen < NAME_SIZE) ? decoded.subjectEmailLen : + NAME_SIZE - 1; + strncpy(cert->issuer.email, decoded.subjectEmail, NAME_SIZE); + cert->issuer.email[sz] = 0; + } + + FreeDecodedCert(&decoded); + + return 0; +} + +#endif /* NO_FILESYSTEM */ +#endif /* CYASSL_CERT_GEN */ + + +#ifdef HAVE_ECC + +/* Der Eoncde r & s ints into out, outLen is (in/out) size */ +int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) +{ + word32 idx = 0; + word32 rSz; /* encoding size */ + word32 sSz; + word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */ + + int rLen = mp_unsigned_bin_size(r); /* big int size */ + int sLen = mp_unsigned_bin_size(s); + int err; + + if (*outLen < (rLen + sLen + headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */ + return -1; + + idx = SetSequence(rLen + sLen + headerSz, out); + + /* store r */ + out[idx++] = ASN_INTEGER; + rSz = SetLength(rLen, &out[idx]); + idx += rSz; + err = mp_to_unsigned_bin(r, &out[idx]); + if (err != MP_OKAY) return err; + idx += rLen; + + /* store s */ + out[idx++] = ASN_INTEGER; + sSz = SetLength(sLen, &out[idx]); + idx += sSz; + err = mp_to_unsigned_bin(s, &out[idx]); + if (err != MP_OKAY) return err; + idx += sLen; + + *outLen = idx; + + return 0; +} + + +/* Der Decode ECC-DSA Signautre, r & s stored as big ints */ +int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) +{ + word32 idx = 0; + int len = 0; + + if (GetSequence(sig, &idx, &len) < 0) + return ASN_ECC_KEY_E; + + if ((word32)len > (sigLen - idx)) + return ASN_ECC_KEY_E; + + if (GetInt(r, sig, &idx) < 0) + return ASN_ECC_KEY_E; + + if (GetInt(s, sig, &idx) < 0) + return ASN_ECC_KEY_E; + + return 0; +} + + +int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, + word32 inSz) +{ + word32 begin = *inOutIdx; + word32 oid = 0; + int version, length; + int privSz, pubSz; + byte b; + byte priv[ECC_MAXSIZE]; + byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ + + if (GetSequence(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + if ((word32)length > (inSz - (*inOutIdx - begin))) + return ASN_INPUT_E; + + if (GetMyVersion(input, inOutIdx, &version) < 0) + return ASN_PARSE_E; + + b = input[*inOutIdx]; + *inOutIdx += 1; + + /* priv type */ + if (b != 4 && b != 6 && b != 7) + return ASN_PARSE_E; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + /* priv key */ + privSz = length; + XMEMCPY(priv, &input[*inOutIdx], privSz); + *inOutIdx += length; + + /* prefix 0 */ + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + /* object id */ + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + while(length--) { + oid += input[*inOutIdx]; + *inOutIdx += 1; + } + if (CheckCurve(oid) < 0) + return ECC_CURVE_OID_E; + + /* prefix 1 */ + b = input[*inOutIdx]; + *inOutIdx += 1; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + + /* key header */ + b = input[*inOutIdx]; + *inOutIdx += 1; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(input, inOutIdx, &length) < 0) + return ASN_PARSE_E; + b = input[*inOutIdx]; + *inOutIdx += 1; + if (b != 0x00) + return ASN_EXPECT_0_E; + + pubSz = length - 1; /* null prefix */ + XMEMCPY(pub, &input[*inOutIdx], pubSz); + + *inOutIdx += length; + + return ecc_import_private_key(priv, privSz, pub, pubSz, key); +} + +#endif /* HAVE_ECC */ diff --git a/release/src/router/cyassl/ctaocrypt/src/coding.c b/release/src/router/cyassl/ctaocrypt/src/coding.c new file mode 100644 index 00000000..5ffabf17 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/coding.c @@ -0,0 +1,229 @@ +/* coding.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "coding.h" + + +enum { + BAD = 0xFF, /* invalid encoding */ + PAD = '=', + PEM_LINE_SZ = 64 +}; + + +static +const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, + BAD, BAD, BAD, BAD, BAD, BAD, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51 + }; + + +int Base64Decode(const byte* in, word32 inLen, byte* out, word32* outLen) +{ + word32 i = 0; + word32 j = 0; + word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); + + plainSz = (plainSz * 3 + 3) / 4; + if (plainSz > *outLen) return -1; + + while (inLen > 3) { + byte b1, b2, b3; + byte e1 = in[j++]; + byte e2 = in[j++]; + byte e3 = in[j++]; + byte e4 = in[j++]; + + int pad3 = 0; + int pad4 = 0; + + if (e1 == 0) /* end file 0's */ + break; + if (e3 == PAD) + pad3 = 1; + if (e4 == PAD) + pad4 = 1; + + e1 = base64Decode[e1 - 0x2B]; + e2 = base64Decode[e2 - 0x2B]; + e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; + e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; + + b1 = (e1 << 2) | (e2 >> 4); + b2 = ((e2 & 0xF) << 4) | (e3 >> 2); + b3 = ((e3 & 0x3) << 6) | e4; + + out[i++] = b1; + if (!pad3) + out[i++] = b2; + if (!pad4) + out[i++] = b3; + else + break; + + inLen -= 4; + if (in[j] == ' ' || in[j] == '\r' || in[j] == '\n') { + byte endLine = in[j++]; + inLen--; + while (endLine == ' ') { /* allow trailing whitespace */ + endLine = in[j++]; + inLen--; + } + if (endLine == '\r') { + endLine = in[j++]; + inLen--; + } + if (endLine != '\n') + return -1; + } + } + *outLen = i; + + return 0; +} + + +#if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) + +static +const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/' + }; + + +/* porting assistance from yaSSL by Raphael HUCK */ +int Base64Encode(const byte* in, word32 inLen, byte* out, word32* outLen) +{ + word32 i = 0, + j = 0, + n = 0; /* new line counter */ + + word32 outSz = (inLen + 3 - 1) / 3 * 4; + outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */ + + if (outSz > *outLen) return -1; + + while (inLen > 2) { + byte b1 = in[j++]; + byte b2 = in[j++]; + byte b3 = in[j++]; + + /* encoded idx */ + byte e1 = b1 >> 2; + byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); + byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6); + byte e4 = b3 & 0x3F; + + /* store */ + out[i++] = base64Encode[e1]; + out[i++] = base64Encode[e2]; + out[i++] = base64Encode[e3]; + out[i++] = base64Encode[e4]; + + inLen -= 3; + + if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) + out[i++] = '\n'; + } + + /* last integral */ + if (inLen) { + int twoBytes = (inLen == 2); + + byte b1 = in[j++]; + byte b2 = (twoBytes) ? in[j++] : 0; + + byte e1 = b1 >> 2; + byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); + byte e3 = (b2 & 0xF) << 2; + + out[i++] = base64Encode[e1]; + out[i++] = base64Encode[e2]; + out[i++] = (twoBytes) ? base64Encode[e3] : PAD; + out[i++] = PAD; + } + + out[i++] = '\n'; + if (i != outSz) + return -1; + *outLen = outSz; + + return 0; +} + + +static +const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, + 10, 11, 12, 13, 14, 15 + }; /* A starts at 0x41 not 0x3A */ + +int Base16Decode(const byte* in, word32 inLen, byte* out, word32* outLen) +{ + word32 inIdx = 0; + word32 outIdx = 0; + + if (inLen % 2) + return -1; + + if (*outLen < (inLen / 2)) + return -1; + + while (inLen) { + byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ + byte b2 = in[inIdx++] - 0x30; + + /* sanity checks */ + if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) + return -1; + if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) + return -1; + + b = hexDecode[b]; + b2 = hexDecode[b2]; + + if (b == BAD || b2 == BAD) + return -1; + + out[outIdx++] = (b << 4) | b2; + inLen -= 2; + } + + *outLen = outIdx; + return 0; +} + + +#endif /* OPENSSL_EXTRA */ diff --git a/release/src/router/cyassl/ctaocrypt/src/des3.c b/release/src/router/cyassl/ctaocrypt/src/des3.c new file mode 100644 index 00000000..d7792fc3 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/des3.c @@ -0,0 +1,493 @@ +/* des3.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_DES3 + +#include "des3.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +/* permuted choice table (key) */ +static const byte pc1[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +/* number left rotations of pc1 */ +static const byte totrot[] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 +}; + +/* permuted choice key (table) */ +static const byte pc2[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +/* End of DES-defined tables */ + +/* bit 0 is left-most in byte */ +static const int bytebit[] = { + 0200,0100,040,020,010,04,02,01 +}; + +const word32 Spbox[8][64] = { +{ +0x01010400,0x00000000,0x00010000,0x01010404, +0x01010004,0x00010404,0x00000004,0x00010000, +0x00000400,0x01010400,0x01010404,0x00000400, +0x01000404,0x01010004,0x01000000,0x00000004, +0x00000404,0x01000400,0x01000400,0x00010400, +0x00010400,0x01010000,0x01010000,0x01000404, +0x00010004,0x01000004,0x01000004,0x00010004, +0x00000000,0x00000404,0x00010404,0x01000000, +0x00010000,0x01010404,0x00000004,0x01010000, +0x01010400,0x01000000,0x01000000,0x00000400, +0x01010004,0x00010000,0x00010400,0x01000004, +0x00000400,0x00000004,0x01000404,0x00010404, +0x01010404,0x00010004,0x01010000,0x01000404, +0x01000004,0x00000404,0x00010404,0x01010400, +0x00000404,0x01000400,0x01000400,0x00000000, +0x00010004,0x00010400,0x00000000,0x01010004}, +{ +0x80108020,0x80008000,0x00008000,0x00108020, +0x00100000,0x00000020,0x80100020,0x80008020, +0x80000020,0x80108020,0x80108000,0x80000000, +0x80008000,0x00100000,0x00000020,0x80100020, +0x00108000,0x00100020,0x80008020,0x00000000, +0x80000000,0x00008000,0x00108020,0x80100000, +0x00100020,0x80000020,0x00000000,0x00108000, +0x00008020,0x80108000,0x80100000,0x00008020, +0x00000000,0x00108020,0x80100020,0x00100000, +0x80008020,0x80100000,0x80108000,0x00008000, +0x80100000,0x80008000,0x00000020,0x80108020, +0x00108020,0x00000020,0x00008000,0x80000000, +0x00008020,0x80108000,0x00100000,0x80000020, +0x00100020,0x80008020,0x80000020,0x00100020, +0x00108000,0x00000000,0x80008000,0x00008020, +0x80000000,0x80100020,0x80108020,0x00108000}, +{ +0x00000208,0x08020200,0x00000000,0x08020008, +0x08000200,0x00000000,0x00020208,0x08000200, +0x00020008,0x08000008,0x08000008,0x00020000, +0x08020208,0x00020008,0x08020000,0x00000208, +0x08000000,0x00000008,0x08020200,0x00000200, +0x00020200,0x08020000,0x08020008,0x00020208, +0x08000208,0x00020200,0x00020000,0x08000208, +0x00000008,0x08020208,0x00000200,0x08000000, +0x08020200,0x08000000,0x00020008,0x00000208, +0x00020000,0x08020200,0x08000200,0x00000000, +0x00000200,0x00020008,0x08020208,0x08000200, +0x08000008,0x00000200,0x00000000,0x08020008, +0x08000208,0x00020000,0x08000000,0x08020208, +0x00000008,0x00020208,0x00020200,0x08000008, +0x08020000,0x08000208,0x00000208,0x08020000, +0x00020208,0x00000008,0x08020008,0x00020200}, +{ +0x00802001,0x00002081,0x00002081,0x00000080, +0x00802080,0x00800081,0x00800001,0x00002001, +0x00000000,0x00802000,0x00802000,0x00802081, +0x00000081,0x00000000,0x00800080,0x00800001, +0x00000001,0x00002000,0x00800000,0x00802001, +0x00000080,0x00800000,0x00002001,0x00002080, +0x00800081,0x00000001,0x00002080,0x00800080, +0x00002000,0x00802080,0x00802081,0x00000081, +0x00800080,0x00800001,0x00802000,0x00802081, +0x00000081,0x00000000,0x00000000,0x00802000, +0x00002080,0x00800080,0x00800081,0x00000001, +0x00802001,0x00002081,0x00002081,0x00000080, +0x00802081,0x00000081,0x00000001,0x00002000, +0x00800001,0x00002001,0x00802080,0x00800081, +0x00002001,0x00002080,0x00800000,0x00802001, +0x00000080,0x00800000,0x00002000,0x00802080}, +{ +0x00000100,0x02080100,0x02080000,0x42000100, +0x00080000,0x00000100,0x40000000,0x02080000, +0x40080100,0x00080000,0x02000100,0x40080100, +0x42000100,0x42080000,0x00080100,0x40000000, +0x02000000,0x40080000,0x40080000,0x00000000, +0x40000100,0x42080100,0x42080100,0x02000100, +0x42080000,0x40000100,0x00000000,0x42000000, +0x02080100,0x02000000,0x42000000,0x00080100, +0x00080000,0x42000100,0x00000100,0x02000000, +0x40000000,0x02080000,0x42000100,0x40080100, +0x02000100,0x40000000,0x42080000,0x02080100, +0x40080100,0x00000100,0x02000000,0x42080000, +0x42080100,0x00080100,0x42000000,0x42080100, +0x02080000,0x00000000,0x40080000,0x42000000, +0x00080100,0x02000100,0x40000100,0x00080000, +0x00000000,0x40080000,0x02080100,0x40000100}, +{ +0x20000010,0x20400000,0x00004000,0x20404010, +0x20400000,0x00000010,0x20404010,0x00400000, +0x20004000,0x00404010,0x00400000,0x20000010, +0x00400010,0x20004000,0x20000000,0x00004010, +0x00000000,0x00400010,0x20004010,0x00004000, +0x00404000,0x20004010,0x00000010,0x20400010, +0x20400010,0x00000000,0x00404010,0x20404000, +0x00004010,0x00404000,0x20404000,0x20000000, +0x20004000,0x00000010,0x20400010,0x00404000, +0x20404010,0x00400000,0x00004010,0x20000010, +0x00400000,0x20004000,0x20000000,0x00004010, +0x20000010,0x20404010,0x00404000,0x20400000, +0x00404010,0x20404000,0x00000000,0x20400010, +0x00000010,0x00004000,0x20400000,0x00404010, +0x00004000,0x00400010,0x20004010,0x00000000, +0x20404000,0x20000000,0x00400010,0x20004010}, +{ +0x00200000,0x04200002,0x04000802,0x00000000, +0x00000800,0x04000802,0x00200802,0x04200800, +0x04200802,0x00200000,0x00000000,0x04000002, +0x00000002,0x04000000,0x04200002,0x00000802, +0x04000800,0x00200802,0x00200002,0x04000800, +0x04000002,0x04200000,0x04200800,0x00200002, +0x04200000,0x00000800,0x00000802,0x04200802, +0x00200800,0x00000002,0x04000000,0x00200800, +0x04000000,0x00200800,0x00200000,0x04000802, +0x04000802,0x04200002,0x04200002,0x00000002, +0x00200002,0x04000000,0x04000800,0x00200000, +0x04200800,0x00000802,0x00200802,0x04200800, +0x00000802,0x04000002,0x04200802,0x04200000, +0x00200800,0x00000000,0x00000002,0x04200802, +0x00000000,0x00200802,0x04200000,0x00000800, +0x04000002,0x04000800,0x00000800,0x00200002}, +{ +0x10001040,0x00001000,0x00040000,0x10041040, +0x10000000,0x10001040,0x00000040,0x10000000, +0x00040040,0x10040000,0x10041040,0x00041000, +0x10041000,0x00041040,0x00001000,0x00000040, +0x10040000,0x10000040,0x10001000,0x00001040, +0x00041000,0x00040040,0x10040040,0x10041000, +0x00001040,0x00000000,0x00000000,0x10040040, +0x10000040,0x10001000,0x00041040,0x00040000, +0x00041040,0x00040000,0x10041000,0x00001000, +0x00000040,0x10040040,0x00001000,0x00041040, +0x10001000,0x00000040,0x10000040,0x10040000, +0x10040040,0x10000000,0x00040000,0x10001040, +0x00000000,0x10041040,0x00040040,0x10000040, +0x10040000,0x10001000,0x10001040,0x00000000, +0x10041040,0x00041000,0x00041000,0x00001040, +0x00001040,0x00040040,0x10000000,0x10041000} +}; + + +static INLINE void IPERM(word32* left, word32* right) +{ + word32 work; + + *right = rotlFixed(*right, 4U); + work = (*left ^ *right) & 0xf0f0f0f0; + *left ^= work; + + *right = rotrFixed(*right^work, 20U); + work = (*left ^ *right) & 0xffff0000; + *left ^= work; + + *right = rotrFixed(*right^work, 18U); + work = (*left ^ *right) & 0x33333333; + *left ^= work; + + *right = rotrFixed(*right^work, 6U); + work = (*left ^ *right) & 0x00ff00ff; + *left ^= work; + + *right = rotlFixed(*right^work, 9U); + work = (*left ^ *right) & 0xaaaaaaaa; + *left = rotlFixed(*left^work, 1U); + *right ^= work; +} + + +static INLINE void FPERM(word32* left, word32* right) +{ + word32 work; + + *right = rotrFixed(*right, 1U); + work = (*left ^ *right) & 0xaaaaaaaa; + *right ^= work; + + *left = rotrFixed(*left^work, 9U); + work = (*left ^ *right) & 0x00ff00ff; + *right ^= work; + + *left = rotlFixed(*left^work, 6U); + work = (*left ^ *right) & 0x33333333; + *right ^= work; + + *left = rotlFixed(*left^work, 18U); + work = (*left ^ *right) & 0xffff0000; + *right ^= work; + + *left = rotlFixed(*left^work, 20U); + work = (*left ^ *right) & 0xf0f0f0f0; + *right ^= work; + + *left = rotrFixed(*left^work, 4U); +} + + +static void DesSetKey(const byte* key, int dir, word32* out) +{ + byte buffer[56+56+8]; + byte *const pc1m = buffer; /* place to modify pc1 into */ + byte *const pcr = pc1m + 56; /* place to rotate pc1 into */ + byte *const ks = pcr + 56; + register int i,j,l; + int m; + + for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */ + l = pc1[j] - 1; /* integer bit location */ + m = l & 07; /* find bit */ + pc1m[j] = (key[l >> 3] & /* find which key byte l is in */ + bytebit[m]) /* and which bit of that byte */ + ? 1 : 0; /* and store 1-bit result */ + } + for (i = 0; i < 16; i++) { /* key chunk for each iteration */ + XMEMSET(ks, 0, 8); /* Clear key schedule */ + for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ + pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28]; + /* rotate left and right halves independently */ + for (j = 0; j < 48; j++){ /* select bits individually */ + /* check bit that goes to ks[j] */ + if (pcr[pc2[j] - 1]){ + /* mask it in if it's there */ + l= j % 6; + ks[j/6] |= bytebit[l] >> 2; + } + } + /* Now convert to odd/even interleaved form for use in F */ + out[2*i] = ((word32)ks[0] << 24) + | ((word32)ks[2] << 16) + | ((word32)ks[4] << 8) + | ((word32)ks[6]); + out[2*i + 1] = ((word32)ks[1] << 24) + | ((word32)ks[3] << 16) + | ((word32)ks[5] << 8) + | ((word32)ks[7]); + } + + /* reverse key schedule order */ + if (dir == DES_DECRYPTION) + for (i = 0; i < 16; i += 2) { + word32 swap = out[i]; + out[i] = out[DES_KS_SIZE - 2 - i]; + out[DES_KS_SIZE - 2 - i] = swap; + + swap = out[i + 1]; + out[i + 1] = out[DES_KS_SIZE - 1 - i]; + out[DES_KS_SIZE - 1 - i] = swap; + } + +} + + +static INLINE int Reverse(int dir) +{ + return !dir; +} + + +void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) +{ + DesSetKey(key, dir, des->key); + + XMEMCPY(des->reg, iv, DES_BLOCK_SIZE); +} + + +void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) +{ + DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]); + DesSetKey(key + 8, Reverse(dir), des->key[1]); + DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]); + + XMEMCPY(des->reg, iv, DES_BLOCK_SIZE); +} + + +void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr) +{ + word32 l = *lIn, r = *rIn, i; + + for (i=0; i<8; i++) + { + word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0]; + l ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = r ^ kptr[4*i+1]; + l ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + + work = rotrFixed(l, 4U) ^ kptr[4*i+2]; + r ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = l ^ kptr[4*i+3]; + r ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + } + + *lIn = l; *rIn = r; +} + + +static void DesProcessBlock(Des* des, const byte* in, byte* out) +{ + word32 l, r; + + XMEMCPY(&l, in, sizeof(l)); + XMEMCPY(&r, in + sizeof(l), sizeof(r)); + #ifdef LITTLE_ENDIAN_ORDER + l = ByteReverseWord32(l); + r = ByteReverseWord32(r); + #endif + IPERM(&l,&r); + + DesRawProcessBlock(&l, &r, des->key); + + FPERM(&l,&r); + #ifdef LITTLE_ENDIAN_ORDER + l = ByteReverseWord32(l); + r = ByteReverseWord32(r); + #endif + XMEMCPY(out, &r, sizeof(r)); + XMEMCPY(out + sizeof(r), &l, sizeof(l)); +} + + +static void Des3ProcessBlock(Des3* des, const byte* in, byte* out) +{ + word32 l, r; + + XMEMCPY(&l, in, sizeof(l)); + XMEMCPY(&r, in + sizeof(l), sizeof(r)); + #ifdef LITTLE_ENDIAN_ORDER + l = ByteReverseWord32(l); + r = ByteReverseWord32(r); + #endif + IPERM(&l,&r); + + DesRawProcessBlock(&l, &r, des->key[0]); + DesRawProcessBlock(&r, &l, des->key[1]); + DesRawProcessBlock(&l, &r, des->key[2]); + + FPERM(&l,&r); + #ifdef LITTLE_ENDIAN_ORDER + l = ByteReverseWord32(l); + r = ByteReverseWord32(r); + #endif + XMEMCPY(out, &r, sizeof(r)); + XMEMCPY(out + sizeof(r), &l, sizeof(l)); +} + + +void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / DES_BLOCK_SIZE; + + while (blocks--) { + xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); + DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg); + XMEMCPY(out, des->reg, DES_BLOCK_SIZE); + + out += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + } +} + + +void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / DES_BLOCK_SIZE; + byte hold[16]; + + while (blocks--) { + XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); + DesProcessBlock(des, (byte*)des->tmp, out); + xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE); + + XMEMCPY(hold, des->reg, DES_BLOCK_SIZE); + XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); + XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE); + + out += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + } +} + + +void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / DES_BLOCK_SIZE; + + while (blocks--) { + xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); + Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg); + XMEMCPY(out, des->reg, DES_BLOCK_SIZE); + + out += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + } +} + + +void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) +{ + word32 blocks = sz / DES_BLOCK_SIZE; + + while (blocks--) { + XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); + Des3ProcessBlock(des, (byte*)des->tmp, out); + xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE); + XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); + + out += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + } +} + + +#endif /* NO_DES3 */ diff --git a/release/src/router/cyassl/ctaocrypt/src/dh.c b/release/src/router/cyassl/ctaocrypt/src/dh.c new file mode 100644 index 00000000..8b3d94b4 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/dh.c @@ -0,0 +1,165 @@ +/* dh.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_DH + +#include "ctc_dh.h" +#include "error.h" + +#ifndef USER_MATH_LIB + #include + #define XPOW(x,y) pow((x),(y)) + #define XLOG(x) log((x)) +#else + /* user's own math lib */ +#endif + + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + + +void InitDhKey(DhKey* key) +{ +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + key->p.dp = 0; + key->g.dp = 0; +#endif +} + + +void FreeDhKey(DhKey* key) +{ +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + mp_clear(&key->p); + mp_clear(&key->g); +#endif +} + + +static word32 DiscreteLogWorkFactor(word32 n) +{ + /* assuming discrete log takes about the same time as factoring */ + if (n<5) + return 0; + else + return (word32)(2.4 * XPOW((double)n, 1.0/3.0) * + XPOW(XLOG((double)n), 2.0/3.0) - 5); +} + + +static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) +{ + word32 sz = mp_unsigned_bin_size(&key->p); + sz = min(sz, 2 * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1); + + RNG_GenerateBlock(rng, priv, sz); + priv[0] |= 0x0C; + + *privSz = sz; +} + + +static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz, + byte* pub, word32* pubSz) +{ + int ret = 0; + + mp_int x; + mp_int y; + + if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) + ret = MP_READ_E; + + if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY) + ret = MP_EXPTMOD_E; + + if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY) + ret = MP_TO_E; + + if (ret == 0) + *pubSz = mp_unsigned_bin_size(&y); + + mp_clear(&y); + mp_clear(&x); + + return ret; +} + + +int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz, + byte* pub, word32* pubSz) +{ + GeneratePrivate(key, rng, priv, privSz); + return GeneratePublic(key, priv, *privSz, pub, pubSz); + +} + +int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, + word32 privSz, const byte* otherPub, word32 pubSz) +{ + int ret = 0; + + mp_int x; + mp_int y; + mp_int z; + + if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) + ret = MP_READ_E; + + if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY) + ret = MP_READ_E; + + if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY) + ret = MP_EXPTMOD_E; + + if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY) + ret = MP_TO_E; + + if (ret == 0) + *agreeSz = mp_unsigned_bin_size(&z); + + mp_clear(&z); + mp_clear(&y); + mp_clear(&x); + + return ret; +} + + +#endif /* NO_DH */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/dsa.c b/release/src/router/cyassl/ctaocrypt/src/dsa.c new file mode 100644 index 00000000..28e328ad --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/dsa.c @@ -0,0 +1,216 @@ +/* dsa.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_DSA + +#include "ctc_dsa.h" +#include "ctc_sha.h" +#include "random.h" +#include "error.h" + + +enum { + DSA_HALF_SIZE = 20, /* r and s size */ + DSA_SIG_SIZE = 40 /* signaure size */ +}; + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitDsaKey(DsaKey* key) +{ + key->type = -1; /* haven't decdied yet */ + +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + key->p.dp = 0; /* public alloc parts */ + key->q.dp = 0; + key->g.dp = 0; + key->y.dp = 0; + + key->x.dp = 0; /* private alloc parts */ +#endif +} + + +void FreeDsaKey(DsaKey* key) +{ +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + if (key->type == DSA_PRIVATE) + mp_clear(&key->x); + mp_clear(&key->y); + mp_clear(&key->g); + mp_clear(&key->q); + mp_clear(&key->p); +#endif +} + + +int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) +{ + mp_int k, kInv, r, s, H; + int ret = 0, sz; + byte buffer[DSA_HALF_SIZE]; + + if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) + return MP_INIT_E; + + sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q)); + + /* generate k */ + RNG_GenerateBlock(rng, buffer, sz); + buffer[0] |= 0x0C; + + if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) + ret = MP_READ_E; + + if (mp_cmp_d(&k, 1) != MP_GT) + ret = MP_CMP_E; + + /* inverse k mod q */ + if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY) + ret = MP_INVMOD_E; + + /* generate r, r = (g exp k mod p) mod q */ + if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) + ret = MP_EXPTMOD_E; + + if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) + ret = MP_MOD_E; + + /* generate H from sha digest */ + if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY) + ret = MP_READ_E; + + /* generate s, s = (kInv * (H + x*r)) % q */ + if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY) + ret = MP_MUL_E; + + if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY) + ret = MP_ADD_E; + + if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY) + ret = MP_MULMOD_E; + + /* write out */ + if (ret == 0) { + int rSz = mp_unsigned_bin_size(&r); + int sSz = mp_unsigned_bin_size(&s); + + if (rSz == DSA_HALF_SIZE - 1) { + out[0] = 0; + out++; + } + + if (mp_to_unsigned_bin(&r, out) != MP_OKAY) + ret = MP_TO_E; + else { + if (sSz == DSA_HALF_SIZE - 1) { + out[rSz] = 0; + out++; + } + ret = mp_to_unsigned_bin(&s, out + rSz); + } + } + + mp_clear(&H); + mp_clear(&s); + mp_clear(&r); + mp_clear(&kInv); + mp_clear(&k); + + return ret; +} + + +int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) +{ + mp_int w, u1, u2, v, r, s; + int ret = 0; + + if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY) + return MP_INIT_E; + + /* set r and s from signature */ + if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY || + mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) + ret = MP_READ_E; + + /* sanity checks */ + + + /* put H into u1 from sha digest */ + if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY) + ret = MP_READ_E; + + /* w = s invmod q */ + if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY) + ret = MP_INVMOD_E; + + /* u1 = (H * w) % q */ + if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY) + ret = MP_MULMOD_E; + + /* u2 = (r * w) % q */ + if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY) + ret = MP_MULMOD_E; + + /* verify v = ((g^u1 * y^u2) mod p) mod q */ + if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY) + ret = MP_EXPTMOD_E; + + if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY) + ret = MP_EXPTMOD_E; + + if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY) + ret = MP_MULMOD_E; + + if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY) + ret = MP_MULMOD_E; + + /* do they match */ + if (ret == 0 && mp_cmp(&r, &v) == MP_EQ) + *answer = 1; + else + *answer = 0; + + mp_clear(&s); + mp_clear(&r); + mp_clear(&u1); + mp_clear(&u2); + mp_clear(&w); + mp_clear(&v); + + return ret; +} + + +#endif /* NO_DSA */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/ecc.c b/release/src/router/cyassl/ctaocrypt/src/ecc.c new file mode 100644 index 00000000..9f03ed2f --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/ecc.c @@ -0,0 +1 @@ +/* dummy ecc.c for dist */ diff --git a/release/src/router/cyassl/ctaocrypt/src/ecc_fp.c b/release/src/router/cyassl/ctaocrypt/src/ecc_fp.c new file mode 100644 index 00000000..c8acf938 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/ecc_fp.c @@ -0,0 +1 @@ +/* dummy ecc_fp.c for dist */ diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mont_small.i b/release/src/router/cyassl/ctaocrypt/src/fp_mont_small.i new file mode 100644 index 00000000..5617d2f4 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mont_small.i @@ -0,0 +1,3838 @@ +#ifdef TFM_SMALL_MONT_SET +/* computes x/R == x (mod N) via Montgomery Reduction */ +void fp_montgomery_reduce_small(fp_int *a, fp_int *m, fp_digit mp) +{ + fp_digit c[FP_SIZE], *_c, *tmpm, mu, cy; + int oldused, x, y, pa; + +#if defined(USE_MEMSET) + /* now zero the buff */ + memset(c, 0, sizeof c); +#endif + pa = m->used; + + /* copy the input */ + oldused = a->used; + for (x = 0; x < oldused; x++) { + c[x] = a->dp[x]; + } +#if !defined(USE_MEMSET) + for (; x < 2*pa+3; x++) { + c[x] = 0; + } +#endif + MONT_START; + + switch (pa) { + case 1: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; +#else + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 2: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 3: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 4: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 5: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 6: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 7: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 8: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 9: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 10: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 11: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 12: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 11; cy = 0; + LOOP_START; + _c = c + 11; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 13: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 11; cy = 0; + LOOP_START; + _c = c + 11; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 12; cy = 0; + LOOP_START; + _c = c + 12; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 14: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 11; cy = 0; + LOOP_START; + _c = c + 11; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 12; cy = 0; + LOOP_START; + _c = c + 12; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 13; cy = 0; + LOOP_START; + _c = c + 13; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 15: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 11; cy = 0; + LOOP_START; + _c = c + 11; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 12; cy = 0; + LOOP_START; + _c = c + 12; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 13; cy = 0; + LOOP_START; + _c = c + 13; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 14; cy = 0; + LOOP_START; + _c = c + 14; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + case 16: + x = 0; cy = 0; + LOOP_START; + _c = c + 0; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 1; cy = 0; + LOOP_START; + _c = c + 1; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 2; cy = 0; + LOOP_START; + _c = c + 2; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 3; cy = 0; + LOOP_START; + _c = c + 3; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 4; cy = 0; + LOOP_START; + _c = c + 4; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 5; cy = 0; + LOOP_START; + _c = c + 5; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 6; cy = 0; + LOOP_START; + _c = c + 6; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 7; cy = 0; + LOOP_START; + _c = c + 7; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 8; cy = 0; + LOOP_START; + _c = c + 8; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 9; cy = 0; + LOOP_START; + _c = c + 9; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 10; cy = 0; + LOOP_START; + _c = c + 10; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 11; cy = 0; + LOOP_START; + _c = c + 11; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 12; cy = 0; + LOOP_START; + _c = c + 12; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 13; cy = 0; + LOOP_START; + _c = c + 13; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 14; cy = 0; + LOOP_START; + _c = c + 14; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + x = 15; cy = 0; + LOOP_START; + _c = c + 15; + tmpm = m->dp; +#ifdef INNERMUL8 + INNERMUL8; _c += 8; tmpm += 8; + INNERMUL8; _c += 8; tmpm += 8; +#else + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; + INNERMUL; ++_c; +#endif + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + break; + } + /* now copy out */ + _c = c + pa; + tmpm = a->dp; + for (x = 0; x < pa+1; x++) { + *tmpm++ = *_c++; + } + + for (; x < oldused; x++) { + *tmpm++ = 0; + } + + MONT_FINI; + + a->used = pa+1; + fp_clamp(a); + + /* if A >= m then A = A - m */ + if (fp_cmp_mag (a, m) != FP_LT) { + s_fp_sub (a, m, a); + } +} + +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_12.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_12.i new file mode 100644 index 00000000..5ec50b87 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_12.i @@ -0,0 +1,108 @@ +#ifdef TFM_MUL12 +void fp_mul_comba12(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[24]; + + memcpy(at, A->dp, 12 * sizeof(fp_digit)); + memcpy(at+12, B->dp, 12 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[12]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); MULADD(at[9], at[12]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); MULADD(at[9], at[13]); MULADD(at[10], at[12]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); MULADD(at[10], at[13]); MULADD(at[11], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); MULADD(at[10], at[14]); MULADD(at[11], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); MULADD(at[11], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); MULADD(at[11], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[10], at[23]); MULADD(at[11], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[11], at[23]); + COMBA_STORE(C->dp[22]); + COMBA_STORE2(C->dp[23]); + C->used = 24; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_17.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_17.i new file mode 100644 index 00000000..d324513f --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_17.i @@ -0,0 +1,148 @@ +#ifdef TFM_MUL17 +void fp_mul_comba17(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[34]; + + memcpy(at, A->dp, 17 * sizeof(fp_digit)); + memcpy(at+17, B->dp, 17 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[17]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[32]); MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); MULADD(at[1], at[32]); MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]); MULADD(at[16], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[1], at[33]); MULADD(at[2], at[32]); MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]); MULADD(at[16], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[2], at[33]); MULADD(at[3], at[32]); MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]); MULADD(at[16], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[3], at[33]); MULADD(at[4], at[32]); MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]); MULADD(at[16], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[4], at[33]); MULADD(at[5], at[32]); MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]); MULADD(at[16], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[5], at[33]); MULADD(at[6], at[32]); MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]); MULADD(at[16], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[6], at[33]); MULADD(at[7], at[32]); MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); MULADD(at[16], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[7], at[33]); MULADD(at[8], at[32]); MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); MULADD(at[16], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[8], at[33]); MULADD(at[9], at[32]); MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); MULADD(at[16], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[9], at[33]); MULADD(at[10], at[32]); MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); MULADD(at[16], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[10], at[33]); MULADD(at[11], at[32]); MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); MULADD(at[16], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[11], at[33]); MULADD(at[12], at[32]); MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); MULADD(at[16], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[12], at[33]); MULADD(at[13], at[32]); MULADD(at[14], at[31]); MULADD(at[15], at[30]); MULADD(at[16], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[13], at[33]); MULADD(at[14], at[32]); MULADD(at[15], at[31]); MULADD(at[16], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[14], at[33]); MULADD(at[15], at[32]); MULADD(at[16], at[31]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[15], at[33]); MULADD(at[16], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[16], at[33]); + COMBA_STORE(C->dp[32]); + COMBA_STORE2(C->dp[33]); + C->used = 34; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_20.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_20.i new file mode 100644 index 00000000..9af6d2c9 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_20.i @@ -0,0 +1,172 @@ +#ifdef TFM_MUL20 +void fp_mul_comba20(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[40]; + + memcpy(at, A->dp, 20 * sizeof(fp_digit)); + memcpy(at+20, B->dp, 20 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[20]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[32]); MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); MULADD(at[1], at[32]); MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]); MULADD(at[16], at[20]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]); MULADD(at[16], at[21]); MULADD(at[17], at[20]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]); MULADD(at[16], at[22]); MULADD(at[17], at[21]); MULADD(at[18], at[20]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); MULADD(at[16], at[23]); MULADD(at[17], at[22]); MULADD(at[18], at[21]); MULADD(at[19], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); MULADD(at[16], at[24]); MULADD(at[17], at[23]); MULADD(at[18], at[22]); MULADD(at[19], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); MULADD(at[16], at[25]); MULADD(at[17], at[24]); MULADD(at[18], at[23]); MULADD(at[19], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); MULADD(at[16], at[26]); MULADD(at[17], at[25]); MULADD(at[18], at[24]); MULADD(at[19], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); MULADD(at[16], at[27]); MULADD(at[17], at[26]); MULADD(at[18], at[25]); MULADD(at[19], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); MULADD(at[16], at[28]); MULADD(at[17], at[27]); MULADD(at[18], at[26]); MULADD(at[19], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); MULADD(at[14], at[31]); MULADD(at[15], at[30]); MULADD(at[16], at[29]); MULADD(at[17], at[28]); MULADD(at[18], at[27]); MULADD(at[19], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); MULADD(at[15], at[31]); MULADD(at[16], at[30]); MULADD(at[17], at[29]); MULADD(at[18], at[28]); MULADD(at[19], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); MULADD(at[16], at[31]); MULADD(at[17], at[30]); MULADD(at[18], at[29]); MULADD(at[19], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); MULADD(at[17], at[31]); MULADD(at[18], at[30]); MULADD(at[19], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); MULADD(at[18], at[31]); MULADD(at[19], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); MULADD(at[19], at[31]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[18], at[39]); MULADD(at[19], at[38]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[19], at[39]); + COMBA_STORE(C->dp[38]); + COMBA_STORE2(C->dp[39]); + C->used = 40; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_24.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_24.i new file mode 100644 index 00000000..bb518c0a --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_24.i @@ -0,0 +1,204 @@ +#ifdef TFM_MUL24 +void fp_mul_comba24(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[48]; + + memcpy(at, A->dp, 24 * sizeof(fp_digit)); + memcpy(at+24, B->dp, 24 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[24]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[32]); MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); MULADD(at[1], at[32]); MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); MULADD(at[16], at[24]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); MULADD(at[16], at[25]); MULADD(at[17], at[24]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); MULADD(at[16], at[26]); MULADD(at[17], at[25]); MULADD(at[18], at[24]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); MULADD(at[16], at[27]); MULADD(at[17], at[26]); MULADD(at[18], at[25]); MULADD(at[19], at[24]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); MULADD(at[16], at[28]); MULADD(at[17], at[27]); MULADD(at[18], at[26]); MULADD(at[19], at[25]); MULADD(at[20], at[24]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); MULADD(at[14], at[31]); MULADD(at[15], at[30]); MULADD(at[16], at[29]); MULADD(at[17], at[28]); MULADD(at[18], at[27]); MULADD(at[19], at[26]); MULADD(at[20], at[25]); MULADD(at[21], at[24]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); MULADD(at[15], at[31]); MULADD(at[16], at[30]); MULADD(at[17], at[29]); MULADD(at[18], at[28]); MULADD(at[19], at[27]); MULADD(at[20], at[26]); MULADD(at[21], at[25]); MULADD(at[22], at[24]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); MULADD(at[16], at[31]); MULADD(at[17], at[30]); MULADD(at[18], at[29]); MULADD(at[19], at[28]); MULADD(at[20], at[27]); MULADD(at[21], at[26]); MULADD(at[22], at[25]); MULADD(at[23], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); MULADD(at[17], at[31]); MULADD(at[18], at[30]); MULADD(at[19], at[29]); MULADD(at[20], at[28]); MULADD(at[21], at[27]); MULADD(at[22], at[26]); MULADD(at[23], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); MULADD(at[18], at[31]); MULADD(at[19], at[30]); MULADD(at[20], at[29]); MULADD(at[21], at[28]); MULADD(at[22], at[27]); MULADD(at[23], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); MULADD(at[19], at[31]); MULADD(at[20], at[30]); MULADD(at[21], at[29]); MULADD(at[22], at[28]); MULADD(at[23], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); MULADD(at[20], at[31]); MULADD(at[21], at[30]); MULADD(at[22], at[29]); MULADD(at[23], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]); MULADD(at[21], at[31]); MULADD(at[22], at[30]); MULADD(at[23], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]); MULADD(at[22], at[31]); MULADD(at[23], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]); MULADD(at[23], at[31]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); + COMBA_STORE(C->dp[38]); + /* 39 */ + COMBA_FORWARD; + MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[22], at[47]); MULADD(at[23], at[46]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[23], at[47]); + COMBA_STORE(C->dp[46]); + COMBA_STORE2(C->dp[47]); + C->used = 48; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_28.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_28.i new file mode 100644 index 00000000..be7d776b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_28.i @@ -0,0 +1,236 @@ +#ifdef TFM_MUL28 +void fp_mul_comba28(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[56]; + + memcpy(at, A->dp, 28 * sizeof(fp_digit)); + memcpy(at+28, B->dp, 28 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[28]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[32]); MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); MULADD(at[1], at[32]); MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); MULADD(at[16], at[28]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); MULADD(at[14], at[31]); MULADD(at[15], at[30]); MULADD(at[16], at[29]); MULADD(at[17], at[28]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); MULADD(at[15], at[31]); MULADD(at[16], at[30]); MULADD(at[17], at[29]); MULADD(at[18], at[28]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); MULADD(at[16], at[31]); MULADD(at[17], at[30]); MULADD(at[18], at[29]); MULADD(at[19], at[28]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); MULADD(at[17], at[31]); MULADD(at[18], at[30]); MULADD(at[19], at[29]); MULADD(at[20], at[28]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); MULADD(at[18], at[31]); MULADD(at[19], at[30]); MULADD(at[20], at[29]); MULADD(at[21], at[28]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); MULADD(at[19], at[31]); MULADD(at[20], at[30]); MULADD(at[21], at[29]); MULADD(at[22], at[28]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); MULADD(at[20], at[31]); MULADD(at[21], at[30]); MULADD(at[22], at[29]); MULADD(at[23], at[28]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]); MULADD(at[21], at[31]); MULADD(at[22], at[30]); MULADD(at[23], at[29]); MULADD(at[24], at[28]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]); MULADD(at[22], at[31]); MULADD(at[23], at[30]); MULADD(at[24], at[29]); MULADD(at[25], at[28]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]); MULADD(at[23], at[31]); MULADD(at[24], at[30]); MULADD(at[25], at[29]); MULADD(at[26], at[28]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]); MULADD(at[24], at[31]); MULADD(at[25], at[30]); MULADD(at[26], at[29]); MULADD(at[27], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]); MULADD(at[25], at[31]); MULADD(at[26], at[30]); MULADD(at[27], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]); MULADD(at[26], at[31]); MULADD(at[27], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]); MULADD(at[27], at[31]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); + COMBA_STORE(C->dp[38]); + /* 39 */ + COMBA_FORWARD; + MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); + COMBA_STORE(C->dp[46]); + /* 47 */ + COMBA_FORWARD; + MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); + COMBA_STORE(C->dp[47]); + /* 48 */ + COMBA_FORWARD; + MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); + COMBA_STORE(C->dp[48]); + /* 49 */ + COMBA_FORWARD; + MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); + COMBA_STORE(C->dp[49]); + /* 50 */ + COMBA_FORWARD; + MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); + COMBA_STORE(C->dp[50]); + /* 51 */ + COMBA_FORWARD; + MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); + COMBA_STORE(C->dp[51]); + /* 52 */ + COMBA_FORWARD; + MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); + COMBA_STORE(C->dp[52]); + /* 53 */ + COMBA_FORWARD; + MULADD(at[26], at[55]); MULADD(at[27], at[54]); + COMBA_STORE(C->dp[53]); + /* 54 */ + COMBA_FORWARD; + MULADD(at[27], at[55]); + COMBA_STORE(C->dp[54]); + COMBA_STORE2(C->dp[55]); + C->used = 56; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_3.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_3.i new file mode 100644 index 00000000..7b1675d6 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_3.i @@ -0,0 +1,36 @@ +#ifdef TFM_MUL3 +void fp_mul_comba3(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[6]; + + memcpy(at, A->dp, 3 * sizeof(fp_digit)); + memcpy(at+3, B->dp, 3 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[3]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[4]); MULADD(at[1], at[3]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[5]); MULADD(at[1], at[4]); MULADD(at[2], at[3]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[1], at[5]); MULADD(at[2], at[4]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[2], at[5]); + COMBA_STORE(C->dp[4]); + COMBA_STORE2(C->dp[5]); + C->used = 6; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_32.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_32.i new file mode 100644 index 00000000..f7e722e7 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_32.i @@ -0,0 +1,282 @@ +#ifdef TFM_MUL32 +void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[64]; + int out_size; + + out_size = A->used + B->used; + memcpy(at, A->dp, 32 * sizeof(fp_digit)); + memcpy(at+32, B->dp, 32 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[32]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[33]); MULADD(at[1], at[32]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]); + COMBA_STORE(C->dp[38]); + + /* early out at 40 digits, 40*32==1280, or two 640 bit operands */ + if (out_size <= 40) { COMBA_STORE2(C->dp[39]); C->used = 40; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; return; } + + /* 39 */ + COMBA_FORWARD; + MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]); + COMBA_STORE(C->dp[46]); + + /* early out at 48 digits, 48*32==1536, or two 768 bit operands */ + if (out_size <= 48) { COMBA_STORE2(C->dp[47]); C->used = 48; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; return; } + + /* 47 */ + COMBA_FORWARD; + MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]); + COMBA_STORE(C->dp[47]); + /* 48 */ + COMBA_FORWARD; + MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]); + COMBA_STORE(C->dp[48]); + /* 49 */ + COMBA_FORWARD; + MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]); + COMBA_STORE(C->dp[49]); + /* 50 */ + COMBA_FORWARD; + MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]); + COMBA_STORE(C->dp[50]); + /* 51 */ + COMBA_FORWARD; + MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]); + COMBA_STORE(C->dp[51]); + /* 52 */ + COMBA_FORWARD; + MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]); + COMBA_STORE(C->dp[52]); + /* 53 */ + COMBA_FORWARD; + MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]); + COMBA_STORE(C->dp[53]); + /* 54 */ + COMBA_FORWARD; + MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]); + COMBA_STORE(C->dp[54]); + + /* early out at 56 digits, 56*32==1792, or two 896 bit operands */ + if (out_size <= 56) { COMBA_STORE2(C->dp[55]); C->used = 56; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; return; } + + /* 55 */ + COMBA_FORWARD; + MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]); + COMBA_STORE(C->dp[55]); + /* 56 */ + COMBA_FORWARD; + MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]); + COMBA_STORE(C->dp[56]); + /* 57 */ + COMBA_FORWARD; + MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]); + COMBA_STORE(C->dp[57]); + /* 58 */ + COMBA_FORWARD; + MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]); + COMBA_STORE(C->dp[58]); + /* 59 */ + COMBA_FORWARD; + MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]); + COMBA_STORE(C->dp[59]); + /* 60 */ + COMBA_FORWARD; + MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]); + COMBA_STORE(C->dp[60]); + /* 61 */ + COMBA_FORWARD; + MULADD(at[30], at[63]); MULADD(at[31], at[62]); + COMBA_STORE(C->dp[61]); + /* 62 */ + COMBA_FORWARD; + MULADD(at[31], at[63]); + COMBA_STORE(C->dp[62]); + COMBA_STORE2(C->dp[63]); + C->used = 64; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_4.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_4.i new file mode 100644 index 00000000..f84c15d7 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_4.i @@ -0,0 +1,44 @@ +#ifdef TFM_MUL4 +void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[8]; + + memcpy(at, A->dp, 4 * sizeof(fp_digit)); + memcpy(at+4, B->dp, 4 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[4]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[5]); MULADD(at[1], at[4]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[2], at[7]); MULADD(at[3], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[3], at[7]); + COMBA_STORE(C->dp[6]); + COMBA_STORE2(C->dp[7]); + C->used = 8; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_48.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_48.i new file mode 100644 index 00000000..ce64bf50 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_48.i @@ -0,0 +1,396 @@ +#ifdef TFM_MUL48 +void fp_mul_comba48(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[96]; + + memcpy(at, A->dp, 48 * sizeof(fp_digit)); + memcpy(at+48, B->dp, 48 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[48]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[49]); MULADD(at[1], at[48]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[64]); MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[65]); MULADD(at[1], at[64]); MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[66]); MULADD(at[1], at[65]); MULADD(at[2], at[64]); MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[67]); MULADD(at[1], at[66]); MULADD(at[2], at[65]); MULADD(at[3], at[64]); MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[68]); MULADD(at[1], at[67]); MULADD(at[2], at[66]); MULADD(at[3], at[65]); MULADD(at[4], at[64]); MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[69]); MULADD(at[1], at[68]); MULADD(at[2], at[67]); MULADD(at[3], at[66]); MULADD(at[4], at[65]); MULADD(at[5], at[64]); MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[70]); MULADD(at[1], at[69]); MULADD(at[2], at[68]); MULADD(at[3], at[67]); MULADD(at[4], at[66]); MULADD(at[5], at[65]); MULADD(at[6], at[64]); MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[71]); MULADD(at[1], at[70]); MULADD(at[2], at[69]); MULADD(at[3], at[68]); MULADD(at[4], at[67]); MULADD(at[5], at[66]); MULADD(at[6], at[65]); MULADD(at[7], at[64]); MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[0], at[72]); MULADD(at[1], at[71]); MULADD(at[2], at[70]); MULADD(at[3], at[69]); MULADD(at[4], at[68]); MULADD(at[5], at[67]); MULADD(at[6], at[66]); MULADD(at[7], at[65]); MULADD(at[8], at[64]); MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[0], at[73]); MULADD(at[1], at[72]); MULADD(at[2], at[71]); MULADD(at[3], at[70]); MULADD(at[4], at[69]); MULADD(at[5], at[68]); MULADD(at[6], at[67]); MULADD(at[7], at[66]); MULADD(at[8], at[65]); MULADD(at[9], at[64]); MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[0], at[74]); MULADD(at[1], at[73]); MULADD(at[2], at[72]); MULADD(at[3], at[71]); MULADD(at[4], at[70]); MULADD(at[5], at[69]); MULADD(at[6], at[68]); MULADD(at[7], at[67]); MULADD(at[8], at[66]); MULADD(at[9], at[65]); MULADD(at[10], at[64]); MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[0], at[75]); MULADD(at[1], at[74]); MULADD(at[2], at[73]); MULADD(at[3], at[72]); MULADD(at[4], at[71]); MULADD(at[5], at[70]); MULADD(at[6], at[69]); MULADD(at[7], at[68]); MULADD(at[8], at[67]); MULADD(at[9], at[66]); MULADD(at[10], at[65]); MULADD(at[11], at[64]); MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[0], at[76]); MULADD(at[1], at[75]); MULADD(at[2], at[74]); MULADD(at[3], at[73]); MULADD(at[4], at[72]); MULADD(at[5], at[71]); MULADD(at[6], at[70]); MULADD(at[7], at[69]); MULADD(at[8], at[68]); MULADD(at[9], at[67]); MULADD(at[10], at[66]); MULADD(at[11], at[65]); MULADD(at[12], at[64]); MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[0], at[77]); MULADD(at[1], at[76]); MULADD(at[2], at[75]); MULADD(at[3], at[74]); MULADD(at[4], at[73]); MULADD(at[5], at[72]); MULADD(at[6], at[71]); MULADD(at[7], at[70]); MULADD(at[8], at[69]); MULADD(at[9], at[68]); MULADD(at[10], at[67]); MULADD(at[11], at[66]); MULADD(at[12], at[65]); MULADD(at[13], at[64]); MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[0], at[78]); MULADD(at[1], at[77]); MULADD(at[2], at[76]); MULADD(at[3], at[75]); MULADD(at[4], at[74]); MULADD(at[5], at[73]); MULADD(at[6], at[72]); MULADD(at[7], at[71]); MULADD(at[8], at[70]); MULADD(at[9], at[69]); MULADD(at[10], at[68]); MULADD(at[11], at[67]); MULADD(at[12], at[66]); MULADD(at[13], at[65]); MULADD(at[14], at[64]); MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[0], at[79]); MULADD(at[1], at[78]); MULADD(at[2], at[77]); MULADD(at[3], at[76]); MULADD(at[4], at[75]); MULADD(at[5], at[74]); MULADD(at[6], at[73]); MULADD(at[7], at[72]); MULADD(at[8], at[71]); MULADD(at[9], at[70]); MULADD(at[10], at[69]); MULADD(at[11], at[68]); MULADD(at[12], at[67]); MULADD(at[13], at[66]); MULADD(at[14], at[65]); MULADD(at[15], at[64]); MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[0], at[80]); MULADD(at[1], at[79]); MULADD(at[2], at[78]); MULADD(at[3], at[77]); MULADD(at[4], at[76]); MULADD(at[5], at[75]); MULADD(at[6], at[74]); MULADD(at[7], at[73]); MULADD(at[8], at[72]); MULADD(at[9], at[71]); MULADD(at[10], at[70]); MULADD(at[11], at[69]); MULADD(at[12], at[68]); MULADD(at[13], at[67]); MULADD(at[14], at[66]); MULADD(at[15], at[65]); MULADD(at[16], at[64]); MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]); MULADD(at[32], at[48]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[0], at[81]); MULADD(at[1], at[80]); MULADD(at[2], at[79]); MULADD(at[3], at[78]); MULADD(at[4], at[77]); MULADD(at[5], at[76]); MULADD(at[6], at[75]); MULADD(at[7], at[74]); MULADD(at[8], at[73]); MULADD(at[9], at[72]); MULADD(at[10], at[71]); MULADD(at[11], at[70]); MULADD(at[12], at[69]); MULADD(at[13], at[68]); MULADD(at[14], at[67]); MULADD(at[15], at[66]); MULADD(at[16], at[65]); MULADD(at[17], at[64]); MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]); MULADD(at[32], at[49]); MULADD(at[33], at[48]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[0], at[82]); MULADD(at[1], at[81]); MULADD(at[2], at[80]); MULADD(at[3], at[79]); MULADD(at[4], at[78]); MULADD(at[5], at[77]); MULADD(at[6], at[76]); MULADD(at[7], at[75]); MULADD(at[8], at[74]); MULADD(at[9], at[73]); MULADD(at[10], at[72]); MULADD(at[11], at[71]); MULADD(at[12], at[70]); MULADD(at[13], at[69]); MULADD(at[14], at[68]); MULADD(at[15], at[67]); MULADD(at[16], at[66]); MULADD(at[17], at[65]); MULADD(at[18], at[64]); MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]); MULADD(at[32], at[50]); MULADD(at[33], at[49]); MULADD(at[34], at[48]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[0], at[83]); MULADD(at[1], at[82]); MULADD(at[2], at[81]); MULADD(at[3], at[80]); MULADD(at[4], at[79]); MULADD(at[5], at[78]); MULADD(at[6], at[77]); MULADD(at[7], at[76]); MULADD(at[8], at[75]); MULADD(at[9], at[74]); MULADD(at[10], at[73]); MULADD(at[11], at[72]); MULADD(at[12], at[71]); MULADD(at[13], at[70]); MULADD(at[14], at[69]); MULADD(at[15], at[68]); MULADD(at[16], at[67]); MULADD(at[17], at[66]); MULADD(at[18], at[65]); MULADD(at[19], at[64]); MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]); MULADD(at[32], at[51]); MULADD(at[33], at[50]); MULADD(at[34], at[49]); MULADD(at[35], at[48]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[0], at[84]); MULADD(at[1], at[83]); MULADD(at[2], at[82]); MULADD(at[3], at[81]); MULADD(at[4], at[80]); MULADD(at[5], at[79]); MULADD(at[6], at[78]); MULADD(at[7], at[77]); MULADD(at[8], at[76]); MULADD(at[9], at[75]); MULADD(at[10], at[74]); MULADD(at[11], at[73]); MULADD(at[12], at[72]); MULADD(at[13], at[71]); MULADD(at[14], at[70]); MULADD(at[15], at[69]); MULADD(at[16], at[68]); MULADD(at[17], at[67]); MULADD(at[18], at[66]); MULADD(at[19], at[65]); MULADD(at[20], at[64]); MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]); MULADD(at[32], at[52]); MULADD(at[33], at[51]); MULADD(at[34], at[50]); MULADD(at[35], at[49]); MULADD(at[36], at[48]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[0], at[85]); MULADD(at[1], at[84]); MULADD(at[2], at[83]); MULADD(at[3], at[82]); MULADD(at[4], at[81]); MULADD(at[5], at[80]); MULADD(at[6], at[79]); MULADD(at[7], at[78]); MULADD(at[8], at[77]); MULADD(at[9], at[76]); MULADD(at[10], at[75]); MULADD(at[11], at[74]); MULADD(at[12], at[73]); MULADD(at[13], at[72]); MULADD(at[14], at[71]); MULADD(at[15], at[70]); MULADD(at[16], at[69]); MULADD(at[17], at[68]); MULADD(at[18], at[67]); MULADD(at[19], at[66]); MULADD(at[20], at[65]); MULADD(at[21], at[64]); MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]); MULADD(at[32], at[53]); MULADD(at[33], at[52]); MULADD(at[34], at[51]); MULADD(at[35], at[50]); MULADD(at[36], at[49]); MULADD(at[37], at[48]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[0], at[86]); MULADD(at[1], at[85]); MULADD(at[2], at[84]); MULADD(at[3], at[83]); MULADD(at[4], at[82]); MULADD(at[5], at[81]); MULADD(at[6], at[80]); MULADD(at[7], at[79]); MULADD(at[8], at[78]); MULADD(at[9], at[77]); MULADD(at[10], at[76]); MULADD(at[11], at[75]); MULADD(at[12], at[74]); MULADD(at[13], at[73]); MULADD(at[14], at[72]); MULADD(at[15], at[71]); MULADD(at[16], at[70]); MULADD(at[17], at[69]); MULADD(at[18], at[68]); MULADD(at[19], at[67]); MULADD(at[20], at[66]); MULADD(at[21], at[65]); MULADD(at[22], at[64]); MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]); MULADD(at[32], at[54]); MULADD(at[33], at[53]); MULADD(at[34], at[52]); MULADD(at[35], at[51]); MULADD(at[36], at[50]); MULADD(at[37], at[49]); MULADD(at[38], at[48]); + COMBA_STORE(C->dp[38]); + /* 39 */ + COMBA_FORWARD; + MULADD(at[0], at[87]); MULADD(at[1], at[86]); MULADD(at[2], at[85]); MULADD(at[3], at[84]); MULADD(at[4], at[83]); MULADD(at[5], at[82]); MULADD(at[6], at[81]); MULADD(at[7], at[80]); MULADD(at[8], at[79]); MULADD(at[9], at[78]); MULADD(at[10], at[77]); MULADD(at[11], at[76]); MULADD(at[12], at[75]); MULADD(at[13], at[74]); MULADD(at[14], at[73]); MULADD(at[15], at[72]); MULADD(at[16], at[71]); MULADD(at[17], at[70]); MULADD(at[18], at[69]); MULADD(at[19], at[68]); MULADD(at[20], at[67]); MULADD(at[21], at[66]); MULADD(at[22], at[65]); MULADD(at[23], at[64]); MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]); MULADD(at[32], at[55]); MULADD(at[33], at[54]); MULADD(at[34], at[53]); MULADD(at[35], at[52]); MULADD(at[36], at[51]); MULADD(at[37], at[50]); MULADD(at[38], at[49]); MULADD(at[39], at[48]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[0], at[88]); MULADD(at[1], at[87]); MULADD(at[2], at[86]); MULADD(at[3], at[85]); MULADD(at[4], at[84]); MULADD(at[5], at[83]); MULADD(at[6], at[82]); MULADD(at[7], at[81]); MULADD(at[8], at[80]); MULADD(at[9], at[79]); MULADD(at[10], at[78]); MULADD(at[11], at[77]); MULADD(at[12], at[76]); MULADD(at[13], at[75]); MULADD(at[14], at[74]); MULADD(at[15], at[73]); MULADD(at[16], at[72]); MULADD(at[17], at[71]); MULADD(at[18], at[70]); MULADD(at[19], at[69]); MULADD(at[20], at[68]); MULADD(at[21], at[67]); MULADD(at[22], at[66]); MULADD(at[23], at[65]); MULADD(at[24], at[64]); MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]); MULADD(at[32], at[56]); MULADD(at[33], at[55]); MULADD(at[34], at[54]); MULADD(at[35], at[53]); MULADD(at[36], at[52]); MULADD(at[37], at[51]); MULADD(at[38], at[50]); MULADD(at[39], at[49]); MULADD(at[40], at[48]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[0], at[89]); MULADD(at[1], at[88]); MULADD(at[2], at[87]); MULADD(at[3], at[86]); MULADD(at[4], at[85]); MULADD(at[5], at[84]); MULADD(at[6], at[83]); MULADD(at[7], at[82]); MULADD(at[8], at[81]); MULADD(at[9], at[80]); MULADD(at[10], at[79]); MULADD(at[11], at[78]); MULADD(at[12], at[77]); MULADD(at[13], at[76]); MULADD(at[14], at[75]); MULADD(at[15], at[74]); MULADD(at[16], at[73]); MULADD(at[17], at[72]); MULADD(at[18], at[71]); MULADD(at[19], at[70]); MULADD(at[20], at[69]); MULADD(at[21], at[68]); MULADD(at[22], at[67]); MULADD(at[23], at[66]); MULADD(at[24], at[65]); MULADD(at[25], at[64]); MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]); MULADD(at[32], at[57]); MULADD(at[33], at[56]); MULADD(at[34], at[55]); MULADD(at[35], at[54]); MULADD(at[36], at[53]); MULADD(at[37], at[52]); MULADD(at[38], at[51]); MULADD(at[39], at[50]); MULADD(at[40], at[49]); MULADD(at[41], at[48]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[0], at[90]); MULADD(at[1], at[89]); MULADD(at[2], at[88]); MULADD(at[3], at[87]); MULADD(at[4], at[86]); MULADD(at[5], at[85]); MULADD(at[6], at[84]); MULADD(at[7], at[83]); MULADD(at[8], at[82]); MULADD(at[9], at[81]); MULADD(at[10], at[80]); MULADD(at[11], at[79]); MULADD(at[12], at[78]); MULADD(at[13], at[77]); MULADD(at[14], at[76]); MULADD(at[15], at[75]); MULADD(at[16], at[74]); MULADD(at[17], at[73]); MULADD(at[18], at[72]); MULADD(at[19], at[71]); MULADD(at[20], at[70]); MULADD(at[21], at[69]); MULADD(at[22], at[68]); MULADD(at[23], at[67]); MULADD(at[24], at[66]); MULADD(at[25], at[65]); MULADD(at[26], at[64]); MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]); MULADD(at[32], at[58]); MULADD(at[33], at[57]); MULADD(at[34], at[56]); MULADD(at[35], at[55]); MULADD(at[36], at[54]); MULADD(at[37], at[53]); MULADD(at[38], at[52]); MULADD(at[39], at[51]); MULADD(at[40], at[50]); MULADD(at[41], at[49]); MULADD(at[42], at[48]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[0], at[91]); MULADD(at[1], at[90]); MULADD(at[2], at[89]); MULADD(at[3], at[88]); MULADD(at[4], at[87]); MULADD(at[5], at[86]); MULADD(at[6], at[85]); MULADD(at[7], at[84]); MULADD(at[8], at[83]); MULADD(at[9], at[82]); MULADD(at[10], at[81]); MULADD(at[11], at[80]); MULADD(at[12], at[79]); MULADD(at[13], at[78]); MULADD(at[14], at[77]); MULADD(at[15], at[76]); MULADD(at[16], at[75]); MULADD(at[17], at[74]); MULADD(at[18], at[73]); MULADD(at[19], at[72]); MULADD(at[20], at[71]); MULADD(at[21], at[70]); MULADD(at[22], at[69]); MULADD(at[23], at[68]); MULADD(at[24], at[67]); MULADD(at[25], at[66]); MULADD(at[26], at[65]); MULADD(at[27], at[64]); MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]); MULADD(at[32], at[59]); MULADD(at[33], at[58]); MULADD(at[34], at[57]); MULADD(at[35], at[56]); MULADD(at[36], at[55]); MULADD(at[37], at[54]); MULADD(at[38], at[53]); MULADD(at[39], at[52]); MULADD(at[40], at[51]); MULADD(at[41], at[50]); MULADD(at[42], at[49]); MULADD(at[43], at[48]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[0], at[92]); MULADD(at[1], at[91]); MULADD(at[2], at[90]); MULADD(at[3], at[89]); MULADD(at[4], at[88]); MULADD(at[5], at[87]); MULADD(at[6], at[86]); MULADD(at[7], at[85]); MULADD(at[8], at[84]); MULADD(at[9], at[83]); MULADD(at[10], at[82]); MULADD(at[11], at[81]); MULADD(at[12], at[80]); MULADD(at[13], at[79]); MULADD(at[14], at[78]); MULADD(at[15], at[77]); MULADD(at[16], at[76]); MULADD(at[17], at[75]); MULADD(at[18], at[74]); MULADD(at[19], at[73]); MULADD(at[20], at[72]); MULADD(at[21], at[71]); MULADD(at[22], at[70]); MULADD(at[23], at[69]); MULADD(at[24], at[68]); MULADD(at[25], at[67]); MULADD(at[26], at[66]); MULADD(at[27], at[65]); MULADD(at[28], at[64]); MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]); MULADD(at[32], at[60]); MULADD(at[33], at[59]); MULADD(at[34], at[58]); MULADD(at[35], at[57]); MULADD(at[36], at[56]); MULADD(at[37], at[55]); MULADD(at[38], at[54]); MULADD(at[39], at[53]); MULADD(at[40], at[52]); MULADD(at[41], at[51]); MULADD(at[42], at[50]); MULADD(at[43], at[49]); MULADD(at[44], at[48]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[0], at[93]); MULADD(at[1], at[92]); MULADD(at[2], at[91]); MULADD(at[3], at[90]); MULADD(at[4], at[89]); MULADD(at[5], at[88]); MULADD(at[6], at[87]); MULADD(at[7], at[86]); MULADD(at[8], at[85]); MULADD(at[9], at[84]); MULADD(at[10], at[83]); MULADD(at[11], at[82]); MULADD(at[12], at[81]); MULADD(at[13], at[80]); MULADD(at[14], at[79]); MULADD(at[15], at[78]); MULADD(at[16], at[77]); MULADD(at[17], at[76]); MULADD(at[18], at[75]); MULADD(at[19], at[74]); MULADD(at[20], at[73]); MULADD(at[21], at[72]); MULADD(at[22], at[71]); MULADD(at[23], at[70]); MULADD(at[24], at[69]); MULADD(at[25], at[68]); MULADD(at[26], at[67]); MULADD(at[27], at[66]); MULADD(at[28], at[65]); MULADD(at[29], at[64]); MULADD(at[30], at[63]); MULADD(at[31], at[62]); MULADD(at[32], at[61]); MULADD(at[33], at[60]); MULADD(at[34], at[59]); MULADD(at[35], at[58]); MULADD(at[36], at[57]); MULADD(at[37], at[56]); MULADD(at[38], at[55]); MULADD(at[39], at[54]); MULADD(at[40], at[53]); MULADD(at[41], at[52]); MULADD(at[42], at[51]); MULADD(at[43], at[50]); MULADD(at[44], at[49]); MULADD(at[45], at[48]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[0], at[94]); MULADD(at[1], at[93]); MULADD(at[2], at[92]); MULADD(at[3], at[91]); MULADD(at[4], at[90]); MULADD(at[5], at[89]); MULADD(at[6], at[88]); MULADD(at[7], at[87]); MULADD(at[8], at[86]); MULADD(at[9], at[85]); MULADD(at[10], at[84]); MULADD(at[11], at[83]); MULADD(at[12], at[82]); MULADD(at[13], at[81]); MULADD(at[14], at[80]); MULADD(at[15], at[79]); MULADD(at[16], at[78]); MULADD(at[17], at[77]); MULADD(at[18], at[76]); MULADD(at[19], at[75]); MULADD(at[20], at[74]); MULADD(at[21], at[73]); MULADD(at[22], at[72]); MULADD(at[23], at[71]); MULADD(at[24], at[70]); MULADD(at[25], at[69]); MULADD(at[26], at[68]); MULADD(at[27], at[67]); MULADD(at[28], at[66]); MULADD(at[29], at[65]); MULADD(at[30], at[64]); MULADD(at[31], at[63]); MULADD(at[32], at[62]); MULADD(at[33], at[61]); MULADD(at[34], at[60]); MULADD(at[35], at[59]); MULADD(at[36], at[58]); MULADD(at[37], at[57]); MULADD(at[38], at[56]); MULADD(at[39], at[55]); MULADD(at[40], at[54]); MULADD(at[41], at[53]); MULADD(at[42], at[52]); MULADD(at[43], at[51]); MULADD(at[44], at[50]); MULADD(at[45], at[49]); MULADD(at[46], at[48]); + COMBA_STORE(C->dp[46]); + /* 47 */ + COMBA_FORWARD; + MULADD(at[0], at[95]); MULADD(at[1], at[94]); MULADD(at[2], at[93]); MULADD(at[3], at[92]); MULADD(at[4], at[91]); MULADD(at[5], at[90]); MULADD(at[6], at[89]); MULADD(at[7], at[88]); MULADD(at[8], at[87]); MULADD(at[9], at[86]); MULADD(at[10], at[85]); MULADD(at[11], at[84]); MULADD(at[12], at[83]); MULADD(at[13], at[82]); MULADD(at[14], at[81]); MULADD(at[15], at[80]); MULADD(at[16], at[79]); MULADD(at[17], at[78]); MULADD(at[18], at[77]); MULADD(at[19], at[76]); MULADD(at[20], at[75]); MULADD(at[21], at[74]); MULADD(at[22], at[73]); MULADD(at[23], at[72]); MULADD(at[24], at[71]); MULADD(at[25], at[70]); MULADD(at[26], at[69]); MULADD(at[27], at[68]); MULADD(at[28], at[67]); MULADD(at[29], at[66]); MULADD(at[30], at[65]); MULADD(at[31], at[64]); MULADD(at[32], at[63]); MULADD(at[33], at[62]); MULADD(at[34], at[61]); MULADD(at[35], at[60]); MULADD(at[36], at[59]); MULADD(at[37], at[58]); MULADD(at[38], at[57]); MULADD(at[39], at[56]); MULADD(at[40], at[55]); MULADD(at[41], at[54]); MULADD(at[42], at[53]); MULADD(at[43], at[52]); MULADD(at[44], at[51]); MULADD(at[45], at[50]); MULADD(at[46], at[49]); MULADD(at[47], at[48]); + COMBA_STORE(C->dp[47]); + /* 48 */ + COMBA_FORWARD; + MULADD(at[1], at[95]); MULADD(at[2], at[94]); MULADD(at[3], at[93]); MULADD(at[4], at[92]); MULADD(at[5], at[91]); MULADD(at[6], at[90]); MULADD(at[7], at[89]); MULADD(at[8], at[88]); MULADD(at[9], at[87]); MULADD(at[10], at[86]); MULADD(at[11], at[85]); MULADD(at[12], at[84]); MULADD(at[13], at[83]); MULADD(at[14], at[82]); MULADD(at[15], at[81]); MULADD(at[16], at[80]); MULADD(at[17], at[79]); MULADD(at[18], at[78]); MULADD(at[19], at[77]); MULADD(at[20], at[76]); MULADD(at[21], at[75]); MULADD(at[22], at[74]); MULADD(at[23], at[73]); MULADD(at[24], at[72]); MULADD(at[25], at[71]); MULADD(at[26], at[70]); MULADD(at[27], at[69]); MULADD(at[28], at[68]); MULADD(at[29], at[67]); MULADD(at[30], at[66]); MULADD(at[31], at[65]); MULADD(at[32], at[64]); MULADD(at[33], at[63]); MULADD(at[34], at[62]); MULADD(at[35], at[61]); MULADD(at[36], at[60]); MULADD(at[37], at[59]); MULADD(at[38], at[58]); MULADD(at[39], at[57]); MULADD(at[40], at[56]); MULADD(at[41], at[55]); MULADD(at[42], at[54]); MULADD(at[43], at[53]); MULADD(at[44], at[52]); MULADD(at[45], at[51]); MULADD(at[46], at[50]); MULADD(at[47], at[49]); + COMBA_STORE(C->dp[48]); + /* 49 */ + COMBA_FORWARD; + MULADD(at[2], at[95]); MULADD(at[3], at[94]); MULADD(at[4], at[93]); MULADD(at[5], at[92]); MULADD(at[6], at[91]); MULADD(at[7], at[90]); MULADD(at[8], at[89]); MULADD(at[9], at[88]); MULADD(at[10], at[87]); MULADD(at[11], at[86]); MULADD(at[12], at[85]); MULADD(at[13], at[84]); MULADD(at[14], at[83]); MULADD(at[15], at[82]); MULADD(at[16], at[81]); MULADD(at[17], at[80]); MULADD(at[18], at[79]); MULADD(at[19], at[78]); MULADD(at[20], at[77]); MULADD(at[21], at[76]); MULADD(at[22], at[75]); MULADD(at[23], at[74]); MULADD(at[24], at[73]); MULADD(at[25], at[72]); MULADD(at[26], at[71]); MULADD(at[27], at[70]); MULADD(at[28], at[69]); MULADD(at[29], at[68]); MULADD(at[30], at[67]); MULADD(at[31], at[66]); MULADD(at[32], at[65]); MULADD(at[33], at[64]); MULADD(at[34], at[63]); MULADD(at[35], at[62]); MULADD(at[36], at[61]); MULADD(at[37], at[60]); MULADD(at[38], at[59]); MULADD(at[39], at[58]); MULADD(at[40], at[57]); MULADD(at[41], at[56]); MULADD(at[42], at[55]); MULADD(at[43], at[54]); MULADD(at[44], at[53]); MULADD(at[45], at[52]); MULADD(at[46], at[51]); MULADD(at[47], at[50]); + COMBA_STORE(C->dp[49]); + /* 50 */ + COMBA_FORWARD; + MULADD(at[3], at[95]); MULADD(at[4], at[94]); MULADD(at[5], at[93]); MULADD(at[6], at[92]); MULADD(at[7], at[91]); MULADD(at[8], at[90]); MULADD(at[9], at[89]); MULADD(at[10], at[88]); MULADD(at[11], at[87]); MULADD(at[12], at[86]); MULADD(at[13], at[85]); MULADD(at[14], at[84]); MULADD(at[15], at[83]); MULADD(at[16], at[82]); MULADD(at[17], at[81]); MULADD(at[18], at[80]); MULADD(at[19], at[79]); MULADD(at[20], at[78]); MULADD(at[21], at[77]); MULADD(at[22], at[76]); MULADD(at[23], at[75]); MULADD(at[24], at[74]); MULADD(at[25], at[73]); MULADD(at[26], at[72]); MULADD(at[27], at[71]); MULADD(at[28], at[70]); MULADD(at[29], at[69]); MULADD(at[30], at[68]); MULADD(at[31], at[67]); MULADD(at[32], at[66]); MULADD(at[33], at[65]); MULADD(at[34], at[64]); MULADD(at[35], at[63]); MULADD(at[36], at[62]); MULADD(at[37], at[61]); MULADD(at[38], at[60]); MULADD(at[39], at[59]); MULADD(at[40], at[58]); MULADD(at[41], at[57]); MULADD(at[42], at[56]); MULADD(at[43], at[55]); MULADD(at[44], at[54]); MULADD(at[45], at[53]); MULADD(at[46], at[52]); MULADD(at[47], at[51]); + COMBA_STORE(C->dp[50]); + /* 51 */ + COMBA_FORWARD; + MULADD(at[4], at[95]); MULADD(at[5], at[94]); MULADD(at[6], at[93]); MULADD(at[7], at[92]); MULADD(at[8], at[91]); MULADD(at[9], at[90]); MULADD(at[10], at[89]); MULADD(at[11], at[88]); MULADD(at[12], at[87]); MULADD(at[13], at[86]); MULADD(at[14], at[85]); MULADD(at[15], at[84]); MULADD(at[16], at[83]); MULADD(at[17], at[82]); MULADD(at[18], at[81]); MULADD(at[19], at[80]); MULADD(at[20], at[79]); MULADD(at[21], at[78]); MULADD(at[22], at[77]); MULADD(at[23], at[76]); MULADD(at[24], at[75]); MULADD(at[25], at[74]); MULADD(at[26], at[73]); MULADD(at[27], at[72]); MULADD(at[28], at[71]); MULADD(at[29], at[70]); MULADD(at[30], at[69]); MULADD(at[31], at[68]); MULADD(at[32], at[67]); MULADD(at[33], at[66]); MULADD(at[34], at[65]); MULADD(at[35], at[64]); MULADD(at[36], at[63]); MULADD(at[37], at[62]); MULADD(at[38], at[61]); MULADD(at[39], at[60]); MULADD(at[40], at[59]); MULADD(at[41], at[58]); MULADD(at[42], at[57]); MULADD(at[43], at[56]); MULADD(at[44], at[55]); MULADD(at[45], at[54]); MULADD(at[46], at[53]); MULADD(at[47], at[52]); + COMBA_STORE(C->dp[51]); + /* 52 */ + COMBA_FORWARD; + MULADD(at[5], at[95]); MULADD(at[6], at[94]); MULADD(at[7], at[93]); MULADD(at[8], at[92]); MULADD(at[9], at[91]); MULADD(at[10], at[90]); MULADD(at[11], at[89]); MULADD(at[12], at[88]); MULADD(at[13], at[87]); MULADD(at[14], at[86]); MULADD(at[15], at[85]); MULADD(at[16], at[84]); MULADD(at[17], at[83]); MULADD(at[18], at[82]); MULADD(at[19], at[81]); MULADD(at[20], at[80]); MULADD(at[21], at[79]); MULADD(at[22], at[78]); MULADD(at[23], at[77]); MULADD(at[24], at[76]); MULADD(at[25], at[75]); MULADD(at[26], at[74]); MULADD(at[27], at[73]); MULADD(at[28], at[72]); MULADD(at[29], at[71]); MULADD(at[30], at[70]); MULADD(at[31], at[69]); MULADD(at[32], at[68]); MULADD(at[33], at[67]); MULADD(at[34], at[66]); MULADD(at[35], at[65]); MULADD(at[36], at[64]); MULADD(at[37], at[63]); MULADD(at[38], at[62]); MULADD(at[39], at[61]); MULADD(at[40], at[60]); MULADD(at[41], at[59]); MULADD(at[42], at[58]); MULADD(at[43], at[57]); MULADD(at[44], at[56]); MULADD(at[45], at[55]); MULADD(at[46], at[54]); MULADD(at[47], at[53]); + COMBA_STORE(C->dp[52]); + /* 53 */ + COMBA_FORWARD; + MULADD(at[6], at[95]); MULADD(at[7], at[94]); MULADD(at[8], at[93]); MULADD(at[9], at[92]); MULADD(at[10], at[91]); MULADD(at[11], at[90]); MULADD(at[12], at[89]); MULADD(at[13], at[88]); MULADD(at[14], at[87]); MULADD(at[15], at[86]); MULADD(at[16], at[85]); MULADD(at[17], at[84]); MULADD(at[18], at[83]); MULADD(at[19], at[82]); MULADD(at[20], at[81]); MULADD(at[21], at[80]); MULADD(at[22], at[79]); MULADD(at[23], at[78]); MULADD(at[24], at[77]); MULADD(at[25], at[76]); MULADD(at[26], at[75]); MULADD(at[27], at[74]); MULADD(at[28], at[73]); MULADD(at[29], at[72]); MULADD(at[30], at[71]); MULADD(at[31], at[70]); MULADD(at[32], at[69]); MULADD(at[33], at[68]); MULADD(at[34], at[67]); MULADD(at[35], at[66]); MULADD(at[36], at[65]); MULADD(at[37], at[64]); MULADD(at[38], at[63]); MULADD(at[39], at[62]); MULADD(at[40], at[61]); MULADD(at[41], at[60]); MULADD(at[42], at[59]); MULADD(at[43], at[58]); MULADD(at[44], at[57]); MULADD(at[45], at[56]); MULADD(at[46], at[55]); MULADD(at[47], at[54]); + COMBA_STORE(C->dp[53]); + /* 54 */ + COMBA_FORWARD; + MULADD(at[7], at[95]); MULADD(at[8], at[94]); MULADD(at[9], at[93]); MULADD(at[10], at[92]); MULADD(at[11], at[91]); MULADD(at[12], at[90]); MULADD(at[13], at[89]); MULADD(at[14], at[88]); MULADD(at[15], at[87]); MULADD(at[16], at[86]); MULADD(at[17], at[85]); MULADD(at[18], at[84]); MULADD(at[19], at[83]); MULADD(at[20], at[82]); MULADD(at[21], at[81]); MULADD(at[22], at[80]); MULADD(at[23], at[79]); MULADD(at[24], at[78]); MULADD(at[25], at[77]); MULADD(at[26], at[76]); MULADD(at[27], at[75]); MULADD(at[28], at[74]); MULADD(at[29], at[73]); MULADD(at[30], at[72]); MULADD(at[31], at[71]); MULADD(at[32], at[70]); MULADD(at[33], at[69]); MULADD(at[34], at[68]); MULADD(at[35], at[67]); MULADD(at[36], at[66]); MULADD(at[37], at[65]); MULADD(at[38], at[64]); MULADD(at[39], at[63]); MULADD(at[40], at[62]); MULADD(at[41], at[61]); MULADD(at[42], at[60]); MULADD(at[43], at[59]); MULADD(at[44], at[58]); MULADD(at[45], at[57]); MULADD(at[46], at[56]); MULADD(at[47], at[55]); + COMBA_STORE(C->dp[54]); + /* 55 */ + COMBA_FORWARD; + MULADD(at[8], at[95]); MULADD(at[9], at[94]); MULADD(at[10], at[93]); MULADD(at[11], at[92]); MULADD(at[12], at[91]); MULADD(at[13], at[90]); MULADD(at[14], at[89]); MULADD(at[15], at[88]); MULADD(at[16], at[87]); MULADD(at[17], at[86]); MULADD(at[18], at[85]); MULADD(at[19], at[84]); MULADD(at[20], at[83]); MULADD(at[21], at[82]); MULADD(at[22], at[81]); MULADD(at[23], at[80]); MULADD(at[24], at[79]); MULADD(at[25], at[78]); MULADD(at[26], at[77]); MULADD(at[27], at[76]); MULADD(at[28], at[75]); MULADD(at[29], at[74]); MULADD(at[30], at[73]); MULADD(at[31], at[72]); MULADD(at[32], at[71]); MULADD(at[33], at[70]); MULADD(at[34], at[69]); MULADD(at[35], at[68]); MULADD(at[36], at[67]); MULADD(at[37], at[66]); MULADD(at[38], at[65]); MULADD(at[39], at[64]); MULADD(at[40], at[63]); MULADD(at[41], at[62]); MULADD(at[42], at[61]); MULADD(at[43], at[60]); MULADD(at[44], at[59]); MULADD(at[45], at[58]); MULADD(at[46], at[57]); MULADD(at[47], at[56]); + COMBA_STORE(C->dp[55]); + /* 56 */ + COMBA_FORWARD; + MULADD(at[9], at[95]); MULADD(at[10], at[94]); MULADD(at[11], at[93]); MULADD(at[12], at[92]); MULADD(at[13], at[91]); MULADD(at[14], at[90]); MULADD(at[15], at[89]); MULADD(at[16], at[88]); MULADD(at[17], at[87]); MULADD(at[18], at[86]); MULADD(at[19], at[85]); MULADD(at[20], at[84]); MULADD(at[21], at[83]); MULADD(at[22], at[82]); MULADD(at[23], at[81]); MULADD(at[24], at[80]); MULADD(at[25], at[79]); MULADD(at[26], at[78]); MULADD(at[27], at[77]); MULADD(at[28], at[76]); MULADD(at[29], at[75]); MULADD(at[30], at[74]); MULADD(at[31], at[73]); MULADD(at[32], at[72]); MULADD(at[33], at[71]); MULADD(at[34], at[70]); MULADD(at[35], at[69]); MULADD(at[36], at[68]); MULADD(at[37], at[67]); MULADD(at[38], at[66]); MULADD(at[39], at[65]); MULADD(at[40], at[64]); MULADD(at[41], at[63]); MULADD(at[42], at[62]); MULADD(at[43], at[61]); MULADD(at[44], at[60]); MULADD(at[45], at[59]); MULADD(at[46], at[58]); MULADD(at[47], at[57]); + COMBA_STORE(C->dp[56]); + /* 57 */ + COMBA_FORWARD; + MULADD(at[10], at[95]); MULADD(at[11], at[94]); MULADD(at[12], at[93]); MULADD(at[13], at[92]); MULADD(at[14], at[91]); MULADD(at[15], at[90]); MULADD(at[16], at[89]); MULADD(at[17], at[88]); MULADD(at[18], at[87]); MULADD(at[19], at[86]); MULADD(at[20], at[85]); MULADD(at[21], at[84]); MULADD(at[22], at[83]); MULADD(at[23], at[82]); MULADD(at[24], at[81]); MULADD(at[25], at[80]); MULADD(at[26], at[79]); MULADD(at[27], at[78]); MULADD(at[28], at[77]); MULADD(at[29], at[76]); MULADD(at[30], at[75]); MULADD(at[31], at[74]); MULADD(at[32], at[73]); MULADD(at[33], at[72]); MULADD(at[34], at[71]); MULADD(at[35], at[70]); MULADD(at[36], at[69]); MULADD(at[37], at[68]); MULADD(at[38], at[67]); MULADD(at[39], at[66]); MULADD(at[40], at[65]); MULADD(at[41], at[64]); MULADD(at[42], at[63]); MULADD(at[43], at[62]); MULADD(at[44], at[61]); MULADD(at[45], at[60]); MULADD(at[46], at[59]); MULADD(at[47], at[58]); + COMBA_STORE(C->dp[57]); + /* 58 */ + COMBA_FORWARD; + MULADD(at[11], at[95]); MULADD(at[12], at[94]); MULADD(at[13], at[93]); MULADD(at[14], at[92]); MULADD(at[15], at[91]); MULADD(at[16], at[90]); MULADD(at[17], at[89]); MULADD(at[18], at[88]); MULADD(at[19], at[87]); MULADD(at[20], at[86]); MULADD(at[21], at[85]); MULADD(at[22], at[84]); MULADD(at[23], at[83]); MULADD(at[24], at[82]); MULADD(at[25], at[81]); MULADD(at[26], at[80]); MULADD(at[27], at[79]); MULADD(at[28], at[78]); MULADD(at[29], at[77]); MULADD(at[30], at[76]); MULADD(at[31], at[75]); MULADD(at[32], at[74]); MULADD(at[33], at[73]); MULADD(at[34], at[72]); MULADD(at[35], at[71]); MULADD(at[36], at[70]); MULADD(at[37], at[69]); MULADD(at[38], at[68]); MULADD(at[39], at[67]); MULADD(at[40], at[66]); MULADD(at[41], at[65]); MULADD(at[42], at[64]); MULADD(at[43], at[63]); MULADD(at[44], at[62]); MULADD(at[45], at[61]); MULADD(at[46], at[60]); MULADD(at[47], at[59]); + COMBA_STORE(C->dp[58]); + /* 59 */ + COMBA_FORWARD; + MULADD(at[12], at[95]); MULADD(at[13], at[94]); MULADD(at[14], at[93]); MULADD(at[15], at[92]); MULADD(at[16], at[91]); MULADD(at[17], at[90]); MULADD(at[18], at[89]); MULADD(at[19], at[88]); MULADD(at[20], at[87]); MULADD(at[21], at[86]); MULADD(at[22], at[85]); MULADD(at[23], at[84]); MULADD(at[24], at[83]); MULADD(at[25], at[82]); MULADD(at[26], at[81]); MULADD(at[27], at[80]); MULADD(at[28], at[79]); MULADD(at[29], at[78]); MULADD(at[30], at[77]); MULADD(at[31], at[76]); MULADD(at[32], at[75]); MULADD(at[33], at[74]); MULADD(at[34], at[73]); MULADD(at[35], at[72]); MULADD(at[36], at[71]); MULADD(at[37], at[70]); MULADD(at[38], at[69]); MULADD(at[39], at[68]); MULADD(at[40], at[67]); MULADD(at[41], at[66]); MULADD(at[42], at[65]); MULADD(at[43], at[64]); MULADD(at[44], at[63]); MULADD(at[45], at[62]); MULADD(at[46], at[61]); MULADD(at[47], at[60]); + COMBA_STORE(C->dp[59]); + /* 60 */ + COMBA_FORWARD; + MULADD(at[13], at[95]); MULADD(at[14], at[94]); MULADD(at[15], at[93]); MULADD(at[16], at[92]); MULADD(at[17], at[91]); MULADD(at[18], at[90]); MULADD(at[19], at[89]); MULADD(at[20], at[88]); MULADD(at[21], at[87]); MULADD(at[22], at[86]); MULADD(at[23], at[85]); MULADD(at[24], at[84]); MULADD(at[25], at[83]); MULADD(at[26], at[82]); MULADD(at[27], at[81]); MULADD(at[28], at[80]); MULADD(at[29], at[79]); MULADD(at[30], at[78]); MULADD(at[31], at[77]); MULADD(at[32], at[76]); MULADD(at[33], at[75]); MULADD(at[34], at[74]); MULADD(at[35], at[73]); MULADD(at[36], at[72]); MULADD(at[37], at[71]); MULADD(at[38], at[70]); MULADD(at[39], at[69]); MULADD(at[40], at[68]); MULADD(at[41], at[67]); MULADD(at[42], at[66]); MULADD(at[43], at[65]); MULADD(at[44], at[64]); MULADD(at[45], at[63]); MULADD(at[46], at[62]); MULADD(at[47], at[61]); + COMBA_STORE(C->dp[60]); + /* 61 */ + COMBA_FORWARD; + MULADD(at[14], at[95]); MULADD(at[15], at[94]); MULADD(at[16], at[93]); MULADD(at[17], at[92]); MULADD(at[18], at[91]); MULADD(at[19], at[90]); MULADD(at[20], at[89]); MULADD(at[21], at[88]); MULADD(at[22], at[87]); MULADD(at[23], at[86]); MULADD(at[24], at[85]); MULADD(at[25], at[84]); MULADD(at[26], at[83]); MULADD(at[27], at[82]); MULADD(at[28], at[81]); MULADD(at[29], at[80]); MULADD(at[30], at[79]); MULADD(at[31], at[78]); MULADD(at[32], at[77]); MULADD(at[33], at[76]); MULADD(at[34], at[75]); MULADD(at[35], at[74]); MULADD(at[36], at[73]); MULADD(at[37], at[72]); MULADD(at[38], at[71]); MULADD(at[39], at[70]); MULADD(at[40], at[69]); MULADD(at[41], at[68]); MULADD(at[42], at[67]); MULADD(at[43], at[66]); MULADD(at[44], at[65]); MULADD(at[45], at[64]); MULADD(at[46], at[63]); MULADD(at[47], at[62]); + COMBA_STORE(C->dp[61]); + /* 62 */ + COMBA_FORWARD; + MULADD(at[15], at[95]); MULADD(at[16], at[94]); MULADD(at[17], at[93]); MULADD(at[18], at[92]); MULADD(at[19], at[91]); MULADD(at[20], at[90]); MULADD(at[21], at[89]); MULADD(at[22], at[88]); MULADD(at[23], at[87]); MULADD(at[24], at[86]); MULADD(at[25], at[85]); MULADD(at[26], at[84]); MULADD(at[27], at[83]); MULADD(at[28], at[82]); MULADD(at[29], at[81]); MULADD(at[30], at[80]); MULADD(at[31], at[79]); MULADD(at[32], at[78]); MULADD(at[33], at[77]); MULADD(at[34], at[76]); MULADD(at[35], at[75]); MULADD(at[36], at[74]); MULADD(at[37], at[73]); MULADD(at[38], at[72]); MULADD(at[39], at[71]); MULADD(at[40], at[70]); MULADD(at[41], at[69]); MULADD(at[42], at[68]); MULADD(at[43], at[67]); MULADD(at[44], at[66]); MULADD(at[45], at[65]); MULADD(at[46], at[64]); MULADD(at[47], at[63]); + COMBA_STORE(C->dp[62]); + /* 63 */ + COMBA_FORWARD; + MULADD(at[16], at[95]); MULADD(at[17], at[94]); MULADD(at[18], at[93]); MULADD(at[19], at[92]); MULADD(at[20], at[91]); MULADD(at[21], at[90]); MULADD(at[22], at[89]); MULADD(at[23], at[88]); MULADD(at[24], at[87]); MULADD(at[25], at[86]); MULADD(at[26], at[85]); MULADD(at[27], at[84]); MULADD(at[28], at[83]); MULADD(at[29], at[82]); MULADD(at[30], at[81]); MULADD(at[31], at[80]); MULADD(at[32], at[79]); MULADD(at[33], at[78]); MULADD(at[34], at[77]); MULADD(at[35], at[76]); MULADD(at[36], at[75]); MULADD(at[37], at[74]); MULADD(at[38], at[73]); MULADD(at[39], at[72]); MULADD(at[40], at[71]); MULADD(at[41], at[70]); MULADD(at[42], at[69]); MULADD(at[43], at[68]); MULADD(at[44], at[67]); MULADD(at[45], at[66]); MULADD(at[46], at[65]); MULADD(at[47], at[64]); + COMBA_STORE(C->dp[63]); + /* 64 */ + COMBA_FORWARD; + MULADD(at[17], at[95]); MULADD(at[18], at[94]); MULADD(at[19], at[93]); MULADD(at[20], at[92]); MULADD(at[21], at[91]); MULADD(at[22], at[90]); MULADD(at[23], at[89]); MULADD(at[24], at[88]); MULADD(at[25], at[87]); MULADD(at[26], at[86]); MULADD(at[27], at[85]); MULADD(at[28], at[84]); MULADD(at[29], at[83]); MULADD(at[30], at[82]); MULADD(at[31], at[81]); MULADD(at[32], at[80]); MULADD(at[33], at[79]); MULADD(at[34], at[78]); MULADD(at[35], at[77]); MULADD(at[36], at[76]); MULADD(at[37], at[75]); MULADD(at[38], at[74]); MULADD(at[39], at[73]); MULADD(at[40], at[72]); MULADD(at[41], at[71]); MULADD(at[42], at[70]); MULADD(at[43], at[69]); MULADD(at[44], at[68]); MULADD(at[45], at[67]); MULADD(at[46], at[66]); MULADD(at[47], at[65]); + COMBA_STORE(C->dp[64]); + /* 65 */ + COMBA_FORWARD; + MULADD(at[18], at[95]); MULADD(at[19], at[94]); MULADD(at[20], at[93]); MULADD(at[21], at[92]); MULADD(at[22], at[91]); MULADD(at[23], at[90]); MULADD(at[24], at[89]); MULADD(at[25], at[88]); MULADD(at[26], at[87]); MULADD(at[27], at[86]); MULADD(at[28], at[85]); MULADD(at[29], at[84]); MULADD(at[30], at[83]); MULADD(at[31], at[82]); MULADD(at[32], at[81]); MULADD(at[33], at[80]); MULADD(at[34], at[79]); MULADD(at[35], at[78]); MULADD(at[36], at[77]); MULADD(at[37], at[76]); MULADD(at[38], at[75]); MULADD(at[39], at[74]); MULADD(at[40], at[73]); MULADD(at[41], at[72]); MULADD(at[42], at[71]); MULADD(at[43], at[70]); MULADD(at[44], at[69]); MULADD(at[45], at[68]); MULADD(at[46], at[67]); MULADD(at[47], at[66]); + COMBA_STORE(C->dp[65]); + /* 66 */ + COMBA_FORWARD; + MULADD(at[19], at[95]); MULADD(at[20], at[94]); MULADD(at[21], at[93]); MULADD(at[22], at[92]); MULADD(at[23], at[91]); MULADD(at[24], at[90]); MULADD(at[25], at[89]); MULADD(at[26], at[88]); MULADD(at[27], at[87]); MULADD(at[28], at[86]); MULADD(at[29], at[85]); MULADD(at[30], at[84]); MULADD(at[31], at[83]); MULADD(at[32], at[82]); MULADD(at[33], at[81]); MULADD(at[34], at[80]); MULADD(at[35], at[79]); MULADD(at[36], at[78]); MULADD(at[37], at[77]); MULADD(at[38], at[76]); MULADD(at[39], at[75]); MULADD(at[40], at[74]); MULADD(at[41], at[73]); MULADD(at[42], at[72]); MULADD(at[43], at[71]); MULADD(at[44], at[70]); MULADD(at[45], at[69]); MULADD(at[46], at[68]); MULADD(at[47], at[67]); + COMBA_STORE(C->dp[66]); + /* 67 */ + COMBA_FORWARD; + MULADD(at[20], at[95]); MULADD(at[21], at[94]); MULADD(at[22], at[93]); MULADD(at[23], at[92]); MULADD(at[24], at[91]); MULADD(at[25], at[90]); MULADD(at[26], at[89]); MULADD(at[27], at[88]); MULADD(at[28], at[87]); MULADD(at[29], at[86]); MULADD(at[30], at[85]); MULADD(at[31], at[84]); MULADD(at[32], at[83]); MULADD(at[33], at[82]); MULADD(at[34], at[81]); MULADD(at[35], at[80]); MULADD(at[36], at[79]); MULADD(at[37], at[78]); MULADD(at[38], at[77]); MULADD(at[39], at[76]); MULADD(at[40], at[75]); MULADD(at[41], at[74]); MULADD(at[42], at[73]); MULADD(at[43], at[72]); MULADD(at[44], at[71]); MULADD(at[45], at[70]); MULADD(at[46], at[69]); MULADD(at[47], at[68]); + COMBA_STORE(C->dp[67]); + /* 68 */ + COMBA_FORWARD; + MULADD(at[21], at[95]); MULADD(at[22], at[94]); MULADD(at[23], at[93]); MULADD(at[24], at[92]); MULADD(at[25], at[91]); MULADD(at[26], at[90]); MULADD(at[27], at[89]); MULADD(at[28], at[88]); MULADD(at[29], at[87]); MULADD(at[30], at[86]); MULADD(at[31], at[85]); MULADD(at[32], at[84]); MULADD(at[33], at[83]); MULADD(at[34], at[82]); MULADD(at[35], at[81]); MULADD(at[36], at[80]); MULADD(at[37], at[79]); MULADD(at[38], at[78]); MULADD(at[39], at[77]); MULADD(at[40], at[76]); MULADD(at[41], at[75]); MULADD(at[42], at[74]); MULADD(at[43], at[73]); MULADD(at[44], at[72]); MULADD(at[45], at[71]); MULADD(at[46], at[70]); MULADD(at[47], at[69]); + COMBA_STORE(C->dp[68]); + /* 69 */ + COMBA_FORWARD; + MULADD(at[22], at[95]); MULADD(at[23], at[94]); MULADD(at[24], at[93]); MULADD(at[25], at[92]); MULADD(at[26], at[91]); MULADD(at[27], at[90]); MULADD(at[28], at[89]); MULADD(at[29], at[88]); MULADD(at[30], at[87]); MULADD(at[31], at[86]); MULADD(at[32], at[85]); MULADD(at[33], at[84]); MULADD(at[34], at[83]); MULADD(at[35], at[82]); MULADD(at[36], at[81]); MULADD(at[37], at[80]); MULADD(at[38], at[79]); MULADD(at[39], at[78]); MULADD(at[40], at[77]); MULADD(at[41], at[76]); MULADD(at[42], at[75]); MULADD(at[43], at[74]); MULADD(at[44], at[73]); MULADD(at[45], at[72]); MULADD(at[46], at[71]); MULADD(at[47], at[70]); + COMBA_STORE(C->dp[69]); + /* 70 */ + COMBA_FORWARD; + MULADD(at[23], at[95]); MULADD(at[24], at[94]); MULADD(at[25], at[93]); MULADD(at[26], at[92]); MULADD(at[27], at[91]); MULADD(at[28], at[90]); MULADD(at[29], at[89]); MULADD(at[30], at[88]); MULADD(at[31], at[87]); MULADD(at[32], at[86]); MULADD(at[33], at[85]); MULADD(at[34], at[84]); MULADD(at[35], at[83]); MULADD(at[36], at[82]); MULADD(at[37], at[81]); MULADD(at[38], at[80]); MULADD(at[39], at[79]); MULADD(at[40], at[78]); MULADD(at[41], at[77]); MULADD(at[42], at[76]); MULADD(at[43], at[75]); MULADD(at[44], at[74]); MULADD(at[45], at[73]); MULADD(at[46], at[72]); MULADD(at[47], at[71]); + COMBA_STORE(C->dp[70]); + /* 71 */ + COMBA_FORWARD; + MULADD(at[24], at[95]); MULADD(at[25], at[94]); MULADD(at[26], at[93]); MULADD(at[27], at[92]); MULADD(at[28], at[91]); MULADD(at[29], at[90]); MULADD(at[30], at[89]); MULADD(at[31], at[88]); MULADD(at[32], at[87]); MULADD(at[33], at[86]); MULADD(at[34], at[85]); MULADD(at[35], at[84]); MULADD(at[36], at[83]); MULADD(at[37], at[82]); MULADD(at[38], at[81]); MULADD(at[39], at[80]); MULADD(at[40], at[79]); MULADD(at[41], at[78]); MULADD(at[42], at[77]); MULADD(at[43], at[76]); MULADD(at[44], at[75]); MULADD(at[45], at[74]); MULADD(at[46], at[73]); MULADD(at[47], at[72]); + COMBA_STORE(C->dp[71]); + /* 72 */ + COMBA_FORWARD; + MULADD(at[25], at[95]); MULADD(at[26], at[94]); MULADD(at[27], at[93]); MULADD(at[28], at[92]); MULADD(at[29], at[91]); MULADD(at[30], at[90]); MULADD(at[31], at[89]); MULADD(at[32], at[88]); MULADD(at[33], at[87]); MULADD(at[34], at[86]); MULADD(at[35], at[85]); MULADD(at[36], at[84]); MULADD(at[37], at[83]); MULADD(at[38], at[82]); MULADD(at[39], at[81]); MULADD(at[40], at[80]); MULADD(at[41], at[79]); MULADD(at[42], at[78]); MULADD(at[43], at[77]); MULADD(at[44], at[76]); MULADD(at[45], at[75]); MULADD(at[46], at[74]); MULADD(at[47], at[73]); + COMBA_STORE(C->dp[72]); + /* 73 */ + COMBA_FORWARD; + MULADD(at[26], at[95]); MULADD(at[27], at[94]); MULADD(at[28], at[93]); MULADD(at[29], at[92]); MULADD(at[30], at[91]); MULADD(at[31], at[90]); MULADD(at[32], at[89]); MULADD(at[33], at[88]); MULADD(at[34], at[87]); MULADD(at[35], at[86]); MULADD(at[36], at[85]); MULADD(at[37], at[84]); MULADD(at[38], at[83]); MULADD(at[39], at[82]); MULADD(at[40], at[81]); MULADD(at[41], at[80]); MULADD(at[42], at[79]); MULADD(at[43], at[78]); MULADD(at[44], at[77]); MULADD(at[45], at[76]); MULADD(at[46], at[75]); MULADD(at[47], at[74]); + COMBA_STORE(C->dp[73]); + /* 74 */ + COMBA_FORWARD; + MULADD(at[27], at[95]); MULADD(at[28], at[94]); MULADD(at[29], at[93]); MULADD(at[30], at[92]); MULADD(at[31], at[91]); MULADD(at[32], at[90]); MULADD(at[33], at[89]); MULADD(at[34], at[88]); MULADD(at[35], at[87]); MULADD(at[36], at[86]); MULADD(at[37], at[85]); MULADD(at[38], at[84]); MULADD(at[39], at[83]); MULADD(at[40], at[82]); MULADD(at[41], at[81]); MULADD(at[42], at[80]); MULADD(at[43], at[79]); MULADD(at[44], at[78]); MULADD(at[45], at[77]); MULADD(at[46], at[76]); MULADD(at[47], at[75]); + COMBA_STORE(C->dp[74]); + /* 75 */ + COMBA_FORWARD; + MULADD(at[28], at[95]); MULADD(at[29], at[94]); MULADD(at[30], at[93]); MULADD(at[31], at[92]); MULADD(at[32], at[91]); MULADD(at[33], at[90]); MULADD(at[34], at[89]); MULADD(at[35], at[88]); MULADD(at[36], at[87]); MULADD(at[37], at[86]); MULADD(at[38], at[85]); MULADD(at[39], at[84]); MULADD(at[40], at[83]); MULADD(at[41], at[82]); MULADD(at[42], at[81]); MULADD(at[43], at[80]); MULADD(at[44], at[79]); MULADD(at[45], at[78]); MULADD(at[46], at[77]); MULADD(at[47], at[76]); + COMBA_STORE(C->dp[75]); + /* 76 */ + COMBA_FORWARD; + MULADD(at[29], at[95]); MULADD(at[30], at[94]); MULADD(at[31], at[93]); MULADD(at[32], at[92]); MULADD(at[33], at[91]); MULADD(at[34], at[90]); MULADD(at[35], at[89]); MULADD(at[36], at[88]); MULADD(at[37], at[87]); MULADD(at[38], at[86]); MULADD(at[39], at[85]); MULADD(at[40], at[84]); MULADD(at[41], at[83]); MULADD(at[42], at[82]); MULADD(at[43], at[81]); MULADD(at[44], at[80]); MULADD(at[45], at[79]); MULADD(at[46], at[78]); MULADD(at[47], at[77]); + COMBA_STORE(C->dp[76]); + /* 77 */ + COMBA_FORWARD; + MULADD(at[30], at[95]); MULADD(at[31], at[94]); MULADD(at[32], at[93]); MULADD(at[33], at[92]); MULADD(at[34], at[91]); MULADD(at[35], at[90]); MULADD(at[36], at[89]); MULADD(at[37], at[88]); MULADD(at[38], at[87]); MULADD(at[39], at[86]); MULADD(at[40], at[85]); MULADD(at[41], at[84]); MULADD(at[42], at[83]); MULADD(at[43], at[82]); MULADD(at[44], at[81]); MULADD(at[45], at[80]); MULADD(at[46], at[79]); MULADD(at[47], at[78]); + COMBA_STORE(C->dp[77]); + /* 78 */ + COMBA_FORWARD; + MULADD(at[31], at[95]); MULADD(at[32], at[94]); MULADD(at[33], at[93]); MULADD(at[34], at[92]); MULADD(at[35], at[91]); MULADD(at[36], at[90]); MULADD(at[37], at[89]); MULADD(at[38], at[88]); MULADD(at[39], at[87]); MULADD(at[40], at[86]); MULADD(at[41], at[85]); MULADD(at[42], at[84]); MULADD(at[43], at[83]); MULADD(at[44], at[82]); MULADD(at[45], at[81]); MULADD(at[46], at[80]); MULADD(at[47], at[79]); + COMBA_STORE(C->dp[78]); + /* 79 */ + COMBA_FORWARD; + MULADD(at[32], at[95]); MULADD(at[33], at[94]); MULADD(at[34], at[93]); MULADD(at[35], at[92]); MULADD(at[36], at[91]); MULADD(at[37], at[90]); MULADD(at[38], at[89]); MULADD(at[39], at[88]); MULADD(at[40], at[87]); MULADD(at[41], at[86]); MULADD(at[42], at[85]); MULADD(at[43], at[84]); MULADD(at[44], at[83]); MULADD(at[45], at[82]); MULADD(at[46], at[81]); MULADD(at[47], at[80]); + COMBA_STORE(C->dp[79]); + /* 80 */ + COMBA_FORWARD; + MULADD(at[33], at[95]); MULADD(at[34], at[94]); MULADD(at[35], at[93]); MULADD(at[36], at[92]); MULADD(at[37], at[91]); MULADD(at[38], at[90]); MULADD(at[39], at[89]); MULADD(at[40], at[88]); MULADD(at[41], at[87]); MULADD(at[42], at[86]); MULADD(at[43], at[85]); MULADD(at[44], at[84]); MULADD(at[45], at[83]); MULADD(at[46], at[82]); MULADD(at[47], at[81]); + COMBA_STORE(C->dp[80]); + /* 81 */ + COMBA_FORWARD; + MULADD(at[34], at[95]); MULADD(at[35], at[94]); MULADD(at[36], at[93]); MULADD(at[37], at[92]); MULADD(at[38], at[91]); MULADD(at[39], at[90]); MULADD(at[40], at[89]); MULADD(at[41], at[88]); MULADD(at[42], at[87]); MULADD(at[43], at[86]); MULADD(at[44], at[85]); MULADD(at[45], at[84]); MULADD(at[46], at[83]); MULADD(at[47], at[82]); + COMBA_STORE(C->dp[81]); + /* 82 */ + COMBA_FORWARD; + MULADD(at[35], at[95]); MULADD(at[36], at[94]); MULADD(at[37], at[93]); MULADD(at[38], at[92]); MULADD(at[39], at[91]); MULADD(at[40], at[90]); MULADD(at[41], at[89]); MULADD(at[42], at[88]); MULADD(at[43], at[87]); MULADD(at[44], at[86]); MULADD(at[45], at[85]); MULADD(at[46], at[84]); MULADD(at[47], at[83]); + COMBA_STORE(C->dp[82]); + /* 83 */ + COMBA_FORWARD; + MULADD(at[36], at[95]); MULADD(at[37], at[94]); MULADD(at[38], at[93]); MULADD(at[39], at[92]); MULADD(at[40], at[91]); MULADD(at[41], at[90]); MULADD(at[42], at[89]); MULADD(at[43], at[88]); MULADD(at[44], at[87]); MULADD(at[45], at[86]); MULADD(at[46], at[85]); MULADD(at[47], at[84]); + COMBA_STORE(C->dp[83]); + /* 84 */ + COMBA_FORWARD; + MULADD(at[37], at[95]); MULADD(at[38], at[94]); MULADD(at[39], at[93]); MULADD(at[40], at[92]); MULADD(at[41], at[91]); MULADD(at[42], at[90]); MULADD(at[43], at[89]); MULADD(at[44], at[88]); MULADD(at[45], at[87]); MULADD(at[46], at[86]); MULADD(at[47], at[85]); + COMBA_STORE(C->dp[84]); + /* 85 */ + COMBA_FORWARD; + MULADD(at[38], at[95]); MULADD(at[39], at[94]); MULADD(at[40], at[93]); MULADD(at[41], at[92]); MULADD(at[42], at[91]); MULADD(at[43], at[90]); MULADD(at[44], at[89]); MULADD(at[45], at[88]); MULADD(at[46], at[87]); MULADD(at[47], at[86]); + COMBA_STORE(C->dp[85]); + /* 86 */ + COMBA_FORWARD; + MULADD(at[39], at[95]); MULADD(at[40], at[94]); MULADD(at[41], at[93]); MULADD(at[42], at[92]); MULADD(at[43], at[91]); MULADD(at[44], at[90]); MULADD(at[45], at[89]); MULADD(at[46], at[88]); MULADD(at[47], at[87]); + COMBA_STORE(C->dp[86]); + /* 87 */ + COMBA_FORWARD; + MULADD(at[40], at[95]); MULADD(at[41], at[94]); MULADD(at[42], at[93]); MULADD(at[43], at[92]); MULADD(at[44], at[91]); MULADD(at[45], at[90]); MULADD(at[46], at[89]); MULADD(at[47], at[88]); + COMBA_STORE(C->dp[87]); + /* 88 */ + COMBA_FORWARD; + MULADD(at[41], at[95]); MULADD(at[42], at[94]); MULADD(at[43], at[93]); MULADD(at[44], at[92]); MULADD(at[45], at[91]); MULADD(at[46], at[90]); MULADD(at[47], at[89]); + COMBA_STORE(C->dp[88]); + /* 89 */ + COMBA_FORWARD; + MULADD(at[42], at[95]); MULADD(at[43], at[94]); MULADD(at[44], at[93]); MULADD(at[45], at[92]); MULADD(at[46], at[91]); MULADD(at[47], at[90]); + COMBA_STORE(C->dp[89]); + /* 90 */ + COMBA_FORWARD; + MULADD(at[43], at[95]); MULADD(at[44], at[94]); MULADD(at[45], at[93]); MULADD(at[46], at[92]); MULADD(at[47], at[91]); + COMBA_STORE(C->dp[90]); + /* 91 */ + COMBA_FORWARD; + MULADD(at[44], at[95]); MULADD(at[45], at[94]); MULADD(at[46], at[93]); MULADD(at[47], at[92]); + COMBA_STORE(C->dp[91]); + /* 92 */ + COMBA_FORWARD; + MULADD(at[45], at[95]); MULADD(at[46], at[94]); MULADD(at[47], at[93]); + COMBA_STORE(C->dp[92]); + /* 93 */ + COMBA_FORWARD; + MULADD(at[46], at[95]); MULADD(at[47], at[94]); + COMBA_STORE(C->dp[93]); + /* 94 */ + COMBA_FORWARD; + MULADD(at[47], at[95]); + COMBA_STORE(C->dp[94]); + COMBA_STORE2(C->dp[95]); + C->used = 96; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_6.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_6.i new file mode 100644 index 00000000..2be49a85 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_6.i @@ -0,0 +1,60 @@ +#ifdef TFM_MUL6 +void fp_mul_comba6(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[12]; + + memcpy(at, A->dp, 6 * sizeof(fp_digit)); + memcpy(at+6, B->dp, 6 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[6]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); MULADD(at[1], at[6]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[8]); MULADD(at[1], at[7]); MULADD(at[2], at[6]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); MULADD(at[3], at[6]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); MULADD(at[4], at[6]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); MULADD(at[5], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); MULADD(at[5], at[7]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[4], at[11]); MULADD(at[5], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[5], at[11]); + COMBA_STORE(C->dp[10]); + COMBA_STORE2(C->dp[11]); + C->used = 12; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_64.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_64.i new file mode 100644 index 00000000..4eb0b923 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_64.i @@ -0,0 +1,524 @@ +#ifdef TFM_MUL64 +void fp_mul_comba64(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[128]; + + memcpy(at, A->dp, 64 * sizeof(fp_digit)); + memcpy(at+64, B->dp, 64 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[64]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[65]); MULADD(at[1], at[64]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[66]); MULADD(at[1], at[65]); MULADD(at[2], at[64]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[67]); MULADD(at[1], at[66]); MULADD(at[2], at[65]); MULADD(at[3], at[64]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[68]); MULADD(at[1], at[67]); MULADD(at[2], at[66]); MULADD(at[3], at[65]); MULADD(at[4], at[64]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[69]); MULADD(at[1], at[68]); MULADD(at[2], at[67]); MULADD(at[3], at[66]); MULADD(at[4], at[65]); MULADD(at[5], at[64]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[70]); MULADD(at[1], at[69]); MULADD(at[2], at[68]); MULADD(at[3], at[67]); MULADD(at[4], at[66]); MULADD(at[5], at[65]); MULADD(at[6], at[64]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[71]); MULADD(at[1], at[70]); MULADD(at[2], at[69]); MULADD(at[3], at[68]); MULADD(at[4], at[67]); MULADD(at[5], at[66]); MULADD(at[6], at[65]); MULADD(at[7], at[64]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[72]); MULADD(at[1], at[71]); MULADD(at[2], at[70]); MULADD(at[3], at[69]); MULADD(at[4], at[68]); MULADD(at[5], at[67]); MULADD(at[6], at[66]); MULADD(at[7], at[65]); MULADD(at[8], at[64]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[73]); MULADD(at[1], at[72]); MULADD(at[2], at[71]); MULADD(at[3], at[70]); MULADD(at[4], at[69]); MULADD(at[5], at[68]); MULADD(at[6], at[67]); MULADD(at[7], at[66]); MULADD(at[8], at[65]); MULADD(at[9], at[64]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[74]); MULADD(at[1], at[73]); MULADD(at[2], at[72]); MULADD(at[3], at[71]); MULADD(at[4], at[70]); MULADD(at[5], at[69]); MULADD(at[6], at[68]); MULADD(at[7], at[67]); MULADD(at[8], at[66]); MULADD(at[9], at[65]); MULADD(at[10], at[64]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[75]); MULADD(at[1], at[74]); MULADD(at[2], at[73]); MULADD(at[3], at[72]); MULADD(at[4], at[71]); MULADD(at[5], at[70]); MULADD(at[6], at[69]); MULADD(at[7], at[68]); MULADD(at[8], at[67]); MULADD(at[9], at[66]); MULADD(at[10], at[65]); MULADD(at[11], at[64]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[76]); MULADD(at[1], at[75]); MULADD(at[2], at[74]); MULADD(at[3], at[73]); MULADD(at[4], at[72]); MULADD(at[5], at[71]); MULADD(at[6], at[70]); MULADD(at[7], at[69]); MULADD(at[8], at[68]); MULADD(at[9], at[67]); MULADD(at[10], at[66]); MULADD(at[11], at[65]); MULADD(at[12], at[64]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[77]); MULADD(at[1], at[76]); MULADD(at[2], at[75]); MULADD(at[3], at[74]); MULADD(at[4], at[73]); MULADD(at[5], at[72]); MULADD(at[6], at[71]); MULADD(at[7], at[70]); MULADD(at[8], at[69]); MULADD(at[9], at[68]); MULADD(at[10], at[67]); MULADD(at[11], at[66]); MULADD(at[12], at[65]); MULADD(at[13], at[64]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[78]); MULADD(at[1], at[77]); MULADD(at[2], at[76]); MULADD(at[3], at[75]); MULADD(at[4], at[74]); MULADD(at[5], at[73]); MULADD(at[6], at[72]); MULADD(at[7], at[71]); MULADD(at[8], at[70]); MULADD(at[9], at[69]); MULADD(at[10], at[68]); MULADD(at[11], at[67]); MULADD(at[12], at[66]); MULADD(at[13], at[65]); MULADD(at[14], at[64]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[79]); MULADD(at[1], at[78]); MULADD(at[2], at[77]); MULADD(at[3], at[76]); MULADD(at[4], at[75]); MULADD(at[5], at[74]); MULADD(at[6], at[73]); MULADD(at[7], at[72]); MULADD(at[8], at[71]); MULADD(at[9], at[70]); MULADD(at[10], at[69]); MULADD(at[11], at[68]); MULADD(at[12], at[67]); MULADD(at[13], at[66]); MULADD(at[14], at[65]); MULADD(at[15], at[64]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[0], at[80]); MULADD(at[1], at[79]); MULADD(at[2], at[78]); MULADD(at[3], at[77]); MULADD(at[4], at[76]); MULADD(at[5], at[75]); MULADD(at[6], at[74]); MULADD(at[7], at[73]); MULADD(at[8], at[72]); MULADD(at[9], at[71]); MULADD(at[10], at[70]); MULADD(at[11], at[69]); MULADD(at[12], at[68]); MULADD(at[13], at[67]); MULADD(at[14], at[66]); MULADD(at[15], at[65]); MULADD(at[16], at[64]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[0], at[81]); MULADD(at[1], at[80]); MULADD(at[2], at[79]); MULADD(at[3], at[78]); MULADD(at[4], at[77]); MULADD(at[5], at[76]); MULADD(at[6], at[75]); MULADD(at[7], at[74]); MULADD(at[8], at[73]); MULADD(at[9], at[72]); MULADD(at[10], at[71]); MULADD(at[11], at[70]); MULADD(at[12], at[69]); MULADD(at[13], at[68]); MULADD(at[14], at[67]); MULADD(at[15], at[66]); MULADD(at[16], at[65]); MULADD(at[17], at[64]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[0], at[82]); MULADD(at[1], at[81]); MULADD(at[2], at[80]); MULADD(at[3], at[79]); MULADD(at[4], at[78]); MULADD(at[5], at[77]); MULADD(at[6], at[76]); MULADD(at[7], at[75]); MULADD(at[8], at[74]); MULADD(at[9], at[73]); MULADD(at[10], at[72]); MULADD(at[11], at[71]); MULADD(at[12], at[70]); MULADD(at[13], at[69]); MULADD(at[14], at[68]); MULADD(at[15], at[67]); MULADD(at[16], at[66]); MULADD(at[17], at[65]); MULADD(at[18], at[64]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[0], at[83]); MULADD(at[1], at[82]); MULADD(at[2], at[81]); MULADD(at[3], at[80]); MULADD(at[4], at[79]); MULADD(at[5], at[78]); MULADD(at[6], at[77]); MULADD(at[7], at[76]); MULADD(at[8], at[75]); MULADD(at[9], at[74]); MULADD(at[10], at[73]); MULADD(at[11], at[72]); MULADD(at[12], at[71]); MULADD(at[13], at[70]); MULADD(at[14], at[69]); MULADD(at[15], at[68]); MULADD(at[16], at[67]); MULADD(at[17], at[66]); MULADD(at[18], at[65]); MULADD(at[19], at[64]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[0], at[84]); MULADD(at[1], at[83]); MULADD(at[2], at[82]); MULADD(at[3], at[81]); MULADD(at[4], at[80]); MULADD(at[5], at[79]); MULADD(at[6], at[78]); MULADD(at[7], at[77]); MULADD(at[8], at[76]); MULADD(at[9], at[75]); MULADD(at[10], at[74]); MULADD(at[11], at[73]); MULADD(at[12], at[72]); MULADD(at[13], at[71]); MULADD(at[14], at[70]); MULADD(at[15], at[69]); MULADD(at[16], at[68]); MULADD(at[17], at[67]); MULADD(at[18], at[66]); MULADD(at[19], at[65]); MULADD(at[20], at[64]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[0], at[85]); MULADD(at[1], at[84]); MULADD(at[2], at[83]); MULADD(at[3], at[82]); MULADD(at[4], at[81]); MULADD(at[5], at[80]); MULADD(at[6], at[79]); MULADD(at[7], at[78]); MULADD(at[8], at[77]); MULADD(at[9], at[76]); MULADD(at[10], at[75]); MULADD(at[11], at[74]); MULADD(at[12], at[73]); MULADD(at[13], at[72]); MULADD(at[14], at[71]); MULADD(at[15], at[70]); MULADD(at[16], at[69]); MULADD(at[17], at[68]); MULADD(at[18], at[67]); MULADD(at[19], at[66]); MULADD(at[20], at[65]); MULADD(at[21], at[64]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[0], at[86]); MULADD(at[1], at[85]); MULADD(at[2], at[84]); MULADD(at[3], at[83]); MULADD(at[4], at[82]); MULADD(at[5], at[81]); MULADD(at[6], at[80]); MULADD(at[7], at[79]); MULADD(at[8], at[78]); MULADD(at[9], at[77]); MULADD(at[10], at[76]); MULADD(at[11], at[75]); MULADD(at[12], at[74]); MULADD(at[13], at[73]); MULADD(at[14], at[72]); MULADD(at[15], at[71]); MULADD(at[16], at[70]); MULADD(at[17], at[69]); MULADD(at[18], at[68]); MULADD(at[19], at[67]); MULADD(at[20], at[66]); MULADD(at[21], at[65]); MULADD(at[22], at[64]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[0], at[87]); MULADD(at[1], at[86]); MULADD(at[2], at[85]); MULADD(at[3], at[84]); MULADD(at[4], at[83]); MULADD(at[5], at[82]); MULADD(at[6], at[81]); MULADD(at[7], at[80]); MULADD(at[8], at[79]); MULADD(at[9], at[78]); MULADD(at[10], at[77]); MULADD(at[11], at[76]); MULADD(at[12], at[75]); MULADD(at[13], at[74]); MULADD(at[14], at[73]); MULADD(at[15], at[72]); MULADD(at[16], at[71]); MULADD(at[17], at[70]); MULADD(at[18], at[69]); MULADD(at[19], at[68]); MULADD(at[20], at[67]); MULADD(at[21], at[66]); MULADD(at[22], at[65]); MULADD(at[23], at[64]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[0], at[88]); MULADD(at[1], at[87]); MULADD(at[2], at[86]); MULADD(at[3], at[85]); MULADD(at[4], at[84]); MULADD(at[5], at[83]); MULADD(at[6], at[82]); MULADD(at[7], at[81]); MULADD(at[8], at[80]); MULADD(at[9], at[79]); MULADD(at[10], at[78]); MULADD(at[11], at[77]); MULADD(at[12], at[76]); MULADD(at[13], at[75]); MULADD(at[14], at[74]); MULADD(at[15], at[73]); MULADD(at[16], at[72]); MULADD(at[17], at[71]); MULADD(at[18], at[70]); MULADD(at[19], at[69]); MULADD(at[20], at[68]); MULADD(at[21], at[67]); MULADD(at[22], at[66]); MULADD(at[23], at[65]); MULADD(at[24], at[64]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[0], at[89]); MULADD(at[1], at[88]); MULADD(at[2], at[87]); MULADD(at[3], at[86]); MULADD(at[4], at[85]); MULADD(at[5], at[84]); MULADD(at[6], at[83]); MULADD(at[7], at[82]); MULADD(at[8], at[81]); MULADD(at[9], at[80]); MULADD(at[10], at[79]); MULADD(at[11], at[78]); MULADD(at[12], at[77]); MULADD(at[13], at[76]); MULADD(at[14], at[75]); MULADD(at[15], at[74]); MULADD(at[16], at[73]); MULADD(at[17], at[72]); MULADD(at[18], at[71]); MULADD(at[19], at[70]); MULADD(at[20], at[69]); MULADD(at[21], at[68]); MULADD(at[22], at[67]); MULADD(at[23], at[66]); MULADD(at[24], at[65]); MULADD(at[25], at[64]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[0], at[90]); MULADD(at[1], at[89]); MULADD(at[2], at[88]); MULADD(at[3], at[87]); MULADD(at[4], at[86]); MULADD(at[5], at[85]); MULADD(at[6], at[84]); MULADD(at[7], at[83]); MULADD(at[8], at[82]); MULADD(at[9], at[81]); MULADD(at[10], at[80]); MULADD(at[11], at[79]); MULADD(at[12], at[78]); MULADD(at[13], at[77]); MULADD(at[14], at[76]); MULADD(at[15], at[75]); MULADD(at[16], at[74]); MULADD(at[17], at[73]); MULADD(at[18], at[72]); MULADD(at[19], at[71]); MULADD(at[20], at[70]); MULADD(at[21], at[69]); MULADD(at[22], at[68]); MULADD(at[23], at[67]); MULADD(at[24], at[66]); MULADD(at[25], at[65]); MULADD(at[26], at[64]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[0], at[91]); MULADD(at[1], at[90]); MULADD(at[2], at[89]); MULADD(at[3], at[88]); MULADD(at[4], at[87]); MULADD(at[5], at[86]); MULADD(at[6], at[85]); MULADD(at[7], at[84]); MULADD(at[8], at[83]); MULADD(at[9], at[82]); MULADD(at[10], at[81]); MULADD(at[11], at[80]); MULADD(at[12], at[79]); MULADD(at[13], at[78]); MULADD(at[14], at[77]); MULADD(at[15], at[76]); MULADD(at[16], at[75]); MULADD(at[17], at[74]); MULADD(at[18], at[73]); MULADD(at[19], at[72]); MULADD(at[20], at[71]); MULADD(at[21], at[70]); MULADD(at[22], at[69]); MULADD(at[23], at[68]); MULADD(at[24], at[67]); MULADD(at[25], at[66]); MULADD(at[26], at[65]); MULADD(at[27], at[64]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[0], at[92]); MULADD(at[1], at[91]); MULADD(at[2], at[90]); MULADD(at[3], at[89]); MULADD(at[4], at[88]); MULADD(at[5], at[87]); MULADD(at[6], at[86]); MULADD(at[7], at[85]); MULADD(at[8], at[84]); MULADD(at[9], at[83]); MULADD(at[10], at[82]); MULADD(at[11], at[81]); MULADD(at[12], at[80]); MULADD(at[13], at[79]); MULADD(at[14], at[78]); MULADD(at[15], at[77]); MULADD(at[16], at[76]); MULADD(at[17], at[75]); MULADD(at[18], at[74]); MULADD(at[19], at[73]); MULADD(at[20], at[72]); MULADD(at[21], at[71]); MULADD(at[22], at[70]); MULADD(at[23], at[69]); MULADD(at[24], at[68]); MULADD(at[25], at[67]); MULADD(at[26], at[66]); MULADD(at[27], at[65]); MULADD(at[28], at[64]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[0], at[93]); MULADD(at[1], at[92]); MULADD(at[2], at[91]); MULADD(at[3], at[90]); MULADD(at[4], at[89]); MULADD(at[5], at[88]); MULADD(at[6], at[87]); MULADD(at[7], at[86]); MULADD(at[8], at[85]); MULADD(at[9], at[84]); MULADD(at[10], at[83]); MULADD(at[11], at[82]); MULADD(at[12], at[81]); MULADD(at[13], at[80]); MULADD(at[14], at[79]); MULADD(at[15], at[78]); MULADD(at[16], at[77]); MULADD(at[17], at[76]); MULADD(at[18], at[75]); MULADD(at[19], at[74]); MULADD(at[20], at[73]); MULADD(at[21], at[72]); MULADD(at[22], at[71]); MULADD(at[23], at[70]); MULADD(at[24], at[69]); MULADD(at[25], at[68]); MULADD(at[26], at[67]); MULADD(at[27], at[66]); MULADD(at[28], at[65]); MULADD(at[29], at[64]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[0], at[94]); MULADD(at[1], at[93]); MULADD(at[2], at[92]); MULADD(at[3], at[91]); MULADD(at[4], at[90]); MULADD(at[5], at[89]); MULADD(at[6], at[88]); MULADD(at[7], at[87]); MULADD(at[8], at[86]); MULADD(at[9], at[85]); MULADD(at[10], at[84]); MULADD(at[11], at[83]); MULADD(at[12], at[82]); MULADD(at[13], at[81]); MULADD(at[14], at[80]); MULADD(at[15], at[79]); MULADD(at[16], at[78]); MULADD(at[17], at[77]); MULADD(at[18], at[76]); MULADD(at[19], at[75]); MULADD(at[20], at[74]); MULADD(at[21], at[73]); MULADD(at[22], at[72]); MULADD(at[23], at[71]); MULADD(at[24], at[70]); MULADD(at[25], at[69]); MULADD(at[26], at[68]); MULADD(at[27], at[67]); MULADD(at[28], at[66]); MULADD(at[29], at[65]); MULADD(at[30], at[64]); + COMBA_STORE(C->dp[30]); + /* 31 */ + COMBA_FORWARD; + MULADD(at[0], at[95]); MULADD(at[1], at[94]); MULADD(at[2], at[93]); MULADD(at[3], at[92]); MULADD(at[4], at[91]); MULADD(at[5], at[90]); MULADD(at[6], at[89]); MULADD(at[7], at[88]); MULADD(at[8], at[87]); MULADD(at[9], at[86]); MULADD(at[10], at[85]); MULADD(at[11], at[84]); MULADD(at[12], at[83]); MULADD(at[13], at[82]); MULADD(at[14], at[81]); MULADD(at[15], at[80]); MULADD(at[16], at[79]); MULADD(at[17], at[78]); MULADD(at[18], at[77]); MULADD(at[19], at[76]); MULADD(at[20], at[75]); MULADD(at[21], at[74]); MULADD(at[22], at[73]); MULADD(at[23], at[72]); MULADD(at[24], at[71]); MULADD(at[25], at[70]); MULADD(at[26], at[69]); MULADD(at[27], at[68]); MULADD(at[28], at[67]); MULADD(at[29], at[66]); MULADD(at[30], at[65]); MULADD(at[31], at[64]); + COMBA_STORE(C->dp[31]); + /* 32 */ + COMBA_FORWARD; + MULADD(at[0], at[96]); MULADD(at[1], at[95]); MULADD(at[2], at[94]); MULADD(at[3], at[93]); MULADD(at[4], at[92]); MULADD(at[5], at[91]); MULADD(at[6], at[90]); MULADD(at[7], at[89]); MULADD(at[8], at[88]); MULADD(at[9], at[87]); MULADD(at[10], at[86]); MULADD(at[11], at[85]); MULADD(at[12], at[84]); MULADD(at[13], at[83]); MULADD(at[14], at[82]); MULADD(at[15], at[81]); MULADD(at[16], at[80]); MULADD(at[17], at[79]); MULADD(at[18], at[78]); MULADD(at[19], at[77]); MULADD(at[20], at[76]); MULADD(at[21], at[75]); MULADD(at[22], at[74]); MULADD(at[23], at[73]); MULADD(at[24], at[72]); MULADD(at[25], at[71]); MULADD(at[26], at[70]); MULADD(at[27], at[69]); MULADD(at[28], at[68]); MULADD(at[29], at[67]); MULADD(at[30], at[66]); MULADD(at[31], at[65]); MULADD(at[32], at[64]); + COMBA_STORE(C->dp[32]); + /* 33 */ + COMBA_FORWARD; + MULADD(at[0], at[97]); MULADD(at[1], at[96]); MULADD(at[2], at[95]); MULADD(at[3], at[94]); MULADD(at[4], at[93]); MULADD(at[5], at[92]); MULADD(at[6], at[91]); MULADD(at[7], at[90]); MULADD(at[8], at[89]); MULADD(at[9], at[88]); MULADD(at[10], at[87]); MULADD(at[11], at[86]); MULADD(at[12], at[85]); MULADD(at[13], at[84]); MULADD(at[14], at[83]); MULADD(at[15], at[82]); MULADD(at[16], at[81]); MULADD(at[17], at[80]); MULADD(at[18], at[79]); MULADD(at[19], at[78]); MULADD(at[20], at[77]); MULADD(at[21], at[76]); MULADD(at[22], at[75]); MULADD(at[23], at[74]); MULADD(at[24], at[73]); MULADD(at[25], at[72]); MULADD(at[26], at[71]); MULADD(at[27], at[70]); MULADD(at[28], at[69]); MULADD(at[29], at[68]); MULADD(at[30], at[67]); MULADD(at[31], at[66]); MULADD(at[32], at[65]); MULADD(at[33], at[64]); + COMBA_STORE(C->dp[33]); + /* 34 */ + COMBA_FORWARD; + MULADD(at[0], at[98]); MULADD(at[1], at[97]); MULADD(at[2], at[96]); MULADD(at[3], at[95]); MULADD(at[4], at[94]); MULADD(at[5], at[93]); MULADD(at[6], at[92]); MULADD(at[7], at[91]); MULADD(at[8], at[90]); MULADD(at[9], at[89]); MULADD(at[10], at[88]); MULADD(at[11], at[87]); MULADD(at[12], at[86]); MULADD(at[13], at[85]); MULADD(at[14], at[84]); MULADD(at[15], at[83]); MULADD(at[16], at[82]); MULADD(at[17], at[81]); MULADD(at[18], at[80]); MULADD(at[19], at[79]); MULADD(at[20], at[78]); MULADD(at[21], at[77]); MULADD(at[22], at[76]); MULADD(at[23], at[75]); MULADD(at[24], at[74]); MULADD(at[25], at[73]); MULADD(at[26], at[72]); MULADD(at[27], at[71]); MULADD(at[28], at[70]); MULADD(at[29], at[69]); MULADD(at[30], at[68]); MULADD(at[31], at[67]); MULADD(at[32], at[66]); MULADD(at[33], at[65]); MULADD(at[34], at[64]); + COMBA_STORE(C->dp[34]); + /* 35 */ + COMBA_FORWARD; + MULADD(at[0], at[99]); MULADD(at[1], at[98]); MULADD(at[2], at[97]); MULADD(at[3], at[96]); MULADD(at[4], at[95]); MULADD(at[5], at[94]); MULADD(at[6], at[93]); MULADD(at[7], at[92]); MULADD(at[8], at[91]); MULADD(at[9], at[90]); MULADD(at[10], at[89]); MULADD(at[11], at[88]); MULADD(at[12], at[87]); MULADD(at[13], at[86]); MULADD(at[14], at[85]); MULADD(at[15], at[84]); MULADD(at[16], at[83]); MULADD(at[17], at[82]); MULADD(at[18], at[81]); MULADD(at[19], at[80]); MULADD(at[20], at[79]); MULADD(at[21], at[78]); MULADD(at[22], at[77]); MULADD(at[23], at[76]); MULADD(at[24], at[75]); MULADD(at[25], at[74]); MULADD(at[26], at[73]); MULADD(at[27], at[72]); MULADD(at[28], at[71]); MULADD(at[29], at[70]); MULADD(at[30], at[69]); MULADD(at[31], at[68]); MULADD(at[32], at[67]); MULADD(at[33], at[66]); MULADD(at[34], at[65]); MULADD(at[35], at[64]); + COMBA_STORE(C->dp[35]); + /* 36 */ + COMBA_FORWARD; + MULADD(at[0], at[100]); MULADD(at[1], at[99]); MULADD(at[2], at[98]); MULADD(at[3], at[97]); MULADD(at[4], at[96]); MULADD(at[5], at[95]); MULADD(at[6], at[94]); MULADD(at[7], at[93]); MULADD(at[8], at[92]); MULADD(at[9], at[91]); MULADD(at[10], at[90]); MULADD(at[11], at[89]); MULADD(at[12], at[88]); MULADD(at[13], at[87]); MULADD(at[14], at[86]); MULADD(at[15], at[85]); MULADD(at[16], at[84]); MULADD(at[17], at[83]); MULADD(at[18], at[82]); MULADD(at[19], at[81]); MULADD(at[20], at[80]); MULADD(at[21], at[79]); MULADD(at[22], at[78]); MULADD(at[23], at[77]); MULADD(at[24], at[76]); MULADD(at[25], at[75]); MULADD(at[26], at[74]); MULADD(at[27], at[73]); MULADD(at[28], at[72]); MULADD(at[29], at[71]); MULADD(at[30], at[70]); MULADD(at[31], at[69]); MULADD(at[32], at[68]); MULADD(at[33], at[67]); MULADD(at[34], at[66]); MULADD(at[35], at[65]); MULADD(at[36], at[64]); + COMBA_STORE(C->dp[36]); + /* 37 */ + COMBA_FORWARD; + MULADD(at[0], at[101]); MULADD(at[1], at[100]); MULADD(at[2], at[99]); MULADD(at[3], at[98]); MULADD(at[4], at[97]); MULADD(at[5], at[96]); MULADD(at[6], at[95]); MULADD(at[7], at[94]); MULADD(at[8], at[93]); MULADD(at[9], at[92]); MULADD(at[10], at[91]); MULADD(at[11], at[90]); MULADD(at[12], at[89]); MULADD(at[13], at[88]); MULADD(at[14], at[87]); MULADD(at[15], at[86]); MULADD(at[16], at[85]); MULADD(at[17], at[84]); MULADD(at[18], at[83]); MULADD(at[19], at[82]); MULADD(at[20], at[81]); MULADD(at[21], at[80]); MULADD(at[22], at[79]); MULADD(at[23], at[78]); MULADD(at[24], at[77]); MULADD(at[25], at[76]); MULADD(at[26], at[75]); MULADD(at[27], at[74]); MULADD(at[28], at[73]); MULADD(at[29], at[72]); MULADD(at[30], at[71]); MULADD(at[31], at[70]); MULADD(at[32], at[69]); MULADD(at[33], at[68]); MULADD(at[34], at[67]); MULADD(at[35], at[66]); MULADD(at[36], at[65]); MULADD(at[37], at[64]); + COMBA_STORE(C->dp[37]); + /* 38 */ + COMBA_FORWARD; + MULADD(at[0], at[102]); MULADD(at[1], at[101]); MULADD(at[2], at[100]); MULADD(at[3], at[99]); MULADD(at[4], at[98]); MULADD(at[5], at[97]); MULADD(at[6], at[96]); MULADD(at[7], at[95]); MULADD(at[8], at[94]); MULADD(at[9], at[93]); MULADD(at[10], at[92]); MULADD(at[11], at[91]); MULADD(at[12], at[90]); MULADD(at[13], at[89]); MULADD(at[14], at[88]); MULADD(at[15], at[87]); MULADD(at[16], at[86]); MULADD(at[17], at[85]); MULADD(at[18], at[84]); MULADD(at[19], at[83]); MULADD(at[20], at[82]); MULADD(at[21], at[81]); MULADD(at[22], at[80]); MULADD(at[23], at[79]); MULADD(at[24], at[78]); MULADD(at[25], at[77]); MULADD(at[26], at[76]); MULADD(at[27], at[75]); MULADD(at[28], at[74]); MULADD(at[29], at[73]); MULADD(at[30], at[72]); MULADD(at[31], at[71]); MULADD(at[32], at[70]); MULADD(at[33], at[69]); MULADD(at[34], at[68]); MULADD(at[35], at[67]); MULADD(at[36], at[66]); MULADD(at[37], at[65]); MULADD(at[38], at[64]); + COMBA_STORE(C->dp[38]); + /* 39 */ + COMBA_FORWARD; + MULADD(at[0], at[103]); MULADD(at[1], at[102]); MULADD(at[2], at[101]); MULADD(at[3], at[100]); MULADD(at[4], at[99]); MULADD(at[5], at[98]); MULADD(at[6], at[97]); MULADD(at[7], at[96]); MULADD(at[8], at[95]); MULADD(at[9], at[94]); MULADD(at[10], at[93]); MULADD(at[11], at[92]); MULADD(at[12], at[91]); MULADD(at[13], at[90]); MULADD(at[14], at[89]); MULADD(at[15], at[88]); MULADD(at[16], at[87]); MULADD(at[17], at[86]); MULADD(at[18], at[85]); MULADD(at[19], at[84]); MULADD(at[20], at[83]); MULADD(at[21], at[82]); MULADD(at[22], at[81]); MULADD(at[23], at[80]); MULADD(at[24], at[79]); MULADD(at[25], at[78]); MULADD(at[26], at[77]); MULADD(at[27], at[76]); MULADD(at[28], at[75]); MULADD(at[29], at[74]); MULADD(at[30], at[73]); MULADD(at[31], at[72]); MULADD(at[32], at[71]); MULADD(at[33], at[70]); MULADD(at[34], at[69]); MULADD(at[35], at[68]); MULADD(at[36], at[67]); MULADD(at[37], at[66]); MULADD(at[38], at[65]); MULADD(at[39], at[64]); + COMBA_STORE(C->dp[39]); + /* 40 */ + COMBA_FORWARD; + MULADD(at[0], at[104]); MULADD(at[1], at[103]); MULADD(at[2], at[102]); MULADD(at[3], at[101]); MULADD(at[4], at[100]); MULADD(at[5], at[99]); MULADD(at[6], at[98]); MULADD(at[7], at[97]); MULADD(at[8], at[96]); MULADD(at[9], at[95]); MULADD(at[10], at[94]); MULADD(at[11], at[93]); MULADD(at[12], at[92]); MULADD(at[13], at[91]); MULADD(at[14], at[90]); MULADD(at[15], at[89]); MULADD(at[16], at[88]); MULADD(at[17], at[87]); MULADD(at[18], at[86]); MULADD(at[19], at[85]); MULADD(at[20], at[84]); MULADD(at[21], at[83]); MULADD(at[22], at[82]); MULADD(at[23], at[81]); MULADD(at[24], at[80]); MULADD(at[25], at[79]); MULADD(at[26], at[78]); MULADD(at[27], at[77]); MULADD(at[28], at[76]); MULADD(at[29], at[75]); MULADD(at[30], at[74]); MULADD(at[31], at[73]); MULADD(at[32], at[72]); MULADD(at[33], at[71]); MULADD(at[34], at[70]); MULADD(at[35], at[69]); MULADD(at[36], at[68]); MULADD(at[37], at[67]); MULADD(at[38], at[66]); MULADD(at[39], at[65]); MULADD(at[40], at[64]); + COMBA_STORE(C->dp[40]); + /* 41 */ + COMBA_FORWARD; + MULADD(at[0], at[105]); MULADD(at[1], at[104]); MULADD(at[2], at[103]); MULADD(at[3], at[102]); MULADD(at[4], at[101]); MULADD(at[5], at[100]); MULADD(at[6], at[99]); MULADD(at[7], at[98]); MULADD(at[8], at[97]); MULADD(at[9], at[96]); MULADD(at[10], at[95]); MULADD(at[11], at[94]); MULADD(at[12], at[93]); MULADD(at[13], at[92]); MULADD(at[14], at[91]); MULADD(at[15], at[90]); MULADD(at[16], at[89]); MULADD(at[17], at[88]); MULADD(at[18], at[87]); MULADD(at[19], at[86]); MULADD(at[20], at[85]); MULADD(at[21], at[84]); MULADD(at[22], at[83]); MULADD(at[23], at[82]); MULADD(at[24], at[81]); MULADD(at[25], at[80]); MULADD(at[26], at[79]); MULADD(at[27], at[78]); MULADD(at[28], at[77]); MULADD(at[29], at[76]); MULADD(at[30], at[75]); MULADD(at[31], at[74]); MULADD(at[32], at[73]); MULADD(at[33], at[72]); MULADD(at[34], at[71]); MULADD(at[35], at[70]); MULADD(at[36], at[69]); MULADD(at[37], at[68]); MULADD(at[38], at[67]); MULADD(at[39], at[66]); MULADD(at[40], at[65]); MULADD(at[41], at[64]); + COMBA_STORE(C->dp[41]); + /* 42 */ + COMBA_FORWARD; + MULADD(at[0], at[106]); MULADD(at[1], at[105]); MULADD(at[2], at[104]); MULADD(at[3], at[103]); MULADD(at[4], at[102]); MULADD(at[5], at[101]); MULADD(at[6], at[100]); MULADD(at[7], at[99]); MULADD(at[8], at[98]); MULADD(at[9], at[97]); MULADD(at[10], at[96]); MULADD(at[11], at[95]); MULADD(at[12], at[94]); MULADD(at[13], at[93]); MULADD(at[14], at[92]); MULADD(at[15], at[91]); MULADD(at[16], at[90]); MULADD(at[17], at[89]); MULADD(at[18], at[88]); MULADD(at[19], at[87]); MULADD(at[20], at[86]); MULADD(at[21], at[85]); MULADD(at[22], at[84]); MULADD(at[23], at[83]); MULADD(at[24], at[82]); MULADD(at[25], at[81]); MULADD(at[26], at[80]); MULADD(at[27], at[79]); MULADD(at[28], at[78]); MULADD(at[29], at[77]); MULADD(at[30], at[76]); MULADD(at[31], at[75]); MULADD(at[32], at[74]); MULADD(at[33], at[73]); MULADD(at[34], at[72]); MULADD(at[35], at[71]); MULADD(at[36], at[70]); MULADD(at[37], at[69]); MULADD(at[38], at[68]); MULADD(at[39], at[67]); MULADD(at[40], at[66]); MULADD(at[41], at[65]); MULADD(at[42], at[64]); + COMBA_STORE(C->dp[42]); + /* 43 */ + COMBA_FORWARD; + MULADD(at[0], at[107]); MULADD(at[1], at[106]); MULADD(at[2], at[105]); MULADD(at[3], at[104]); MULADD(at[4], at[103]); MULADD(at[5], at[102]); MULADD(at[6], at[101]); MULADD(at[7], at[100]); MULADD(at[8], at[99]); MULADD(at[9], at[98]); MULADD(at[10], at[97]); MULADD(at[11], at[96]); MULADD(at[12], at[95]); MULADD(at[13], at[94]); MULADD(at[14], at[93]); MULADD(at[15], at[92]); MULADD(at[16], at[91]); MULADD(at[17], at[90]); MULADD(at[18], at[89]); MULADD(at[19], at[88]); MULADD(at[20], at[87]); MULADD(at[21], at[86]); MULADD(at[22], at[85]); MULADD(at[23], at[84]); MULADD(at[24], at[83]); MULADD(at[25], at[82]); MULADD(at[26], at[81]); MULADD(at[27], at[80]); MULADD(at[28], at[79]); MULADD(at[29], at[78]); MULADD(at[30], at[77]); MULADD(at[31], at[76]); MULADD(at[32], at[75]); MULADD(at[33], at[74]); MULADD(at[34], at[73]); MULADD(at[35], at[72]); MULADD(at[36], at[71]); MULADD(at[37], at[70]); MULADD(at[38], at[69]); MULADD(at[39], at[68]); MULADD(at[40], at[67]); MULADD(at[41], at[66]); MULADD(at[42], at[65]); MULADD(at[43], at[64]); + COMBA_STORE(C->dp[43]); + /* 44 */ + COMBA_FORWARD; + MULADD(at[0], at[108]); MULADD(at[1], at[107]); MULADD(at[2], at[106]); MULADD(at[3], at[105]); MULADD(at[4], at[104]); MULADD(at[5], at[103]); MULADD(at[6], at[102]); MULADD(at[7], at[101]); MULADD(at[8], at[100]); MULADD(at[9], at[99]); MULADD(at[10], at[98]); MULADD(at[11], at[97]); MULADD(at[12], at[96]); MULADD(at[13], at[95]); MULADD(at[14], at[94]); MULADD(at[15], at[93]); MULADD(at[16], at[92]); MULADD(at[17], at[91]); MULADD(at[18], at[90]); MULADD(at[19], at[89]); MULADD(at[20], at[88]); MULADD(at[21], at[87]); MULADD(at[22], at[86]); MULADD(at[23], at[85]); MULADD(at[24], at[84]); MULADD(at[25], at[83]); MULADD(at[26], at[82]); MULADD(at[27], at[81]); MULADD(at[28], at[80]); MULADD(at[29], at[79]); MULADD(at[30], at[78]); MULADD(at[31], at[77]); MULADD(at[32], at[76]); MULADD(at[33], at[75]); MULADD(at[34], at[74]); MULADD(at[35], at[73]); MULADD(at[36], at[72]); MULADD(at[37], at[71]); MULADD(at[38], at[70]); MULADD(at[39], at[69]); MULADD(at[40], at[68]); MULADD(at[41], at[67]); MULADD(at[42], at[66]); MULADD(at[43], at[65]); MULADD(at[44], at[64]); + COMBA_STORE(C->dp[44]); + /* 45 */ + COMBA_FORWARD; + MULADD(at[0], at[109]); MULADD(at[1], at[108]); MULADD(at[2], at[107]); MULADD(at[3], at[106]); MULADD(at[4], at[105]); MULADD(at[5], at[104]); MULADD(at[6], at[103]); MULADD(at[7], at[102]); MULADD(at[8], at[101]); MULADD(at[9], at[100]); MULADD(at[10], at[99]); MULADD(at[11], at[98]); MULADD(at[12], at[97]); MULADD(at[13], at[96]); MULADD(at[14], at[95]); MULADD(at[15], at[94]); MULADD(at[16], at[93]); MULADD(at[17], at[92]); MULADD(at[18], at[91]); MULADD(at[19], at[90]); MULADD(at[20], at[89]); MULADD(at[21], at[88]); MULADD(at[22], at[87]); MULADD(at[23], at[86]); MULADD(at[24], at[85]); MULADD(at[25], at[84]); MULADD(at[26], at[83]); MULADD(at[27], at[82]); MULADD(at[28], at[81]); MULADD(at[29], at[80]); MULADD(at[30], at[79]); MULADD(at[31], at[78]); MULADD(at[32], at[77]); MULADD(at[33], at[76]); MULADD(at[34], at[75]); MULADD(at[35], at[74]); MULADD(at[36], at[73]); MULADD(at[37], at[72]); MULADD(at[38], at[71]); MULADD(at[39], at[70]); MULADD(at[40], at[69]); MULADD(at[41], at[68]); MULADD(at[42], at[67]); MULADD(at[43], at[66]); MULADD(at[44], at[65]); MULADD(at[45], at[64]); + COMBA_STORE(C->dp[45]); + /* 46 */ + COMBA_FORWARD; + MULADD(at[0], at[110]); MULADD(at[1], at[109]); MULADD(at[2], at[108]); MULADD(at[3], at[107]); MULADD(at[4], at[106]); MULADD(at[5], at[105]); MULADD(at[6], at[104]); MULADD(at[7], at[103]); MULADD(at[8], at[102]); MULADD(at[9], at[101]); MULADD(at[10], at[100]); MULADD(at[11], at[99]); MULADD(at[12], at[98]); MULADD(at[13], at[97]); MULADD(at[14], at[96]); MULADD(at[15], at[95]); MULADD(at[16], at[94]); MULADD(at[17], at[93]); MULADD(at[18], at[92]); MULADD(at[19], at[91]); MULADD(at[20], at[90]); MULADD(at[21], at[89]); MULADD(at[22], at[88]); MULADD(at[23], at[87]); MULADD(at[24], at[86]); MULADD(at[25], at[85]); MULADD(at[26], at[84]); MULADD(at[27], at[83]); MULADD(at[28], at[82]); MULADD(at[29], at[81]); MULADD(at[30], at[80]); MULADD(at[31], at[79]); MULADD(at[32], at[78]); MULADD(at[33], at[77]); MULADD(at[34], at[76]); MULADD(at[35], at[75]); MULADD(at[36], at[74]); MULADD(at[37], at[73]); MULADD(at[38], at[72]); MULADD(at[39], at[71]); MULADD(at[40], at[70]); MULADD(at[41], at[69]); MULADD(at[42], at[68]); MULADD(at[43], at[67]); MULADD(at[44], at[66]); MULADD(at[45], at[65]); MULADD(at[46], at[64]); + COMBA_STORE(C->dp[46]); + /* 47 */ + COMBA_FORWARD; + MULADD(at[0], at[111]); MULADD(at[1], at[110]); MULADD(at[2], at[109]); MULADD(at[3], at[108]); MULADD(at[4], at[107]); MULADD(at[5], at[106]); MULADD(at[6], at[105]); MULADD(at[7], at[104]); MULADD(at[8], at[103]); MULADD(at[9], at[102]); MULADD(at[10], at[101]); MULADD(at[11], at[100]); MULADD(at[12], at[99]); MULADD(at[13], at[98]); MULADD(at[14], at[97]); MULADD(at[15], at[96]); MULADD(at[16], at[95]); MULADD(at[17], at[94]); MULADD(at[18], at[93]); MULADD(at[19], at[92]); MULADD(at[20], at[91]); MULADD(at[21], at[90]); MULADD(at[22], at[89]); MULADD(at[23], at[88]); MULADD(at[24], at[87]); MULADD(at[25], at[86]); MULADD(at[26], at[85]); MULADD(at[27], at[84]); MULADD(at[28], at[83]); MULADD(at[29], at[82]); MULADD(at[30], at[81]); MULADD(at[31], at[80]); MULADD(at[32], at[79]); MULADD(at[33], at[78]); MULADD(at[34], at[77]); MULADD(at[35], at[76]); MULADD(at[36], at[75]); MULADD(at[37], at[74]); MULADD(at[38], at[73]); MULADD(at[39], at[72]); MULADD(at[40], at[71]); MULADD(at[41], at[70]); MULADD(at[42], at[69]); MULADD(at[43], at[68]); MULADD(at[44], at[67]); MULADD(at[45], at[66]); MULADD(at[46], at[65]); MULADD(at[47], at[64]); + COMBA_STORE(C->dp[47]); + /* 48 */ + COMBA_FORWARD; + MULADD(at[0], at[112]); MULADD(at[1], at[111]); MULADD(at[2], at[110]); MULADD(at[3], at[109]); MULADD(at[4], at[108]); MULADD(at[5], at[107]); MULADD(at[6], at[106]); MULADD(at[7], at[105]); MULADD(at[8], at[104]); MULADD(at[9], at[103]); MULADD(at[10], at[102]); MULADD(at[11], at[101]); MULADD(at[12], at[100]); MULADD(at[13], at[99]); MULADD(at[14], at[98]); MULADD(at[15], at[97]); MULADD(at[16], at[96]); MULADD(at[17], at[95]); MULADD(at[18], at[94]); MULADD(at[19], at[93]); MULADD(at[20], at[92]); MULADD(at[21], at[91]); MULADD(at[22], at[90]); MULADD(at[23], at[89]); MULADD(at[24], at[88]); MULADD(at[25], at[87]); MULADD(at[26], at[86]); MULADD(at[27], at[85]); MULADD(at[28], at[84]); MULADD(at[29], at[83]); MULADD(at[30], at[82]); MULADD(at[31], at[81]); MULADD(at[32], at[80]); MULADD(at[33], at[79]); MULADD(at[34], at[78]); MULADD(at[35], at[77]); MULADD(at[36], at[76]); MULADD(at[37], at[75]); MULADD(at[38], at[74]); MULADD(at[39], at[73]); MULADD(at[40], at[72]); MULADD(at[41], at[71]); MULADD(at[42], at[70]); MULADD(at[43], at[69]); MULADD(at[44], at[68]); MULADD(at[45], at[67]); MULADD(at[46], at[66]); MULADD(at[47], at[65]); MULADD(at[48], at[64]); + COMBA_STORE(C->dp[48]); + /* 49 */ + COMBA_FORWARD; + MULADD(at[0], at[113]); MULADD(at[1], at[112]); MULADD(at[2], at[111]); MULADD(at[3], at[110]); MULADD(at[4], at[109]); MULADD(at[5], at[108]); MULADD(at[6], at[107]); MULADD(at[7], at[106]); MULADD(at[8], at[105]); MULADD(at[9], at[104]); MULADD(at[10], at[103]); MULADD(at[11], at[102]); MULADD(at[12], at[101]); MULADD(at[13], at[100]); MULADD(at[14], at[99]); MULADD(at[15], at[98]); MULADD(at[16], at[97]); MULADD(at[17], at[96]); MULADD(at[18], at[95]); MULADD(at[19], at[94]); MULADD(at[20], at[93]); MULADD(at[21], at[92]); MULADD(at[22], at[91]); MULADD(at[23], at[90]); MULADD(at[24], at[89]); MULADD(at[25], at[88]); MULADD(at[26], at[87]); MULADD(at[27], at[86]); MULADD(at[28], at[85]); MULADD(at[29], at[84]); MULADD(at[30], at[83]); MULADD(at[31], at[82]); MULADD(at[32], at[81]); MULADD(at[33], at[80]); MULADD(at[34], at[79]); MULADD(at[35], at[78]); MULADD(at[36], at[77]); MULADD(at[37], at[76]); MULADD(at[38], at[75]); MULADD(at[39], at[74]); MULADD(at[40], at[73]); MULADD(at[41], at[72]); MULADD(at[42], at[71]); MULADD(at[43], at[70]); MULADD(at[44], at[69]); MULADD(at[45], at[68]); MULADD(at[46], at[67]); MULADD(at[47], at[66]); MULADD(at[48], at[65]); MULADD(at[49], at[64]); + COMBA_STORE(C->dp[49]); + /* 50 */ + COMBA_FORWARD; + MULADD(at[0], at[114]); MULADD(at[1], at[113]); MULADD(at[2], at[112]); MULADD(at[3], at[111]); MULADD(at[4], at[110]); MULADD(at[5], at[109]); MULADD(at[6], at[108]); MULADD(at[7], at[107]); MULADD(at[8], at[106]); MULADD(at[9], at[105]); MULADD(at[10], at[104]); MULADD(at[11], at[103]); MULADD(at[12], at[102]); MULADD(at[13], at[101]); MULADD(at[14], at[100]); MULADD(at[15], at[99]); MULADD(at[16], at[98]); MULADD(at[17], at[97]); MULADD(at[18], at[96]); MULADD(at[19], at[95]); MULADD(at[20], at[94]); MULADD(at[21], at[93]); MULADD(at[22], at[92]); MULADD(at[23], at[91]); MULADD(at[24], at[90]); MULADD(at[25], at[89]); MULADD(at[26], at[88]); MULADD(at[27], at[87]); MULADD(at[28], at[86]); MULADD(at[29], at[85]); MULADD(at[30], at[84]); MULADD(at[31], at[83]); MULADD(at[32], at[82]); MULADD(at[33], at[81]); MULADD(at[34], at[80]); MULADD(at[35], at[79]); MULADD(at[36], at[78]); MULADD(at[37], at[77]); MULADD(at[38], at[76]); MULADD(at[39], at[75]); MULADD(at[40], at[74]); MULADD(at[41], at[73]); MULADD(at[42], at[72]); MULADD(at[43], at[71]); MULADD(at[44], at[70]); MULADD(at[45], at[69]); MULADD(at[46], at[68]); MULADD(at[47], at[67]); MULADD(at[48], at[66]); MULADD(at[49], at[65]); MULADD(at[50], at[64]); + COMBA_STORE(C->dp[50]); + /* 51 */ + COMBA_FORWARD; + MULADD(at[0], at[115]); MULADD(at[1], at[114]); MULADD(at[2], at[113]); MULADD(at[3], at[112]); MULADD(at[4], at[111]); MULADD(at[5], at[110]); MULADD(at[6], at[109]); MULADD(at[7], at[108]); MULADD(at[8], at[107]); MULADD(at[9], at[106]); MULADD(at[10], at[105]); MULADD(at[11], at[104]); MULADD(at[12], at[103]); MULADD(at[13], at[102]); MULADD(at[14], at[101]); MULADD(at[15], at[100]); MULADD(at[16], at[99]); MULADD(at[17], at[98]); MULADD(at[18], at[97]); MULADD(at[19], at[96]); MULADD(at[20], at[95]); MULADD(at[21], at[94]); MULADD(at[22], at[93]); MULADD(at[23], at[92]); MULADD(at[24], at[91]); MULADD(at[25], at[90]); MULADD(at[26], at[89]); MULADD(at[27], at[88]); MULADD(at[28], at[87]); MULADD(at[29], at[86]); MULADD(at[30], at[85]); MULADD(at[31], at[84]); MULADD(at[32], at[83]); MULADD(at[33], at[82]); MULADD(at[34], at[81]); MULADD(at[35], at[80]); MULADD(at[36], at[79]); MULADD(at[37], at[78]); MULADD(at[38], at[77]); MULADD(at[39], at[76]); MULADD(at[40], at[75]); MULADD(at[41], at[74]); MULADD(at[42], at[73]); MULADD(at[43], at[72]); MULADD(at[44], at[71]); MULADD(at[45], at[70]); MULADD(at[46], at[69]); MULADD(at[47], at[68]); MULADD(at[48], at[67]); MULADD(at[49], at[66]); MULADD(at[50], at[65]); MULADD(at[51], at[64]); + COMBA_STORE(C->dp[51]); + /* 52 */ + COMBA_FORWARD; + MULADD(at[0], at[116]); MULADD(at[1], at[115]); MULADD(at[2], at[114]); MULADD(at[3], at[113]); MULADD(at[4], at[112]); MULADD(at[5], at[111]); MULADD(at[6], at[110]); MULADD(at[7], at[109]); MULADD(at[8], at[108]); MULADD(at[9], at[107]); MULADD(at[10], at[106]); MULADD(at[11], at[105]); MULADD(at[12], at[104]); MULADD(at[13], at[103]); MULADD(at[14], at[102]); MULADD(at[15], at[101]); MULADD(at[16], at[100]); MULADD(at[17], at[99]); MULADD(at[18], at[98]); MULADD(at[19], at[97]); MULADD(at[20], at[96]); MULADD(at[21], at[95]); MULADD(at[22], at[94]); MULADD(at[23], at[93]); MULADD(at[24], at[92]); MULADD(at[25], at[91]); MULADD(at[26], at[90]); MULADD(at[27], at[89]); MULADD(at[28], at[88]); MULADD(at[29], at[87]); MULADD(at[30], at[86]); MULADD(at[31], at[85]); MULADD(at[32], at[84]); MULADD(at[33], at[83]); MULADD(at[34], at[82]); MULADD(at[35], at[81]); MULADD(at[36], at[80]); MULADD(at[37], at[79]); MULADD(at[38], at[78]); MULADD(at[39], at[77]); MULADD(at[40], at[76]); MULADD(at[41], at[75]); MULADD(at[42], at[74]); MULADD(at[43], at[73]); MULADD(at[44], at[72]); MULADD(at[45], at[71]); MULADD(at[46], at[70]); MULADD(at[47], at[69]); MULADD(at[48], at[68]); MULADD(at[49], at[67]); MULADD(at[50], at[66]); MULADD(at[51], at[65]); MULADD(at[52], at[64]); + COMBA_STORE(C->dp[52]); + /* 53 */ + COMBA_FORWARD; + MULADD(at[0], at[117]); MULADD(at[1], at[116]); MULADD(at[2], at[115]); MULADD(at[3], at[114]); MULADD(at[4], at[113]); MULADD(at[5], at[112]); MULADD(at[6], at[111]); MULADD(at[7], at[110]); MULADD(at[8], at[109]); MULADD(at[9], at[108]); MULADD(at[10], at[107]); MULADD(at[11], at[106]); MULADD(at[12], at[105]); MULADD(at[13], at[104]); MULADD(at[14], at[103]); MULADD(at[15], at[102]); MULADD(at[16], at[101]); MULADD(at[17], at[100]); MULADD(at[18], at[99]); MULADD(at[19], at[98]); MULADD(at[20], at[97]); MULADD(at[21], at[96]); MULADD(at[22], at[95]); MULADD(at[23], at[94]); MULADD(at[24], at[93]); MULADD(at[25], at[92]); MULADD(at[26], at[91]); MULADD(at[27], at[90]); MULADD(at[28], at[89]); MULADD(at[29], at[88]); MULADD(at[30], at[87]); MULADD(at[31], at[86]); MULADD(at[32], at[85]); MULADD(at[33], at[84]); MULADD(at[34], at[83]); MULADD(at[35], at[82]); MULADD(at[36], at[81]); MULADD(at[37], at[80]); MULADD(at[38], at[79]); MULADD(at[39], at[78]); MULADD(at[40], at[77]); MULADD(at[41], at[76]); MULADD(at[42], at[75]); MULADD(at[43], at[74]); MULADD(at[44], at[73]); MULADD(at[45], at[72]); MULADD(at[46], at[71]); MULADD(at[47], at[70]); MULADD(at[48], at[69]); MULADD(at[49], at[68]); MULADD(at[50], at[67]); MULADD(at[51], at[66]); MULADD(at[52], at[65]); MULADD(at[53], at[64]); + COMBA_STORE(C->dp[53]); + /* 54 */ + COMBA_FORWARD; + MULADD(at[0], at[118]); MULADD(at[1], at[117]); MULADD(at[2], at[116]); MULADD(at[3], at[115]); MULADD(at[4], at[114]); MULADD(at[5], at[113]); MULADD(at[6], at[112]); MULADD(at[7], at[111]); MULADD(at[8], at[110]); MULADD(at[9], at[109]); MULADD(at[10], at[108]); MULADD(at[11], at[107]); MULADD(at[12], at[106]); MULADD(at[13], at[105]); MULADD(at[14], at[104]); MULADD(at[15], at[103]); MULADD(at[16], at[102]); MULADD(at[17], at[101]); MULADD(at[18], at[100]); MULADD(at[19], at[99]); MULADD(at[20], at[98]); MULADD(at[21], at[97]); MULADD(at[22], at[96]); MULADD(at[23], at[95]); MULADD(at[24], at[94]); MULADD(at[25], at[93]); MULADD(at[26], at[92]); MULADD(at[27], at[91]); MULADD(at[28], at[90]); MULADD(at[29], at[89]); MULADD(at[30], at[88]); MULADD(at[31], at[87]); MULADD(at[32], at[86]); MULADD(at[33], at[85]); MULADD(at[34], at[84]); MULADD(at[35], at[83]); MULADD(at[36], at[82]); MULADD(at[37], at[81]); MULADD(at[38], at[80]); MULADD(at[39], at[79]); MULADD(at[40], at[78]); MULADD(at[41], at[77]); MULADD(at[42], at[76]); MULADD(at[43], at[75]); MULADD(at[44], at[74]); MULADD(at[45], at[73]); MULADD(at[46], at[72]); MULADD(at[47], at[71]); MULADD(at[48], at[70]); MULADD(at[49], at[69]); MULADD(at[50], at[68]); MULADD(at[51], at[67]); MULADD(at[52], at[66]); MULADD(at[53], at[65]); MULADD(at[54], at[64]); + COMBA_STORE(C->dp[54]); + /* 55 */ + COMBA_FORWARD; + MULADD(at[0], at[119]); MULADD(at[1], at[118]); MULADD(at[2], at[117]); MULADD(at[3], at[116]); MULADD(at[4], at[115]); MULADD(at[5], at[114]); MULADD(at[6], at[113]); MULADD(at[7], at[112]); MULADD(at[8], at[111]); MULADD(at[9], at[110]); MULADD(at[10], at[109]); MULADD(at[11], at[108]); MULADD(at[12], at[107]); MULADD(at[13], at[106]); MULADD(at[14], at[105]); MULADD(at[15], at[104]); MULADD(at[16], at[103]); MULADD(at[17], at[102]); MULADD(at[18], at[101]); MULADD(at[19], at[100]); MULADD(at[20], at[99]); MULADD(at[21], at[98]); MULADD(at[22], at[97]); MULADD(at[23], at[96]); MULADD(at[24], at[95]); MULADD(at[25], at[94]); MULADD(at[26], at[93]); MULADD(at[27], at[92]); MULADD(at[28], at[91]); MULADD(at[29], at[90]); MULADD(at[30], at[89]); MULADD(at[31], at[88]); MULADD(at[32], at[87]); MULADD(at[33], at[86]); MULADD(at[34], at[85]); MULADD(at[35], at[84]); MULADD(at[36], at[83]); MULADD(at[37], at[82]); MULADD(at[38], at[81]); MULADD(at[39], at[80]); MULADD(at[40], at[79]); MULADD(at[41], at[78]); MULADD(at[42], at[77]); MULADD(at[43], at[76]); MULADD(at[44], at[75]); MULADD(at[45], at[74]); MULADD(at[46], at[73]); MULADD(at[47], at[72]); MULADD(at[48], at[71]); MULADD(at[49], at[70]); MULADD(at[50], at[69]); MULADD(at[51], at[68]); MULADD(at[52], at[67]); MULADD(at[53], at[66]); MULADD(at[54], at[65]); MULADD(at[55], at[64]); + COMBA_STORE(C->dp[55]); + /* 56 */ + COMBA_FORWARD; + MULADD(at[0], at[120]); MULADD(at[1], at[119]); MULADD(at[2], at[118]); MULADD(at[3], at[117]); MULADD(at[4], at[116]); MULADD(at[5], at[115]); MULADD(at[6], at[114]); MULADD(at[7], at[113]); MULADD(at[8], at[112]); MULADD(at[9], at[111]); MULADD(at[10], at[110]); MULADD(at[11], at[109]); MULADD(at[12], at[108]); MULADD(at[13], at[107]); MULADD(at[14], at[106]); MULADD(at[15], at[105]); MULADD(at[16], at[104]); MULADD(at[17], at[103]); MULADD(at[18], at[102]); MULADD(at[19], at[101]); MULADD(at[20], at[100]); MULADD(at[21], at[99]); MULADD(at[22], at[98]); MULADD(at[23], at[97]); MULADD(at[24], at[96]); MULADD(at[25], at[95]); MULADD(at[26], at[94]); MULADD(at[27], at[93]); MULADD(at[28], at[92]); MULADD(at[29], at[91]); MULADD(at[30], at[90]); MULADD(at[31], at[89]); MULADD(at[32], at[88]); MULADD(at[33], at[87]); MULADD(at[34], at[86]); MULADD(at[35], at[85]); MULADD(at[36], at[84]); MULADD(at[37], at[83]); MULADD(at[38], at[82]); MULADD(at[39], at[81]); MULADD(at[40], at[80]); MULADD(at[41], at[79]); MULADD(at[42], at[78]); MULADD(at[43], at[77]); MULADD(at[44], at[76]); MULADD(at[45], at[75]); MULADD(at[46], at[74]); MULADD(at[47], at[73]); MULADD(at[48], at[72]); MULADD(at[49], at[71]); MULADD(at[50], at[70]); MULADD(at[51], at[69]); MULADD(at[52], at[68]); MULADD(at[53], at[67]); MULADD(at[54], at[66]); MULADD(at[55], at[65]); MULADD(at[56], at[64]); + COMBA_STORE(C->dp[56]); + /* 57 */ + COMBA_FORWARD; + MULADD(at[0], at[121]); MULADD(at[1], at[120]); MULADD(at[2], at[119]); MULADD(at[3], at[118]); MULADD(at[4], at[117]); MULADD(at[5], at[116]); MULADD(at[6], at[115]); MULADD(at[7], at[114]); MULADD(at[8], at[113]); MULADD(at[9], at[112]); MULADD(at[10], at[111]); MULADD(at[11], at[110]); MULADD(at[12], at[109]); MULADD(at[13], at[108]); MULADD(at[14], at[107]); MULADD(at[15], at[106]); MULADD(at[16], at[105]); MULADD(at[17], at[104]); MULADD(at[18], at[103]); MULADD(at[19], at[102]); MULADD(at[20], at[101]); MULADD(at[21], at[100]); MULADD(at[22], at[99]); MULADD(at[23], at[98]); MULADD(at[24], at[97]); MULADD(at[25], at[96]); MULADD(at[26], at[95]); MULADD(at[27], at[94]); MULADD(at[28], at[93]); MULADD(at[29], at[92]); MULADD(at[30], at[91]); MULADD(at[31], at[90]); MULADD(at[32], at[89]); MULADD(at[33], at[88]); MULADD(at[34], at[87]); MULADD(at[35], at[86]); MULADD(at[36], at[85]); MULADD(at[37], at[84]); MULADD(at[38], at[83]); MULADD(at[39], at[82]); MULADD(at[40], at[81]); MULADD(at[41], at[80]); MULADD(at[42], at[79]); MULADD(at[43], at[78]); MULADD(at[44], at[77]); MULADD(at[45], at[76]); MULADD(at[46], at[75]); MULADD(at[47], at[74]); MULADD(at[48], at[73]); MULADD(at[49], at[72]); MULADD(at[50], at[71]); MULADD(at[51], at[70]); MULADD(at[52], at[69]); MULADD(at[53], at[68]); MULADD(at[54], at[67]); MULADD(at[55], at[66]); MULADD(at[56], at[65]); MULADD(at[57], at[64]); + COMBA_STORE(C->dp[57]); + /* 58 */ + COMBA_FORWARD; + MULADD(at[0], at[122]); MULADD(at[1], at[121]); MULADD(at[2], at[120]); MULADD(at[3], at[119]); MULADD(at[4], at[118]); MULADD(at[5], at[117]); MULADD(at[6], at[116]); MULADD(at[7], at[115]); MULADD(at[8], at[114]); MULADD(at[9], at[113]); MULADD(at[10], at[112]); MULADD(at[11], at[111]); MULADD(at[12], at[110]); MULADD(at[13], at[109]); MULADD(at[14], at[108]); MULADD(at[15], at[107]); MULADD(at[16], at[106]); MULADD(at[17], at[105]); MULADD(at[18], at[104]); MULADD(at[19], at[103]); MULADD(at[20], at[102]); MULADD(at[21], at[101]); MULADD(at[22], at[100]); MULADD(at[23], at[99]); MULADD(at[24], at[98]); MULADD(at[25], at[97]); MULADD(at[26], at[96]); MULADD(at[27], at[95]); MULADD(at[28], at[94]); MULADD(at[29], at[93]); MULADD(at[30], at[92]); MULADD(at[31], at[91]); MULADD(at[32], at[90]); MULADD(at[33], at[89]); MULADD(at[34], at[88]); MULADD(at[35], at[87]); MULADD(at[36], at[86]); MULADD(at[37], at[85]); MULADD(at[38], at[84]); MULADD(at[39], at[83]); MULADD(at[40], at[82]); MULADD(at[41], at[81]); MULADD(at[42], at[80]); MULADD(at[43], at[79]); MULADD(at[44], at[78]); MULADD(at[45], at[77]); MULADD(at[46], at[76]); MULADD(at[47], at[75]); MULADD(at[48], at[74]); MULADD(at[49], at[73]); MULADD(at[50], at[72]); MULADD(at[51], at[71]); MULADD(at[52], at[70]); MULADD(at[53], at[69]); MULADD(at[54], at[68]); MULADD(at[55], at[67]); MULADD(at[56], at[66]); MULADD(at[57], at[65]); MULADD(at[58], at[64]); + COMBA_STORE(C->dp[58]); + /* 59 */ + COMBA_FORWARD; + MULADD(at[0], at[123]); MULADD(at[1], at[122]); MULADD(at[2], at[121]); MULADD(at[3], at[120]); MULADD(at[4], at[119]); MULADD(at[5], at[118]); MULADD(at[6], at[117]); MULADD(at[7], at[116]); MULADD(at[8], at[115]); MULADD(at[9], at[114]); MULADD(at[10], at[113]); MULADD(at[11], at[112]); MULADD(at[12], at[111]); MULADD(at[13], at[110]); MULADD(at[14], at[109]); MULADD(at[15], at[108]); MULADD(at[16], at[107]); MULADD(at[17], at[106]); MULADD(at[18], at[105]); MULADD(at[19], at[104]); MULADD(at[20], at[103]); MULADD(at[21], at[102]); MULADD(at[22], at[101]); MULADD(at[23], at[100]); MULADD(at[24], at[99]); MULADD(at[25], at[98]); MULADD(at[26], at[97]); MULADD(at[27], at[96]); MULADD(at[28], at[95]); MULADD(at[29], at[94]); MULADD(at[30], at[93]); MULADD(at[31], at[92]); MULADD(at[32], at[91]); MULADD(at[33], at[90]); MULADD(at[34], at[89]); MULADD(at[35], at[88]); MULADD(at[36], at[87]); MULADD(at[37], at[86]); MULADD(at[38], at[85]); MULADD(at[39], at[84]); MULADD(at[40], at[83]); MULADD(at[41], at[82]); MULADD(at[42], at[81]); MULADD(at[43], at[80]); MULADD(at[44], at[79]); MULADD(at[45], at[78]); MULADD(at[46], at[77]); MULADD(at[47], at[76]); MULADD(at[48], at[75]); MULADD(at[49], at[74]); MULADD(at[50], at[73]); MULADD(at[51], at[72]); MULADD(at[52], at[71]); MULADD(at[53], at[70]); MULADD(at[54], at[69]); MULADD(at[55], at[68]); MULADD(at[56], at[67]); MULADD(at[57], at[66]); MULADD(at[58], at[65]); MULADD(at[59], at[64]); + COMBA_STORE(C->dp[59]); + /* 60 */ + COMBA_FORWARD; + MULADD(at[0], at[124]); MULADD(at[1], at[123]); MULADD(at[2], at[122]); MULADD(at[3], at[121]); MULADD(at[4], at[120]); MULADD(at[5], at[119]); MULADD(at[6], at[118]); MULADD(at[7], at[117]); MULADD(at[8], at[116]); MULADD(at[9], at[115]); MULADD(at[10], at[114]); MULADD(at[11], at[113]); MULADD(at[12], at[112]); MULADD(at[13], at[111]); MULADD(at[14], at[110]); MULADD(at[15], at[109]); MULADD(at[16], at[108]); MULADD(at[17], at[107]); MULADD(at[18], at[106]); MULADD(at[19], at[105]); MULADD(at[20], at[104]); MULADD(at[21], at[103]); MULADD(at[22], at[102]); MULADD(at[23], at[101]); MULADD(at[24], at[100]); MULADD(at[25], at[99]); MULADD(at[26], at[98]); MULADD(at[27], at[97]); MULADD(at[28], at[96]); MULADD(at[29], at[95]); MULADD(at[30], at[94]); MULADD(at[31], at[93]); MULADD(at[32], at[92]); MULADD(at[33], at[91]); MULADD(at[34], at[90]); MULADD(at[35], at[89]); MULADD(at[36], at[88]); MULADD(at[37], at[87]); MULADD(at[38], at[86]); MULADD(at[39], at[85]); MULADD(at[40], at[84]); MULADD(at[41], at[83]); MULADD(at[42], at[82]); MULADD(at[43], at[81]); MULADD(at[44], at[80]); MULADD(at[45], at[79]); MULADD(at[46], at[78]); MULADD(at[47], at[77]); MULADD(at[48], at[76]); MULADD(at[49], at[75]); MULADD(at[50], at[74]); MULADD(at[51], at[73]); MULADD(at[52], at[72]); MULADD(at[53], at[71]); MULADD(at[54], at[70]); MULADD(at[55], at[69]); MULADD(at[56], at[68]); MULADD(at[57], at[67]); MULADD(at[58], at[66]); MULADD(at[59], at[65]); MULADD(at[60], at[64]); + COMBA_STORE(C->dp[60]); + /* 61 */ + COMBA_FORWARD; + MULADD(at[0], at[125]); MULADD(at[1], at[124]); MULADD(at[2], at[123]); MULADD(at[3], at[122]); MULADD(at[4], at[121]); MULADD(at[5], at[120]); MULADD(at[6], at[119]); MULADD(at[7], at[118]); MULADD(at[8], at[117]); MULADD(at[9], at[116]); MULADD(at[10], at[115]); MULADD(at[11], at[114]); MULADD(at[12], at[113]); MULADD(at[13], at[112]); MULADD(at[14], at[111]); MULADD(at[15], at[110]); MULADD(at[16], at[109]); MULADD(at[17], at[108]); MULADD(at[18], at[107]); MULADD(at[19], at[106]); MULADD(at[20], at[105]); MULADD(at[21], at[104]); MULADD(at[22], at[103]); MULADD(at[23], at[102]); MULADD(at[24], at[101]); MULADD(at[25], at[100]); MULADD(at[26], at[99]); MULADD(at[27], at[98]); MULADD(at[28], at[97]); MULADD(at[29], at[96]); MULADD(at[30], at[95]); MULADD(at[31], at[94]); MULADD(at[32], at[93]); MULADD(at[33], at[92]); MULADD(at[34], at[91]); MULADD(at[35], at[90]); MULADD(at[36], at[89]); MULADD(at[37], at[88]); MULADD(at[38], at[87]); MULADD(at[39], at[86]); MULADD(at[40], at[85]); MULADD(at[41], at[84]); MULADD(at[42], at[83]); MULADD(at[43], at[82]); MULADD(at[44], at[81]); MULADD(at[45], at[80]); MULADD(at[46], at[79]); MULADD(at[47], at[78]); MULADD(at[48], at[77]); MULADD(at[49], at[76]); MULADD(at[50], at[75]); MULADD(at[51], at[74]); MULADD(at[52], at[73]); MULADD(at[53], at[72]); MULADD(at[54], at[71]); MULADD(at[55], at[70]); MULADD(at[56], at[69]); MULADD(at[57], at[68]); MULADD(at[58], at[67]); MULADD(at[59], at[66]); MULADD(at[60], at[65]); MULADD(at[61], at[64]); + COMBA_STORE(C->dp[61]); + /* 62 */ + COMBA_FORWARD; + MULADD(at[0], at[126]); MULADD(at[1], at[125]); MULADD(at[2], at[124]); MULADD(at[3], at[123]); MULADD(at[4], at[122]); MULADD(at[5], at[121]); MULADD(at[6], at[120]); MULADD(at[7], at[119]); MULADD(at[8], at[118]); MULADD(at[9], at[117]); MULADD(at[10], at[116]); MULADD(at[11], at[115]); MULADD(at[12], at[114]); MULADD(at[13], at[113]); MULADD(at[14], at[112]); MULADD(at[15], at[111]); MULADD(at[16], at[110]); MULADD(at[17], at[109]); MULADD(at[18], at[108]); MULADD(at[19], at[107]); MULADD(at[20], at[106]); MULADD(at[21], at[105]); MULADD(at[22], at[104]); MULADD(at[23], at[103]); MULADD(at[24], at[102]); MULADD(at[25], at[101]); MULADD(at[26], at[100]); MULADD(at[27], at[99]); MULADD(at[28], at[98]); MULADD(at[29], at[97]); MULADD(at[30], at[96]); MULADD(at[31], at[95]); MULADD(at[32], at[94]); MULADD(at[33], at[93]); MULADD(at[34], at[92]); MULADD(at[35], at[91]); MULADD(at[36], at[90]); MULADD(at[37], at[89]); MULADD(at[38], at[88]); MULADD(at[39], at[87]); MULADD(at[40], at[86]); MULADD(at[41], at[85]); MULADD(at[42], at[84]); MULADD(at[43], at[83]); MULADD(at[44], at[82]); MULADD(at[45], at[81]); MULADD(at[46], at[80]); MULADD(at[47], at[79]); MULADD(at[48], at[78]); MULADD(at[49], at[77]); MULADD(at[50], at[76]); MULADD(at[51], at[75]); MULADD(at[52], at[74]); MULADD(at[53], at[73]); MULADD(at[54], at[72]); MULADD(at[55], at[71]); MULADD(at[56], at[70]); MULADD(at[57], at[69]); MULADD(at[58], at[68]); MULADD(at[59], at[67]); MULADD(at[60], at[66]); MULADD(at[61], at[65]); MULADD(at[62], at[64]); + COMBA_STORE(C->dp[62]); + /* 63 */ + COMBA_FORWARD; + MULADD(at[0], at[127]); MULADD(at[1], at[126]); MULADD(at[2], at[125]); MULADD(at[3], at[124]); MULADD(at[4], at[123]); MULADD(at[5], at[122]); MULADD(at[6], at[121]); MULADD(at[7], at[120]); MULADD(at[8], at[119]); MULADD(at[9], at[118]); MULADD(at[10], at[117]); MULADD(at[11], at[116]); MULADD(at[12], at[115]); MULADD(at[13], at[114]); MULADD(at[14], at[113]); MULADD(at[15], at[112]); MULADD(at[16], at[111]); MULADD(at[17], at[110]); MULADD(at[18], at[109]); MULADD(at[19], at[108]); MULADD(at[20], at[107]); MULADD(at[21], at[106]); MULADD(at[22], at[105]); MULADD(at[23], at[104]); MULADD(at[24], at[103]); MULADD(at[25], at[102]); MULADD(at[26], at[101]); MULADD(at[27], at[100]); MULADD(at[28], at[99]); MULADD(at[29], at[98]); MULADD(at[30], at[97]); MULADD(at[31], at[96]); MULADD(at[32], at[95]); MULADD(at[33], at[94]); MULADD(at[34], at[93]); MULADD(at[35], at[92]); MULADD(at[36], at[91]); MULADD(at[37], at[90]); MULADD(at[38], at[89]); MULADD(at[39], at[88]); MULADD(at[40], at[87]); MULADD(at[41], at[86]); MULADD(at[42], at[85]); MULADD(at[43], at[84]); MULADD(at[44], at[83]); MULADD(at[45], at[82]); MULADD(at[46], at[81]); MULADD(at[47], at[80]); MULADD(at[48], at[79]); MULADD(at[49], at[78]); MULADD(at[50], at[77]); MULADD(at[51], at[76]); MULADD(at[52], at[75]); MULADD(at[53], at[74]); MULADD(at[54], at[73]); MULADD(at[55], at[72]); MULADD(at[56], at[71]); MULADD(at[57], at[70]); MULADD(at[58], at[69]); MULADD(at[59], at[68]); MULADD(at[60], at[67]); MULADD(at[61], at[66]); MULADD(at[62], at[65]); MULADD(at[63], at[64]); + COMBA_STORE(C->dp[63]); + /* 64 */ + COMBA_FORWARD; + MULADD(at[1], at[127]); MULADD(at[2], at[126]); MULADD(at[3], at[125]); MULADD(at[4], at[124]); MULADD(at[5], at[123]); MULADD(at[6], at[122]); MULADD(at[7], at[121]); MULADD(at[8], at[120]); MULADD(at[9], at[119]); MULADD(at[10], at[118]); MULADD(at[11], at[117]); MULADD(at[12], at[116]); MULADD(at[13], at[115]); MULADD(at[14], at[114]); MULADD(at[15], at[113]); MULADD(at[16], at[112]); MULADD(at[17], at[111]); MULADD(at[18], at[110]); MULADD(at[19], at[109]); MULADD(at[20], at[108]); MULADD(at[21], at[107]); MULADD(at[22], at[106]); MULADD(at[23], at[105]); MULADD(at[24], at[104]); MULADD(at[25], at[103]); MULADD(at[26], at[102]); MULADD(at[27], at[101]); MULADD(at[28], at[100]); MULADD(at[29], at[99]); MULADD(at[30], at[98]); MULADD(at[31], at[97]); MULADD(at[32], at[96]); MULADD(at[33], at[95]); MULADD(at[34], at[94]); MULADD(at[35], at[93]); MULADD(at[36], at[92]); MULADD(at[37], at[91]); MULADD(at[38], at[90]); MULADD(at[39], at[89]); MULADD(at[40], at[88]); MULADD(at[41], at[87]); MULADD(at[42], at[86]); MULADD(at[43], at[85]); MULADD(at[44], at[84]); MULADD(at[45], at[83]); MULADD(at[46], at[82]); MULADD(at[47], at[81]); MULADD(at[48], at[80]); MULADD(at[49], at[79]); MULADD(at[50], at[78]); MULADD(at[51], at[77]); MULADD(at[52], at[76]); MULADD(at[53], at[75]); MULADD(at[54], at[74]); MULADD(at[55], at[73]); MULADD(at[56], at[72]); MULADD(at[57], at[71]); MULADD(at[58], at[70]); MULADD(at[59], at[69]); MULADD(at[60], at[68]); MULADD(at[61], at[67]); MULADD(at[62], at[66]); MULADD(at[63], at[65]); + COMBA_STORE(C->dp[64]); + /* 65 */ + COMBA_FORWARD; + MULADD(at[2], at[127]); MULADD(at[3], at[126]); MULADD(at[4], at[125]); MULADD(at[5], at[124]); MULADD(at[6], at[123]); MULADD(at[7], at[122]); MULADD(at[8], at[121]); MULADD(at[9], at[120]); MULADD(at[10], at[119]); MULADD(at[11], at[118]); MULADD(at[12], at[117]); MULADD(at[13], at[116]); MULADD(at[14], at[115]); MULADD(at[15], at[114]); MULADD(at[16], at[113]); MULADD(at[17], at[112]); MULADD(at[18], at[111]); MULADD(at[19], at[110]); MULADD(at[20], at[109]); MULADD(at[21], at[108]); MULADD(at[22], at[107]); MULADD(at[23], at[106]); MULADD(at[24], at[105]); MULADD(at[25], at[104]); MULADD(at[26], at[103]); MULADD(at[27], at[102]); MULADD(at[28], at[101]); MULADD(at[29], at[100]); MULADD(at[30], at[99]); MULADD(at[31], at[98]); MULADD(at[32], at[97]); MULADD(at[33], at[96]); MULADD(at[34], at[95]); MULADD(at[35], at[94]); MULADD(at[36], at[93]); MULADD(at[37], at[92]); MULADD(at[38], at[91]); MULADD(at[39], at[90]); MULADD(at[40], at[89]); MULADD(at[41], at[88]); MULADD(at[42], at[87]); MULADD(at[43], at[86]); MULADD(at[44], at[85]); MULADD(at[45], at[84]); MULADD(at[46], at[83]); MULADD(at[47], at[82]); MULADD(at[48], at[81]); MULADD(at[49], at[80]); MULADD(at[50], at[79]); MULADD(at[51], at[78]); MULADD(at[52], at[77]); MULADD(at[53], at[76]); MULADD(at[54], at[75]); MULADD(at[55], at[74]); MULADD(at[56], at[73]); MULADD(at[57], at[72]); MULADD(at[58], at[71]); MULADD(at[59], at[70]); MULADD(at[60], at[69]); MULADD(at[61], at[68]); MULADD(at[62], at[67]); MULADD(at[63], at[66]); + COMBA_STORE(C->dp[65]); + /* 66 */ + COMBA_FORWARD; + MULADD(at[3], at[127]); MULADD(at[4], at[126]); MULADD(at[5], at[125]); MULADD(at[6], at[124]); MULADD(at[7], at[123]); MULADD(at[8], at[122]); MULADD(at[9], at[121]); MULADD(at[10], at[120]); MULADD(at[11], at[119]); MULADD(at[12], at[118]); MULADD(at[13], at[117]); MULADD(at[14], at[116]); MULADD(at[15], at[115]); MULADD(at[16], at[114]); MULADD(at[17], at[113]); MULADD(at[18], at[112]); MULADD(at[19], at[111]); MULADD(at[20], at[110]); MULADD(at[21], at[109]); MULADD(at[22], at[108]); MULADD(at[23], at[107]); MULADD(at[24], at[106]); MULADD(at[25], at[105]); MULADD(at[26], at[104]); MULADD(at[27], at[103]); MULADD(at[28], at[102]); MULADD(at[29], at[101]); MULADD(at[30], at[100]); MULADD(at[31], at[99]); MULADD(at[32], at[98]); MULADD(at[33], at[97]); MULADD(at[34], at[96]); MULADD(at[35], at[95]); MULADD(at[36], at[94]); MULADD(at[37], at[93]); MULADD(at[38], at[92]); MULADD(at[39], at[91]); MULADD(at[40], at[90]); MULADD(at[41], at[89]); MULADD(at[42], at[88]); MULADD(at[43], at[87]); MULADD(at[44], at[86]); MULADD(at[45], at[85]); MULADD(at[46], at[84]); MULADD(at[47], at[83]); MULADD(at[48], at[82]); MULADD(at[49], at[81]); MULADD(at[50], at[80]); MULADD(at[51], at[79]); MULADD(at[52], at[78]); MULADD(at[53], at[77]); MULADD(at[54], at[76]); MULADD(at[55], at[75]); MULADD(at[56], at[74]); MULADD(at[57], at[73]); MULADD(at[58], at[72]); MULADD(at[59], at[71]); MULADD(at[60], at[70]); MULADD(at[61], at[69]); MULADD(at[62], at[68]); MULADD(at[63], at[67]); + COMBA_STORE(C->dp[66]); + /* 67 */ + COMBA_FORWARD; + MULADD(at[4], at[127]); MULADD(at[5], at[126]); MULADD(at[6], at[125]); MULADD(at[7], at[124]); MULADD(at[8], at[123]); MULADD(at[9], at[122]); MULADD(at[10], at[121]); MULADD(at[11], at[120]); MULADD(at[12], at[119]); MULADD(at[13], at[118]); MULADD(at[14], at[117]); MULADD(at[15], at[116]); MULADD(at[16], at[115]); MULADD(at[17], at[114]); MULADD(at[18], at[113]); MULADD(at[19], at[112]); MULADD(at[20], at[111]); MULADD(at[21], at[110]); MULADD(at[22], at[109]); MULADD(at[23], at[108]); MULADD(at[24], at[107]); MULADD(at[25], at[106]); MULADD(at[26], at[105]); MULADD(at[27], at[104]); MULADD(at[28], at[103]); MULADD(at[29], at[102]); MULADD(at[30], at[101]); MULADD(at[31], at[100]); MULADD(at[32], at[99]); MULADD(at[33], at[98]); MULADD(at[34], at[97]); MULADD(at[35], at[96]); MULADD(at[36], at[95]); MULADD(at[37], at[94]); MULADD(at[38], at[93]); MULADD(at[39], at[92]); MULADD(at[40], at[91]); MULADD(at[41], at[90]); MULADD(at[42], at[89]); MULADD(at[43], at[88]); MULADD(at[44], at[87]); MULADD(at[45], at[86]); MULADD(at[46], at[85]); MULADD(at[47], at[84]); MULADD(at[48], at[83]); MULADD(at[49], at[82]); MULADD(at[50], at[81]); MULADD(at[51], at[80]); MULADD(at[52], at[79]); MULADD(at[53], at[78]); MULADD(at[54], at[77]); MULADD(at[55], at[76]); MULADD(at[56], at[75]); MULADD(at[57], at[74]); MULADD(at[58], at[73]); MULADD(at[59], at[72]); MULADD(at[60], at[71]); MULADD(at[61], at[70]); MULADD(at[62], at[69]); MULADD(at[63], at[68]); + COMBA_STORE(C->dp[67]); + /* 68 */ + COMBA_FORWARD; + MULADD(at[5], at[127]); MULADD(at[6], at[126]); MULADD(at[7], at[125]); MULADD(at[8], at[124]); MULADD(at[9], at[123]); MULADD(at[10], at[122]); MULADD(at[11], at[121]); MULADD(at[12], at[120]); MULADD(at[13], at[119]); MULADD(at[14], at[118]); MULADD(at[15], at[117]); MULADD(at[16], at[116]); MULADD(at[17], at[115]); MULADD(at[18], at[114]); MULADD(at[19], at[113]); MULADD(at[20], at[112]); MULADD(at[21], at[111]); MULADD(at[22], at[110]); MULADD(at[23], at[109]); MULADD(at[24], at[108]); MULADD(at[25], at[107]); MULADD(at[26], at[106]); MULADD(at[27], at[105]); MULADD(at[28], at[104]); MULADD(at[29], at[103]); MULADD(at[30], at[102]); MULADD(at[31], at[101]); MULADD(at[32], at[100]); MULADD(at[33], at[99]); MULADD(at[34], at[98]); MULADD(at[35], at[97]); MULADD(at[36], at[96]); MULADD(at[37], at[95]); MULADD(at[38], at[94]); MULADD(at[39], at[93]); MULADD(at[40], at[92]); MULADD(at[41], at[91]); MULADD(at[42], at[90]); MULADD(at[43], at[89]); MULADD(at[44], at[88]); MULADD(at[45], at[87]); MULADD(at[46], at[86]); MULADD(at[47], at[85]); MULADD(at[48], at[84]); MULADD(at[49], at[83]); MULADD(at[50], at[82]); MULADD(at[51], at[81]); MULADD(at[52], at[80]); MULADD(at[53], at[79]); MULADD(at[54], at[78]); MULADD(at[55], at[77]); MULADD(at[56], at[76]); MULADD(at[57], at[75]); MULADD(at[58], at[74]); MULADD(at[59], at[73]); MULADD(at[60], at[72]); MULADD(at[61], at[71]); MULADD(at[62], at[70]); MULADD(at[63], at[69]); + COMBA_STORE(C->dp[68]); + /* 69 */ + COMBA_FORWARD; + MULADD(at[6], at[127]); MULADD(at[7], at[126]); MULADD(at[8], at[125]); MULADD(at[9], at[124]); MULADD(at[10], at[123]); MULADD(at[11], at[122]); MULADD(at[12], at[121]); MULADD(at[13], at[120]); MULADD(at[14], at[119]); MULADD(at[15], at[118]); MULADD(at[16], at[117]); MULADD(at[17], at[116]); MULADD(at[18], at[115]); MULADD(at[19], at[114]); MULADD(at[20], at[113]); MULADD(at[21], at[112]); MULADD(at[22], at[111]); MULADD(at[23], at[110]); MULADD(at[24], at[109]); MULADD(at[25], at[108]); MULADD(at[26], at[107]); MULADD(at[27], at[106]); MULADD(at[28], at[105]); MULADD(at[29], at[104]); MULADD(at[30], at[103]); MULADD(at[31], at[102]); MULADD(at[32], at[101]); MULADD(at[33], at[100]); MULADD(at[34], at[99]); MULADD(at[35], at[98]); MULADD(at[36], at[97]); MULADD(at[37], at[96]); MULADD(at[38], at[95]); MULADD(at[39], at[94]); MULADD(at[40], at[93]); MULADD(at[41], at[92]); MULADD(at[42], at[91]); MULADD(at[43], at[90]); MULADD(at[44], at[89]); MULADD(at[45], at[88]); MULADD(at[46], at[87]); MULADD(at[47], at[86]); MULADD(at[48], at[85]); MULADD(at[49], at[84]); MULADD(at[50], at[83]); MULADD(at[51], at[82]); MULADD(at[52], at[81]); MULADD(at[53], at[80]); MULADD(at[54], at[79]); MULADD(at[55], at[78]); MULADD(at[56], at[77]); MULADD(at[57], at[76]); MULADD(at[58], at[75]); MULADD(at[59], at[74]); MULADD(at[60], at[73]); MULADD(at[61], at[72]); MULADD(at[62], at[71]); MULADD(at[63], at[70]); + COMBA_STORE(C->dp[69]); + /* 70 */ + COMBA_FORWARD; + MULADD(at[7], at[127]); MULADD(at[8], at[126]); MULADD(at[9], at[125]); MULADD(at[10], at[124]); MULADD(at[11], at[123]); MULADD(at[12], at[122]); MULADD(at[13], at[121]); MULADD(at[14], at[120]); MULADD(at[15], at[119]); MULADD(at[16], at[118]); MULADD(at[17], at[117]); MULADD(at[18], at[116]); MULADD(at[19], at[115]); MULADD(at[20], at[114]); MULADD(at[21], at[113]); MULADD(at[22], at[112]); MULADD(at[23], at[111]); MULADD(at[24], at[110]); MULADD(at[25], at[109]); MULADD(at[26], at[108]); MULADD(at[27], at[107]); MULADD(at[28], at[106]); MULADD(at[29], at[105]); MULADD(at[30], at[104]); MULADD(at[31], at[103]); MULADD(at[32], at[102]); MULADD(at[33], at[101]); MULADD(at[34], at[100]); MULADD(at[35], at[99]); MULADD(at[36], at[98]); MULADD(at[37], at[97]); MULADD(at[38], at[96]); MULADD(at[39], at[95]); MULADD(at[40], at[94]); MULADD(at[41], at[93]); MULADD(at[42], at[92]); MULADD(at[43], at[91]); MULADD(at[44], at[90]); MULADD(at[45], at[89]); MULADD(at[46], at[88]); MULADD(at[47], at[87]); MULADD(at[48], at[86]); MULADD(at[49], at[85]); MULADD(at[50], at[84]); MULADD(at[51], at[83]); MULADD(at[52], at[82]); MULADD(at[53], at[81]); MULADD(at[54], at[80]); MULADD(at[55], at[79]); MULADD(at[56], at[78]); MULADD(at[57], at[77]); MULADD(at[58], at[76]); MULADD(at[59], at[75]); MULADD(at[60], at[74]); MULADD(at[61], at[73]); MULADD(at[62], at[72]); MULADD(at[63], at[71]); + COMBA_STORE(C->dp[70]); + /* 71 */ + COMBA_FORWARD; + MULADD(at[8], at[127]); MULADD(at[9], at[126]); MULADD(at[10], at[125]); MULADD(at[11], at[124]); MULADD(at[12], at[123]); MULADD(at[13], at[122]); MULADD(at[14], at[121]); MULADD(at[15], at[120]); MULADD(at[16], at[119]); MULADD(at[17], at[118]); MULADD(at[18], at[117]); MULADD(at[19], at[116]); MULADD(at[20], at[115]); MULADD(at[21], at[114]); MULADD(at[22], at[113]); MULADD(at[23], at[112]); MULADD(at[24], at[111]); MULADD(at[25], at[110]); MULADD(at[26], at[109]); MULADD(at[27], at[108]); MULADD(at[28], at[107]); MULADD(at[29], at[106]); MULADD(at[30], at[105]); MULADD(at[31], at[104]); MULADD(at[32], at[103]); MULADD(at[33], at[102]); MULADD(at[34], at[101]); MULADD(at[35], at[100]); MULADD(at[36], at[99]); MULADD(at[37], at[98]); MULADD(at[38], at[97]); MULADD(at[39], at[96]); MULADD(at[40], at[95]); MULADD(at[41], at[94]); MULADD(at[42], at[93]); MULADD(at[43], at[92]); MULADD(at[44], at[91]); MULADD(at[45], at[90]); MULADD(at[46], at[89]); MULADD(at[47], at[88]); MULADD(at[48], at[87]); MULADD(at[49], at[86]); MULADD(at[50], at[85]); MULADD(at[51], at[84]); MULADD(at[52], at[83]); MULADD(at[53], at[82]); MULADD(at[54], at[81]); MULADD(at[55], at[80]); MULADD(at[56], at[79]); MULADD(at[57], at[78]); MULADD(at[58], at[77]); MULADD(at[59], at[76]); MULADD(at[60], at[75]); MULADD(at[61], at[74]); MULADD(at[62], at[73]); MULADD(at[63], at[72]); + COMBA_STORE(C->dp[71]); + /* 72 */ + COMBA_FORWARD; + MULADD(at[9], at[127]); MULADD(at[10], at[126]); MULADD(at[11], at[125]); MULADD(at[12], at[124]); MULADD(at[13], at[123]); MULADD(at[14], at[122]); MULADD(at[15], at[121]); MULADD(at[16], at[120]); MULADD(at[17], at[119]); MULADD(at[18], at[118]); MULADD(at[19], at[117]); MULADD(at[20], at[116]); MULADD(at[21], at[115]); MULADD(at[22], at[114]); MULADD(at[23], at[113]); MULADD(at[24], at[112]); MULADD(at[25], at[111]); MULADD(at[26], at[110]); MULADD(at[27], at[109]); MULADD(at[28], at[108]); MULADD(at[29], at[107]); MULADD(at[30], at[106]); MULADD(at[31], at[105]); MULADD(at[32], at[104]); MULADD(at[33], at[103]); MULADD(at[34], at[102]); MULADD(at[35], at[101]); MULADD(at[36], at[100]); MULADD(at[37], at[99]); MULADD(at[38], at[98]); MULADD(at[39], at[97]); MULADD(at[40], at[96]); MULADD(at[41], at[95]); MULADD(at[42], at[94]); MULADD(at[43], at[93]); MULADD(at[44], at[92]); MULADD(at[45], at[91]); MULADD(at[46], at[90]); MULADD(at[47], at[89]); MULADD(at[48], at[88]); MULADD(at[49], at[87]); MULADD(at[50], at[86]); MULADD(at[51], at[85]); MULADD(at[52], at[84]); MULADD(at[53], at[83]); MULADD(at[54], at[82]); MULADD(at[55], at[81]); MULADD(at[56], at[80]); MULADD(at[57], at[79]); MULADD(at[58], at[78]); MULADD(at[59], at[77]); MULADD(at[60], at[76]); MULADD(at[61], at[75]); MULADD(at[62], at[74]); MULADD(at[63], at[73]); + COMBA_STORE(C->dp[72]); + /* 73 */ + COMBA_FORWARD; + MULADD(at[10], at[127]); MULADD(at[11], at[126]); MULADD(at[12], at[125]); MULADD(at[13], at[124]); MULADD(at[14], at[123]); MULADD(at[15], at[122]); MULADD(at[16], at[121]); MULADD(at[17], at[120]); MULADD(at[18], at[119]); MULADD(at[19], at[118]); MULADD(at[20], at[117]); MULADD(at[21], at[116]); MULADD(at[22], at[115]); MULADD(at[23], at[114]); MULADD(at[24], at[113]); MULADD(at[25], at[112]); MULADD(at[26], at[111]); MULADD(at[27], at[110]); MULADD(at[28], at[109]); MULADD(at[29], at[108]); MULADD(at[30], at[107]); MULADD(at[31], at[106]); MULADD(at[32], at[105]); MULADD(at[33], at[104]); MULADD(at[34], at[103]); MULADD(at[35], at[102]); MULADD(at[36], at[101]); MULADD(at[37], at[100]); MULADD(at[38], at[99]); MULADD(at[39], at[98]); MULADD(at[40], at[97]); MULADD(at[41], at[96]); MULADD(at[42], at[95]); MULADD(at[43], at[94]); MULADD(at[44], at[93]); MULADD(at[45], at[92]); MULADD(at[46], at[91]); MULADD(at[47], at[90]); MULADD(at[48], at[89]); MULADD(at[49], at[88]); MULADD(at[50], at[87]); MULADD(at[51], at[86]); MULADD(at[52], at[85]); MULADD(at[53], at[84]); MULADD(at[54], at[83]); MULADD(at[55], at[82]); MULADD(at[56], at[81]); MULADD(at[57], at[80]); MULADD(at[58], at[79]); MULADD(at[59], at[78]); MULADD(at[60], at[77]); MULADD(at[61], at[76]); MULADD(at[62], at[75]); MULADD(at[63], at[74]); + COMBA_STORE(C->dp[73]); + /* 74 */ + COMBA_FORWARD; + MULADD(at[11], at[127]); MULADD(at[12], at[126]); MULADD(at[13], at[125]); MULADD(at[14], at[124]); MULADD(at[15], at[123]); MULADD(at[16], at[122]); MULADD(at[17], at[121]); MULADD(at[18], at[120]); MULADD(at[19], at[119]); MULADD(at[20], at[118]); MULADD(at[21], at[117]); MULADD(at[22], at[116]); MULADD(at[23], at[115]); MULADD(at[24], at[114]); MULADD(at[25], at[113]); MULADD(at[26], at[112]); MULADD(at[27], at[111]); MULADD(at[28], at[110]); MULADD(at[29], at[109]); MULADD(at[30], at[108]); MULADD(at[31], at[107]); MULADD(at[32], at[106]); MULADD(at[33], at[105]); MULADD(at[34], at[104]); MULADD(at[35], at[103]); MULADD(at[36], at[102]); MULADD(at[37], at[101]); MULADD(at[38], at[100]); MULADD(at[39], at[99]); MULADD(at[40], at[98]); MULADD(at[41], at[97]); MULADD(at[42], at[96]); MULADD(at[43], at[95]); MULADD(at[44], at[94]); MULADD(at[45], at[93]); MULADD(at[46], at[92]); MULADD(at[47], at[91]); MULADD(at[48], at[90]); MULADD(at[49], at[89]); MULADD(at[50], at[88]); MULADD(at[51], at[87]); MULADD(at[52], at[86]); MULADD(at[53], at[85]); MULADD(at[54], at[84]); MULADD(at[55], at[83]); MULADD(at[56], at[82]); MULADD(at[57], at[81]); MULADD(at[58], at[80]); MULADD(at[59], at[79]); MULADD(at[60], at[78]); MULADD(at[61], at[77]); MULADD(at[62], at[76]); MULADD(at[63], at[75]); + COMBA_STORE(C->dp[74]); + /* 75 */ + COMBA_FORWARD; + MULADD(at[12], at[127]); MULADD(at[13], at[126]); MULADD(at[14], at[125]); MULADD(at[15], at[124]); MULADD(at[16], at[123]); MULADD(at[17], at[122]); MULADD(at[18], at[121]); MULADD(at[19], at[120]); MULADD(at[20], at[119]); MULADD(at[21], at[118]); MULADD(at[22], at[117]); MULADD(at[23], at[116]); MULADD(at[24], at[115]); MULADD(at[25], at[114]); MULADD(at[26], at[113]); MULADD(at[27], at[112]); MULADD(at[28], at[111]); MULADD(at[29], at[110]); MULADD(at[30], at[109]); MULADD(at[31], at[108]); MULADD(at[32], at[107]); MULADD(at[33], at[106]); MULADD(at[34], at[105]); MULADD(at[35], at[104]); MULADD(at[36], at[103]); MULADD(at[37], at[102]); MULADD(at[38], at[101]); MULADD(at[39], at[100]); MULADD(at[40], at[99]); MULADD(at[41], at[98]); MULADD(at[42], at[97]); MULADD(at[43], at[96]); MULADD(at[44], at[95]); MULADD(at[45], at[94]); MULADD(at[46], at[93]); MULADD(at[47], at[92]); MULADD(at[48], at[91]); MULADD(at[49], at[90]); MULADD(at[50], at[89]); MULADD(at[51], at[88]); MULADD(at[52], at[87]); MULADD(at[53], at[86]); MULADD(at[54], at[85]); MULADD(at[55], at[84]); MULADD(at[56], at[83]); MULADD(at[57], at[82]); MULADD(at[58], at[81]); MULADD(at[59], at[80]); MULADD(at[60], at[79]); MULADD(at[61], at[78]); MULADD(at[62], at[77]); MULADD(at[63], at[76]); + COMBA_STORE(C->dp[75]); + /* 76 */ + COMBA_FORWARD; + MULADD(at[13], at[127]); MULADD(at[14], at[126]); MULADD(at[15], at[125]); MULADD(at[16], at[124]); MULADD(at[17], at[123]); MULADD(at[18], at[122]); MULADD(at[19], at[121]); MULADD(at[20], at[120]); MULADD(at[21], at[119]); MULADD(at[22], at[118]); MULADD(at[23], at[117]); MULADD(at[24], at[116]); MULADD(at[25], at[115]); MULADD(at[26], at[114]); MULADD(at[27], at[113]); MULADD(at[28], at[112]); MULADD(at[29], at[111]); MULADD(at[30], at[110]); MULADD(at[31], at[109]); MULADD(at[32], at[108]); MULADD(at[33], at[107]); MULADD(at[34], at[106]); MULADD(at[35], at[105]); MULADD(at[36], at[104]); MULADD(at[37], at[103]); MULADD(at[38], at[102]); MULADD(at[39], at[101]); MULADD(at[40], at[100]); MULADD(at[41], at[99]); MULADD(at[42], at[98]); MULADD(at[43], at[97]); MULADD(at[44], at[96]); MULADD(at[45], at[95]); MULADD(at[46], at[94]); MULADD(at[47], at[93]); MULADD(at[48], at[92]); MULADD(at[49], at[91]); MULADD(at[50], at[90]); MULADD(at[51], at[89]); MULADD(at[52], at[88]); MULADD(at[53], at[87]); MULADD(at[54], at[86]); MULADD(at[55], at[85]); MULADD(at[56], at[84]); MULADD(at[57], at[83]); MULADD(at[58], at[82]); MULADD(at[59], at[81]); MULADD(at[60], at[80]); MULADD(at[61], at[79]); MULADD(at[62], at[78]); MULADD(at[63], at[77]); + COMBA_STORE(C->dp[76]); + /* 77 */ + COMBA_FORWARD; + MULADD(at[14], at[127]); MULADD(at[15], at[126]); MULADD(at[16], at[125]); MULADD(at[17], at[124]); MULADD(at[18], at[123]); MULADD(at[19], at[122]); MULADD(at[20], at[121]); MULADD(at[21], at[120]); MULADD(at[22], at[119]); MULADD(at[23], at[118]); MULADD(at[24], at[117]); MULADD(at[25], at[116]); MULADD(at[26], at[115]); MULADD(at[27], at[114]); MULADD(at[28], at[113]); MULADD(at[29], at[112]); MULADD(at[30], at[111]); MULADD(at[31], at[110]); MULADD(at[32], at[109]); MULADD(at[33], at[108]); MULADD(at[34], at[107]); MULADD(at[35], at[106]); MULADD(at[36], at[105]); MULADD(at[37], at[104]); MULADD(at[38], at[103]); MULADD(at[39], at[102]); MULADD(at[40], at[101]); MULADD(at[41], at[100]); MULADD(at[42], at[99]); MULADD(at[43], at[98]); MULADD(at[44], at[97]); MULADD(at[45], at[96]); MULADD(at[46], at[95]); MULADD(at[47], at[94]); MULADD(at[48], at[93]); MULADD(at[49], at[92]); MULADD(at[50], at[91]); MULADD(at[51], at[90]); MULADD(at[52], at[89]); MULADD(at[53], at[88]); MULADD(at[54], at[87]); MULADD(at[55], at[86]); MULADD(at[56], at[85]); MULADD(at[57], at[84]); MULADD(at[58], at[83]); MULADD(at[59], at[82]); MULADD(at[60], at[81]); MULADD(at[61], at[80]); MULADD(at[62], at[79]); MULADD(at[63], at[78]); + COMBA_STORE(C->dp[77]); + /* 78 */ + COMBA_FORWARD; + MULADD(at[15], at[127]); MULADD(at[16], at[126]); MULADD(at[17], at[125]); MULADD(at[18], at[124]); MULADD(at[19], at[123]); MULADD(at[20], at[122]); MULADD(at[21], at[121]); MULADD(at[22], at[120]); MULADD(at[23], at[119]); MULADD(at[24], at[118]); MULADD(at[25], at[117]); MULADD(at[26], at[116]); MULADD(at[27], at[115]); MULADD(at[28], at[114]); MULADD(at[29], at[113]); MULADD(at[30], at[112]); MULADD(at[31], at[111]); MULADD(at[32], at[110]); MULADD(at[33], at[109]); MULADD(at[34], at[108]); MULADD(at[35], at[107]); MULADD(at[36], at[106]); MULADD(at[37], at[105]); MULADD(at[38], at[104]); MULADD(at[39], at[103]); MULADD(at[40], at[102]); MULADD(at[41], at[101]); MULADD(at[42], at[100]); MULADD(at[43], at[99]); MULADD(at[44], at[98]); MULADD(at[45], at[97]); MULADD(at[46], at[96]); MULADD(at[47], at[95]); MULADD(at[48], at[94]); MULADD(at[49], at[93]); MULADD(at[50], at[92]); MULADD(at[51], at[91]); MULADD(at[52], at[90]); MULADD(at[53], at[89]); MULADD(at[54], at[88]); MULADD(at[55], at[87]); MULADD(at[56], at[86]); MULADD(at[57], at[85]); MULADD(at[58], at[84]); MULADD(at[59], at[83]); MULADD(at[60], at[82]); MULADD(at[61], at[81]); MULADD(at[62], at[80]); MULADD(at[63], at[79]); + COMBA_STORE(C->dp[78]); + /* 79 */ + COMBA_FORWARD; + MULADD(at[16], at[127]); MULADD(at[17], at[126]); MULADD(at[18], at[125]); MULADD(at[19], at[124]); MULADD(at[20], at[123]); MULADD(at[21], at[122]); MULADD(at[22], at[121]); MULADD(at[23], at[120]); MULADD(at[24], at[119]); MULADD(at[25], at[118]); MULADD(at[26], at[117]); MULADD(at[27], at[116]); MULADD(at[28], at[115]); MULADD(at[29], at[114]); MULADD(at[30], at[113]); MULADD(at[31], at[112]); MULADD(at[32], at[111]); MULADD(at[33], at[110]); MULADD(at[34], at[109]); MULADD(at[35], at[108]); MULADD(at[36], at[107]); MULADD(at[37], at[106]); MULADD(at[38], at[105]); MULADD(at[39], at[104]); MULADD(at[40], at[103]); MULADD(at[41], at[102]); MULADD(at[42], at[101]); MULADD(at[43], at[100]); MULADD(at[44], at[99]); MULADD(at[45], at[98]); MULADD(at[46], at[97]); MULADD(at[47], at[96]); MULADD(at[48], at[95]); MULADD(at[49], at[94]); MULADD(at[50], at[93]); MULADD(at[51], at[92]); MULADD(at[52], at[91]); MULADD(at[53], at[90]); MULADD(at[54], at[89]); MULADD(at[55], at[88]); MULADD(at[56], at[87]); MULADD(at[57], at[86]); MULADD(at[58], at[85]); MULADD(at[59], at[84]); MULADD(at[60], at[83]); MULADD(at[61], at[82]); MULADD(at[62], at[81]); MULADD(at[63], at[80]); + COMBA_STORE(C->dp[79]); + /* 80 */ + COMBA_FORWARD; + MULADD(at[17], at[127]); MULADD(at[18], at[126]); MULADD(at[19], at[125]); MULADD(at[20], at[124]); MULADD(at[21], at[123]); MULADD(at[22], at[122]); MULADD(at[23], at[121]); MULADD(at[24], at[120]); MULADD(at[25], at[119]); MULADD(at[26], at[118]); MULADD(at[27], at[117]); MULADD(at[28], at[116]); MULADD(at[29], at[115]); MULADD(at[30], at[114]); MULADD(at[31], at[113]); MULADD(at[32], at[112]); MULADD(at[33], at[111]); MULADD(at[34], at[110]); MULADD(at[35], at[109]); MULADD(at[36], at[108]); MULADD(at[37], at[107]); MULADD(at[38], at[106]); MULADD(at[39], at[105]); MULADD(at[40], at[104]); MULADD(at[41], at[103]); MULADD(at[42], at[102]); MULADD(at[43], at[101]); MULADD(at[44], at[100]); MULADD(at[45], at[99]); MULADD(at[46], at[98]); MULADD(at[47], at[97]); MULADD(at[48], at[96]); MULADD(at[49], at[95]); MULADD(at[50], at[94]); MULADD(at[51], at[93]); MULADD(at[52], at[92]); MULADD(at[53], at[91]); MULADD(at[54], at[90]); MULADD(at[55], at[89]); MULADD(at[56], at[88]); MULADD(at[57], at[87]); MULADD(at[58], at[86]); MULADD(at[59], at[85]); MULADD(at[60], at[84]); MULADD(at[61], at[83]); MULADD(at[62], at[82]); MULADD(at[63], at[81]); + COMBA_STORE(C->dp[80]); + /* 81 */ + COMBA_FORWARD; + MULADD(at[18], at[127]); MULADD(at[19], at[126]); MULADD(at[20], at[125]); MULADD(at[21], at[124]); MULADD(at[22], at[123]); MULADD(at[23], at[122]); MULADD(at[24], at[121]); MULADD(at[25], at[120]); MULADD(at[26], at[119]); MULADD(at[27], at[118]); MULADD(at[28], at[117]); MULADD(at[29], at[116]); MULADD(at[30], at[115]); MULADD(at[31], at[114]); MULADD(at[32], at[113]); MULADD(at[33], at[112]); MULADD(at[34], at[111]); MULADD(at[35], at[110]); MULADD(at[36], at[109]); MULADD(at[37], at[108]); MULADD(at[38], at[107]); MULADD(at[39], at[106]); MULADD(at[40], at[105]); MULADD(at[41], at[104]); MULADD(at[42], at[103]); MULADD(at[43], at[102]); MULADD(at[44], at[101]); MULADD(at[45], at[100]); MULADD(at[46], at[99]); MULADD(at[47], at[98]); MULADD(at[48], at[97]); MULADD(at[49], at[96]); MULADD(at[50], at[95]); MULADD(at[51], at[94]); MULADD(at[52], at[93]); MULADD(at[53], at[92]); MULADD(at[54], at[91]); MULADD(at[55], at[90]); MULADD(at[56], at[89]); MULADD(at[57], at[88]); MULADD(at[58], at[87]); MULADD(at[59], at[86]); MULADD(at[60], at[85]); MULADD(at[61], at[84]); MULADD(at[62], at[83]); MULADD(at[63], at[82]); + COMBA_STORE(C->dp[81]); + /* 82 */ + COMBA_FORWARD; + MULADD(at[19], at[127]); MULADD(at[20], at[126]); MULADD(at[21], at[125]); MULADD(at[22], at[124]); MULADD(at[23], at[123]); MULADD(at[24], at[122]); MULADD(at[25], at[121]); MULADD(at[26], at[120]); MULADD(at[27], at[119]); MULADD(at[28], at[118]); MULADD(at[29], at[117]); MULADD(at[30], at[116]); MULADD(at[31], at[115]); MULADD(at[32], at[114]); MULADD(at[33], at[113]); MULADD(at[34], at[112]); MULADD(at[35], at[111]); MULADD(at[36], at[110]); MULADD(at[37], at[109]); MULADD(at[38], at[108]); MULADD(at[39], at[107]); MULADD(at[40], at[106]); MULADD(at[41], at[105]); MULADD(at[42], at[104]); MULADD(at[43], at[103]); MULADD(at[44], at[102]); MULADD(at[45], at[101]); MULADD(at[46], at[100]); MULADD(at[47], at[99]); MULADD(at[48], at[98]); MULADD(at[49], at[97]); MULADD(at[50], at[96]); MULADD(at[51], at[95]); MULADD(at[52], at[94]); MULADD(at[53], at[93]); MULADD(at[54], at[92]); MULADD(at[55], at[91]); MULADD(at[56], at[90]); MULADD(at[57], at[89]); MULADD(at[58], at[88]); MULADD(at[59], at[87]); MULADD(at[60], at[86]); MULADD(at[61], at[85]); MULADD(at[62], at[84]); MULADD(at[63], at[83]); + COMBA_STORE(C->dp[82]); + /* 83 */ + COMBA_FORWARD; + MULADD(at[20], at[127]); MULADD(at[21], at[126]); MULADD(at[22], at[125]); MULADD(at[23], at[124]); MULADD(at[24], at[123]); MULADD(at[25], at[122]); MULADD(at[26], at[121]); MULADD(at[27], at[120]); MULADD(at[28], at[119]); MULADD(at[29], at[118]); MULADD(at[30], at[117]); MULADD(at[31], at[116]); MULADD(at[32], at[115]); MULADD(at[33], at[114]); MULADD(at[34], at[113]); MULADD(at[35], at[112]); MULADD(at[36], at[111]); MULADD(at[37], at[110]); MULADD(at[38], at[109]); MULADD(at[39], at[108]); MULADD(at[40], at[107]); MULADD(at[41], at[106]); MULADD(at[42], at[105]); MULADD(at[43], at[104]); MULADD(at[44], at[103]); MULADD(at[45], at[102]); MULADD(at[46], at[101]); MULADD(at[47], at[100]); MULADD(at[48], at[99]); MULADD(at[49], at[98]); MULADD(at[50], at[97]); MULADD(at[51], at[96]); MULADD(at[52], at[95]); MULADD(at[53], at[94]); MULADD(at[54], at[93]); MULADD(at[55], at[92]); MULADD(at[56], at[91]); MULADD(at[57], at[90]); MULADD(at[58], at[89]); MULADD(at[59], at[88]); MULADD(at[60], at[87]); MULADD(at[61], at[86]); MULADD(at[62], at[85]); MULADD(at[63], at[84]); + COMBA_STORE(C->dp[83]); + /* 84 */ + COMBA_FORWARD; + MULADD(at[21], at[127]); MULADD(at[22], at[126]); MULADD(at[23], at[125]); MULADD(at[24], at[124]); MULADD(at[25], at[123]); MULADD(at[26], at[122]); MULADD(at[27], at[121]); MULADD(at[28], at[120]); MULADD(at[29], at[119]); MULADD(at[30], at[118]); MULADD(at[31], at[117]); MULADD(at[32], at[116]); MULADD(at[33], at[115]); MULADD(at[34], at[114]); MULADD(at[35], at[113]); MULADD(at[36], at[112]); MULADD(at[37], at[111]); MULADD(at[38], at[110]); MULADD(at[39], at[109]); MULADD(at[40], at[108]); MULADD(at[41], at[107]); MULADD(at[42], at[106]); MULADD(at[43], at[105]); MULADD(at[44], at[104]); MULADD(at[45], at[103]); MULADD(at[46], at[102]); MULADD(at[47], at[101]); MULADD(at[48], at[100]); MULADD(at[49], at[99]); MULADD(at[50], at[98]); MULADD(at[51], at[97]); MULADD(at[52], at[96]); MULADD(at[53], at[95]); MULADD(at[54], at[94]); MULADD(at[55], at[93]); MULADD(at[56], at[92]); MULADD(at[57], at[91]); MULADD(at[58], at[90]); MULADD(at[59], at[89]); MULADD(at[60], at[88]); MULADD(at[61], at[87]); MULADD(at[62], at[86]); MULADD(at[63], at[85]); + COMBA_STORE(C->dp[84]); + /* 85 */ + COMBA_FORWARD; + MULADD(at[22], at[127]); MULADD(at[23], at[126]); MULADD(at[24], at[125]); MULADD(at[25], at[124]); MULADD(at[26], at[123]); MULADD(at[27], at[122]); MULADD(at[28], at[121]); MULADD(at[29], at[120]); MULADD(at[30], at[119]); MULADD(at[31], at[118]); MULADD(at[32], at[117]); MULADD(at[33], at[116]); MULADD(at[34], at[115]); MULADD(at[35], at[114]); MULADD(at[36], at[113]); MULADD(at[37], at[112]); MULADD(at[38], at[111]); MULADD(at[39], at[110]); MULADD(at[40], at[109]); MULADD(at[41], at[108]); MULADD(at[42], at[107]); MULADD(at[43], at[106]); MULADD(at[44], at[105]); MULADD(at[45], at[104]); MULADD(at[46], at[103]); MULADD(at[47], at[102]); MULADD(at[48], at[101]); MULADD(at[49], at[100]); MULADD(at[50], at[99]); MULADD(at[51], at[98]); MULADD(at[52], at[97]); MULADD(at[53], at[96]); MULADD(at[54], at[95]); MULADD(at[55], at[94]); MULADD(at[56], at[93]); MULADD(at[57], at[92]); MULADD(at[58], at[91]); MULADD(at[59], at[90]); MULADD(at[60], at[89]); MULADD(at[61], at[88]); MULADD(at[62], at[87]); MULADD(at[63], at[86]); + COMBA_STORE(C->dp[85]); + /* 86 */ + COMBA_FORWARD; + MULADD(at[23], at[127]); MULADD(at[24], at[126]); MULADD(at[25], at[125]); MULADD(at[26], at[124]); MULADD(at[27], at[123]); MULADD(at[28], at[122]); MULADD(at[29], at[121]); MULADD(at[30], at[120]); MULADD(at[31], at[119]); MULADD(at[32], at[118]); MULADD(at[33], at[117]); MULADD(at[34], at[116]); MULADD(at[35], at[115]); MULADD(at[36], at[114]); MULADD(at[37], at[113]); MULADD(at[38], at[112]); MULADD(at[39], at[111]); MULADD(at[40], at[110]); MULADD(at[41], at[109]); MULADD(at[42], at[108]); MULADD(at[43], at[107]); MULADD(at[44], at[106]); MULADD(at[45], at[105]); MULADD(at[46], at[104]); MULADD(at[47], at[103]); MULADD(at[48], at[102]); MULADD(at[49], at[101]); MULADD(at[50], at[100]); MULADD(at[51], at[99]); MULADD(at[52], at[98]); MULADD(at[53], at[97]); MULADD(at[54], at[96]); MULADD(at[55], at[95]); MULADD(at[56], at[94]); MULADD(at[57], at[93]); MULADD(at[58], at[92]); MULADD(at[59], at[91]); MULADD(at[60], at[90]); MULADD(at[61], at[89]); MULADD(at[62], at[88]); MULADD(at[63], at[87]); + COMBA_STORE(C->dp[86]); + /* 87 */ + COMBA_FORWARD; + MULADD(at[24], at[127]); MULADD(at[25], at[126]); MULADD(at[26], at[125]); MULADD(at[27], at[124]); MULADD(at[28], at[123]); MULADD(at[29], at[122]); MULADD(at[30], at[121]); MULADD(at[31], at[120]); MULADD(at[32], at[119]); MULADD(at[33], at[118]); MULADD(at[34], at[117]); MULADD(at[35], at[116]); MULADD(at[36], at[115]); MULADD(at[37], at[114]); MULADD(at[38], at[113]); MULADD(at[39], at[112]); MULADD(at[40], at[111]); MULADD(at[41], at[110]); MULADD(at[42], at[109]); MULADD(at[43], at[108]); MULADD(at[44], at[107]); MULADD(at[45], at[106]); MULADD(at[46], at[105]); MULADD(at[47], at[104]); MULADD(at[48], at[103]); MULADD(at[49], at[102]); MULADD(at[50], at[101]); MULADD(at[51], at[100]); MULADD(at[52], at[99]); MULADD(at[53], at[98]); MULADD(at[54], at[97]); MULADD(at[55], at[96]); MULADD(at[56], at[95]); MULADD(at[57], at[94]); MULADD(at[58], at[93]); MULADD(at[59], at[92]); MULADD(at[60], at[91]); MULADD(at[61], at[90]); MULADD(at[62], at[89]); MULADD(at[63], at[88]); + COMBA_STORE(C->dp[87]); + /* 88 */ + COMBA_FORWARD; + MULADD(at[25], at[127]); MULADD(at[26], at[126]); MULADD(at[27], at[125]); MULADD(at[28], at[124]); MULADD(at[29], at[123]); MULADD(at[30], at[122]); MULADD(at[31], at[121]); MULADD(at[32], at[120]); MULADD(at[33], at[119]); MULADD(at[34], at[118]); MULADD(at[35], at[117]); MULADD(at[36], at[116]); MULADD(at[37], at[115]); MULADD(at[38], at[114]); MULADD(at[39], at[113]); MULADD(at[40], at[112]); MULADD(at[41], at[111]); MULADD(at[42], at[110]); MULADD(at[43], at[109]); MULADD(at[44], at[108]); MULADD(at[45], at[107]); MULADD(at[46], at[106]); MULADD(at[47], at[105]); MULADD(at[48], at[104]); MULADD(at[49], at[103]); MULADD(at[50], at[102]); MULADD(at[51], at[101]); MULADD(at[52], at[100]); MULADD(at[53], at[99]); MULADD(at[54], at[98]); MULADD(at[55], at[97]); MULADD(at[56], at[96]); MULADD(at[57], at[95]); MULADD(at[58], at[94]); MULADD(at[59], at[93]); MULADD(at[60], at[92]); MULADD(at[61], at[91]); MULADD(at[62], at[90]); MULADD(at[63], at[89]); + COMBA_STORE(C->dp[88]); + /* 89 */ + COMBA_FORWARD; + MULADD(at[26], at[127]); MULADD(at[27], at[126]); MULADD(at[28], at[125]); MULADD(at[29], at[124]); MULADD(at[30], at[123]); MULADD(at[31], at[122]); MULADD(at[32], at[121]); MULADD(at[33], at[120]); MULADD(at[34], at[119]); MULADD(at[35], at[118]); MULADD(at[36], at[117]); MULADD(at[37], at[116]); MULADD(at[38], at[115]); MULADD(at[39], at[114]); MULADD(at[40], at[113]); MULADD(at[41], at[112]); MULADD(at[42], at[111]); MULADD(at[43], at[110]); MULADD(at[44], at[109]); MULADD(at[45], at[108]); MULADD(at[46], at[107]); MULADD(at[47], at[106]); MULADD(at[48], at[105]); MULADD(at[49], at[104]); MULADD(at[50], at[103]); MULADD(at[51], at[102]); MULADD(at[52], at[101]); MULADD(at[53], at[100]); MULADD(at[54], at[99]); MULADD(at[55], at[98]); MULADD(at[56], at[97]); MULADD(at[57], at[96]); MULADD(at[58], at[95]); MULADD(at[59], at[94]); MULADD(at[60], at[93]); MULADD(at[61], at[92]); MULADD(at[62], at[91]); MULADD(at[63], at[90]); + COMBA_STORE(C->dp[89]); + /* 90 */ + COMBA_FORWARD; + MULADD(at[27], at[127]); MULADD(at[28], at[126]); MULADD(at[29], at[125]); MULADD(at[30], at[124]); MULADD(at[31], at[123]); MULADD(at[32], at[122]); MULADD(at[33], at[121]); MULADD(at[34], at[120]); MULADD(at[35], at[119]); MULADD(at[36], at[118]); MULADD(at[37], at[117]); MULADD(at[38], at[116]); MULADD(at[39], at[115]); MULADD(at[40], at[114]); MULADD(at[41], at[113]); MULADD(at[42], at[112]); MULADD(at[43], at[111]); MULADD(at[44], at[110]); MULADD(at[45], at[109]); MULADD(at[46], at[108]); MULADD(at[47], at[107]); MULADD(at[48], at[106]); MULADD(at[49], at[105]); MULADD(at[50], at[104]); MULADD(at[51], at[103]); MULADD(at[52], at[102]); MULADD(at[53], at[101]); MULADD(at[54], at[100]); MULADD(at[55], at[99]); MULADD(at[56], at[98]); MULADD(at[57], at[97]); MULADD(at[58], at[96]); MULADD(at[59], at[95]); MULADD(at[60], at[94]); MULADD(at[61], at[93]); MULADD(at[62], at[92]); MULADD(at[63], at[91]); + COMBA_STORE(C->dp[90]); + /* 91 */ + COMBA_FORWARD; + MULADD(at[28], at[127]); MULADD(at[29], at[126]); MULADD(at[30], at[125]); MULADD(at[31], at[124]); MULADD(at[32], at[123]); MULADD(at[33], at[122]); MULADD(at[34], at[121]); MULADD(at[35], at[120]); MULADD(at[36], at[119]); MULADD(at[37], at[118]); MULADD(at[38], at[117]); MULADD(at[39], at[116]); MULADD(at[40], at[115]); MULADD(at[41], at[114]); MULADD(at[42], at[113]); MULADD(at[43], at[112]); MULADD(at[44], at[111]); MULADD(at[45], at[110]); MULADD(at[46], at[109]); MULADD(at[47], at[108]); MULADD(at[48], at[107]); MULADD(at[49], at[106]); MULADD(at[50], at[105]); MULADD(at[51], at[104]); MULADD(at[52], at[103]); MULADD(at[53], at[102]); MULADD(at[54], at[101]); MULADD(at[55], at[100]); MULADD(at[56], at[99]); MULADD(at[57], at[98]); MULADD(at[58], at[97]); MULADD(at[59], at[96]); MULADD(at[60], at[95]); MULADD(at[61], at[94]); MULADD(at[62], at[93]); MULADD(at[63], at[92]); + COMBA_STORE(C->dp[91]); + /* 92 */ + COMBA_FORWARD; + MULADD(at[29], at[127]); MULADD(at[30], at[126]); MULADD(at[31], at[125]); MULADD(at[32], at[124]); MULADD(at[33], at[123]); MULADD(at[34], at[122]); MULADD(at[35], at[121]); MULADD(at[36], at[120]); MULADD(at[37], at[119]); MULADD(at[38], at[118]); MULADD(at[39], at[117]); MULADD(at[40], at[116]); MULADD(at[41], at[115]); MULADD(at[42], at[114]); MULADD(at[43], at[113]); MULADD(at[44], at[112]); MULADD(at[45], at[111]); MULADD(at[46], at[110]); MULADD(at[47], at[109]); MULADD(at[48], at[108]); MULADD(at[49], at[107]); MULADD(at[50], at[106]); MULADD(at[51], at[105]); MULADD(at[52], at[104]); MULADD(at[53], at[103]); MULADD(at[54], at[102]); MULADD(at[55], at[101]); MULADD(at[56], at[100]); MULADD(at[57], at[99]); MULADD(at[58], at[98]); MULADD(at[59], at[97]); MULADD(at[60], at[96]); MULADD(at[61], at[95]); MULADD(at[62], at[94]); MULADD(at[63], at[93]); + COMBA_STORE(C->dp[92]); + /* 93 */ + COMBA_FORWARD; + MULADD(at[30], at[127]); MULADD(at[31], at[126]); MULADD(at[32], at[125]); MULADD(at[33], at[124]); MULADD(at[34], at[123]); MULADD(at[35], at[122]); MULADD(at[36], at[121]); MULADD(at[37], at[120]); MULADD(at[38], at[119]); MULADD(at[39], at[118]); MULADD(at[40], at[117]); MULADD(at[41], at[116]); MULADD(at[42], at[115]); MULADD(at[43], at[114]); MULADD(at[44], at[113]); MULADD(at[45], at[112]); MULADD(at[46], at[111]); MULADD(at[47], at[110]); MULADD(at[48], at[109]); MULADD(at[49], at[108]); MULADD(at[50], at[107]); MULADD(at[51], at[106]); MULADD(at[52], at[105]); MULADD(at[53], at[104]); MULADD(at[54], at[103]); MULADD(at[55], at[102]); MULADD(at[56], at[101]); MULADD(at[57], at[100]); MULADD(at[58], at[99]); MULADD(at[59], at[98]); MULADD(at[60], at[97]); MULADD(at[61], at[96]); MULADD(at[62], at[95]); MULADD(at[63], at[94]); + COMBA_STORE(C->dp[93]); + /* 94 */ + COMBA_FORWARD; + MULADD(at[31], at[127]); MULADD(at[32], at[126]); MULADD(at[33], at[125]); MULADD(at[34], at[124]); MULADD(at[35], at[123]); MULADD(at[36], at[122]); MULADD(at[37], at[121]); MULADD(at[38], at[120]); MULADD(at[39], at[119]); MULADD(at[40], at[118]); MULADD(at[41], at[117]); MULADD(at[42], at[116]); MULADD(at[43], at[115]); MULADD(at[44], at[114]); MULADD(at[45], at[113]); MULADD(at[46], at[112]); MULADD(at[47], at[111]); MULADD(at[48], at[110]); MULADD(at[49], at[109]); MULADD(at[50], at[108]); MULADD(at[51], at[107]); MULADD(at[52], at[106]); MULADD(at[53], at[105]); MULADD(at[54], at[104]); MULADD(at[55], at[103]); MULADD(at[56], at[102]); MULADD(at[57], at[101]); MULADD(at[58], at[100]); MULADD(at[59], at[99]); MULADD(at[60], at[98]); MULADD(at[61], at[97]); MULADD(at[62], at[96]); MULADD(at[63], at[95]); + COMBA_STORE(C->dp[94]); + /* 95 */ + COMBA_FORWARD; + MULADD(at[32], at[127]); MULADD(at[33], at[126]); MULADD(at[34], at[125]); MULADD(at[35], at[124]); MULADD(at[36], at[123]); MULADD(at[37], at[122]); MULADD(at[38], at[121]); MULADD(at[39], at[120]); MULADD(at[40], at[119]); MULADD(at[41], at[118]); MULADD(at[42], at[117]); MULADD(at[43], at[116]); MULADD(at[44], at[115]); MULADD(at[45], at[114]); MULADD(at[46], at[113]); MULADD(at[47], at[112]); MULADD(at[48], at[111]); MULADD(at[49], at[110]); MULADD(at[50], at[109]); MULADD(at[51], at[108]); MULADD(at[52], at[107]); MULADD(at[53], at[106]); MULADD(at[54], at[105]); MULADD(at[55], at[104]); MULADD(at[56], at[103]); MULADD(at[57], at[102]); MULADD(at[58], at[101]); MULADD(at[59], at[100]); MULADD(at[60], at[99]); MULADD(at[61], at[98]); MULADD(at[62], at[97]); MULADD(at[63], at[96]); + COMBA_STORE(C->dp[95]); + /* 96 */ + COMBA_FORWARD; + MULADD(at[33], at[127]); MULADD(at[34], at[126]); MULADD(at[35], at[125]); MULADD(at[36], at[124]); MULADD(at[37], at[123]); MULADD(at[38], at[122]); MULADD(at[39], at[121]); MULADD(at[40], at[120]); MULADD(at[41], at[119]); MULADD(at[42], at[118]); MULADD(at[43], at[117]); MULADD(at[44], at[116]); MULADD(at[45], at[115]); MULADD(at[46], at[114]); MULADD(at[47], at[113]); MULADD(at[48], at[112]); MULADD(at[49], at[111]); MULADD(at[50], at[110]); MULADD(at[51], at[109]); MULADD(at[52], at[108]); MULADD(at[53], at[107]); MULADD(at[54], at[106]); MULADD(at[55], at[105]); MULADD(at[56], at[104]); MULADD(at[57], at[103]); MULADD(at[58], at[102]); MULADD(at[59], at[101]); MULADD(at[60], at[100]); MULADD(at[61], at[99]); MULADD(at[62], at[98]); MULADD(at[63], at[97]); + COMBA_STORE(C->dp[96]); + /* 97 */ + COMBA_FORWARD; + MULADD(at[34], at[127]); MULADD(at[35], at[126]); MULADD(at[36], at[125]); MULADD(at[37], at[124]); MULADD(at[38], at[123]); MULADD(at[39], at[122]); MULADD(at[40], at[121]); MULADD(at[41], at[120]); MULADD(at[42], at[119]); MULADD(at[43], at[118]); MULADD(at[44], at[117]); MULADD(at[45], at[116]); MULADD(at[46], at[115]); MULADD(at[47], at[114]); MULADD(at[48], at[113]); MULADD(at[49], at[112]); MULADD(at[50], at[111]); MULADD(at[51], at[110]); MULADD(at[52], at[109]); MULADD(at[53], at[108]); MULADD(at[54], at[107]); MULADD(at[55], at[106]); MULADD(at[56], at[105]); MULADD(at[57], at[104]); MULADD(at[58], at[103]); MULADD(at[59], at[102]); MULADD(at[60], at[101]); MULADD(at[61], at[100]); MULADD(at[62], at[99]); MULADD(at[63], at[98]); + COMBA_STORE(C->dp[97]); + /* 98 */ + COMBA_FORWARD; + MULADD(at[35], at[127]); MULADD(at[36], at[126]); MULADD(at[37], at[125]); MULADD(at[38], at[124]); MULADD(at[39], at[123]); MULADD(at[40], at[122]); MULADD(at[41], at[121]); MULADD(at[42], at[120]); MULADD(at[43], at[119]); MULADD(at[44], at[118]); MULADD(at[45], at[117]); MULADD(at[46], at[116]); MULADD(at[47], at[115]); MULADD(at[48], at[114]); MULADD(at[49], at[113]); MULADD(at[50], at[112]); MULADD(at[51], at[111]); MULADD(at[52], at[110]); MULADD(at[53], at[109]); MULADD(at[54], at[108]); MULADD(at[55], at[107]); MULADD(at[56], at[106]); MULADD(at[57], at[105]); MULADD(at[58], at[104]); MULADD(at[59], at[103]); MULADD(at[60], at[102]); MULADD(at[61], at[101]); MULADD(at[62], at[100]); MULADD(at[63], at[99]); + COMBA_STORE(C->dp[98]); + /* 99 */ + COMBA_FORWARD; + MULADD(at[36], at[127]); MULADD(at[37], at[126]); MULADD(at[38], at[125]); MULADD(at[39], at[124]); MULADD(at[40], at[123]); MULADD(at[41], at[122]); MULADD(at[42], at[121]); MULADD(at[43], at[120]); MULADD(at[44], at[119]); MULADD(at[45], at[118]); MULADD(at[46], at[117]); MULADD(at[47], at[116]); MULADD(at[48], at[115]); MULADD(at[49], at[114]); MULADD(at[50], at[113]); MULADD(at[51], at[112]); MULADD(at[52], at[111]); MULADD(at[53], at[110]); MULADD(at[54], at[109]); MULADD(at[55], at[108]); MULADD(at[56], at[107]); MULADD(at[57], at[106]); MULADD(at[58], at[105]); MULADD(at[59], at[104]); MULADD(at[60], at[103]); MULADD(at[61], at[102]); MULADD(at[62], at[101]); MULADD(at[63], at[100]); + COMBA_STORE(C->dp[99]); + /* 100 */ + COMBA_FORWARD; + MULADD(at[37], at[127]); MULADD(at[38], at[126]); MULADD(at[39], at[125]); MULADD(at[40], at[124]); MULADD(at[41], at[123]); MULADD(at[42], at[122]); MULADD(at[43], at[121]); MULADD(at[44], at[120]); MULADD(at[45], at[119]); MULADD(at[46], at[118]); MULADD(at[47], at[117]); MULADD(at[48], at[116]); MULADD(at[49], at[115]); MULADD(at[50], at[114]); MULADD(at[51], at[113]); MULADD(at[52], at[112]); MULADD(at[53], at[111]); MULADD(at[54], at[110]); MULADD(at[55], at[109]); MULADD(at[56], at[108]); MULADD(at[57], at[107]); MULADD(at[58], at[106]); MULADD(at[59], at[105]); MULADD(at[60], at[104]); MULADD(at[61], at[103]); MULADD(at[62], at[102]); MULADD(at[63], at[101]); + COMBA_STORE(C->dp[100]); + /* 101 */ + COMBA_FORWARD; + MULADD(at[38], at[127]); MULADD(at[39], at[126]); MULADD(at[40], at[125]); MULADD(at[41], at[124]); MULADD(at[42], at[123]); MULADD(at[43], at[122]); MULADD(at[44], at[121]); MULADD(at[45], at[120]); MULADD(at[46], at[119]); MULADD(at[47], at[118]); MULADD(at[48], at[117]); MULADD(at[49], at[116]); MULADD(at[50], at[115]); MULADD(at[51], at[114]); MULADD(at[52], at[113]); MULADD(at[53], at[112]); MULADD(at[54], at[111]); MULADD(at[55], at[110]); MULADD(at[56], at[109]); MULADD(at[57], at[108]); MULADD(at[58], at[107]); MULADD(at[59], at[106]); MULADD(at[60], at[105]); MULADD(at[61], at[104]); MULADD(at[62], at[103]); MULADD(at[63], at[102]); + COMBA_STORE(C->dp[101]); + /* 102 */ + COMBA_FORWARD; + MULADD(at[39], at[127]); MULADD(at[40], at[126]); MULADD(at[41], at[125]); MULADD(at[42], at[124]); MULADD(at[43], at[123]); MULADD(at[44], at[122]); MULADD(at[45], at[121]); MULADD(at[46], at[120]); MULADD(at[47], at[119]); MULADD(at[48], at[118]); MULADD(at[49], at[117]); MULADD(at[50], at[116]); MULADD(at[51], at[115]); MULADD(at[52], at[114]); MULADD(at[53], at[113]); MULADD(at[54], at[112]); MULADD(at[55], at[111]); MULADD(at[56], at[110]); MULADD(at[57], at[109]); MULADD(at[58], at[108]); MULADD(at[59], at[107]); MULADD(at[60], at[106]); MULADD(at[61], at[105]); MULADD(at[62], at[104]); MULADD(at[63], at[103]); + COMBA_STORE(C->dp[102]); + /* 103 */ + COMBA_FORWARD; + MULADD(at[40], at[127]); MULADD(at[41], at[126]); MULADD(at[42], at[125]); MULADD(at[43], at[124]); MULADD(at[44], at[123]); MULADD(at[45], at[122]); MULADD(at[46], at[121]); MULADD(at[47], at[120]); MULADD(at[48], at[119]); MULADD(at[49], at[118]); MULADD(at[50], at[117]); MULADD(at[51], at[116]); MULADD(at[52], at[115]); MULADD(at[53], at[114]); MULADD(at[54], at[113]); MULADD(at[55], at[112]); MULADD(at[56], at[111]); MULADD(at[57], at[110]); MULADD(at[58], at[109]); MULADD(at[59], at[108]); MULADD(at[60], at[107]); MULADD(at[61], at[106]); MULADD(at[62], at[105]); MULADD(at[63], at[104]); + COMBA_STORE(C->dp[103]); + /* 104 */ + COMBA_FORWARD; + MULADD(at[41], at[127]); MULADD(at[42], at[126]); MULADD(at[43], at[125]); MULADD(at[44], at[124]); MULADD(at[45], at[123]); MULADD(at[46], at[122]); MULADD(at[47], at[121]); MULADD(at[48], at[120]); MULADD(at[49], at[119]); MULADD(at[50], at[118]); MULADD(at[51], at[117]); MULADD(at[52], at[116]); MULADD(at[53], at[115]); MULADD(at[54], at[114]); MULADD(at[55], at[113]); MULADD(at[56], at[112]); MULADD(at[57], at[111]); MULADD(at[58], at[110]); MULADD(at[59], at[109]); MULADD(at[60], at[108]); MULADD(at[61], at[107]); MULADD(at[62], at[106]); MULADD(at[63], at[105]); + COMBA_STORE(C->dp[104]); + /* 105 */ + COMBA_FORWARD; + MULADD(at[42], at[127]); MULADD(at[43], at[126]); MULADD(at[44], at[125]); MULADD(at[45], at[124]); MULADD(at[46], at[123]); MULADD(at[47], at[122]); MULADD(at[48], at[121]); MULADD(at[49], at[120]); MULADD(at[50], at[119]); MULADD(at[51], at[118]); MULADD(at[52], at[117]); MULADD(at[53], at[116]); MULADD(at[54], at[115]); MULADD(at[55], at[114]); MULADD(at[56], at[113]); MULADD(at[57], at[112]); MULADD(at[58], at[111]); MULADD(at[59], at[110]); MULADD(at[60], at[109]); MULADD(at[61], at[108]); MULADD(at[62], at[107]); MULADD(at[63], at[106]); + COMBA_STORE(C->dp[105]); + /* 106 */ + COMBA_FORWARD; + MULADD(at[43], at[127]); MULADD(at[44], at[126]); MULADD(at[45], at[125]); MULADD(at[46], at[124]); MULADD(at[47], at[123]); MULADD(at[48], at[122]); MULADD(at[49], at[121]); MULADD(at[50], at[120]); MULADD(at[51], at[119]); MULADD(at[52], at[118]); MULADD(at[53], at[117]); MULADD(at[54], at[116]); MULADD(at[55], at[115]); MULADD(at[56], at[114]); MULADD(at[57], at[113]); MULADD(at[58], at[112]); MULADD(at[59], at[111]); MULADD(at[60], at[110]); MULADD(at[61], at[109]); MULADD(at[62], at[108]); MULADD(at[63], at[107]); + COMBA_STORE(C->dp[106]); + /* 107 */ + COMBA_FORWARD; + MULADD(at[44], at[127]); MULADD(at[45], at[126]); MULADD(at[46], at[125]); MULADD(at[47], at[124]); MULADD(at[48], at[123]); MULADD(at[49], at[122]); MULADD(at[50], at[121]); MULADD(at[51], at[120]); MULADD(at[52], at[119]); MULADD(at[53], at[118]); MULADD(at[54], at[117]); MULADD(at[55], at[116]); MULADD(at[56], at[115]); MULADD(at[57], at[114]); MULADD(at[58], at[113]); MULADD(at[59], at[112]); MULADD(at[60], at[111]); MULADD(at[61], at[110]); MULADD(at[62], at[109]); MULADD(at[63], at[108]); + COMBA_STORE(C->dp[107]); + /* 108 */ + COMBA_FORWARD; + MULADD(at[45], at[127]); MULADD(at[46], at[126]); MULADD(at[47], at[125]); MULADD(at[48], at[124]); MULADD(at[49], at[123]); MULADD(at[50], at[122]); MULADD(at[51], at[121]); MULADD(at[52], at[120]); MULADD(at[53], at[119]); MULADD(at[54], at[118]); MULADD(at[55], at[117]); MULADD(at[56], at[116]); MULADD(at[57], at[115]); MULADD(at[58], at[114]); MULADD(at[59], at[113]); MULADD(at[60], at[112]); MULADD(at[61], at[111]); MULADD(at[62], at[110]); MULADD(at[63], at[109]); + COMBA_STORE(C->dp[108]); + /* 109 */ + COMBA_FORWARD; + MULADD(at[46], at[127]); MULADD(at[47], at[126]); MULADD(at[48], at[125]); MULADD(at[49], at[124]); MULADD(at[50], at[123]); MULADD(at[51], at[122]); MULADD(at[52], at[121]); MULADD(at[53], at[120]); MULADD(at[54], at[119]); MULADD(at[55], at[118]); MULADD(at[56], at[117]); MULADD(at[57], at[116]); MULADD(at[58], at[115]); MULADD(at[59], at[114]); MULADD(at[60], at[113]); MULADD(at[61], at[112]); MULADD(at[62], at[111]); MULADD(at[63], at[110]); + COMBA_STORE(C->dp[109]); + /* 110 */ + COMBA_FORWARD; + MULADD(at[47], at[127]); MULADD(at[48], at[126]); MULADD(at[49], at[125]); MULADD(at[50], at[124]); MULADD(at[51], at[123]); MULADD(at[52], at[122]); MULADD(at[53], at[121]); MULADD(at[54], at[120]); MULADD(at[55], at[119]); MULADD(at[56], at[118]); MULADD(at[57], at[117]); MULADD(at[58], at[116]); MULADD(at[59], at[115]); MULADD(at[60], at[114]); MULADD(at[61], at[113]); MULADD(at[62], at[112]); MULADD(at[63], at[111]); + COMBA_STORE(C->dp[110]); + /* 111 */ + COMBA_FORWARD; + MULADD(at[48], at[127]); MULADD(at[49], at[126]); MULADD(at[50], at[125]); MULADD(at[51], at[124]); MULADD(at[52], at[123]); MULADD(at[53], at[122]); MULADD(at[54], at[121]); MULADD(at[55], at[120]); MULADD(at[56], at[119]); MULADD(at[57], at[118]); MULADD(at[58], at[117]); MULADD(at[59], at[116]); MULADD(at[60], at[115]); MULADD(at[61], at[114]); MULADD(at[62], at[113]); MULADD(at[63], at[112]); + COMBA_STORE(C->dp[111]); + /* 112 */ + COMBA_FORWARD; + MULADD(at[49], at[127]); MULADD(at[50], at[126]); MULADD(at[51], at[125]); MULADD(at[52], at[124]); MULADD(at[53], at[123]); MULADD(at[54], at[122]); MULADD(at[55], at[121]); MULADD(at[56], at[120]); MULADD(at[57], at[119]); MULADD(at[58], at[118]); MULADD(at[59], at[117]); MULADD(at[60], at[116]); MULADD(at[61], at[115]); MULADD(at[62], at[114]); MULADD(at[63], at[113]); + COMBA_STORE(C->dp[112]); + /* 113 */ + COMBA_FORWARD; + MULADD(at[50], at[127]); MULADD(at[51], at[126]); MULADD(at[52], at[125]); MULADD(at[53], at[124]); MULADD(at[54], at[123]); MULADD(at[55], at[122]); MULADD(at[56], at[121]); MULADD(at[57], at[120]); MULADD(at[58], at[119]); MULADD(at[59], at[118]); MULADD(at[60], at[117]); MULADD(at[61], at[116]); MULADD(at[62], at[115]); MULADD(at[63], at[114]); + COMBA_STORE(C->dp[113]); + /* 114 */ + COMBA_FORWARD; + MULADD(at[51], at[127]); MULADD(at[52], at[126]); MULADD(at[53], at[125]); MULADD(at[54], at[124]); MULADD(at[55], at[123]); MULADD(at[56], at[122]); MULADD(at[57], at[121]); MULADD(at[58], at[120]); MULADD(at[59], at[119]); MULADD(at[60], at[118]); MULADD(at[61], at[117]); MULADD(at[62], at[116]); MULADD(at[63], at[115]); + COMBA_STORE(C->dp[114]); + /* 115 */ + COMBA_FORWARD; + MULADD(at[52], at[127]); MULADD(at[53], at[126]); MULADD(at[54], at[125]); MULADD(at[55], at[124]); MULADD(at[56], at[123]); MULADD(at[57], at[122]); MULADD(at[58], at[121]); MULADD(at[59], at[120]); MULADD(at[60], at[119]); MULADD(at[61], at[118]); MULADD(at[62], at[117]); MULADD(at[63], at[116]); + COMBA_STORE(C->dp[115]); + /* 116 */ + COMBA_FORWARD; + MULADD(at[53], at[127]); MULADD(at[54], at[126]); MULADD(at[55], at[125]); MULADD(at[56], at[124]); MULADD(at[57], at[123]); MULADD(at[58], at[122]); MULADD(at[59], at[121]); MULADD(at[60], at[120]); MULADD(at[61], at[119]); MULADD(at[62], at[118]); MULADD(at[63], at[117]); + COMBA_STORE(C->dp[116]); + /* 117 */ + COMBA_FORWARD; + MULADD(at[54], at[127]); MULADD(at[55], at[126]); MULADD(at[56], at[125]); MULADD(at[57], at[124]); MULADD(at[58], at[123]); MULADD(at[59], at[122]); MULADD(at[60], at[121]); MULADD(at[61], at[120]); MULADD(at[62], at[119]); MULADD(at[63], at[118]); + COMBA_STORE(C->dp[117]); + /* 118 */ + COMBA_FORWARD; + MULADD(at[55], at[127]); MULADD(at[56], at[126]); MULADD(at[57], at[125]); MULADD(at[58], at[124]); MULADD(at[59], at[123]); MULADD(at[60], at[122]); MULADD(at[61], at[121]); MULADD(at[62], at[120]); MULADD(at[63], at[119]); + COMBA_STORE(C->dp[118]); + /* 119 */ + COMBA_FORWARD; + MULADD(at[56], at[127]); MULADD(at[57], at[126]); MULADD(at[58], at[125]); MULADD(at[59], at[124]); MULADD(at[60], at[123]); MULADD(at[61], at[122]); MULADD(at[62], at[121]); MULADD(at[63], at[120]); + COMBA_STORE(C->dp[119]); + /* 120 */ + COMBA_FORWARD; + MULADD(at[57], at[127]); MULADD(at[58], at[126]); MULADD(at[59], at[125]); MULADD(at[60], at[124]); MULADD(at[61], at[123]); MULADD(at[62], at[122]); MULADD(at[63], at[121]); + COMBA_STORE(C->dp[120]); + /* 121 */ + COMBA_FORWARD; + MULADD(at[58], at[127]); MULADD(at[59], at[126]); MULADD(at[60], at[125]); MULADD(at[61], at[124]); MULADD(at[62], at[123]); MULADD(at[63], at[122]); + COMBA_STORE(C->dp[121]); + /* 122 */ + COMBA_FORWARD; + MULADD(at[59], at[127]); MULADD(at[60], at[126]); MULADD(at[61], at[125]); MULADD(at[62], at[124]); MULADD(at[63], at[123]); + COMBA_STORE(C->dp[122]); + /* 123 */ + COMBA_FORWARD; + MULADD(at[60], at[127]); MULADD(at[61], at[126]); MULADD(at[62], at[125]); MULADD(at[63], at[124]); + COMBA_STORE(C->dp[123]); + /* 124 */ + COMBA_FORWARD; + MULADD(at[61], at[127]); MULADD(at[62], at[126]); MULADD(at[63], at[125]); + COMBA_STORE(C->dp[124]); + /* 125 */ + COMBA_FORWARD; + MULADD(at[62], at[127]); MULADD(at[63], at[126]); + COMBA_STORE(C->dp[125]); + /* 126 */ + COMBA_FORWARD; + MULADD(at[63], at[127]); + COMBA_STORE(C->dp[126]); + COMBA_STORE2(C->dp[127]); + C->used = 128; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_7.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_7.i new file mode 100644 index 00000000..15486c5c --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_7.i @@ -0,0 +1,68 @@ +#ifdef TFM_MUL7 +void fp_mul_comba7(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[14]; + + memcpy(at, A->dp, 7 * sizeof(fp_digit)); + memcpy(at+7, B->dp, 7 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[7]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[8]); MULADD(at[1], at[7]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); MULADD(at[5], at[7]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); MULADD(at[6], at[7]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[5], at[13]); MULADD(at[6], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[6], at[13]); + COMBA_STORE(C->dp[12]); + COMBA_STORE2(C->dp[13]); + C->used = 14; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_8.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_8.i new file mode 100644 index 00000000..acd0c6a5 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_8.i @@ -0,0 +1,76 @@ +#ifdef TFM_MUL8 +void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[16]; + + memcpy(at, A->dp, 8 * sizeof(fp_digit)); + memcpy(at+8, B->dp, 8 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[8]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); MULADD(at[7], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[6], at[15]); MULADD(at[7], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[7], at[15]); + COMBA_STORE(C->dp[14]); + COMBA_STORE2(C->dp[15]); + C->used = 16; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_9.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_9.i new file mode 100644 index 00000000..902276df --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_9.i @@ -0,0 +1,84 @@ +#ifdef TFM_MUL9 +void fp_mul_comba9(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[18]; + + memcpy(at, A->dp, 9 * sizeof(fp_digit)); + memcpy(at+9, B->dp, 9 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[9]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); MULADD(at[8], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); MULADD(at[8], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); MULADD(at[8], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[7], at[17]); MULADD(at[8], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[8], at[17]); + COMBA_STORE(C->dp[16]); + COMBA_STORE2(C->dp[17]); + C->used = 18; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; +} +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_small_set.i b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_small_set.i new file mode 100644 index 00000000..75c07a66 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_mul_comba_small_set.i @@ -0,0 +1,1225 @@ +#if defined(TFM_SMALL_SET) +void fp_mul_comba_small(fp_int *A, fp_int *B, fp_int *C) +{ + fp_digit c0, c1, c2, at[32]; + switch (MAX(A->used, B->used)) { + + case 1: + memcpy(at, A->dp, 1 * sizeof(fp_digit)); + memcpy(at+1, B->dp, 1 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[1]); + COMBA_STORE(C->dp[0]); + COMBA_STORE2(C->dp[1]); + C->used = 2; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 2: + memcpy(at, A->dp, 2 * sizeof(fp_digit)); + memcpy(at+2, B->dp, 2 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[2]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[3]); MULADD(at[1], at[2]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[1], at[3]); + COMBA_STORE(C->dp[2]); + COMBA_STORE2(C->dp[3]); + C->used = 4; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 3: + memcpy(at, A->dp, 3 * sizeof(fp_digit)); + memcpy(at+3, B->dp, 3 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[3]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[4]); MULADD(at[1], at[3]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[5]); MULADD(at[1], at[4]); MULADD(at[2], at[3]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[1], at[5]); MULADD(at[2], at[4]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[2], at[5]); + COMBA_STORE(C->dp[4]); + COMBA_STORE2(C->dp[5]); + C->used = 6; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 4: + memcpy(at, A->dp, 4 * sizeof(fp_digit)); + memcpy(at+4, B->dp, 4 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[4]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[5]); MULADD(at[1], at[4]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[2], at[7]); MULADD(at[3], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[3], at[7]); + COMBA_STORE(C->dp[6]); + COMBA_STORE2(C->dp[7]); + C->used = 8; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 5: + memcpy(at, A->dp, 5 * sizeof(fp_digit)); + memcpy(at+5, B->dp, 5 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[5]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[6]); MULADD(at[1], at[5]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[8]); MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); MULADD(at[3], at[6]); MULADD(at[4], at[5]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); MULADD(at[4], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[3], at[9]); MULADD(at[4], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[4], at[9]); + COMBA_STORE(C->dp[8]); + COMBA_STORE2(C->dp[9]); + C->used = 10; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 6: + memcpy(at, A->dp, 6 * sizeof(fp_digit)); + memcpy(at+6, B->dp, 6 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[6]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[7]); MULADD(at[1], at[6]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[8]); MULADD(at[1], at[7]); MULADD(at[2], at[6]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); MULADD(at[3], at[6]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); MULADD(at[4], at[6]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); MULADD(at[5], at[6]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); MULADD(at[5], at[7]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[4], at[11]); MULADD(at[5], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[5], at[11]); + COMBA_STORE(C->dp[10]); + COMBA_STORE2(C->dp[11]); + C->used = 12; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 7: + memcpy(at, A->dp, 7 * sizeof(fp_digit)); + memcpy(at+7, B->dp, 7 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[7]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[8]); MULADD(at[1], at[7]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); MULADD(at[5], at[7]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); MULADD(at[6], at[7]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[5], at[13]); MULADD(at[6], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[6], at[13]); + COMBA_STORE(C->dp[12]); + COMBA_STORE2(C->dp[13]); + C->used = 14; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 8: + memcpy(at, A->dp, 8 * sizeof(fp_digit)); + memcpy(at+8, B->dp, 8 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[8]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[9]); MULADD(at[1], at[8]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); MULADD(at[7], at[8]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[6], at[15]); MULADD(at[7], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[7], at[15]); + COMBA_STORE(C->dp[14]); + COMBA_STORE2(C->dp[15]); + C->used = 16; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 9: + memcpy(at, A->dp, 9 * sizeof(fp_digit)); + memcpy(at+9, B->dp, 9 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[9]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[10]); MULADD(at[1], at[9]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); MULADD(at[8], at[9]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); MULADD(at[8], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); MULADD(at[8], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[7], at[17]); MULADD(at[8], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[8], at[17]); + COMBA_STORE(C->dp[16]); + COMBA_STORE2(C->dp[17]); + C->used = 18; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 10: + memcpy(at, A->dp, 10 * sizeof(fp_digit)); + memcpy(at+10, B->dp, 10 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[10]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[11]); MULADD(at[1], at[10]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); MULADD(at[8], at[10]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); MULADD(at[8], at[11]); MULADD(at[9], at[10]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); MULADD(at[9], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); MULADD(at[9], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); MULADD(at[9], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[8], at[19]); MULADD(at[9], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[9], at[19]); + COMBA_STORE(C->dp[18]); + COMBA_STORE2(C->dp[19]); + C->used = 20; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 11: + memcpy(at, A->dp, 11 * sizeof(fp_digit)); + memcpy(at+11, B->dp, 11 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[11]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[12]); MULADD(at[1], at[11]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); MULADD(at[8], at[11]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); MULADD(at[9], at[11]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); MULADD(at[9], at[12]); MULADD(at[10], at[11]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); MULADD(at[9], at[13]); MULADD(at[10], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); MULADD(at[10], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); MULADD(at[10], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[9], at[21]); MULADD(at[10], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[10], at[21]); + COMBA_STORE(C->dp[20]); + COMBA_STORE2(C->dp[21]); + C->used = 22; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 12: + memcpy(at, A->dp, 12 * sizeof(fp_digit)); + memcpy(at+12, B->dp, 12 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[12]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[13]); MULADD(at[1], at[12]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); MULADD(at[8], at[12]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); MULADD(at[9], at[12]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); MULADD(at[9], at[13]); MULADD(at[10], at[12]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); MULADD(at[10], at[13]); MULADD(at[11], at[12]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); MULADD(at[10], at[14]); MULADD(at[11], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); MULADD(at[11], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); MULADD(at[11], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[10], at[23]); MULADD(at[11], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[11], at[23]); + COMBA_STORE(C->dp[22]); + COMBA_STORE2(C->dp[23]); + C->used = 24; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 13: + memcpy(at, A->dp, 13 * sizeof(fp_digit)); + memcpy(at+13, B->dp, 13 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[13]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[14]); MULADD(at[1], at[13]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); MULADD(at[8], at[13]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); MULADD(at[9], at[13]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); MULADD(at[10], at[13]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); MULADD(at[10], at[14]); MULADD(at[11], at[13]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); MULADD(at[11], at[14]); MULADD(at[12], at[13]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); MULADD(at[11], at[15]); MULADD(at[12], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); MULADD(at[12], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[11], at[25]); MULADD(at[12], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[12], at[25]); + COMBA_STORE(C->dp[24]); + COMBA_STORE2(C->dp[25]); + C->used = 26; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 14: + memcpy(at, A->dp, 14 * sizeof(fp_digit)); + memcpy(at+14, B->dp, 14 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[14]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[15]); MULADD(at[1], at[14]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); MULADD(at[2], at[14]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); MULADD(at[3], at[14]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); MULADD(at[4], at[14]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); MULADD(at[5], at[14]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); MULADD(at[6], at[14]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); MULADD(at[7], at[14]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); MULADD(at[8], at[14]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); MULADD(at[9], at[14]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); MULADD(at[10], at[14]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); MULADD(at[11], at[14]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); MULADD(at[11], at[15]); MULADD(at[12], at[14]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); MULADD(at[12], at[15]); MULADD(at[13], at[14]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); MULADD(at[13], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[12], at[27]); MULADD(at[13], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[13], at[27]); + COMBA_STORE(C->dp[26]); + COMBA_STORE2(C->dp[27]); + C->used = 28; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 15: + memcpy(at, A->dp, 15 * sizeof(fp_digit)); + memcpy(at+15, B->dp, 15 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[15]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[16]); MULADD(at[1], at[15]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); MULADD(at[2], at[15]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); MULADD(at[3], at[15]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); MULADD(at[4], at[15]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); MULADD(at[5], at[15]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); MULADD(at[6], at[15]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); MULADD(at[7], at[15]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); MULADD(at[8], at[15]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); MULADD(at[9], at[15]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); MULADD(at[10], at[15]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); MULADD(at[11], at[15]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); MULADD(at[12], at[15]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); MULADD(at[13], at[15]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]); MULADD(at[14], at[15]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[13], at[29]); MULADD(at[14], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[14], at[29]); + COMBA_STORE(C->dp[28]); + COMBA_STORE2(C->dp[29]); + C->used = 30; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + + case 16: + memcpy(at, A->dp, 16 * sizeof(fp_digit)); + memcpy(at+16, B->dp, 16 * sizeof(fp_digit)); + COMBA_START; + + COMBA_CLEAR; + /* 0 */ + MULADD(at[0], at[16]); + COMBA_STORE(C->dp[0]); + /* 1 */ + COMBA_FORWARD; + MULADD(at[0], at[17]); MULADD(at[1], at[16]); + COMBA_STORE(C->dp[1]); + /* 2 */ + COMBA_FORWARD; + MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); + COMBA_STORE(C->dp[2]); + /* 3 */ + COMBA_FORWARD; + MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); + COMBA_STORE(C->dp[3]); + /* 4 */ + COMBA_FORWARD; + MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); + COMBA_STORE(C->dp[4]); + /* 5 */ + COMBA_FORWARD; + MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); + COMBA_STORE(C->dp[5]); + /* 6 */ + COMBA_FORWARD; + MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); + COMBA_STORE(C->dp[6]); + /* 7 */ + COMBA_FORWARD; + MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); + COMBA_STORE(C->dp[7]); + /* 8 */ + COMBA_FORWARD; + MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); + COMBA_STORE(C->dp[8]); + /* 9 */ + COMBA_FORWARD; + MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); + COMBA_STORE(C->dp[9]); + /* 10 */ + COMBA_FORWARD; + MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); + COMBA_STORE(C->dp[10]); + /* 11 */ + COMBA_FORWARD; + MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); + COMBA_STORE(C->dp[11]); + /* 12 */ + COMBA_FORWARD; + MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); + COMBA_STORE(C->dp[12]); + /* 13 */ + COMBA_FORWARD; + MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]); + COMBA_STORE(C->dp[13]); + /* 14 */ + COMBA_FORWARD; + MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]); + COMBA_STORE(C->dp[14]); + /* 15 */ + COMBA_FORWARD; + MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]); + COMBA_STORE(C->dp[15]); + /* 16 */ + COMBA_FORWARD; + MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]); + COMBA_STORE(C->dp[16]); + /* 17 */ + COMBA_FORWARD; + MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]); + COMBA_STORE(C->dp[17]); + /* 18 */ + COMBA_FORWARD; + MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]); + COMBA_STORE(C->dp[18]); + /* 19 */ + COMBA_FORWARD; + MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]); + COMBA_STORE(C->dp[19]); + /* 20 */ + COMBA_FORWARD; + MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]); + COMBA_STORE(C->dp[20]); + /* 21 */ + COMBA_FORWARD; + MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]); + COMBA_STORE(C->dp[21]); + /* 22 */ + COMBA_FORWARD; + MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]); + COMBA_STORE(C->dp[22]); + /* 23 */ + COMBA_FORWARD; + MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); + COMBA_STORE(C->dp[23]); + /* 24 */ + COMBA_FORWARD; + MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); + COMBA_STORE(C->dp[24]); + /* 25 */ + COMBA_FORWARD; + MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); + COMBA_STORE(C->dp[25]); + /* 26 */ + COMBA_FORWARD; + MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); + COMBA_STORE(C->dp[26]); + /* 27 */ + COMBA_FORWARD; + MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); + COMBA_STORE(C->dp[27]); + /* 28 */ + COMBA_FORWARD; + MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); + COMBA_STORE(C->dp[28]); + /* 29 */ + COMBA_FORWARD; + MULADD(at[14], at[31]); MULADD(at[15], at[30]); + COMBA_STORE(C->dp[29]); + /* 30 */ + COMBA_FORWARD; + MULADD(at[15], at[31]); + COMBA_STORE(C->dp[30]); + COMBA_STORE2(C->dp[31]); + C->used = 32; + C->sign = A->sign ^ B->sign; + fp_clamp(C); + COMBA_FINI; + break; + } +} + +#endif diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_12.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_12.i new file mode 100644 index 00000000..95e82d77 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_12.i @@ -0,0 +1,135 @@ +#ifdef TFM_SQR12 +void fp_sqr_comba12(fp_int *A, fp_int *B) +{ + fp_digit *a, b[24], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADD2(a[7], a[11]); SQRADD2(a[8], a[10]); SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADD2(a[8], a[11]); SQRADD2(a[9], a[10]); + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADD2(a[9], a[11]); SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADD2(a[10], a[11]); + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + COMBA_STORE2(b[23]); + COMBA_FINI; + + B->used = 24; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 24 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_17.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_17.i new file mode 100644 index 00000000..0084d6c0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_17.i @@ -0,0 +1,185 @@ +#ifdef TFM_SQR17 +void fp_sqr_comba17(fp_int *A, fp_int *B) +{ + fp_digit *a, b[34], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADD2(a[12], a[16]); SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADD2(a[13], a[16]); SQRADD2(a[14], a[15]); + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADD2(a[14], a[16]); SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADD2(a[15], a[16]); + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + COMBA_STORE2(b[33]); + COMBA_FINI; + + B->used = 34; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 34 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_20.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_20.i new file mode 100644 index 00000000..5011ffeb --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_20.i @@ -0,0 +1,218 @@ +#ifdef TFM_SQR20 +void fp_sqr_comba20(fp_int *A, fp_int *B) +{ + fp_digit *a, b[40], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADD2(a[15], a[19]); SQRADD2(a[16], a[18]); SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADD2(a[16], a[19]); SQRADD2(a[17], a[18]); + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADD2(a[17], a[19]); SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADD2(a[18], a[19]); + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + COMBA_STORE2(b[39]); + COMBA_FINI; + + B->used = 40; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 40 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_24.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_24.i new file mode 100644 index 00000000..20d484c4 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_24.i @@ -0,0 +1,258 @@ +#ifdef TFM_SQR24 +void fp_sqr_comba24(fp_int *A, fp_int *B) +{ + fp_digit *a, b[48], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADD2(a[19], a[23]); SQRADD2(a[20], a[22]); SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADD2(a[20], a[23]); SQRADD2(a[21], a[22]); + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADD2(a[21], a[23]); SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADD2(a[22], a[23]); + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + COMBA_STORE2(b[47]); + COMBA_FINI; + + B->used = 48; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 48 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_28.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_28.i new file mode 100644 index 00000000..57f6c60c --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_28.i @@ -0,0 +1,298 @@ +#ifdef TFM_SQR28 +void fp_sqr_comba28(fp_int *A, fp_int *B) +{ + fp_digit *a, b[56], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADDSC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + + /* output 47 */ + CARRY_FORWARD; + SQRADDSC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; + COMBA_STORE(b[47]); + + /* output 48 */ + CARRY_FORWARD; + SQRADDSC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); + COMBA_STORE(b[48]); + + /* output 49 */ + CARRY_FORWARD; + SQRADDSC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; + COMBA_STORE(b[49]); + + /* output 50 */ + CARRY_FORWARD; + SQRADD2(a[23], a[27]); SQRADD2(a[24], a[26]); SQRADD(a[25], a[25]); + COMBA_STORE(b[50]); + + /* output 51 */ + CARRY_FORWARD; + SQRADD2(a[24], a[27]); SQRADD2(a[25], a[26]); + COMBA_STORE(b[51]); + + /* output 52 */ + CARRY_FORWARD; + SQRADD2(a[25], a[27]); SQRADD(a[26], a[26]); + COMBA_STORE(b[52]); + + /* output 53 */ + CARRY_FORWARD; + SQRADD2(a[26], a[27]); + COMBA_STORE(b[53]); + + /* output 54 */ + CARRY_FORWARD; + SQRADD(a[27], a[27]); + COMBA_STORE(b[54]); + COMBA_STORE2(b[55]); + COMBA_FINI; + + B->used = 56; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 56 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_3.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_3.i new file mode 100644 index 00000000..c776702b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_3.i @@ -0,0 +1,45 @@ +#ifdef TFM_SQR3 +void fp_sqr_comba3(fp_int *A, fp_int *B) +{ + fp_digit *a, b[6], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + COMBA_STORE2(b[5]); + COMBA_FINI; + + B->used = 6; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 6 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_32.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_32.i new file mode 100644 index 00000000..baaee43b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_32.i @@ -0,0 +1,338 @@ +#ifdef TFM_SQR32 +void fp_sqr_comba32(fp_int *A, fp_int *B) +{ + fp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + + /* output 47 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; + COMBA_STORE(b[47]); + + /* output 48 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); + COMBA_STORE(b[48]); + + /* output 49 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; + COMBA_STORE(b[49]); + + /* output 50 */ + CARRY_FORWARD; + SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); + COMBA_STORE(b[50]); + + /* output 51 */ + CARRY_FORWARD; + SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; + COMBA_STORE(b[51]); + + /* output 52 */ + CARRY_FORWARD; + SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); + COMBA_STORE(b[52]); + + /* output 53 */ + CARRY_FORWARD; + SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; + COMBA_STORE(b[53]); + + /* output 54 */ + CARRY_FORWARD; + SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); + COMBA_STORE(b[54]); + + /* output 55 */ + CARRY_FORWARD; + SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; + COMBA_STORE(b[55]); + + /* output 56 */ + CARRY_FORWARD; + SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); + COMBA_STORE(b[56]); + + /* output 57 */ + CARRY_FORWARD; + SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; + COMBA_STORE(b[57]); + + /* output 58 */ + CARRY_FORWARD; + SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]); + COMBA_STORE(b[58]); + + /* output 59 */ + CARRY_FORWARD; + SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]); + COMBA_STORE(b[59]); + + /* output 60 */ + CARRY_FORWARD; + SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]); + COMBA_STORE(b[60]); + + /* output 61 */ + CARRY_FORWARD; + SQRADD2(a[30], a[31]); + COMBA_STORE(b[61]); + + /* output 62 */ + CARRY_FORWARD; + SQRADD(a[31], a[31]); + COMBA_STORE(b[62]); + COMBA_STORE2(b[63]); + COMBA_FINI; + + B->used = 64; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 64 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_4.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_4.i new file mode 100644 index 00000000..dcf1b705 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_4.i @@ -0,0 +1,55 @@ +#ifdef TFM_SQR4 +void fp_sqr_comba4(fp_int *A, fp_int *B) +{ + fp_digit *a, b[8], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADD2(a[2], a[3]); + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + COMBA_STORE2(b[7]); + COMBA_FINI; + + B->used = 8; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 8 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_48.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_48.i new file mode 100644 index 00000000..26fbd46f --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_48.i @@ -0,0 +1,498 @@ +#ifdef TFM_SQR48 +void fp_sqr_comba48(fp_int *A, fp_int *B) +{ + fp_digit *a, b[96], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[32]); SQRADDAC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[33]); SQRADDAC(a[1], a[32]); SQRADDAC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[34]); SQRADDAC(a[1], a[33]); SQRADDAC(a[2], a[32]); SQRADDAC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[35]); SQRADDAC(a[1], a[34]); SQRADDAC(a[2], a[33]); SQRADDAC(a[3], a[32]); SQRADDAC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[36]); SQRADDAC(a[1], a[35]); SQRADDAC(a[2], a[34]); SQRADDAC(a[3], a[33]); SQRADDAC(a[4], a[32]); SQRADDAC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[37]); SQRADDAC(a[1], a[36]); SQRADDAC(a[2], a[35]); SQRADDAC(a[3], a[34]); SQRADDAC(a[4], a[33]); SQRADDAC(a[5], a[32]); SQRADDAC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[38]); SQRADDAC(a[1], a[37]); SQRADDAC(a[2], a[36]); SQRADDAC(a[3], a[35]); SQRADDAC(a[4], a[34]); SQRADDAC(a[5], a[33]); SQRADDAC(a[6], a[32]); SQRADDAC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[39]); SQRADDAC(a[1], a[38]); SQRADDAC(a[2], a[37]); SQRADDAC(a[3], a[36]); SQRADDAC(a[4], a[35]); SQRADDAC(a[5], a[34]); SQRADDAC(a[6], a[33]); SQRADDAC(a[7], a[32]); SQRADDAC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[40]); SQRADDAC(a[1], a[39]); SQRADDAC(a[2], a[38]); SQRADDAC(a[3], a[37]); SQRADDAC(a[4], a[36]); SQRADDAC(a[5], a[35]); SQRADDAC(a[6], a[34]); SQRADDAC(a[7], a[33]); SQRADDAC(a[8], a[32]); SQRADDAC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[41]); SQRADDAC(a[1], a[40]); SQRADDAC(a[2], a[39]); SQRADDAC(a[3], a[38]); SQRADDAC(a[4], a[37]); SQRADDAC(a[5], a[36]); SQRADDAC(a[6], a[35]); SQRADDAC(a[7], a[34]); SQRADDAC(a[8], a[33]); SQRADDAC(a[9], a[32]); SQRADDAC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[42]); SQRADDAC(a[1], a[41]); SQRADDAC(a[2], a[40]); SQRADDAC(a[3], a[39]); SQRADDAC(a[4], a[38]); SQRADDAC(a[5], a[37]); SQRADDAC(a[6], a[36]); SQRADDAC(a[7], a[35]); SQRADDAC(a[8], a[34]); SQRADDAC(a[9], a[33]); SQRADDAC(a[10], a[32]); SQRADDAC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[43]); SQRADDAC(a[1], a[42]); SQRADDAC(a[2], a[41]); SQRADDAC(a[3], a[40]); SQRADDAC(a[4], a[39]); SQRADDAC(a[5], a[38]); SQRADDAC(a[6], a[37]); SQRADDAC(a[7], a[36]); SQRADDAC(a[8], a[35]); SQRADDAC(a[9], a[34]); SQRADDAC(a[10], a[33]); SQRADDAC(a[11], a[32]); SQRADDAC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[44]); SQRADDAC(a[1], a[43]); SQRADDAC(a[2], a[42]); SQRADDAC(a[3], a[41]); SQRADDAC(a[4], a[40]); SQRADDAC(a[5], a[39]); SQRADDAC(a[6], a[38]); SQRADDAC(a[7], a[37]); SQRADDAC(a[8], a[36]); SQRADDAC(a[9], a[35]); SQRADDAC(a[10], a[34]); SQRADDAC(a[11], a[33]); SQRADDAC(a[12], a[32]); SQRADDAC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[45]); SQRADDAC(a[1], a[44]); SQRADDAC(a[2], a[43]); SQRADDAC(a[3], a[42]); SQRADDAC(a[4], a[41]); SQRADDAC(a[5], a[40]); SQRADDAC(a[6], a[39]); SQRADDAC(a[7], a[38]); SQRADDAC(a[8], a[37]); SQRADDAC(a[9], a[36]); SQRADDAC(a[10], a[35]); SQRADDAC(a[11], a[34]); SQRADDAC(a[12], a[33]); SQRADDAC(a[13], a[32]); SQRADDAC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[46]); SQRADDAC(a[1], a[45]); SQRADDAC(a[2], a[44]); SQRADDAC(a[3], a[43]); SQRADDAC(a[4], a[42]); SQRADDAC(a[5], a[41]); SQRADDAC(a[6], a[40]); SQRADDAC(a[7], a[39]); SQRADDAC(a[8], a[38]); SQRADDAC(a[9], a[37]); SQRADDAC(a[10], a[36]); SQRADDAC(a[11], a[35]); SQRADDAC(a[12], a[34]); SQRADDAC(a[13], a[33]); SQRADDAC(a[14], a[32]); SQRADDAC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + + /* output 47 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[47]); SQRADDAC(a[1], a[46]); SQRADDAC(a[2], a[45]); SQRADDAC(a[3], a[44]); SQRADDAC(a[4], a[43]); SQRADDAC(a[5], a[42]); SQRADDAC(a[6], a[41]); SQRADDAC(a[7], a[40]); SQRADDAC(a[8], a[39]); SQRADDAC(a[9], a[38]); SQRADDAC(a[10], a[37]); SQRADDAC(a[11], a[36]); SQRADDAC(a[12], a[35]); SQRADDAC(a[13], a[34]); SQRADDAC(a[14], a[33]); SQRADDAC(a[15], a[32]); SQRADDAC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; + COMBA_STORE(b[47]); + + /* output 48 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[47]); SQRADDAC(a[2], a[46]); SQRADDAC(a[3], a[45]); SQRADDAC(a[4], a[44]); SQRADDAC(a[5], a[43]); SQRADDAC(a[6], a[42]); SQRADDAC(a[7], a[41]); SQRADDAC(a[8], a[40]); SQRADDAC(a[9], a[39]); SQRADDAC(a[10], a[38]); SQRADDAC(a[11], a[37]); SQRADDAC(a[12], a[36]); SQRADDAC(a[13], a[35]); SQRADDAC(a[14], a[34]); SQRADDAC(a[15], a[33]); SQRADDAC(a[16], a[32]); SQRADDAC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); + COMBA_STORE(b[48]); + + /* output 49 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[47]); SQRADDAC(a[3], a[46]); SQRADDAC(a[4], a[45]); SQRADDAC(a[5], a[44]); SQRADDAC(a[6], a[43]); SQRADDAC(a[7], a[42]); SQRADDAC(a[8], a[41]); SQRADDAC(a[9], a[40]); SQRADDAC(a[10], a[39]); SQRADDAC(a[11], a[38]); SQRADDAC(a[12], a[37]); SQRADDAC(a[13], a[36]); SQRADDAC(a[14], a[35]); SQRADDAC(a[15], a[34]); SQRADDAC(a[16], a[33]); SQRADDAC(a[17], a[32]); SQRADDAC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; + COMBA_STORE(b[49]); + + /* output 50 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[47]); SQRADDAC(a[4], a[46]); SQRADDAC(a[5], a[45]); SQRADDAC(a[6], a[44]); SQRADDAC(a[7], a[43]); SQRADDAC(a[8], a[42]); SQRADDAC(a[9], a[41]); SQRADDAC(a[10], a[40]); SQRADDAC(a[11], a[39]); SQRADDAC(a[12], a[38]); SQRADDAC(a[13], a[37]); SQRADDAC(a[14], a[36]); SQRADDAC(a[15], a[35]); SQRADDAC(a[16], a[34]); SQRADDAC(a[17], a[33]); SQRADDAC(a[18], a[32]); SQRADDAC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); + COMBA_STORE(b[50]); + + /* output 51 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[47]); SQRADDAC(a[5], a[46]); SQRADDAC(a[6], a[45]); SQRADDAC(a[7], a[44]); SQRADDAC(a[8], a[43]); SQRADDAC(a[9], a[42]); SQRADDAC(a[10], a[41]); SQRADDAC(a[11], a[40]); SQRADDAC(a[12], a[39]); SQRADDAC(a[13], a[38]); SQRADDAC(a[14], a[37]); SQRADDAC(a[15], a[36]); SQRADDAC(a[16], a[35]); SQRADDAC(a[17], a[34]); SQRADDAC(a[18], a[33]); SQRADDAC(a[19], a[32]); SQRADDAC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; + COMBA_STORE(b[51]); + + /* output 52 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[47]); SQRADDAC(a[6], a[46]); SQRADDAC(a[7], a[45]); SQRADDAC(a[8], a[44]); SQRADDAC(a[9], a[43]); SQRADDAC(a[10], a[42]); SQRADDAC(a[11], a[41]); SQRADDAC(a[12], a[40]); SQRADDAC(a[13], a[39]); SQRADDAC(a[14], a[38]); SQRADDAC(a[15], a[37]); SQRADDAC(a[16], a[36]); SQRADDAC(a[17], a[35]); SQRADDAC(a[18], a[34]); SQRADDAC(a[19], a[33]); SQRADDAC(a[20], a[32]); SQRADDAC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); + COMBA_STORE(b[52]); + + /* output 53 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[47]); SQRADDAC(a[7], a[46]); SQRADDAC(a[8], a[45]); SQRADDAC(a[9], a[44]); SQRADDAC(a[10], a[43]); SQRADDAC(a[11], a[42]); SQRADDAC(a[12], a[41]); SQRADDAC(a[13], a[40]); SQRADDAC(a[14], a[39]); SQRADDAC(a[15], a[38]); SQRADDAC(a[16], a[37]); SQRADDAC(a[17], a[36]); SQRADDAC(a[18], a[35]); SQRADDAC(a[19], a[34]); SQRADDAC(a[20], a[33]); SQRADDAC(a[21], a[32]); SQRADDAC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; + COMBA_STORE(b[53]); + + /* output 54 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[47]); SQRADDAC(a[8], a[46]); SQRADDAC(a[9], a[45]); SQRADDAC(a[10], a[44]); SQRADDAC(a[11], a[43]); SQRADDAC(a[12], a[42]); SQRADDAC(a[13], a[41]); SQRADDAC(a[14], a[40]); SQRADDAC(a[15], a[39]); SQRADDAC(a[16], a[38]); SQRADDAC(a[17], a[37]); SQRADDAC(a[18], a[36]); SQRADDAC(a[19], a[35]); SQRADDAC(a[20], a[34]); SQRADDAC(a[21], a[33]); SQRADDAC(a[22], a[32]); SQRADDAC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); + COMBA_STORE(b[54]); + + /* output 55 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[47]); SQRADDAC(a[9], a[46]); SQRADDAC(a[10], a[45]); SQRADDAC(a[11], a[44]); SQRADDAC(a[12], a[43]); SQRADDAC(a[13], a[42]); SQRADDAC(a[14], a[41]); SQRADDAC(a[15], a[40]); SQRADDAC(a[16], a[39]); SQRADDAC(a[17], a[38]); SQRADDAC(a[18], a[37]); SQRADDAC(a[19], a[36]); SQRADDAC(a[20], a[35]); SQRADDAC(a[21], a[34]); SQRADDAC(a[22], a[33]); SQRADDAC(a[23], a[32]); SQRADDAC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; + COMBA_STORE(b[55]); + + /* output 56 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[47]); SQRADDAC(a[10], a[46]); SQRADDAC(a[11], a[45]); SQRADDAC(a[12], a[44]); SQRADDAC(a[13], a[43]); SQRADDAC(a[14], a[42]); SQRADDAC(a[15], a[41]); SQRADDAC(a[16], a[40]); SQRADDAC(a[17], a[39]); SQRADDAC(a[18], a[38]); SQRADDAC(a[19], a[37]); SQRADDAC(a[20], a[36]); SQRADDAC(a[21], a[35]); SQRADDAC(a[22], a[34]); SQRADDAC(a[23], a[33]); SQRADDAC(a[24], a[32]); SQRADDAC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); + COMBA_STORE(b[56]); + + /* output 57 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[47]); SQRADDAC(a[11], a[46]); SQRADDAC(a[12], a[45]); SQRADDAC(a[13], a[44]); SQRADDAC(a[14], a[43]); SQRADDAC(a[15], a[42]); SQRADDAC(a[16], a[41]); SQRADDAC(a[17], a[40]); SQRADDAC(a[18], a[39]); SQRADDAC(a[19], a[38]); SQRADDAC(a[20], a[37]); SQRADDAC(a[21], a[36]); SQRADDAC(a[22], a[35]); SQRADDAC(a[23], a[34]); SQRADDAC(a[24], a[33]); SQRADDAC(a[25], a[32]); SQRADDAC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; + COMBA_STORE(b[57]); + + /* output 58 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[47]); SQRADDAC(a[12], a[46]); SQRADDAC(a[13], a[45]); SQRADDAC(a[14], a[44]); SQRADDAC(a[15], a[43]); SQRADDAC(a[16], a[42]); SQRADDAC(a[17], a[41]); SQRADDAC(a[18], a[40]); SQRADDAC(a[19], a[39]); SQRADDAC(a[20], a[38]); SQRADDAC(a[21], a[37]); SQRADDAC(a[22], a[36]); SQRADDAC(a[23], a[35]); SQRADDAC(a[24], a[34]); SQRADDAC(a[25], a[33]); SQRADDAC(a[26], a[32]); SQRADDAC(a[27], a[31]); SQRADDAC(a[28], a[30]); SQRADDDB; SQRADD(a[29], a[29]); + COMBA_STORE(b[58]); + + /* output 59 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[47]); SQRADDAC(a[13], a[46]); SQRADDAC(a[14], a[45]); SQRADDAC(a[15], a[44]); SQRADDAC(a[16], a[43]); SQRADDAC(a[17], a[42]); SQRADDAC(a[18], a[41]); SQRADDAC(a[19], a[40]); SQRADDAC(a[20], a[39]); SQRADDAC(a[21], a[38]); SQRADDAC(a[22], a[37]); SQRADDAC(a[23], a[36]); SQRADDAC(a[24], a[35]); SQRADDAC(a[25], a[34]); SQRADDAC(a[26], a[33]); SQRADDAC(a[27], a[32]); SQRADDAC(a[28], a[31]); SQRADDAC(a[29], a[30]); SQRADDDB; + COMBA_STORE(b[59]); + + /* output 60 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[47]); SQRADDAC(a[14], a[46]); SQRADDAC(a[15], a[45]); SQRADDAC(a[16], a[44]); SQRADDAC(a[17], a[43]); SQRADDAC(a[18], a[42]); SQRADDAC(a[19], a[41]); SQRADDAC(a[20], a[40]); SQRADDAC(a[21], a[39]); SQRADDAC(a[22], a[38]); SQRADDAC(a[23], a[37]); SQRADDAC(a[24], a[36]); SQRADDAC(a[25], a[35]); SQRADDAC(a[26], a[34]); SQRADDAC(a[27], a[33]); SQRADDAC(a[28], a[32]); SQRADDAC(a[29], a[31]); SQRADDDB; SQRADD(a[30], a[30]); + COMBA_STORE(b[60]); + + /* output 61 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[47]); SQRADDAC(a[15], a[46]); SQRADDAC(a[16], a[45]); SQRADDAC(a[17], a[44]); SQRADDAC(a[18], a[43]); SQRADDAC(a[19], a[42]); SQRADDAC(a[20], a[41]); SQRADDAC(a[21], a[40]); SQRADDAC(a[22], a[39]); SQRADDAC(a[23], a[38]); SQRADDAC(a[24], a[37]); SQRADDAC(a[25], a[36]); SQRADDAC(a[26], a[35]); SQRADDAC(a[27], a[34]); SQRADDAC(a[28], a[33]); SQRADDAC(a[29], a[32]); SQRADDAC(a[30], a[31]); SQRADDDB; + COMBA_STORE(b[61]); + + /* output 62 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[47]); SQRADDAC(a[16], a[46]); SQRADDAC(a[17], a[45]); SQRADDAC(a[18], a[44]); SQRADDAC(a[19], a[43]); SQRADDAC(a[20], a[42]); SQRADDAC(a[21], a[41]); SQRADDAC(a[22], a[40]); SQRADDAC(a[23], a[39]); SQRADDAC(a[24], a[38]); SQRADDAC(a[25], a[37]); SQRADDAC(a[26], a[36]); SQRADDAC(a[27], a[35]); SQRADDAC(a[28], a[34]); SQRADDAC(a[29], a[33]); SQRADDAC(a[30], a[32]); SQRADDDB; SQRADD(a[31], a[31]); + COMBA_STORE(b[62]); + + /* output 63 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[47]); SQRADDAC(a[17], a[46]); SQRADDAC(a[18], a[45]); SQRADDAC(a[19], a[44]); SQRADDAC(a[20], a[43]); SQRADDAC(a[21], a[42]); SQRADDAC(a[22], a[41]); SQRADDAC(a[23], a[40]); SQRADDAC(a[24], a[39]); SQRADDAC(a[25], a[38]); SQRADDAC(a[26], a[37]); SQRADDAC(a[27], a[36]); SQRADDAC(a[28], a[35]); SQRADDAC(a[29], a[34]); SQRADDAC(a[30], a[33]); SQRADDAC(a[31], a[32]); SQRADDDB; + COMBA_STORE(b[63]); + + /* output 64 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[47]); SQRADDAC(a[18], a[46]); SQRADDAC(a[19], a[45]); SQRADDAC(a[20], a[44]); SQRADDAC(a[21], a[43]); SQRADDAC(a[22], a[42]); SQRADDAC(a[23], a[41]); SQRADDAC(a[24], a[40]); SQRADDAC(a[25], a[39]); SQRADDAC(a[26], a[38]); SQRADDAC(a[27], a[37]); SQRADDAC(a[28], a[36]); SQRADDAC(a[29], a[35]); SQRADDAC(a[30], a[34]); SQRADDAC(a[31], a[33]); SQRADDDB; SQRADD(a[32], a[32]); + COMBA_STORE(b[64]); + + /* output 65 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[47]); SQRADDAC(a[19], a[46]); SQRADDAC(a[20], a[45]); SQRADDAC(a[21], a[44]); SQRADDAC(a[22], a[43]); SQRADDAC(a[23], a[42]); SQRADDAC(a[24], a[41]); SQRADDAC(a[25], a[40]); SQRADDAC(a[26], a[39]); SQRADDAC(a[27], a[38]); SQRADDAC(a[28], a[37]); SQRADDAC(a[29], a[36]); SQRADDAC(a[30], a[35]); SQRADDAC(a[31], a[34]); SQRADDAC(a[32], a[33]); SQRADDDB; + COMBA_STORE(b[65]); + + /* output 66 */ + CARRY_FORWARD; + SQRADDSC(a[19], a[47]); SQRADDAC(a[20], a[46]); SQRADDAC(a[21], a[45]); SQRADDAC(a[22], a[44]); SQRADDAC(a[23], a[43]); SQRADDAC(a[24], a[42]); SQRADDAC(a[25], a[41]); SQRADDAC(a[26], a[40]); SQRADDAC(a[27], a[39]); SQRADDAC(a[28], a[38]); SQRADDAC(a[29], a[37]); SQRADDAC(a[30], a[36]); SQRADDAC(a[31], a[35]); SQRADDAC(a[32], a[34]); SQRADDDB; SQRADD(a[33], a[33]); + COMBA_STORE(b[66]); + + /* output 67 */ + CARRY_FORWARD; + SQRADDSC(a[20], a[47]); SQRADDAC(a[21], a[46]); SQRADDAC(a[22], a[45]); SQRADDAC(a[23], a[44]); SQRADDAC(a[24], a[43]); SQRADDAC(a[25], a[42]); SQRADDAC(a[26], a[41]); SQRADDAC(a[27], a[40]); SQRADDAC(a[28], a[39]); SQRADDAC(a[29], a[38]); SQRADDAC(a[30], a[37]); SQRADDAC(a[31], a[36]); SQRADDAC(a[32], a[35]); SQRADDAC(a[33], a[34]); SQRADDDB; + COMBA_STORE(b[67]); + + /* output 68 */ + CARRY_FORWARD; + SQRADDSC(a[21], a[47]); SQRADDAC(a[22], a[46]); SQRADDAC(a[23], a[45]); SQRADDAC(a[24], a[44]); SQRADDAC(a[25], a[43]); SQRADDAC(a[26], a[42]); SQRADDAC(a[27], a[41]); SQRADDAC(a[28], a[40]); SQRADDAC(a[29], a[39]); SQRADDAC(a[30], a[38]); SQRADDAC(a[31], a[37]); SQRADDAC(a[32], a[36]); SQRADDAC(a[33], a[35]); SQRADDDB; SQRADD(a[34], a[34]); + COMBA_STORE(b[68]); + + /* output 69 */ + CARRY_FORWARD; + SQRADDSC(a[22], a[47]); SQRADDAC(a[23], a[46]); SQRADDAC(a[24], a[45]); SQRADDAC(a[25], a[44]); SQRADDAC(a[26], a[43]); SQRADDAC(a[27], a[42]); SQRADDAC(a[28], a[41]); SQRADDAC(a[29], a[40]); SQRADDAC(a[30], a[39]); SQRADDAC(a[31], a[38]); SQRADDAC(a[32], a[37]); SQRADDAC(a[33], a[36]); SQRADDAC(a[34], a[35]); SQRADDDB; + COMBA_STORE(b[69]); + + /* output 70 */ + CARRY_FORWARD; + SQRADDSC(a[23], a[47]); SQRADDAC(a[24], a[46]); SQRADDAC(a[25], a[45]); SQRADDAC(a[26], a[44]); SQRADDAC(a[27], a[43]); SQRADDAC(a[28], a[42]); SQRADDAC(a[29], a[41]); SQRADDAC(a[30], a[40]); SQRADDAC(a[31], a[39]); SQRADDAC(a[32], a[38]); SQRADDAC(a[33], a[37]); SQRADDAC(a[34], a[36]); SQRADDDB; SQRADD(a[35], a[35]); + COMBA_STORE(b[70]); + + /* output 71 */ + CARRY_FORWARD; + SQRADDSC(a[24], a[47]); SQRADDAC(a[25], a[46]); SQRADDAC(a[26], a[45]); SQRADDAC(a[27], a[44]); SQRADDAC(a[28], a[43]); SQRADDAC(a[29], a[42]); SQRADDAC(a[30], a[41]); SQRADDAC(a[31], a[40]); SQRADDAC(a[32], a[39]); SQRADDAC(a[33], a[38]); SQRADDAC(a[34], a[37]); SQRADDAC(a[35], a[36]); SQRADDDB; + COMBA_STORE(b[71]); + + /* output 72 */ + CARRY_FORWARD; + SQRADDSC(a[25], a[47]); SQRADDAC(a[26], a[46]); SQRADDAC(a[27], a[45]); SQRADDAC(a[28], a[44]); SQRADDAC(a[29], a[43]); SQRADDAC(a[30], a[42]); SQRADDAC(a[31], a[41]); SQRADDAC(a[32], a[40]); SQRADDAC(a[33], a[39]); SQRADDAC(a[34], a[38]); SQRADDAC(a[35], a[37]); SQRADDDB; SQRADD(a[36], a[36]); + COMBA_STORE(b[72]); + + /* output 73 */ + CARRY_FORWARD; + SQRADDSC(a[26], a[47]); SQRADDAC(a[27], a[46]); SQRADDAC(a[28], a[45]); SQRADDAC(a[29], a[44]); SQRADDAC(a[30], a[43]); SQRADDAC(a[31], a[42]); SQRADDAC(a[32], a[41]); SQRADDAC(a[33], a[40]); SQRADDAC(a[34], a[39]); SQRADDAC(a[35], a[38]); SQRADDAC(a[36], a[37]); SQRADDDB; + COMBA_STORE(b[73]); + + /* output 74 */ + CARRY_FORWARD; + SQRADDSC(a[27], a[47]); SQRADDAC(a[28], a[46]); SQRADDAC(a[29], a[45]); SQRADDAC(a[30], a[44]); SQRADDAC(a[31], a[43]); SQRADDAC(a[32], a[42]); SQRADDAC(a[33], a[41]); SQRADDAC(a[34], a[40]); SQRADDAC(a[35], a[39]); SQRADDAC(a[36], a[38]); SQRADDDB; SQRADD(a[37], a[37]); + COMBA_STORE(b[74]); + + /* output 75 */ + CARRY_FORWARD; + SQRADDSC(a[28], a[47]); SQRADDAC(a[29], a[46]); SQRADDAC(a[30], a[45]); SQRADDAC(a[31], a[44]); SQRADDAC(a[32], a[43]); SQRADDAC(a[33], a[42]); SQRADDAC(a[34], a[41]); SQRADDAC(a[35], a[40]); SQRADDAC(a[36], a[39]); SQRADDAC(a[37], a[38]); SQRADDDB; + COMBA_STORE(b[75]); + + /* output 76 */ + CARRY_FORWARD; + SQRADDSC(a[29], a[47]); SQRADDAC(a[30], a[46]); SQRADDAC(a[31], a[45]); SQRADDAC(a[32], a[44]); SQRADDAC(a[33], a[43]); SQRADDAC(a[34], a[42]); SQRADDAC(a[35], a[41]); SQRADDAC(a[36], a[40]); SQRADDAC(a[37], a[39]); SQRADDDB; SQRADD(a[38], a[38]); + COMBA_STORE(b[76]); + + /* output 77 */ + CARRY_FORWARD; + SQRADDSC(a[30], a[47]); SQRADDAC(a[31], a[46]); SQRADDAC(a[32], a[45]); SQRADDAC(a[33], a[44]); SQRADDAC(a[34], a[43]); SQRADDAC(a[35], a[42]); SQRADDAC(a[36], a[41]); SQRADDAC(a[37], a[40]); SQRADDAC(a[38], a[39]); SQRADDDB; + COMBA_STORE(b[77]); + + /* output 78 */ + CARRY_FORWARD; + SQRADDSC(a[31], a[47]); SQRADDAC(a[32], a[46]); SQRADDAC(a[33], a[45]); SQRADDAC(a[34], a[44]); SQRADDAC(a[35], a[43]); SQRADDAC(a[36], a[42]); SQRADDAC(a[37], a[41]); SQRADDAC(a[38], a[40]); SQRADDDB; SQRADD(a[39], a[39]); + COMBA_STORE(b[78]); + + /* output 79 */ + CARRY_FORWARD; + SQRADDSC(a[32], a[47]); SQRADDAC(a[33], a[46]); SQRADDAC(a[34], a[45]); SQRADDAC(a[35], a[44]); SQRADDAC(a[36], a[43]); SQRADDAC(a[37], a[42]); SQRADDAC(a[38], a[41]); SQRADDAC(a[39], a[40]); SQRADDDB; + COMBA_STORE(b[79]); + + /* output 80 */ + CARRY_FORWARD; + SQRADDSC(a[33], a[47]); SQRADDAC(a[34], a[46]); SQRADDAC(a[35], a[45]); SQRADDAC(a[36], a[44]); SQRADDAC(a[37], a[43]); SQRADDAC(a[38], a[42]); SQRADDAC(a[39], a[41]); SQRADDDB; SQRADD(a[40], a[40]); + COMBA_STORE(b[80]); + + /* output 81 */ + CARRY_FORWARD; + SQRADDSC(a[34], a[47]); SQRADDAC(a[35], a[46]); SQRADDAC(a[36], a[45]); SQRADDAC(a[37], a[44]); SQRADDAC(a[38], a[43]); SQRADDAC(a[39], a[42]); SQRADDAC(a[40], a[41]); SQRADDDB; + COMBA_STORE(b[81]); + + /* output 82 */ + CARRY_FORWARD; + SQRADDSC(a[35], a[47]); SQRADDAC(a[36], a[46]); SQRADDAC(a[37], a[45]); SQRADDAC(a[38], a[44]); SQRADDAC(a[39], a[43]); SQRADDAC(a[40], a[42]); SQRADDDB; SQRADD(a[41], a[41]); + COMBA_STORE(b[82]); + + /* output 83 */ + CARRY_FORWARD; + SQRADDSC(a[36], a[47]); SQRADDAC(a[37], a[46]); SQRADDAC(a[38], a[45]); SQRADDAC(a[39], a[44]); SQRADDAC(a[40], a[43]); SQRADDAC(a[41], a[42]); SQRADDDB; + COMBA_STORE(b[83]); + + /* output 84 */ + CARRY_FORWARD; + SQRADDSC(a[37], a[47]); SQRADDAC(a[38], a[46]); SQRADDAC(a[39], a[45]); SQRADDAC(a[40], a[44]); SQRADDAC(a[41], a[43]); SQRADDDB; SQRADD(a[42], a[42]); + COMBA_STORE(b[84]); + + /* output 85 */ + CARRY_FORWARD; + SQRADDSC(a[38], a[47]); SQRADDAC(a[39], a[46]); SQRADDAC(a[40], a[45]); SQRADDAC(a[41], a[44]); SQRADDAC(a[42], a[43]); SQRADDDB; + COMBA_STORE(b[85]); + + /* output 86 */ + CARRY_FORWARD; + SQRADDSC(a[39], a[47]); SQRADDAC(a[40], a[46]); SQRADDAC(a[41], a[45]); SQRADDAC(a[42], a[44]); SQRADDDB; SQRADD(a[43], a[43]); + COMBA_STORE(b[86]); + + /* output 87 */ + CARRY_FORWARD; + SQRADDSC(a[40], a[47]); SQRADDAC(a[41], a[46]); SQRADDAC(a[42], a[45]); SQRADDAC(a[43], a[44]); SQRADDDB; + COMBA_STORE(b[87]); + + /* output 88 */ + CARRY_FORWARD; + SQRADDSC(a[41], a[47]); SQRADDAC(a[42], a[46]); SQRADDAC(a[43], a[45]); SQRADDDB; SQRADD(a[44], a[44]); + COMBA_STORE(b[88]); + + /* output 89 */ + CARRY_FORWARD; + SQRADDSC(a[42], a[47]); SQRADDAC(a[43], a[46]); SQRADDAC(a[44], a[45]); SQRADDDB; + COMBA_STORE(b[89]); + + /* output 90 */ + CARRY_FORWARD; + SQRADD2(a[43], a[47]); SQRADD2(a[44], a[46]); SQRADD(a[45], a[45]); + COMBA_STORE(b[90]); + + /* output 91 */ + CARRY_FORWARD; + SQRADD2(a[44], a[47]); SQRADD2(a[45], a[46]); + COMBA_STORE(b[91]); + + /* output 92 */ + CARRY_FORWARD; + SQRADD2(a[45], a[47]); SQRADD(a[46], a[46]); + COMBA_STORE(b[92]); + + /* output 93 */ + CARRY_FORWARD; + SQRADD2(a[46], a[47]); + COMBA_STORE(b[93]); + + /* output 94 */ + CARRY_FORWARD; + SQRADD(a[47], a[47]); + COMBA_STORE(b[94]); + COMBA_STORE2(b[95]); + COMBA_FINI; + + B->used = 96; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 96 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_6.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_6.i new file mode 100644 index 00000000..01167807 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_6.i @@ -0,0 +1,75 @@ +#ifdef TFM_SQR6 +void fp_sqr_comba6(fp_int *A, fp_int *B) +{ + fp_digit *a, b[12], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD2(a[1], a[5]); SQRADD2(a[2], a[4]); SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADD2(a[2], a[5]); SQRADD2(a[3], a[4]); + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADD2(a[3], a[5]); SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADD2(a[4], a[5]); + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + COMBA_STORE2(b[11]); + COMBA_FINI; + + B->used = 12; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 12 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_64.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_64.i new file mode 100644 index 00000000..68beed1a --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_64.i @@ -0,0 +1,658 @@ +#ifdef TFM_SQR64 +void fp_sqr_comba64(fp_int *A, fp_int *B) +{ + fp_digit *a, b[128], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + + /* output 31 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; + COMBA_STORE(b[31]); + + /* output 32 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[32]); SQRADDAC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); + COMBA_STORE(b[32]); + + /* output 33 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[33]); SQRADDAC(a[1], a[32]); SQRADDAC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; + COMBA_STORE(b[33]); + + /* output 34 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[34]); SQRADDAC(a[1], a[33]); SQRADDAC(a[2], a[32]); SQRADDAC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); + COMBA_STORE(b[34]); + + /* output 35 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[35]); SQRADDAC(a[1], a[34]); SQRADDAC(a[2], a[33]); SQRADDAC(a[3], a[32]); SQRADDAC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; + COMBA_STORE(b[35]); + + /* output 36 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[36]); SQRADDAC(a[1], a[35]); SQRADDAC(a[2], a[34]); SQRADDAC(a[3], a[33]); SQRADDAC(a[4], a[32]); SQRADDAC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); + COMBA_STORE(b[36]); + + /* output 37 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[37]); SQRADDAC(a[1], a[36]); SQRADDAC(a[2], a[35]); SQRADDAC(a[3], a[34]); SQRADDAC(a[4], a[33]); SQRADDAC(a[5], a[32]); SQRADDAC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; + COMBA_STORE(b[37]); + + /* output 38 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[38]); SQRADDAC(a[1], a[37]); SQRADDAC(a[2], a[36]); SQRADDAC(a[3], a[35]); SQRADDAC(a[4], a[34]); SQRADDAC(a[5], a[33]); SQRADDAC(a[6], a[32]); SQRADDAC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); + COMBA_STORE(b[38]); + + /* output 39 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[39]); SQRADDAC(a[1], a[38]); SQRADDAC(a[2], a[37]); SQRADDAC(a[3], a[36]); SQRADDAC(a[4], a[35]); SQRADDAC(a[5], a[34]); SQRADDAC(a[6], a[33]); SQRADDAC(a[7], a[32]); SQRADDAC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; + COMBA_STORE(b[39]); + + /* output 40 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[40]); SQRADDAC(a[1], a[39]); SQRADDAC(a[2], a[38]); SQRADDAC(a[3], a[37]); SQRADDAC(a[4], a[36]); SQRADDAC(a[5], a[35]); SQRADDAC(a[6], a[34]); SQRADDAC(a[7], a[33]); SQRADDAC(a[8], a[32]); SQRADDAC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); + COMBA_STORE(b[40]); + + /* output 41 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[41]); SQRADDAC(a[1], a[40]); SQRADDAC(a[2], a[39]); SQRADDAC(a[3], a[38]); SQRADDAC(a[4], a[37]); SQRADDAC(a[5], a[36]); SQRADDAC(a[6], a[35]); SQRADDAC(a[7], a[34]); SQRADDAC(a[8], a[33]); SQRADDAC(a[9], a[32]); SQRADDAC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; + COMBA_STORE(b[41]); + + /* output 42 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[42]); SQRADDAC(a[1], a[41]); SQRADDAC(a[2], a[40]); SQRADDAC(a[3], a[39]); SQRADDAC(a[4], a[38]); SQRADDAC(a[5], a[37]); SQRADDAC(a[6], a[36]); SQRADDAC(a[7], a[35]); SQRADDAC(a[8], a[34]); SQRADDAC(a[9], a[33]); SQRADDAC(a[10], a[32]); SQRADDAC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); + COMBA_STORE(b[42]); + + /* output 43 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[43]); SQRADDAC(a[1], a[42]); SQRADDAC(a[2], a[41]); SQRADDAC(a[3], a[40]); SQRADDAC(a[4], a[39]); SQRADDAC(a[5], a[38]); SQRADDAC(a[6], a[37]); SQRADDAC(a[7], a[36]); SQRADDAC(a[8], a[35]); SQRADDAC(a[9], a[34]); SQRADDAC(a[10], a[33]); SQRADDAC(a[11], a[32]); SQRADDAC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; + COMBA_STORE(b[43]); + + /* output 44 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[44]); SQRADDAC(a[1], a[43]); SQRADDAC(a[2], a[42]); SQRADDAC(a[3], a[41]); SQRADDAC(a[4], a[40]); SQRADDAC(a[5], a[39]); SQRADDAC(a[6], a[38]); SQRADDAC(a[7], a[37]); SQRADDAC(a[8], a[36]); SQRADDAC(a[9], a[35]); SQRADDAC(a[10], a[34]); SQRADDAC(a[11], a[33]); SQRADDAC(a[12], a[32]); SQRADDAC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); + COMBA_STORE(b[44]); + + /* output 45 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[45]); SQRADDAC(a[1], a[44]); SQRADDAC(a[2], a[43]); SQRADDAC(a[3], a[42]); SQRADDAC(a[4], a[41]); SQRADDAC(a[5], a[40]); SQRADDAC(a[6], a[39]); SQRADDAC(a[7], a[38]); SQRADDAC(a[8], a[37]); SQRADDAC(a[9], a[36]); SQRADDAC(a[10], a[35]); SQRADDAC(a[11], a[34]); SQRADDAC(a[12], a[33]); SQRADDAC(a[13], a[32]); SQRADDAC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; + COMBA_STORE(b[45]); + + /* output 46 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[46]); SQRADDAC(a[1], a[45]); SQRADDAC(a[2], a[44]); SQRADDAC(a[3], a[43]); SQRADDAC(a[4], a[42]); SQRADDAC(a[5], a[41]); SQRADDAC(a[6], a[40]); SQRADDAC(a[7], a[39]); SQRADDAC(a[8], a[38]); SQRADDAC(a[9], a[37]); SQRADDAC(a[10], a[36]); SQRADDAC(a[11], a[35]); SQRADDAC(a[12], a[34]); SQRADDAC(a[13], a[33]); SQRADDAC(a[14], a[32]); SQRADDAC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); + COMBA_STORE(b[46]); + + /* output 47 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[47]); SQRADDAC(a[1], a[46]); SQRADDAC(a[2], a[45]); SQRADDAC(a[3], a[44]); SQRADDAC(a[4], a[43]); SQRADDAC(a[5], a[42]); SQRADDAC(a[6], a[41]); SQRADDAC(a[7], a[40]); SQRADDAC(a[8], a[39]); SQRADDAC(a[9], a[38]); SQRADDAC(a[10], a[37]); SQRADDAC(a[11], a[36]); SQRADDAC(a[12], a[35]); SQRADDAC(a[13], a[34]); SQRADDAC(a[14], a[33]); SQRADDAC(a[15], a[32]); SQRADDAC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; + COMBA_STORE(b[47]); + + /* output 48 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[48]); SQRADDAC(a[1], a[47]); SQRADDAC(a[2], a[46]); SQRADDAC(a[3], a[45]); SQRADDAC(a[4], a[44]); SQRADDAC(a[5], a[43]); SQRADDAC(a[6], a[42]); SQRADDAC(a[7], a[41]); SQRADDAC(a[8], a[40]); SQRADDAC(a[9], a[39]); SQRADDAC(a[10], a[38]); SQRADDAC(a[11], a[37]); SQRADDAC(a[12], a[36]); SQRADDAC(a[13], a[35]); SQRADDAC(a[14], a[34]); SQRADDAC(a[15], a[33]); SQRADDAC(a[16], a[32]); SQRADDAC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); + COMBA_STORE(b[48]); + + /* output 49 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[49]); SQRADDAC(a[1], a[48]); SQRADDAC(a[2], a[47]); SQRADDAC(a[3], a[46]); SQRADDAC(a[4], a[45]); SQRADDAC(a[5], a[44]); SQRADDAC(a[6], a[43]); SQRADDAC(a[7], a[42]); SQRADDAC(a[8], a[41]); SQRADDAC(a[9], a[40]); SQRADDAC(a[10], a[39]); SQRADDAC(a[11], a[38]); SQRADDAC(a[12], a[37]); SQRADDAC(a[13], a[36]); SQRADDAC(a[14], a[35]); SQRADDAC(a[15], a[34]); SQRADDAC(a[16], a[33]); SQRADDAC(a[17], a[32]); SQRADDAC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; + COMBA_STORE(b[49]); + + /* output 50 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[50]); SQRADDAC(a[1], a[49]); SQRADDAC(a[2], a[48]); SQRADDAC(a[3], a[47]); SQRADDAC(a[4], a[46]); SQRADDAC(a[5], a[45]); SQRADDAC(a[6], a[44]); SQRADDAC(a[7], a[43]); SQRADDAC(a[8], a[42]); SQRADDAC(a[9], a[41]); SQRADDAC(a[10], a[40]); SQRADDAC(a[11], a[39]); SQRADDAC(a[12], a[38]); SQRADDAC(a[13], a[37]); SQRADDAC(a[14], a[36]); SQRADDAC(a[15], a[35]); SQRADDAC(a[16], a[34]); SQRADDAC(a[17], a[33]); SQRADDAC(a[18], a[32]); SQRADDAC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); + COMBA_STORE(b[50]); + + /* output 51 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[51]); SQRADDAC(a[1], a[50]); SQRADDAC(a[2], a[49]); SQRADDAC(a[3], a[48]); SQRADDAC(a[4], a[47]); SQRADDAC(a[5], a[46]); SQRADDAC(a[6], a[45]); SQRADDAC(a[7], a[44]); SQRADDAC(a[8], a[43]); SQRADDAC(a[9], a[42]); SQRADDAC(a[10], a[41]); SQRADDAC(a[11], a[40]); SQRADDAC(a[12], a[39]); SQRADDAC(a[13], a[38]); SQRADDAC(a[14], a[37]); SQRADDAC(a[15], a[36]); SQRADDAC(a[16], a[35]); SQRADDAC(a[17], a[34]); SQRADDAC(a[18], a[33]); SQRADDAC(a[19], a[32]); SQRADDAC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; + COMBA_STORE(b[51]); + + /* output 52 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[52]); SQRADDAC(a[1], a[51]); SQRADDAC(a[2], a[50]); SQRADDAC(a[3], a[49]); SQRADDAC(a[4], a[48]); SQRADDAC(a[5], a[47]); SQRADDAC(a[6], a[46]); SQRADDAC(a[7], a[45]); SQRADDAC(a[8], a[44]); SQRADDAC(a[9], a[43]); SQRADDAC(a[10], a[42]); SQRADDAC(a[11], a[41]); SQRADDAC(a[12], a[40]); SQRADDAC(a[13], a[39]); SQRADDAC(a[14], a[38]); SQRADDAC(a[15], a[37]); SQRADDAC(a[16], a[36]); SQRADDAC(a[17], a[35]); SQRADDAC(a[18], a[34]); SQRADDAC(a[19], a[33]); SQRADDAC(a[20], a[32]); SQRADDAC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); + COMBA_STORE(b[52]); + + /* output 53 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[53]); SQRADDAC(a[1], a[52]); SQRADDAC(a[2], a[51]); SQRADDAC(a[3], a[50]); SQRADDAC(a[4], a[49]); SQRADDAC(a[5], a[48]); SQRADDAC(a[6], a[47]); SQRADDAC(a[7], a[46]); SQRADDAC(a[8], a[45]); SQRADDAC(a[9], a[44]); SQRADDAC(a[10], a[43]); SQRADDAC(a[11], a[42]); SQRADDAC(a[12], a[41]); SQRADDAC(a[13], a[40]); SQRADDAC(a[14], a[39]); SQRADDAC(a[15], a[38]); SQRADDAC(a[16], a[37]); SQRADDAC(a[17], a[36]); SQRADDAC(a[18], a[35]); SQRADDAC(a[19], a[34]); SQRADDAC(a[20], a[33]); SQRADDAC(a[21], a[32]); SQRADDAC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; + COMBA_STORE(b[53]); + + /* output 54 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[54]); SQRADDAC(a[1], a[53]); SQRADDAC(a[2], a[52]); SQRADDAC(a[3], a[51]); SQRADDAC(a[4], a[50]); SQRADDAC(a[5], a[49]); SQRADDAC(a[6], a[48]); SQRADDAC(a[7], a[47]); SQRADDAC(a[8], a[46]); SQRADDAC(a[9], a[45]); SQRADDAC(a[10], a[44]); SQRADDAC(a[11], a[43]); SQRADDAC(a[12], a[42]); SQRADDAC(a[13], a[41]); SQRADDAC(a[14], a[40]); SQRADDAC(a[15], a[39]); SQRADDAC(a[16], a[38]); SQRADDAC(a[17], a[37]); SQRADDAC(a[18], a[36]); SQRADDAC(a[19], a[35]); SQRADDAC(a[20], a[34]); SQRADDAC(a[21], a[33]); SQRADDAC(a[22], a[32]); SQRADDAC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); + COMBA_STORE(b[54]); + + /* output 55 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[55]); SQRADDAC(a[1], a[54]); SQRADDAC(a[2], a[53]); SQRADDAC(a[3], a[52]); SQRADDAC(a[4], a[51]); SQRADDAC(a[5], a[50]); SQRADDAC(a[6], a[49]); SQRADDAC(a[7], a[48]); SQRADDAC(a[8], a[47]); SQRADDAC(a[9], a[46]); SQRADDAC(a[10], a[45]); SQRADDAC(a[11], a[44]); SQRADDAC(a[12], a[43]); SQRADDAC(a[13], a[42]); SQRADDAC(a[14], a[41]); SQRADDAC(a[15], a[40]); SQRADDAC(a[16], a[39]); SQRADDAC(a[17], a[38]); SQRADDAC(a[18], a[37]); SQRADDAC(a[19], a[36]); SQRADDAC(a[20], a[35]); SQRADDAC(a[21], a[34]); SQRADDAC(a[22], a[33]); SQRADDAC(a[23], a[32]); SQRADDAC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; + COMBA_STORE(b[55]); + + /* output 56 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[56]); SQRADDAC(a[1], a[55]); SQRADDAC(a[2], a[54]); SQRADDAC(a[3], a[53]); SQRADDAC(a[4], a[52]); SQRADDAC(a[5], a[51]); SQRADDAC(a[6], a[50]); SQRADDAC(a[7], a[49]); SQRADDAC(a[8], a[48]); SQRADDAC(a[9], a[47]); SQRADDAC(a[10], a[46]); SQRADDAC(a[11], a[45]); SQRADDAC(a[12], a[44]); SQRADDAC(a[13], a[43]); SQRADDAC(a[14], a[42]); SQRADDAC(a[15], a[41]); SQRADDAC(a[16], a[40]); SQRADDAC(a[17], a[39]); SQRADDAC(a[18], a[38]); SQRADDAC(a[19], a[37]); SQRADDAC(a[20], a[36]); SQRADDAC(a[21], a[35]); SQRADDAC(a[22], a[34]); SQRADDAC(a[23], a[33]); SQRADDAC(a[24], a[32]); SQRADDAC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); + COMBA_STORE(b[56]); + + /* output 57 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[57]); SQRADDAC(a[1], a[56]); SQRADDAC(a[2], a[55]); SQRADDAC(a[3], a[54]); SQRADDAC(a[4], a[53]); SQRADDAC(a[5], a[52]); SQRADDAC(a[6], a[51]); SQRADDAC(a[7], a[50]); SQRADDAC(a[8], a[49]); SQRADDAC(a[9], a[48]); SQRADDAC(a[10], a[47]); SQRADDAC(a[11], a[46]); SQRADDAC(a[12], a[45]); SQRADDAC(a[13], a[44]); SQRADDAC(a[14], a[43]); SQRADDAC(a[15], a[42]); SQRADDAC(a[16], a[41]); SQRADDAC(a[17], a[40]); SQRADDAC(a[18], a[39]); SQRADDAC(a[19], a[38]); SQRADDAC(a[20], a[37]); SQRADDAC(a[21], a[36]); SQRADDAC(a[22], a[35]); SQRADDAC(a[23], a[34]); SQRADDAC(a[24], a[33]); SQRADDAC(a[25], a[32]); SQRADDAC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; + COMBA_STORE(b[57]); + + /* output 58 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[58]); SQRADDAC(a[1], a[57]); SQRADDAC(a[2], a[56]); SQRADDAC(a[3], a[55]); SQRADDAC(a[4], a[54]); SQRADDAC(a[5], a[53]); SQRADDAC(a[6], a[52]); SQRADDAC(a[7], a[51]); SQRADDAC(a[8], a[50]); SQRADDAC(a[9], a[49]); SQRADDAC(a[10], a[48]); SQRADDAC(a[11], a[47]); SQRADDAC(a[12], a[46]); SQRADDAC(a[13], a[45]); SQRADDAC(a[14], a[44]); SQRADDAC(a[15], a[43]); SQRADDAC(a[16], a[42]); SQRADDAC(a[17], a[41]); SQRADDAC(a[18], a[40]); SQRADDAC(a[19], a[39]); SQRADDAC(a[20], a[38]); SQRADDAC(a[21], a[37]); SQRADDAC(a[22], a[36]); SQRADDAC(a[23], a[35]); SQRADDAC(a[24], a[34]); SQRADDAC(a[25], a[33]); SQRADDAC(a[26], a[32]); SQRADDAC(a[27], a[31]); SQRADDAC(a[28], a[30]); SQRADDDB; SQRADD(a[29], a[29]); + COMBA_STORE(b[58]); + + /* output 59 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[59]); SQRADDAC(a[1], a[58]); SQRADDAC(a[2], a[57]); SQRADDAC(a[3], a[56]); SQRADDAC(a[4], a[55]); SQRADDAC(a[5], a[54]); SQRADDAC(a[6], a[53]); SQRADDAC(a[7], a[52]); SQRADDAC(a[8], a[51]); SQRADDAC(a[9], a[50]); SQRADDAC(a[10], a[49]); SQRADDAC(a[11], a[48]); SQRADDAC(a[12], a[47]); SQRADDAC(a[13], a[46]); SQRADDAC(a[14], a[45]); SQRADDAC(a[15], a[44]); SQRADDAC(a[16], a[43]); SQRADDAC(a[17], a[42]); SQRADDAC(a[18], a[41]); SQRADDAC(a[19], a[40]); SQRADDAC(a[20], a[39]); SQRADDAC(a[21], a[38]); SQRADDAC(a[22], a[37]); SQRADDAC(a[23], a[36]); SQRADDAC(a[24], a[35]); SQRADDAC(a[25], a[34]); SQRADDAC(a[26], a[33]); SQRADDAC(a[27], a[32]); SQRADDAC(a[28], a[31]); SQRADDAC(a[29], a[30]); SQRADDDB; + COMBA_STORE(b[59]); + + /* output 60 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[60]); SQRADDAC(a[1], a[59]); SQRADDAC(a[2], a[58]); SQRADDAC(a[3], a[57]); SQRADDAC(a[4], a[56]); SQRADDAC(a[5], a[55]); SQRADDAC(a[6], a[54]); SQRADDAC(a[7], a[53]); SQRADDAC(a[8], a[52]); SQRADDAC(a[9], a[51]); SQRADDAC(a[10], a[50]); SQRADDAC(a[11], a[49]); SQRADDAC(a[12], a[48]); SQRADDAC(a[13], a[47]); SQRADDAC(a[14], a[46]); SQRADDAC(a[15], a[45]); SQRADDAC(a[16], a[44]); SQRADDAC(a[17], a[43]); SQRADDAC(a[18], a[42]); SQRADDAC(a[19], a[41]); SQRADDAC(a[20], a[40]); SQRADDAC(a[21], a[39]); SQRADDAC(a[22], a[38]); SQRADDAC(a[23], a[37]); SQRADDAC(a[24], a[36]); SQRADDAC(a[25], a[35]); SQRADDAC(a[26], a[34]); SQRADDAC(a[27], a[33]); SQRADDAC(a[28], a[32]); SQRADDAC(a[29], a[31]); SQRADDDB; SQRADD(a[30], a[30]); + COMBA_STORE(b[60]); + + /* output 61 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[61]); SQRADDAC(a[1], a[60]); SQRADDAC(a[2], a[59]); SQRADDAC(a[3], a[58]); SQRADDAC(a[4], a[57]); SQRADDAC(a[5], a[56]); SQRADDAC(a[6], a[55]); SQRADDAC(a[7], a[54]); SQRADDAC(a[8], a[53]); SQRADDAC(a[9], a[52]); SQRADDAC(a[10], a[51]); SQRADDAC(a[11], a[50]); SQRADDAC(a[12], a[49]); SQRADDAC(a[13], a[48]); SQRADDAC(a[14], a[47]); SQRADDAC(a[15], a[46]); SQRADDAC(a[16], a[45]); SQRADDAC(a[17], a[44]); SQRADDAC(a[18], a[43]); SQRADDAC(a[19], a[42]); SQRADDAC(a[20], a[41]); SQRADDAC(a[21], a[40]); SQRADDAC(a[22], a[39]); SQRADDAC(a[23], a[38]); SQRADDAC(a[24], a[37]); SQRADDAC(a[25], a[36]); SQRADDAC(a[26], a[35]); SQRADDAC(a[27], a[34]); SQRADDAC(a[28], a[33]); SQRADDAC(a[29], a[32]); SQRADDAC(a[30], a[31]); SQRADDDB; + COMBA_STORE(b[61]); + + /* output 62 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[62]); SQRADDAC(a[1], a[61]); SQRADDAC(a[2], a[60]); SQRADDAC(a[3], a[59]); SQRADDAC(a[4], a[58]); SQRADDAC(a[5], a[57]); SQRADDAC(a[6], a[56]); SQRADDAC(a[7], a[55]); SQRADDAC(a[8], a[54]); SQRADDAC(a[9], a[53]); SQRADDAC(a[10], a[52]); SQRADDAC(a[11], a[51]); SQRADDAC(a[12], a[50]); SQRADDAC(a[13], a[49]); SQRADDAC(a[14], a[48]); SQRADDAC(a[15], a[47]); SQRADDAC(a[16], a[46]); SQRADDAC(a[17], a[45]); SQRADDAC(a[18], a[44]); SQRADDAC(a[19], a[43]); SQRADDAC(a[20], a[42]); SQRADDAC(a[21], a[41]); SQRADDAC(a[22], a[40]); SQRADDAC(a[23], a[39]); SQRADDAC(a[24], a[38]); SQRADDAC(a[25], a[37]); SQRADDAC(a[26], a[36]); SQRADDAC(a[27], a[35]); SQRADDAC(a[28], a[34]); SQRADDAC(a[29], a[33]); SQRADDAC(a[30], a[32]); SQRADDDB; SQRADD(a[31], a[31]); + COMBA_STORE(b[62]); + + /* output 63 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[63]); SQRADDAC(a[1], a[62]); SQRADDAC(a[2], a[61]); SQRADDAC(a[3], a[60]); SQRADDAC(a[4], a[59]); SQRADDAC(a[5], a[58]); SQRADDAC(a[6], a[57]); SQRADDAC(a[7], a[56]); SQRADDAC(a[8], a[55]); SQRADDAC(a[9], a[54]); SQRADDAC(a[10], a[53]); SQRADDAC(a[11], a[52]); SQRADDAC(a[12], a[51]); SQRADDAC(a[13], a[50]); SQRADDAC(a[14], a[49]); SQRADDAC(a[15], a[48]); SQRADDAC(a[16], a[47]); SQRADDAC(a[17], a[46]); SQRADDAC(a[18], a[45]); SQRADDAC(a[19], a[44]); SQRADDAC(a[20], a[43]); SQRADDAC(a[21], a[42]); SQRADDAC(a[22], a[41]); SQRADDAC(a[23], a[40]); SQRADDAC(a[24], a[39]); SQRADDAC(a[25], a[38]); SQRADDAC(a[26], a[37]); SQRADDAC(a[27], a[36]); SQRADDAC(a[28], a[35]); SQRADDAC(a[29], a[34]); SQRADDAC(a[30], a[33]); SQRADDAC(a[31], a[32]); SQRADDDB; + COMBA_STORE(b[63]); + + /* output 64 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[63]); SQRADDAC(a[2], a[62]); SQRADDAC(a[3], a[61]); SQRADDAC(a[4], a[60]); SQRADDAC(a[5], a[59]); SQRADDAC(a[6], a[58]); SQRADDAC(a[7], a[57]); SQRADDAC(a[8], a[56]); SQRADDAC(a[9], a[55]); SQRADDAC(a[10], a[54]); SQRADDAC(a[11], a[53]); SQRADDAC(a[12], a[52]); SQRADDAC(a[13], a[51]); SQRADDAC(a[14], a[50]); SQRADDAC(a[15], a[49]); SQRADDAC(a[16], a[48]); SQRADDAC(a[17], a[47]); SQRADDAC(a[18], a[46]); SQRADDAC(a[19], a[45]); SQRADDAC(a[20], a[44]); SQRADDAC(a[21], a[43]); SQRADDAC(a[22], a[42]); SQRADDAC(a[23], a[41]); SQRADDAC(a[24], a[40]); SQRADDAC(a[25], a[39]); SQRADDAC(a[26], a[38]); SQRADDAC(a[27], a[37]); SQRADDAC(a[28], a[36]); SQRADDAC(a[29], a[35]); SQRADDAC(a[30], a[34]); SQRADDAC(a[31], a[33]); SQRADDDB; SQRADD(a[32], a[32]); + COMBA_STORE(b[64]); + + /* output 65 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[63]); SQRADDAC(a[3], a[62]); SQRADDAC(a[4], a[61]); SQRADDAC(a[5], a[60]); SQRADDAC(a[6], a[59]); SQRADDAC(a[7], a[58]); SQRADDAC(a[8], a[57]); SQRADDAC(a[9], a[56]); SQRADDAC(a[10], a[55]); SQRADDAC(a[11], a[54]); SQRADDAC(a[12], a[53]); SQRADDAC(a[13], a[52]); SQRADDAC(a[14], a[51]); SQRADDAC(a[15], a[50]); SQRADDAC(a[16], a[49]); SQRADDAC(a[17], a[48]); SQRADDAC(a[18], a[47]); SQRADDAC(a[19], a[46]); SQRADDAC(a[20], a[45]); SQRADDAC(a[21], a[44]); SQRADDAC(a[22], a[43]); SQRADDAC(a[23], a[42]); SQRADDAC(a[24], a[41]); SQRADDAC(a[25], a[40]); SQRADDAC(a[26], a[39]); SQRADDAC(a[27], a[38]); SQRADDAC(a[28], a[37]); SQRADDAC(a[29], a[36]); SQRADDAC(a[30], a[35]); SQRADDAC(a[31], a[34]); SQRADDAC(a[32], a[33]); SQRADDDB; + COMBA_STORE(b[65]); + + /* output 66 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[63]); SQRADDAC(a[4], a[62]); SQRADDAC(a[5], a[61]); SQRADDAC(a[6], a[60]); SQRADDAC(a[7], a[59]); SQRADDAC(a[8], a[58]); SQRADDAC(a[9], a[57]); SQRADDAC(a[10], a[56]); SQRADDAC(a[11], a[55]); SQRADDAC(a[12], a[54]); SQRADDAC(a[13], a[53]); SQRADDAC(a[14], a[52]); SQRADDAC(a[15], a[51]); SQRADDAC(a[16], a[50]); SQRADDAC(a[17], a[49]); SQRADDAC(a[18], a[48]); SQRADDAC(a[19], a[47]); SQRADDAC(a[20], a[46]); SQRADDAC(a[21], a[45]); SQRADDAC(a[22], a[44]); SQRADDAC(a[23], a[43]); SQRADDAC(a[24], a[42]); SQRADDAC(a[25], a[41]); SQRADDAC(a[26], a[40]); SQRADDAC(a[27], a[39]); SQRADDAC(a[28], a[38]); SQRADDAC(a[29], a[37]); SQRADDAC(a[30], a[36]); SQRADDAC(a[31], a[35]); SQRADDAC(a[32], a[34]); SQRADDDB; SQRADD(a[33], a[33]); + COMBA_STORE(b[66]); + + /* output 67 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[63]); SQRADDAC(a[5], a[62]); SQRADDAC(a[6], a[61]); SQRADDAC(a[7], a[60]); SQRADDAC(a[8], a[59]); SQRADDAC(a[9], a[58]); SQRADDAC(a[10], a[57]); SQRADDAC(a[11], a[56]); SQRADDAC(a[12], a[55]); SQRADDAC(a[13], a[54]); SQRADDAC(a[14], a[53]); SQRADDAC(a[15], a[52]); SQRADDAC(a[16], a[51]); SQRADDAC(a[17], a[50]); SQRADDAC(a[18], a[49]); SQRADDAC(a[19], a[48]); SQRADDAC(a[20], a[47]); SQRADDAC(a[21], a[46]); SQRADDAC(a[22], a[45]); SQRADDAC(a[23], a[44]); SQRADDAC(a[24], a[43]); SQRADDAC(a[25], a[42]); SQRADDAC(a[26], a[41]); SQRADDAC(a[27], a[40]); SQRADDAC(a[28], a[39]); SQRADDAC(a[29], a[38]); SQRADDAC(a[30], a[37]); SQRADDAC(a[31], a[36]); SQRADDAC(a[32], a[35]); SQRADDAC(a[33], a[34]); SQRADDDB; + COMBA_STORE(b[67]); + + /* output 68 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[63]); SQRADDAC(a[6], a[62]); SQRADDAC(a[7], a[61]); SQRADDAC(a[8], a[60]); SQRADDAC(a[9], a[59]); SQRADDAC(a[10], a[58]); SQRADDAC(a[11], a[57]); SQRADDAC(a[12], a[56]); SQRADDAC(a[13], a[55]); SQRADDAC(a[14], a[54]); SQRADDAC(a[15], a[53]); SQRADDAC(a[16], a[52]); SQRADDAC(a[17], a[51]); SQRADDAC(a[18], a[50]); SQRADDAC(a[19], a[49]); SQRADDAC(a[20], a[48]); SQRADDAC(a[21], a[47]); SQRADDAC(a[22], a[46]); SQRADDAC(a[23], a[45]); SQRADDAC(a[24], a[44]); SQRADDAC(a[25], a[43]); SQRADDAC(a[26], a[42]); SQRADDAC(a[27], a[41]); SQRADDAC(a[28], a[40]); SQRADDAC(a[29], a[39]); SQRADDAC(a[30], a[38]); SQRADDAC(a[31], a[37]); SQRADDAC(a[32], a[36]); SQRADDAC(a[33], a[35]); SQRADDDB; SQRADD(a[34], a[34]); + COMBA_STORE(b[68]); + + /* output 69 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[63]); SQRADDAC(a[7], a[62]); SQRADDAC(a[8], a[61]); SQRADDAC(a[9], a[60]); SQRADDAC(a[10], a[59]); SQRADDAC(a[11], a[58]); SQRADDAC(a[12], a[57]); SQRADDAC(a[13], a[56]); SQRADDAC(a[14], a[55]); SQRADDAC(a[15], a[54]); SQRADDAC(a[16], a[53]); SQRADDAC(a[17], a[52]); SQRADDAC(a[18], a[51]); SQRADDAC(a[19], a[50]); SQRADDAC(a[20], a[49]); SQRADDAC(a[21], a[48]); SQRADDAC(a[22], a[47]); SQRADDAC(a[23], a[46]); SQRADDAC(a[24], a[45]); SQRADDAC(a[25], a[44]); SQRADDAC(a[26], a[43]); SQRADDAC(a[27], a[42]); SQRADDAC(a[28], a[41]); SQRADDAC(a[29], a[40]); SQRADDAC(a[30], a[39]); SQRADDAC(a[31], a[38]); SQRADDAC(a[32], a[37]); SQRADDAC(a[33], a[36]); SQRADDAC(a[34], a[35]); SQRADDDB; + COMBA_STORE(b[69]); + + /* output 70 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[63]); SQRADDAC(a[8], a[62]); SQRADDAC(a[9], a[61]); SQRADDAC(a[10], a[60]); SQRADDAC(a[11], a[59]); SQRADDAC(a[12], a[58]); SQRADDAC(a[13], a[57]); SQRADDAC(a[14], a[56]); SQRADDAC(a[15], a[55]); SQRADDAC(a[16], a[54]); SQRADDAC(a[17], a[53]); SQRADDAC(a[18], a[52]); SQRADDAC(a[19], a[51]); SQRADDAC(a[20], a[50]); SQRADDAC(a[21], a[49]); SQRADDAC(a[22], a[48]); SQRADDAC(a[23], a[47]); SQRADDAC(a[24], a[46]); SQRADDAC(a[25], a[45]); SQRADDAC(a[26], a[44]); SQRADDAC(a[27], a[43]); SQRADDAC(a[28], a[42]); SQRADDAC(a[29], a[41]); SQRADDAC(a[30], a[40]); SQRADDAC(a[31], a[39]); SQRADDAC(a[32], a[38]); SQRADDAC(a[33], a[37]); SQRADDAC(a[34], a[36]); SQRADDDB; SQRADD(a[35], a[35]); + COMBA_STORE(b[70]); + + /* output 71 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[63]); SQRADDAC(a[9], a[62]); SQRADDAC(a[10], a[61]); SQRADDAC(a[11], a[60]); SQRADDAC(a[12], a[59]); SQRADDAC(a[13], a[58]); SQRADDAC(a[14], a[57]); SQRADDAC(a[15], a[56]); SQRADDAC(a[16], a[55]); SQRADDAC(a[17], a[54]); SQRADDAC(a[18], a[53]); SQRADDAC(a[19], a[52]); SQRADDAC(a[20], a[51]); SQRADDAC(a[21], a[50]); SQRADDAC(a[22], a[49]); SQRADDAC(a[23], a[48]); SQRADDAC(a[24], a[47]); SQRADDAC(a[25], a[46]); SQRADDAC(a[26], a[45]); SQRADDAC(a[27], a[44]); SQRADDAC(a[28], a[43]); SQRADDAC(a[29], a[42]); SQRADDAC(a[30], a[41]); SQRADDAC(a[31], a[40]); SQRADDAC(a[32], a[39]); SQRADDAC(a[33], a[38]); SQRADDAC(a[34], a[37]); SQRADDAC(a[35], a[36]); SQRADDDB; + COMBA_STORE(b[71]); + + /* output 72 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[63]); SQRADDAC(a[10], a[62]); SQRADDAC(a[11], a[61]); SQRADDAC(a[12], a[60]); SQRADDAC(a[13], a[59]); SQRADDAC(a[14], a[58]); SQRADDAC(a[15], a[57]); SQRADDAC(a[16], a[56]); SQRADDAC(a[17], a[55]); SQRADDAC(a[18], a[54]); SQRADDAC(a[19], a[53]); SQRADDAC(a[20], a[52]); SQRADDAC(a[21], a[51]); SQRADDAC(a[22], a[50]); SQRADDAC(a[23], a[49]); SQRADDAC(a[24], a[48]); SQRADDAC(a[25], a[47]); SQRADDAC(a[26], a[46]); SQRADDAC(a[27], a[45]); SQRADDAC(a[28], a[44]); SQRADDAC(a[29], a[43]); SQRADDAC(a[30], a[42]); SQRADDAC(a[31], a[41]); SQRADDAC(a[32], a[40]); SQRADDAC(a[33], a[39]); SQRADDAC(a[34], a[38]); SQRADDAC(a[35], a[37]); SQRADDDB; SQRADD(a[36], a[36]); + COMBA_STORE(b[72]); + + /* output 73 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[63]); SQRADDAC(a[11], a[62]); SQRADDAC(a[12], a[61]); SQRADDAC(a[13], a[60]); SQRADDAC(a[14], a[59]); SQRADDAC(a[15], a[58]); SQRADDAC(a[16], a[57]); SQRADDAC(a[17], a[56]); SQRADDAC(a[18], a[55]); SQRADDAC(a[19], a[54]); SQRADDAC(a[20], a[53]); SQRADDAC(a[21], a[52]); SQRADDAC(a[22], a[51]); SQRADDAC(a[23], a[50]); SQRADDAC(a[24], a[49]); SQRADDAC(a[25], a[48]); SQRADDAC(a[26], a[47]); SQRADDAC(a[27], a[46]); SQRADDAC(a[28], a[45]); SQRADDAC(a[29], a[44]); SQRADDAC(a[30], a[43]); SQRADDAC(a[31], a[42]); SQRADDAC(a[32], a[41]); SQRADDAC(a[33], a[40]); SQRADDAC(a[34], a[39]); SQRADDAC(a[35], a[38]); SQRADDAC(a[36], a[37]); SQRADDDB; + COMBA_STORE(b[73]); + + /* output 74 */ + CARRY_FORWARD; + SQRADDSC(a[11], a[63]); SQRADDAC(a[12], a[62]); SQRADDAC(a[13], a[61]); SQRADDAC(a[14], a[60]); SQRADDAC(a[15], a[59]); SQRADDAC(a[16], a[58]); SQRADDAC(a[17], a[57]); SQRADDAC(a[18], a[56]); SQRADDAC(a[19], a[55]); SQRADDAC(a[20], a[54]); SQRADDAC(a[21], a[53]); SQRADDAC(a[22], a[52]); SQRADDAC(a[23], a[51]); SQRADDAC(a[24], a[50]); SQRADDAC(a[25], a[49]); SQRADDAC(a[26], a[48]); SQRADDAC(a[27], a[47]); SQRADDAC(a[28], a[46]); SQRADDAC(a[29], a[45]); SQRADDAC(a[30], a[44]); SQRADDAC(a[31], a[43]); SQRADDAC(a[32], a[42]); SQRADDAC(a[33], a[41]); SQRADDAC(a[34], a[40]); SQRADDAC(a[35], a[39]); SQRADDAC(a[36], a[38]); SQRADDDB; SQRADD(a[37], a[37]); + COMBA_STORE(b[74]); + + /* output 75 */ + CARRY_FORWARD; + SQRADDSC(a[12], a[63]); SQRADDAC(a[13], a[62]); SQRADDAC(a[14], a[61]); SQRADDAC(a[15], a[60]); SQRADDAC(a[16], a[59]); SQRADDAC(a[17], a[58]); SQRADDAC(a[18], a[57]); SQRADDAC(a[19], a[56]); SQRADDAC(a[20], a[55]); SQRADDAC(a[21], a[54]); SQRADDAC(a[22], a[53]); SQRADDAC(a[23], a[52]); SQRADDAC(a[24], a[51]); SQRADDAC(a[25], a[50]); SQRADDAC(a[26], a[49]); SQRADDAC(a[27], a[48]); SQRADDAC(a[28], a[47]); SQRADDAC(a[29], a[46]); SQRADDAC(a[30], a[45]); SQRADDAC(a[31], a[44]); SQRADDAC(a[32], a[43]); SQRADDAC(a[33], a[42]); SQRADDAC(a[34], a[41]); SQRADDAC(a[35], a[40]); SQRADDAC(a[36], a[39]); SQRADDAC(a[37], a[38]); SQRADDDB; + COMBA_STORE(b[75]); + + /* output 76 */ + CARRY_FORWARD; + SQRADDSC(a[13], a[63]); SQRADDAC(a[14], a[62]); SQRADDAC(a[15], a[61]); SQRADDAC(a[16], a[60]); SQRADDAC(a[17], a[59]); SQRADDAC(a[18], a[58]); SQRADDAC(a[19], a[57]); SQRADDAC(a[20], a[56]); SQRADDAC(a[21], a[55]); SQRADDAC(a[22], a[54]); SQRADDAC(a[23], a[53]); SQRADDAC(a[24], a[52]); SQRADDAC(a[25], a[51]); SQRADDAC(a[26], a[50]); SQRADDAC(a[27], a[49]); SQRADDAC(a[28], a[48]); SQRADDAC(a[29], a[47]); SQRADDAC(a[30], a[46]); SQRADDAC(a[31], a[45]); SQRADDAC(a[32], a[44]); SQRADDAC(a[33], a[43]); SQRADDAC(a[34], a[42]); SQRADDAC(a[35], a[41]); SQRADDAC(a[36], a[40]); SQRADDAC(a[37], a[39]); SQRADDDB; SQRADD(a[38], a[38]); + COMBA_STORE(b[76]); + + /* output 77 */ + CARRY_FORWARD; + SQRADDSC(a[14], a[63]); SQRADDAC(a[15], a[62]); SQRADDAC(a[16], a[61]); SQRADDAC(a[17], a[60]); SQRADDAC(a[18], a[59]); SQRADDAC(a[19], a[58]); SQRADDAC(a[20], a[57]); SQRADDAC(a[21], a[56]); SQRADDAC(a[22], a[55]); SQRADDAC(a[23], a[54]); SQRADDAC(a[24], a[53]); SQRADDAC(a[25], a[52]); SQRADDAC(a[26], a[51]); SQRADDAC(a[27], a[50]); SQRADDAC(a[28], a[49]); SQRADDAC(a[29], a[48]); SQRADDAC(a[30], a[47]); SQRADDAC(a[31], a[46]); SQRADDAC(a[32], a[45]); SQRADDAC(a[33], a[44]); SQRADDAC(a[34], a[43]); SQRADDAC(a[35], a[42]); SQRADDAC(a[36], a[41]); SQRADDAC(a[37], a[40]); SQRADDAC(a[38], a[39]); SQRADDDB; + COMBA_STORE(b[77]); + + /* output 78 */ + CARRY_FORWARD; + SQRADDSC(a[15], a[63]); SQRADDAC(a[16], a[62]); SQRADDAC(a[17], a[61]); SQRADDAC(a[18], a[60]); SQRADDAC(a[19], a[59]); SQRADDAC(a[20], a[58]); SQRADDAC(a[21], a[57]); SQRADDAC(a[22], a[56]); SQRADDAC(a[23], a[55]); SQRADDAC(a[24], a[54]); SQRADDAC(a[25], a[53]); SQRADDAC(a[26], a[52]); SQRADDAC(a[27], a[51]); SQRADDAC(a[28], a[50]); SQRADDAC(a[29], a[49]); SQRADDAC(a[30], a[48]); SQRADDAC(a[31], a[47]); SQRADDAC(a[32], a[46]); SQRADDAC(a[33], a[45]); SQRADDAC(a[34], a[44]); SQRADDAC(a[35], a[43]); SQRADDAC(a[36], a[42]); SQRADDAC(a[37], a[41]); SQRADDAC(a[38], a[40]); SQRADDDB; SQRADD(a[39], a[39]); + COMBA_STORE(b[78]); + + /* output 79 */ + CARRY_FORWARD; + SQRADDSC(a[16], a[63]); SQRADDAC(a[17], a[62]); SQRADDAC(a[18], a[61]); SQRADDAC(a[19], a[60]); SQRADDAC(a[20], a[59]); SQRADDAC(a[21], a[58]); SQRADDAC(a[22], a[57]); SQRADDAC(a[23], a[56]); SQRADDAC(a[24], a[55]); SQRADDAC(a[25], a[54]); SQRADDAC(a[26], a[53]); SQRADDAC(a[27], a[52]); SQRADDAC(a[28], a[51]); SQRADDAC(a[29], a[50]); SQRADDAC(a[30], a[49]); SQRADDAC(a[31], a[48]); SQRADDAC(a[32], a[47]); SQRADDAC(a[33], a[46]); SQRADDAC(a[34], a[45]); SQRADDAC(a[35], a[44]); SQRADDAC(a[36], a[43]); SQRADDAC(a[37], a[42]); SQRADDAC(a[38], a[41]); SQRADDAC(a[39], a[40]); SQRADDDB; + COMBA_STORE(b[79]); + + /* output 80 */ + CARRY_FORWARD; + SQRADDSC(a[17], a[63]); SQRADDAC(a[18], a[62]); SQRADDAC(a[19], a[61]); SQRADDAC(a[20], a[60]); SQRADDAC(a[21], a[59]); SQRADDAC(a[22], a[58]); SQRADDAC(a[23], a[57]); SQRADDAC(a[24], a[56]); SQRADDAC(a[25], a[55]); SQRADDAC(a[26], a[54]); SQRADDAC(a[27], a[53]); SQRADDAC(a[28], a[52]); SQRADDAC(a[29], a[51]); SQRADDAC(a[30], a[50]); SQRADDAC(a[31], a[49]); SQRADDAC(a[32], a[48]); SQRADDAC(a[33], a[47]); SQRADDAC(a[34], a[46]); SQRADDAC(a[35], a[45]); SQRADDAC(a[36], a[44]); SQRADDAC(a[37], a[43]); SQRADDAC(a[38], a[42]); SQRADDAC(a[39], a[41]); SQRADDDB; SQRADD(a[40], a[40]); + COMBA_STORE(b[80]); + + /* output 81 */ + CARRY_FORWARD; + SQRADDSC(a[18], a[63]); SQRADDAC(a[19], a[62]); SQRADDAC(a[20], a[61]); SQRADDAC(a[21], a[60]); SQRADDAC(a[22], a[59]); SQRADDAC(a[23], a[58]); SQRADDAC(a[24], a[57]); SQRADDAC(a[25], a[56]); SQRADDAC(a[26], a[55]); SQRADDAC(a[27], a[54]); SQRADDAC(a[28], a[53]); SQRADDAC(a[29], a[52]); SQRADDAC(a[30], a[51]); SQRADDAC(a[31], a[50]); SQRADDAC(a[32], a[49]); SQRADDAC(a[33], a[48]); SQRADDAC(a[34], a[47]); SQRADDAC(a[35], a[46]); SQRADDAC(a[36], a[45]); SQRADDAC(a[37], a[44]); SQRADDAC(a[38], a[43]); SQRADDAC(a[39], a[42]); SQRADDAC(a[40], a[41]); SQRADDDB; + COMBA_STORE(b[81]); + + /* output 82 */ + CARRY_FORWARD; + SQRADDSC(a[19], a[63]); SQRADDAC(a[20], a[62]); SQRADDAC(a[21], a[61]); SQRADDAC(a[22], a[60]); SQRADDAC(a[23], a[59]); SQRADDAC(a[24], a[58]); SQRADDAC(a[25], a[57]); SQRADDAC(a[26], a[56]); SQRADDAC(a[27], a[55]); SQRADDAC(a[28], a[54]); SQRADDAC(a[29], a[53]); SQRADDAC(a[30], a[52]); SQRADDAC(a[31], a[51]); SQRADDAC(a[32], a[50]); SQRADDAC(a[33], a[49]); SQRADDAC(a[34], a[48]); SQRADDAC(a[35], a[47]); SQRADDAC(a[36], a[46]); SQRADDAC(a[37], a[45]); SQRADDAC(a[38], a[44]); SQRADDAC(a[39], a[43]); SQRADDAC(a[40], a[42]); SQRADDDB; SQRADD(a[41], a[41]); + COMBA_STORE(b[82]); + + /* output 83 */ + CARRY_FORWARD; + SQRADDSC(a[20], a[63]); SQRADDAC(a[21], a[62]); SQRADDAC(a[22], a[61]); SQRADDAC(a[23], a[60]); SQRADDAC(a[24], a[59]); SQRADDAC(a[25], a[58]); SQRADDAC(a[26], a[57]); SQRADDAC(a[27], a[56]); SQRADDAC(a[28], a[55]); SQRADDAC(a[29], a[54]); SQRADDAC(a[30], a[53]); SQRADDAC(a[31], a[52]); SQRADDAC(a[32], a[51]); SQRADDAC(a[33], a[50]); SQRADDAC(a[34], a[49]); SQRADDAC(a[35], a[48]); SQRADDAC(a[36], a[47]); SQRADDAC(a[37], a[46]); SQRADDAC(a[38], a[45]); SQRADDAC(a[39], a[44]); SQRADDAC(a[40], a[43]); SQRADDAC(a[41], a[42]); SQRADDDB; + COMBA_STORE(b[83]); + + /* output 84 */ + CARRY_FORWARD; + SQRADDSC(a[21], a[63]); SQRADDAC(a[22], a[62]); SQRADDAC(a[23], a[61]); SQRADDAC(a[24], a[60]); SQRADDAC(a[25], a[59]); SQRADDAC(a[26], a[58]); SQRADDAC(a[27], a[57]); SQRADDAC(a[28], a[56]); SQRADDAC(a[29], a[55]); SQRADDAC(a[30], a[54]); SQRADDAC(a[31], a[53]); SQRADDAC(a[32], a[52]); SQRADDAC(a[33], a[51]); SQRADDAC(a[34], a[50]); SQRADDAC(a[35], a[49]); SQRADDAC(a[36], a[48]); SQRADDAC(a[37], a[47]); SQRADDAC(a[38], a[46]); SQRADDAC(a[39], a[45]); SQRADDAC(a[40], a[44]); SQRADDAC(a[41], a[43]); SQRADDDB; SQRADD(a[42], a[42]); + COMBA_STORE(b[84]); + + /* output 85 */ + CARRY_FORWARD; + SQRADDSC(a[22], a[63]); SQRADDAC(a[23], a[62]); SQRADDAC(a[24], a[61]); SQRADDAC(a[25], a[60]); SQRADDAC(a[26], a[59]); SQRADDAC(a[27], a[58]); SQRADDAC(a[28], a[57]); SQRADDAC(a[29], a[56]); SQRADDAC(a[30], a[55]); SQRADDAC(a[31], a[54]); SQRADDAC(a[32], a[53]); SQRADDAC(a[33], a[52]); SQRADDAC(a[34], a[51]); SQRADDAC(a[35], a[50]); SQRADDAC(a[36], a[49]); SQRADDAC(a[37], a[48]); SQRADDAC(a[38], a[47]); SQRADDAC(a[39], a[46]); SQRADDAC(a[40], a[45]); SQRADDAC(a[41], a[44]); SQRADDAC(a[42], a[43]); SQRADDDB; + COMBA_STORE(b[85]); + + /* output 86 */ + CARRY_FORWARD; + SQRADDSC(a[23], a[63]); SQRADDAC(a[24], a[62]); SQRADDAC(a[25], a[61]); SQRADDAC(a[26], a[60]); SQRADDAC(a[27], a[59]); SQRADDAC(a[28], a[58]); SQRADDAC(a[29], a[57]); SQRADDAC(a[30], a[56]); SQRADDAC(a[31], a[55]); SQRADDAC(a[32], a[54]); SQRADDAC(a[33], a[53]); SQRADDAC(a[34], a[52]); SQRADDAC(a[35], a[51]); SQRADDAC(a[36], a[50]); SQRADDAC(a[37], a[49]); SQRADDAC(a[38], a[48]); SQRADDAC(a[39], a[47]); SQRADDAC(a[40], a[46]); SQRADDAC(a[41], a[45]); SQRADDAC(a[42], a[44]); SQRADDDB; SQRADD(a[43], a[43]); + COMBA_STORE(b[86]); + + /* output 87 */ + CARRY_FORWARD; + SQRADDSC(a[24], a[63]); SQRADDAC(a[25], a[62]); SQRADDAC(a[26], a[61]); SQRADDAC(a[27], a[60]); SQRADDAC(a[28], a[59]); SQRADDAC(a[29], a[58]); SQRADDAC(a[30], a[57]); SQRADDAC(a[31], a[56]); SQRADDAC(a[32], a[55]); SQRADDAC(a[33], a[54]); SQRADDAC(a[34], a[53]); SQRADDAC(a[35], a[52]); SQRADDAC(a[36], a[51]); SQRADDAC(a[37], a[50]); SQRADDAC(a[38], a[49]); SQRADDAC(a[39], a[48]); SQRADDAC(a[40], a[47]); SQRADDAC(a[41], a[46]); SQRADDAC(a[42], a[45]); SQRADDAC(a[43], a[44]); SQRADDDB; + COMBA_STORE(b[87]); + + /* output 88 */ + CARRY_FORWARD; + SQRADDSC(a[25], a[63]); SQRADDAC(a[26], a[62]); SQRADDAC(a[27], a[61]); SQRADDAC(a[28], a[60]); SQRADDAC(a[29], a[59]); SQRADDAC(a[30], a[58]); SQRADDAC(a[31], a[57]); SQRADDAC(a[32], a[56]); SQRADDAC(a[33], a[55]); SQRADDAC(a[34], a[54]); SQRADDAC(a[35], a[53]); SQRADDAC(a[36], a[52]); SQRADDAC(a[37], a[51]); SQRADDAC(a[38], a[50]); SQRADDAC(a[39], a[49]); SQRADDAC(a[40], a[48]); SQRADDAC(a[41], a[47]); SQRADDAC(a[42], a[46]); SQRADDAC(a[43], a[45]); SQRADDDB; SQRADD(a[44], a[44]); + COMBA_STORE(b[88]); + + /* output 89 */ + CARRY_FORWARD; + SQRADDSC(a[26], a[63]); SQRADDAC(a[27], a[62]); SQRADDAC(a[28], a[61]); SQRADDAC(a[29], a[60]); SQRADDAC(a[30], a[59]); SQRADDAC(a[31], a[58]); SQRADDAC(a[32], a[57]); SQRADDAC(a[33], a[56]); SQRADDAC(a[34], a[55]); SQRADDAC(a[35], a[54]); SQRADDAC(a[36], a[53]); SQRADDAC(a[37], a[52]); SQRADDAC(a[38], a[51]); SQRADDAC(a[39], a[50]); SQRADDAC(a[40], a[49]); SQRADDAC(a[41], a[48]); SQRADDAC(a[42], a[47]); SQRADDAC(a[43], a[46]); SQRADDAC(a[44], a[45]); SQRADDDB; + COMBA_STORE(b[89]); + + /* output 90 */ + CARRY_FORWARD; + SQRADDSC(a[27], a[63]); SQRADDAC(a[28], a[62]); SQRADDAC(a[29], a[61]); SQRADDAC(a[30], a[60]); SQRADDAC(a[31], a[59]); SQRADDAC(a[32], a[58]); SQRADDAC(a[33], a[57]); SQRADDAC(a[34], a[56]); SQRADDAC(a[35], a[55]); SQRADDAC(a[36], a[54]); SQRADDAC(a[37], a[53]); SQRADDAC(a[38], a[52]); SQRADDAC(a[39], a[51]); SQRADDAC(a[40], a[50]); SQRADDAC(a[41], a[49]); SQRADDAC(a[42], a[48]); SQRADDAC(a[43], a[47]); SQRADDAC(a[44], a[46]); SQRADDDB; SQRADD(a[45], a[45]); + COMBA_STORE(b[90]); + + /* output 91 */ + CARRY_FORWARD; + SQRADDSC(a[28], a[63]); SQRADDAC(a[29], a[62]); SQRADDAC(a[30], a[61]); SQRADDAC(a[31], a[60]); SQRADDAC(a[32], a[59]); SQRADDAC(a[33], a[58]); SQRADDAC(a[34], a[57]); SQRADDAC(a[35], a[56]); SQRADDAC(a[36], a[55]); SQRADDAC(a[37], a[54]); SQRADDAC(a[38], a[53]); SQRADDAC(a[39], a[52]); SQRADDAC(a[40], a[51]); SQRADDAC(a[41], a[50]); SQRADDAC(a[42], a[49]); SQRADDAC(a[43], a[48]); SQRADDAC(a[44], a[47]); SQRADDAC(a[45], a[46]); SQRADDDB; + COMBA_STORE(b[91]); + + /* output 92 */ + CARRY_FORWARD; + SQRADDSC(a[29], a[63]); SQRADDAC(a[30], a[62]); SQRADDAC(a[31], a[61]); SQRADDAC(a[32], a[60]); SQRADDAC(a[33], a[59]); SQRADDAC(a[34], a[58]); SQRADDAC(a[35], a[57]); SQRADDAC(a[36], a[56]); SQRADDAC(a[37], a[55]); SQRADDAC(a[38], a[54]); SQRADDAC(a[39], a[53]); SQRADDAC(a[40], a[52]); SQRADDAC(a[41], a[51]); SQRADDAC(a[42], a[50]); SQRADDAC(a[43], a[49]); SQRADDAC(a[44], a[48]); SQRADDAC(a[45], a[47]); SQRADDDB; SQRADD(a[46], a[46]); + COMBA_STORE(b[92]); + + /* output 93 */ + CARRY_FORWARD; + SQRADDSC(a[30], a[63]); SQRADDAC(a[31], a[62]); SQRADDAC(a[32], a[61]); SQRADDAC(a[33], a[60]); SQRADDAC(a[34], a[59]); SQRADDAC(a[35], a[58]); SQRADDAC(a[36], a[57]); SQRADDAC(a[37], a[56]); SQRADDAC(a[38], a[55]); SQRADDAC(a[39], a[54]); SQRADDAC(a[40], a[53]); SQRADDAC(a[41], a[52]); SQRADDAC(a[42], a[51]); SQRADDAC(a[43], a[50]); SQRADDAC(a[44], a[49]); SQRADDAC(a[45], a[48]); SQRADDAC(a[46], a[47]); SQRADDDB; + COMBA_STORE(b[93]); + + /* output 94 */ + CARRY_FORWARD; + SQRADDSC(a[31], a[63]); SQRADDAC(a[32], a[62]); SQRADDAC(a[33], a[61]); SQRADDAC(a[34], a[60]); SQRADDAC(a[35], a[59]); SQRADDAC(a[36], a[58]); SQRADDAC(a[37], a[57]); SQRADDAC(a[38], a[56]); SQRADDAC(a[39], a[55]); SQRADDAC(a[40], a[54]); SQRADDAC(a[41], a[53]); SQRADDAC(a[42], a[52]); SQRADDAC(a[43], a[51]); SQRADDAC(a[44], a[50]); SQRADDAC(a[45], a[49]); SQRADDAC(a[46], a[48]); SQRADDDB; SQRADD(a[47], a[47]); + COMBA_STORE(b[94]); + + /* output 95 */ + CARRY_FORWARD; + SQRADDSC(a[32], a[63]); SQRADDAC(a[33], a[62]); SQRADDAC(a[34], a[61]); SQRADDAC(a[35], a[60]); SQRADDAC(a[36], a[59]); SQRADDAC(a[37], a[58]); SQRADDAC(a[38], a[57]); SQRADDAC(a[39], a[56]); SQRADDAC(a[40], a[55]); SQRADDAC(a[41], a[54]); SQRADDAC(a[42], a[53]); SQRADDAC(a[43], a[52]); SQRADDAC(a[44], a[51]); SQRADDAC(a[45], a[50]); SQRADDAC(a[46], a[49]); SQRADDAC(a[47], a[48]); SQRADDDB; + COMBA_STORE(b[95]); + + /* output 96 */ + CARRY_FORWARD; + SQRADDSC(a[33], a[63]); SQRADDAC(a[34], a[62]); SQRADDAC(a[35], a[61]); SQRADDAC(a[36], a[60]); SQRADDAC(a[37], a[59]); SQRADDAC(a[38], a[58]); SQRADDAC(a[39], a[57]); SQRADDAC(a[40], a[56]); SQRADDAC(a[41], a[55]); SQRADDAC(a[42], a[54]); SQRADDAC(a[43], a[53]); SQRADDAC(a[44], a[52]); SQRADDAC(a[45], a[51]); SQRADDAC(a[46], a[50]); SQRADDAC(a[47], a[49]); SQRADDDB; SQRADD(a[48], a[48]); + COMBA_STORE(b[96]); + + /* output 97 */ + CARRY_FORWARD; + SQRADDSC(a[34], a[63]); SQRADDAC(a[35], a[62]); SQRADDAC(a[36], a[61]); SQRADDAC(a[37], a[60]); SQRADDAC(a[38], a[59]); SQRADDAC(a[39], a[58]); SQRADDAC(a[40], a[57]); SQRADDAC(a[41], a[56]); SQRADDAC(a[42], a[55]); SQRADDAC(a[43], a[54]); SQRADDAC(a[44], a[53]); SQRADDAC(a[45], a[52]); SQRADDAC(a[46], a[51]); SQRADDAC(a[47], a[50]); SQRADDAC(a[48], a[49]); SQRADDDB; + COMBA_STORE(b[97]); + + /* output 98 */ + CARRY_FORWARD; + SQRADDSC(a[35], a[63]); SQRADDAC(a[36], a[62]); SQRADDAC(a[37], a[61]); SQRADDAC(a[38], a[60]); SQRADDAC(a[39], a[59]); SQRADDAC(a[40], a[58]); SQRADDAC(a[41], a[57]); SQRADDAC(a[42], a[56]); SQRADDAC(a[43], a[55]); SQRADDAC(a[44], a[54]); SQRADDAC(a[45], a[53]); SQRADDAC(a[46], a[52]); SQRADDAC(a[47], a[51]); SQRADDAC(a[48], a[50]); SQRADDDB; SQRADD(a[49], a[49]); + COMBA_STORE(b[98]); + + /* output 99 */ + CARRY_FORWARD; + SQRADDSC(a[36], a[63]); SQRADDAC(a[37], a[62]); SQRADDAC(a[38], a[61]); SQRADDAC(a[39], a[60]); SQRADDAC(a[40], a[59]); SQRADDAC(a[41], a[58]); SQRADDAC(a[42], a[57]); SQRADDAC(a[43], a[56]); SQRADDAC(a[44], a[55]); SQRADDAC(a[45], a[54]); SQRADDAC(a[46], a[53]); SQRADDAC(a[47], a[52]); SQRADDAC(a[48], a[51]); SQRADDAC(a[49], a[50]); SQRADDDB; + COMBA_STORE(b[99]); + + /* output 100 */ + CARRY_FORWARD; + SQRADDSC(a[37], a[63]); SQRADDAC(a[38], a[62]); SQRADDAC(a[39], a[61]); SQRADDAC(a[40], a[60]); SQRADDAC(a[41], a[59]); SQRADDAC(a[42], a[58]); SQRADDAC(a[43], a[57]); SQRADDAC(a[44], a[56]); SQRADDAC(a[45], a[55]); SQRADDAC(a[46], a[54]); SQRADDAC(a[47], a[53]); SQRADDAC(a[48], a[52]); SQRADDAC(a[49], a[51]); SQRADDDB; SQRADD(a[50], a[50]); + COMBA_STORE(b[100]); + + /* output 101 */ + CARRY_FORWARD; + SQRADDSC(a[38], a[63]); SQRADDAC(a[39], a[62]); SQRADDAC(a[40], a[61]); SQRADDAC(a[41], a[60]); SQRADDAC(a[42], a[59]); SQRADDAC(a[43], a[58]); SQRADDAC(a[44], a[57]); SQRADDAC(a[45], a[56]); SQRADDAC(a[46], a[55]); SQRADDAC(a[47], a[54]); SQRADDAC(a[48], a[53]); SQRADDAC(a[49], a[52]); SQRADDAC(a[50], a[51]); SQRADDDB; + COMBA_STORE(b[101]); + + /* output 102 */ + CARRY_FORWARD; + SQRADDSC(a[39], a[63]); SQRADDAC(a[40], a[62]); SQRADDAC(a[41], a[61]); SQRADDAC(a[42], a[60]); SQRADDAC(a[43], a[59]); SQRADDAC(a[44], a[58]); SQRADDAC(a[45], a[57]); SQRADDAC(a[46], a[56]); SQRADDAC(a[47], a[55]); SQRADDAC(a[48], a[54]); SQRADDAC(a[49], a[53]); SQRADDAC(a[50], a[52]); SQRADDDB; SQRADD(a[51], a[51]); + COMBA_STORE(b[102]); + + /* output 103 */ + CARRY_FORWARD; + SQRADDSC(a[40], a[63]); SQRADDAC(a[41], a[62]); SQRADDAC(a[42], a[61]); SQRADDAC(a[43], a[60]); SQRADDAC(a[44], a[59]); SQRADDAC(a[45], a[58]); SQRADDAC(a[46], a[57]); SQRADDAC(a[47], a[56]); SQRADDAC(a[48], a[55]); SQRADDAC(a[49], a[54]); SQRADDAC(a[50], a[53]); SQRADDAC(a[51], a[52]); SQRADDDB; + COMBA_STORE(b[103]); + + /* output 104 */ + CARRY_FORWARD; + SQRADDSC(a[41], a[63]); SQRADDAC(a[42], a[62]); SQRADDAC(a[43], a[61]); SQRADDAC(a[44], a[60]); SQRADDAC(a[45], a[59]); SQRADDAC(a[46], a[58]); SQRADDAC(a[47], a[57]); SQRADDAC(a[48], a[56]); SQRADDAC(a[49], a[55]); SQRADDAC(a[50], a[54]); SQRADDAC(a[51], a[53]); SQRADDDB; SQRADD(a[52], a[52]); + COMBA_STORE(b[104]); + + /* output 105 */ + CARRY_FORWARD; + SQRADDSC(a[42], a[63]); SQRADDAC(a[43], a[62]); SQRADDAC(a[44], a[61]); SQRADDAC(a[45], a[60]); SQRADDAC(a[46], a[59]); SQRADDAC(a[47], a[58]); SQRADDAC(a[48], a[57]); SQRADDAC(a[49], a[56]); SQRADDAC(a[50], a[55]); SQRADDAC(a[51], a[54]); SQRADDAC(a[52], a[53]); SQRADDDB; + COMBA_STORE(b[105]); + + /* output 106 */ + CARRY_FORWARD; + SQRADDSC(a[43], a[63]); SQRADDAC(a[44], a[62]); SQRADDAC(a[45], a[61]); SQRADDAC(a[46], a[60]); SQRADDAC(a[47], a[59]); SQRADDAC(a[48], a[58]); SQRADDAC(a[49], a[57]); SQRADDAC(a[50], a[56]); SQRADDAC(a[51], a[55]); SQRADDAC(a[52], a[54]); SQRADDDB; SQRADD(a[53], a[53]); + COMBA_STORE(b[106]); + + /* output 107 */ + CARRY_FORWARD; + SQRADDSC(a[44], a[63]); SQRADDAC(a[45], a[62]); SQRADDAC(a[46], a[61]); SQRADDAC(a[47], a[60]); SQRADDAC(a[48], a[59]); SQRADDAC(a[49], a[58]); SQRADDAC(a[50], a[57]); SQRADDAC(a[51], a[56]); SQRADDAC(a[52], a[55]); SQRADDAC(a[53], a[54]); SQRADDDB; + COMBA_STORE(b[107]); + + /* output 108 */ + CARRY_FORWARD; + SQRADDSC(a[45], a[63]); SQRADDAC(a[46], a[62]); SQRADDAC(a[47], a[61]); SQRADDAC(a[48], a[60]); SQRADDAC(a[49], a[59]); SQRADDAC(a[50], a[58]); SQRADDAC(a[51], a[57]); SQRADDAC(a[52], a[56]); SQRADDAC(a[53], a[55]); SQRADDDB; SQRADD(a[54], a[54]); + COMBA_STORE(b[108]); + + /* output 109 */ + CARRY_FORWARD; + SQRADDSC(a[46], a[63]); SQRADDAC(a[47], a[62]); SQRADDAC(a[48], a[61]); SQRADDAC(a[49], a[60]); SQRADDAC(a[50], a[59]); SQRADDAC(a[51], a[58]); SQRADDAC(a[52], a[57]); SQRADDAC(a[53], a[56]); SQRADDAC(a[54], a[55]); SQRADDDB; + COMBA_STORE(b[109]); + + /* output 110 */ + CARRY_FORWARD; + SQRADDSC(a[47], a[63]); SQRADDAC(a[48], a[62]); SQRADDAC(a[49], a[61]); SQRADDAC(a[50], a[60]); SQRADDAC(a[51], a[59]); SQRADDAC(a[52], a[58]); SQRADDAC(a[53], a[57]); SQRADDAC(a[54], a[56]); SQRADDDB; SQRADD(a[55], a[55]); + COMBA_STORE(b[110]); + + /* output 111 */ + CARRY_FORWARD; + SQRADDSC(a[48], a[63]); SQRADDAC(a[49], a[62]); SQRADDAC(a[50], a[61]); SQRADDAC(a[51], a[60]); SQRADDAC(a[52], a[59]); SQRADDAC(a[53], a[58]); SQRADDAC(a[54], a[57]); SQRADDAC(a[55], a[56]); SQRADDDB; + COMBA_STORE(b[111]); + + /* output 112 */ + CARRY_FORWARD; + SQRADDSC(a[49], a[63]); SQRADDAC(a[50], a[62]); SQRADDAC(a[51], a[61]); SQRADDAC(a[52], a[60]); SQRADDAC(a[53], a[59]); SQRADDAC(a[54], a[58]); SQRADDAC(a[55], a[57]); SQRADDDB; SQRADD(a[56], a[56]); + COMBA_STORE(b[112]); + + /* output 113 */ + CARRY_FORWARD; + SQRADDSC(a[50], a[63]); SQRADDAC(a[51], a[62]); SQRADDAC(a[52], a[61]); SQRADDAC(a[53], a[60]); SQRADDAC(a[54], a[59]); SQRADDAC(a[55], a[58]); SQRADDAC(a[56], a[57]); SQRADDDB; + COMBA_STORE(b[113]); + + /* output 114 */ + CARRY_FORWARD; + SQRADDSC(a[51], a[63]); SQRADDAC(a[52], a[62]); SQRADDAC(a[53], a[61]); SQRADDAC(a[54], a[60]); SQRADDAC(a[55], a[59]); SQRADDAC(a[56], a[58]); SQRADDDB; SQRADD(a[57], a[57]); + COMBA_STORE(b[114]); + + /* output 115 */ + CARRY_FORWARD; + SQRADDSC(a[52], a[63]); SQRADDAC(a[53], a[62]); SQRADDAC(a[54], a[61]); SQRADDAC(a[55], a[60]); SQRADDAC(a[56], a[59]); SQRADDAC(a[57], a[58]); SQRADDDB; + COMBA_STORE(b[115]); + + /* output 116 */ + CARRY_FORWARD; + SQRADDSC(a[53], a[63]); SQRADDAC(a[54], a[62]); SQRADDAC(a[55], a[61]); SQRADDAC(a[56], a[60]); SQRADDAC(a[57], a[59]); SQRADDDB; SQRADD(a[58], a[58]); + COMBA_STORE(b[116]); + + /* output 117 */ + CARRY_FORWARD; + SQRADDSC(a[54], a[63]); SQRADDAC(a[55], a[62]); SQRADDAC(a[56], a[61]); SQRADDAC(a[57], a[60]); SQRADDAC(a[58], a[59]); SQRADDDB; + COMBA_STORE(b[117]); + + /* output 118 */ + CARRY_FORWARD; + SQRADDSC(a[55], a[63]); SQRADDAC(a[56], a[62]); SQRADDAC(a[57], a[61]); SQRADDAC(a[58], a[60]); SQRADDDB; SQRADD(a[59], a[59]); + COMBA_STORE(b[118]); + + /* output 119 */ + CARRY_FORWARD; + SQRADDSC(a[56], a[63]); SQRADDAC(a[57], a[62]); SQRADDAC(a[58], a[61]); SQRADDAC(a[59], a[60]); SQRADDDB; + COMBA_STORE(b[119]); + + /* output 120 */ + CARRY_FORWARD; + SQRADDSC(a[57], a[63]); SQRADDAC(a[58], a[62]); SQRADDAC(a[59], a[61]); SQRADDDB; SQRADD(a[60], a[60]); + COMBA_STORE(b[120]); + + /* output 121 */ + CARRY_FORWARD; + SQRADDSC(a[58], a[63]); SQRADDAC(a[59], a[62]); SQRADDAC(a[60], a[61]); SQRADDDB; + COMBA_STORE(b[121]); + + /* output 122 */ + CARRY_FORWARD; + SQRADD2(a[59], a[63]); SQRADD2(a[60], a[62]); SQRADD(a[61], a[61]); + COMBA_STORE(b[122]); + + /* output 123 */ + CARRY_FORWARD; + SQRADD2(a[60], a[63]); SQRADD2(a[61], a[62]); + COMBA_STORE(b[123]); + + /* output 124 */ + CARRY_FORWARD; + SQRADD2(a[61], a[63]); SQRADD(a[62], a[62]); + COMBA_STORE(b[124]); + + /* output 125 */ + CARRY_FORWARD; + SQRADD2(a[62], a[63]); + COMBA_STORE(b[125]); + + /* output 126 */ + CARRY_FORWARD; + SQRADD(a[63], a[63]); + COMBA_STORE(b[126]); + COMBA_STORE2(b[127]); + COMBA_FINI; + + B->used = 128; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 128 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_7.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_7.i new file mode 100644 index 00000000..9774991b --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_7.i @@ -0,0 +1,85 @@ +#ifdef TFM_SQR7 +void fp_sqr_comba7(fp_int *A, fp_int *B) +{ + fp_digit *a, b[14], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADD2(a[2], a[6]); SQRADD2(a[3], a[5]); SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADD2(a[3], a[6]); SQRADD2(a[4], a[5]); + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADD2(a[5], a[6]); + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + COMBA_STORE2(b[13]); + COMBA_FINI; + + B->used = 14; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 14 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_8.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_8.i new file mode 100644 index 00000000..e9d003b0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_8.i @@ -0,0 +1,95 @@ +#ifdef TFM_SQR8 +void fp_sqr_comba8(fp_int *A, fp_int *B) +{ + fp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]); + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADD2(a[6], a[7]); + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + COMBA_STORE2(b[15]); + COMBA_FINI; + + B->used = 16; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 16 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_9.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_9.i new file mode 100644 index 00000000..531a3252 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_9.i @@ -0,0 +1,105 @@ +#ifdef TFM_SQR9 +void fp_sqr_comba9(fp_int *A, fp_int *B) +{ + fp_digit *a, b[18], c0, c1, c2, sc0, sc1, sc2; + + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD2(a[4], a[8]); SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADD2(a[5], a[8]); SQRADD2(a[6], a[7]); + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD2(a[6], a[8]); SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADD2(a[7], a[8]); + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + COMBA_STORE2(b[17]); + COMBA_FINI; + + B->used = 18; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 18 * sizeof(fp_digit)); + fp_clamp(B); +} +#endif + + diff --git a/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_small_set.i b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_small_set.i new file mode 100644 index 00000000..29c3d1dd --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/fp_sqr_comba_small_set.i @@ -0,0 +1,1515 @@ +#if defined(TFM_SMALL_SET) +void fp_sqr_comba_small(fp_int *A, fp_int *B) +{ + fp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2; +#ifdef TFM_ISO + fp_word tt; +#endif + switch (A->used) { + case 1: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + COMBA_STORE2(b[1]); + COMBA_FINI; + + B->used = 2; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 2 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 2: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + COMBA_STORE2(b[3]); + COMBA_FINI; + + B->used = 4; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 4 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 3: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + COMBA_STORE2(b[5]); + COMBA_FINI; + + B->used = 6; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 6 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 4: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADD2(a[2], a[3]); + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + COMBA_STORE2(b[7]); + COMBA_FINI; + + B->used = 8; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 8 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 5: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADD2(a[1], a[4]); SQRADD2(a[2], a[3]); + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD2(a[2], a[4]); SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADD2(a[3], a[4]); + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + COMBA_STORE2(b[9]); + COMBA_FINI; + + B->used = 10; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 10 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 6: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADD2(a[1], a[5]); SQRADD2(a[2], a[4]); SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADD2(a[2], a[5]); SQRADD2(a[3], a[4]); + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADD2(a[3], a[5]); SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADD2(a[4], a[5]); + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + COMBA_STORE2(b[11]); + COMBA_FINI; + + B->used = 12; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 12 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 7: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADD2(a[2], a[6]); SQRADD2(a[3], a[5]); SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADD2(a[3], a[6]); SQRADD2(a[4], a[5]); + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADD2(a[5], a[6]); + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + COMBA_STORE2(b[13]); + COMBA_FINI; + + B->used = 14; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 14 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 8: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]); + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADD2(a[6], a[7]); + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + COMBA_STORE2(b[15]); + COMBA_FINI; + + B->used = 16; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 16 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 9: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADD2(a[4], a[8]); SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADD2(a[5], a[8]); SQRADD2(a[6], a[7]); + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD2(a[6], a[8]); SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADD2(a[7], a[8]); + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + COMBA_STORE2(b[17]); + COMBA_FINI; + + B->used = 18; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 18 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 10: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADD2(a[5], a[9]); SQRADD2(a[6], a[8]); SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADD2(a[6], a[9]); SQRADD2(a[7], a[8]); + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADD2(a[7], a[9]); SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADD2(a[8], a[9]); + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + COMBA_STORE2(b[19]); + COMBA_FINI; + + B->used = 20; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 20 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 11: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADD2(a[6], a[10]); SQRADD2(a[7], a[9]); SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADD2(a[7], a[10]); SQRADD2(a[8], a[9]); + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADD2(a[8], a[10]); SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADD2(a[9], a[10]); + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + COMBA_STORE2(b[21]); + COMBA_FINI; + + B->used = 22; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 22 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 12: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADD2(a[7], a[11]); SQRADD2(a[8], a[10]); SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADD2(a[8], a[11]); SQRADD2(a[9], a[10]); + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADD2(a[9], a[11]); SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADD2(a[10], a[11]); + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + COMBA_STORE2(b[23]); + COMBA_FINI; + + B->used = 24; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 24 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 13: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADD2(a[8], a[12]); SQRADD2(a[9], a[11]); SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADD2(a[9], a[12]); SQRADD2(a[10], a[11]); + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADD2(a[10], a[12]); SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADD2(a[11], a[12]); + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + COMBA_STORE2(b[25]); + COMBA_FINI; + + B->used = 26; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 26 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 14: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADD2(a[9], a[13]); SQRADD2(a[10], a[12]); SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADD2(a[10], a[13]); SQRADD2(a[11], a[12]); + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADD2(a[11], a[13]); SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADD2(a[12], a[13]); + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + COMBA_STORE2(b[27]); + COMBA_FINI; + + B->used = 28; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 28 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 15: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADD2(a[10], a[14]); SQRADD2(a[11], a[13]); SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADD2(a[11], a[14]); SQRADD2(a[12], a[13]); + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADD2(a[13], a[14]); + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + COMBA_STORE2(b[29]); + COMBA_FINI; + + B->used = 30; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 30 * sizeof(fp_digit)); + fp_clamp(B); + break; + + case 16: + a = A->dp; + COMBA_START; + + /* clear carries */ + CLEAR_CARRY; + + /* output 0 */ + SQRADD(a[0],a[0]); + COMBA_STORE(b[0]); + + /* output 1 */ + CARRY_FORWARD; + SQRADD2(a[0], a[1]); + COMBA_STORE(b[1]); + + /* output 2 */ + CARRY_FORWARD; + SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); + COMBA_STORE(b[2]); + + /* output 3 */ + CARRY_FORWARD; + SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); + COMBA_STORE(b[3]); + + /* output 4 */ + CARRY_FORWARD; + SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); + COMBA_STORE(b[4]); + + /* output 5 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; + COMBA_STORE(b[5]); + + /* output 6 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); + COMBA_STORE(b[6]); + + /* output 7 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; + COMBA_STORE(b[7]); + + /* output 8 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); + COMBA_STORE(b[8]); + + /* output 9 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; + COMBA_STORE(b[9]); + + /* output 10 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); + COMBA_STORE(b[10]); + + /* output 11 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; + COMBA_STORE(b[11]); + + /* output 12 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); + COMBA_STORE(b[12]); + + /* output 13 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; + COMBA_STORE(b[13]); + + /* output 14 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); + COMBA_STORE(b[14]); + + /* output 15 */ + CARRY_FORWARD; + SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; + COMBA_STORE(b[15]); + + /* output 16 */ + CARRY_FORWARD; + SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); + COMBA_STORE(b[16]); + + /* output 17 */ + CARRY_FORWARD; + SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; + COMBA_STORE(b[17]); + + /* output 18 */ + CARRY_FORWARD; + SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); + COMBA_STORE(b[18]); + + /* output 19 */ + CARRY_FORWARD; + SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; + COMBA_STORE(b[19]); + + /* output 20 */ + CARRY_FORWARD; + SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); + COMBA_STORE(b[20]); + + /* output 21 */ + CARRY_FORWARD; + SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; + COMBA_STORE(b[21]); + + /* output 22 */ + CARRY_FORWARD; + SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); + COMBA_STORE(b[22]); + + /* output 23 */ + CARRY_FORWARD; + SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; + COMBA_STORE(b[23]); + + /* output 24 */ + CARRY_FORWARD; + SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); + COMBA_STORE(b[24]); + + /* output 25 */ + CARRY_FORWARD; + SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; + COMBA_STORE(b[25]); + + /* output 26 */ + CARRY_FORWARD; + SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]); + COMBA_STORE(b[26]); + + /* output 27 */ + CARRY_FORWARD; + SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]); + COMBA_STORE(b[27]); + + /* output 28 */ + CARRY_FORWARD; + SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]); + COMBA_STORE(b[28]); + + /* output 29 */ + CARRY_FORWARD; + SQRADD2(a[14], a[15]); + COMBA_STORE(b[29]); + + /* output 30 */ + CARRY_FORWARD; + SQRADD(a[15], a[15]); + COMBA_STORE(b[30]); + COMBA_STORE2(b[31]); + COMBA_FINI; + + B->used = 32; + B->sign = FP_ZPOS; + memcpy(B->dp, b, 32 * sizeof(fp_digit)); + fp_clamp(B); + break; +} +} + +#endif /* TFM_SMALL_SET */ diff --git a/release/src/router/cyassl/ctaocrypt/src/hc128.c b/release/src/router/cyassl/ctaocrypt/src/hc128.c new file mode 100644 index 00000000..1ecb8f00 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/hc128.c @@ -0,0 +1,317 @@ +/* hc128.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_HC128 + +#include "hc128.h" +#include "misc.c" + + +#ifdef BIG_ENDIAN_ORDER + #define LITTLE32(x) ByteReverseWord32(x) +#else + #define LITTLE32(x) (x) +#endif + + +/*h1 function*/ +#define h1(ctx, x, y) { \ + byte a,c; \ + a = (byte) (x); \ + c = (byte) ((x) >> 16); \ + y = (ctx->T[512+a])+(ctx->T[512+256+c]); \ +} + +/*h2 function*/ +#define h2(ctx, x, y) { \ + byte a,c; \ + a = (byte) (x); \ + c = (byte) ((x) >> 16); \ + y = (ctx->T[a])+(ctx->T[256+c]); \ +} + +/*one step of HC-128, update P and generate 32 bits keystream*/ +#define step_P(ctx,u,v,a,b,c,d,n){ \ + word32 tem0,tem1,tem2,tem3; \ + h1((ctx),(ctx->X[(d)]),tem3); \ + tem0 = rotrFixed((ctx->T[(v)]),23); \ + tem1 = rotrFixed((ctx->X[(c)]),10); \ + tem2 = rotrFixed((ctx->X[(b)]),8); \ + (ctx->T[(u)]) += tem2+(tem0 ^ tem1); \ + (ctx->X[(a)]) = (ctx->T[(u)]); \ + (n) = tem3 ^ (ctx->T[(u)]) ; \ +} + +/*one step of HC-128, update Q and generate 32 bits keystream*/ +#define step_Q(ctx,u,v,a,b,c,d,n){ \ + word32 tem0,tem1,tem2,tem3; \ + h2((ctx),(ctx->Y[(d)]),tem3); \ + tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ + tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ + tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ + (ctx->T[(u)]) += tem2 + (tem0 ^ tem1); \ + (ctx->Y[(a)]) = (ctx->T[(u)]); \ + (n) = tem3 ^ (ctx->T[(u)]) ; \ +} + +/*16 steps of HC-128, generate 512 bits keystream*/ +static void generate_keystream(HC128* ctx, word32* keystream) +{ + word32 cc,dd; + cc = ctx->counter1024 & 0x1ff; + dd = (cc+16)&0x1ff; + + if (ctx->counter1024 < 512) + { + ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; + step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]); + step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]); + step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]); + step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]); + step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]); + step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]); + step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]); + step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]); + step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]); + step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]); + step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]); + step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]); + step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]); + step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]); + step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]); + step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]); + } + else + { + ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; + step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]); + step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]); + step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]); + step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]); + step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]); + step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]); + step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]); + step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]); + step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]); + step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]); + step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]); + step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]); + step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]); + step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]); + step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]); + step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]); + } +} + + +/* The following defines the initialization functions */ +#define f1(x) (rotrFixed((x),7) ^ rotrFixed((x),18) ^ ((x) >> 3)) +#define f2(x) (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10)) + +/*update table P*/ +#define update_P(ctx,u,v,a,b,c,d){ \ + word32 tem0,tem1,tem2,tem3; \ + tem0 = rotrFixed((ctx->T[(v)]),23); \ + tem1 = rotrFixed((ctx->X[(c)]),10); \ + tem2 = rotrFixed((ctx->X[(b)]),8); \ + h1((ctx),(ctx->X[(d)]),tem3); \ + (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ + (ctx->X[(a)]) = (ctx->T[(u)]); \ +} + +/*update table Q*/ +#define update_Q(ctx,u,v,a,b,c,d){ \ + word32 tem0,tem1,tem2,tem3; \ + tem0 = rotrFixed((ctx->T[(v)]),(32-23)); \ + tem1 = rotrFixed((ctx->Y[(c)]),(32-10)); \ + tem2 = rotrFixed((ctx->Y[(b)]),(32-8)); \ + h2((ctx),(ctx->Y[(d)]),tem3); \ + (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \ + (ctx->Y[(a)]) = (ctx->T[(u)]); \ +} + +/*16 steps of HC-128, without generating keystream, */ +/*but use the outputs to update P and Q*/ +static void setup_update(HC128* ctx) /*each time 16 steps*/ +{ + word32 cc,dd; + cc = ctx->counter1024 & 0x1ff; + dd = (cc+16)&0x1ff; + + if (ctx->counter1024 < 512) + { + ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; + update_P(ctx, cc+0, cc+1, 0, 6, 13, 4); + update_P(ctx, cc+1, cc+2, 1, 7, 14, 5); + update_P(ctx, cc+2, cc+3, 2, 8, 15, 6); + update_P(ctx, cc+3, cc+4, 3, 9, 0, 7); + update_P(ctx, cc+4, cc+5, 4, 10,1, 8); + update_P(ctx, cc+5, cc+6, 5, 11,2, 9); + update_P(ctx, cc+6, cc+7, 6, 12,3, 10); + update_P(ctx, cc+7, cc+8, 7, 13,4, 11); + update_P(ctx, cc+8, cc+9, 8, 14,5, 12); + update_P(ctx, cc+9, cc+10,9, 15,6, 13); + update_P(ctx, cc+10,cc+11,10,0, 7, 14); + update_P(ctx, cc+11,cc+12,11,1, 8, 15); + update_P(ctx, cc+12,cc+13,12,2, 9, 0); + update_P(ctx, cc+13,cc+14,13,3, 10, 1); + update_P(ctx, cc+14,cc+15,14,4, 11, 2); + update_P(ctx, cc+15,dd+0, 15,5, 12, 3); + } + else + { + ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff; + update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4); + update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5); + update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6); + update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7); + update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8); + update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9); + update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10); + update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11); + update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12); + update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13); + update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14); + update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15); + update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0); + update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1); + update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2); + update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3); + } +} + + +/* for the 128-bit key: key[0]...key[15] +* key[0] is the least significant byte of ctx->key[0] (K_0); +* key[3] is the most significant byte of ctx->key[0] (K_0); +* ... +* key[12] is the least significant byte of ctx->key[3] (K_3) +* key[15] is the most significant byte of ctx->key[3] (K_3) +* +* for the 128-bit iv: iv[0]...iv[15] +* iv[0] is the least significant byte of ctx->iv[0] (IV_0); +* iv[3] is the most significant byte of ctx->iv[0] (IV_0); +* ... +* iv[12] is the least significant byte of ctx->iv[3] (IV_3) +* iv[15] is the most significant byte of ctx->iv[3] (IV_3) +*/ + + + +static void Hc128_SetIV(HC128* ctx, const byte* iv) +{ + word32 i; + + for (i = 0; i < (128 >> 5); i++) + ctx->iv[i] = LITTLE32(((word32*)iv)[i]); + + for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4]; + + /* expand the key and IV into the table T */ + /* (expand the key and IV into the table P and Q) */ + + for (i = 0; i < 8; i++) ctx->T[i] = ctx->key[i]; + for (i = 8; i < 16; i++) ctx->T[i] = ctx->iv[i-8]; + + for (i = 16; i < (256+16); i++) + ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + + ctx->T[i-16]+i; + + for (i = 0; i < 16; i++) ctx->T[i] = ctx->T[256+i]; + + for (i = 16; i < 1024; i++) + ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + + ctx->T[i-16]+256+i; + + /* initialize counter1024, X and Y */ + ctx->counter1024 = 0; + for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i]; + for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i]; + + /* run the cipher 1024 steps before generating the output */ + for (i = 0; i < 64; i++) setup_update(ctx); +} + + +void Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv) +{ + word32 i; + + /* Key size in bits 128 */ + for (i = 0; i < (128 >> 5); i++) + ctx->key[i] = LITTLE32(((word32*)key)[i]); + + for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4]; + + Hc128_SetIV(ctx, iv); +} + + +/* The following defines the encryption of data stream */ +void Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen) +{ + word32 i, keystream[16]; + + for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64) + { + generate_keystream(ctx, keystream); + + /* unroll loop */ + ((word32*)output)[0] = ((word32*)input)[0] ^ LITTLE32(keystream[0]); + ((word32*)output)[1] = ((word32*)input)[1] ^ LITTLE32(keystream[1]); + ((word32*)output)[2] = ((word32*)input)[2] ^ LITTLE32(keystream[2]); + ((word32*)output)[3] = ((word32*)input)[3] ^ LITTLE32(keystream[3]); + ((word32*)output)[4] = ((word32*)input)[4] ^ LITTLE32(keystream[4]); + ((word32*)output)[5] = ((word32*)input)[5] ^ LITTLE32(keystream[5]); + ((word32*)output)[6] = ((word32*)input)[6] ^ LITTLE32(keystream[6]); + ((word32*)output)[7] = ((word32*)input)[7] ^ LITTLE32(keystream[7]); + ((word32*)output)[8] = ((word32*)input)[8] ^ LITTLE32(keystream[8]); + ((word32*)output)[9] = ((word32*)input)[9] ^ LITTLE32(keystream[9]); + ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]); + ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]); + ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]); + ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]); + ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]); + ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]); + } + + if (msglen > 0) + { + generate_keystream(ctx, keystream); + +#ifdef BIG_ENDIAN_ORDER + { + word32 wordsLeft = msglen / sizeof(word32); + if (msglen % sizeof(word32)) wordsLeft++; + + ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32)); + } +#endif + + for (i = 0; i < msglen; i++) + output[i] = input[i] ^ ((byte*)keystream)[i]; + } + +} + + +#endif /* NO_HC128 */ diff --git a/release/src/router/cyassl/ctaocrypt/src/hmac.c b/release/src/router/cyassl/ctaocrypt/src/hmac.c new file mode 100644 index 00000000..abeacb2f --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/hmac.c @@ -0,0 +1,158 @@ +/* hmac.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_HMAC + +#include "ctc_hmac.h" + + + +static int InitHmac(Hmac* hmac, int type) +{ + hmac->innerHashKeyed = 0; + hmac->macType = type; + + if (!(type == MD5 || type == SHA || type == SHA256)) + return -1; + + if (type == MD5) + InitMd5(&hmac->hash.md5); + else if (type == SHA) + InitSha(&hmac->hash.sha); +#ifndef NO_SHA256 + else if (type == SHA256) + InitSha256(&hmac->hash.sha256); +#endif + + return 0; +} + + +void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) +{ + byte* ip = (byte*) hmac->ipad; + byte* op = (byte*) hmac->opad; + word32 i; + + InitHmac(hmac, type); + + if (length <= HMAC_BLOCK_SIZE) + XMEMCPY(ip, key, length); + else { + if (hmac->macType == MD5) { + Md5Update(&hmac->hash.md5, key, length); + Md5Final(&hmac->hash.md5, ip); + length = MD5_DIGEST_SIZE; + } + else if (hmac->macType == SHA) { + ShaUpdate(&hmac->hash.sha, key, length); + ShaFinal(&hmac->hash.sha, ip); + length = SHA_DIGEST_SIZE; + } +#ifndef NO_SHA256 + else if (hmac->macType == SHA256) { + Sha256Update(&hmac->hash.sha256, key, length); + Sha256Final(&hmac->hash.sha256, ip); + length = SHA256_DIGEST_SIZE; + } +#endif + } + XMEMSET(ip + length, 0, HMAC_BLOCK_SIZE - length); + + for(i = 0; i < HMAC_BLOCK_SIZE; i++) { + op[i] = ip[i] ^ OPAD; + ip[i] ^= IPAD; + } +} + + +static void HmacKeyInnerHash(Hmac* hmac) +{ + if (hmac->macType == MD5) + Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); + else if (hmac->macType == SHA) + ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); +#ifndef NO_SHA256 + else if (hmac->macType == SHA256) + Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); +#endif + + hmac->innerHashKeyed = 1; +} + + +void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) +{ + if (!hmac->innerHashKeyed) + HmacKeyInnerHash(hmac); + + if (hmac->macType == MD5) + Md5Update(&hmac->hash.md5, msg, length); + else if (hmac->macType == SHA) + ShaUpdate(&hmac->hash.sha, msg, length); +#ifndef NO_SHA256 + else if (hmac->macType == SHA256) + Sha256Update(&hmac->hash.sha256, msg, length); +#endif + +} + + +void HmacFinal(Hmac* hmac, byte* hash) +{ + if (!hmac->innerHashKeyed) + HmacKeyInnerHash(hmac); + + if (hmac->macType == MD5) { + Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); + + Md5Update(&hmac->hash.md5, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); + + Md5Final(&hmac->hash.md5, hash); + } + else if (hmac->macType ==SHA) { + ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); + + ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); + + ShaFinal(&hmac->hash.sha, hash); + } +#ifndef NO_SHA256 + else if (hmac->macType ==SHA256) { + Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); + + Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, + SHA256_DIGEST_SIZE); + + Sha256Final(&hmac->hash.sha256, hash); + } +#endif + + hmac->innerHashKeyed = 0; +} + + +#endif /* NO_HMAC */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/integer.c b/release/src/router/cyassl/ctaocrypt/src/integer.c new file mode 100644 index 00000000..c8f1adb6 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/integer.c @@ -0,0 +1,4359 @@ +/* integer.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + + +#include "os_settings.h" /* in case user set USE_FAST_MATH there */ + +#ifndef USE_FAST_MATH + +#include "integer.h" + + +/* handle up to 6 inits */ +int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, + mp_int* f) +{ + int res = MP_OKAY; + + if (a && ((res = mp_init(a)) != MP_OKAY)) + return res; + + if (b && ((res = mp_init(b)) != MP_OKAY)) { + mp_clear(a); + return res; + } + + if (c && ((res = mp_init(c)) != MP_OKAY)) { + mp_clear(a); mp_clear(b); + return res; + } + + if (d && ((res = mp_init(d)) != MP_OKAY)) { + mp_clear(a); mp_clear(b); mp_clear(c); + return res; + } + + if (e && ((res = mp_init(e)) != MP_OKAY)) { + mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); + return res; + } + + if (f && ((res = mp_init(f)) != MP_OKAY)) { + mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e); + return res; + } + + return res; +} + + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC, 0, + DYNAMIC_TYPE_BIGINT); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} + + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} + + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} + + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} + + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, 0, + DYNAMIC_TYPE_BIGINT); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + + +/* shift right by a certain bit count (store quotient in c, optional + remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous + word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + + +/* set to zero */ +void mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} + + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} + + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) << + (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} + + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} + + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + mp_clear(&tmpX); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear(&tmpG); + mp_clear(&tmpX); + return err; +#else + /* no invmod */ + return MP_VAL; +#endif + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \ + defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} + + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif +} + + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on slow invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + + /* we need y = |a| */ + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +LBL_ERR:mp_clear(&x); + mp_clear(&y); + mp_clear(&u); + mp_clear(&v); + mp_clear(&B); + mp_clear(&D); + return res; +} + + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B)) != MP_OKAY) { + return res; + } + + /* init rest of tmps temps */ + if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear(&x); + mp_clear(&y); + mp_clear(&u); + mp_clear(&v); + mp_clear(&A); + mp_clear(&B); + mp_clear(&C); + mp_clear(&D); + return res; +} + + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} + + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} + + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} + + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} + + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} + + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear(&ta); + mp_clear(&tb); + mp_clear(&tq); + mp_clear(&q); + return res; +} + + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} + + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + + +/* determines if reduce_2k_l can be used */ +int mp_reduce_is_2k_l(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + /* if more than half of the digits are -1 we're sold */ + for (iy = ix = 0; ix < a->used; ix++) { + if (a->dp[ix] == MP_MASK) { + ++iy; + } + } + return (iy >= (a->used/2)) ? MP_YES : MP_NO; + + } + return MP_NO; +} + + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iw; + mp_digit iz; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return MP_NO; + } + iz <<= 1; + if (iz > (mp_digit)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return MP_YES; +} + + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular + * exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, + int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few + calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + /* TAO, switched mp_word casts to mp_digit to shut up compiler */ + *rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} + + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} + + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} + + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Joong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} + + +/* reduces a modulo n where n is of the form 2**p - d */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* determines the setup value */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} + + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} + + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} + + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} + + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} + + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} + + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, 0, + DYNAMIC_TYPE_BIGINT); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} + + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} + + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} + + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} + + +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} + + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} + + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} + + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* determines the setup value */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} + + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} + + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix <= pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + + +#if defined(CYASSL_KEY_GEN) || defined(HAVE_ECC) + +/* c = a * a (mod b) */ +int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} + + +int mp_sub_d (mp_int* a, mp_digit b, mp_int* c); + +/* single digit addition */ +int mp_add_d (mp_int* a, mp_digit b, mp_int* c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + + +/* single digit subtraction */ +int mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif /* CYASSL_KEY_GEN || HAVE_ECC */ + + +#ifdef CYASSL_KEY_GEN + +int mp_cnt_lsb(mp_int *a); + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b==0) || (b & (b-1))) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} + + +const mp_digit ltm_prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; + + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto LBL_Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto LBL_Y; + } + } + + /* probably prime now */ + *result = MP_YES; +LBL_Y:mp_clear (&y); +LBL_R:mp_clear (&r); +LBL_N1:mp_clear (&n1); + return err; +} + + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} + + +/* + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, ltm_prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + + if (res == MP_NO) { + goto LBL_B; + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B:mp_clear (&b); + return err; +} + + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto LBL_T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +LBL_T: + mp_clear(&t1); + mp_clear(&t2); + return res; +} + + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == MP_YES) { + return mp_abs (b, c); + } + if (mp_iszero (b) == MP_YES) { + return mp_abs (a, c); + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto LBL_U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +LBL_V:mp_clear (&u); +LBL_U:mp_clear (&v); + return res; +} + + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} + +#endif /* CYASSL_KEY_GEN */ + + +#ifdef HAVE_ECC + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, const char *str, int radix) +{ + int y, res, neg; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} + +#endif /* HAVE_ECC */ + +#endif /* USE_FAST_MATH */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/md4.c b/release/src/router/cyassl/ctaocrypt/src/md4.c new file mode 100644 index 00000000..0dcc59d0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/md4.c @@ -0,0 +1,215 @@ +/* md4.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_MD4 + +#include "ctc_md4.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitMd4(Md4* md4) +{ + md4->digest[0] = 0x67452301L; + md4->digest[1] = 0xefcdab89L; + md4->digest[2] = 0x98badcfeL; + md4->digest[3] = 0x10325476L; + + md4->buffLen = 0; + md4->loLen = 0; + md4->hiLen = 0; +} + + +static void Transform(Md4* md4) +{ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + + /* Copy context->state[] to working vars */ + word32 A = md4->digest[0]; + word32 B = md4->digest[1]; + word32 C = md4->digest[2]; + word32 D = md4->digest[3]; + +#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 1, 7); + function(C,D,A,B, 2,11); + function(B,C,D,A, 3,19); + function(A,B,C,D, 4, 3); + function(D,A,B,C, 5, 7); + function(C,D,A,B, 6,11); + function(B,C,D,A, 7,19); + function(A,B,C,D, 8, 3); + function(D,A,B,C, 9, 7); + function(C,D,A,B,10,11); + function(B,C,D,A,11,19); + function(A,B,C,D,12, 3); + function(D,A,B,C,13, 7); + function(C,D,A,B,14,11); + function(B,C,D,A,15,19); + +#undef function +#define function(a,b,c,d,k,s) \ + a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s); + + function(A,B,C,D, 0, 3); + function(D,A,B,C, 4, 5); + function(C,D,A,B, 8, 9); + function(B,C,D,A,12,13); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 5, 5); + function(C,D,A,B, 9, 9); + function(B,C,D,A,13,13); + function(A,B,C,D, 2, 3); + function(D,A,B,C, 6, 5); + function(C,D,A,B,10, 9); + function(B,C,D,A,14,13); + function(A,B,C,D, 3, 3); + function(D,A,B,C, 7, 5); + function(C,D,A,B,11, 9); + function(B,C,D,A,15,13); + +#undef function +#define function(a,b,c,d,k,s) \ + a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s); + + function(A,B,C,D, 0, 3); + function(D,A,B,C, 8, 9); + function(C,D,A,B, 4,11); + function(B,C,D,A,12,15); + function(A,B,C,D, 2, 3); + function(D,A,B,C,10, 9); + function(C,D,A,B, 6,11); + function(B,C,D,A,14,15); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 9, 9); + function(C,D,A,B, 5,11); + function(B,C,D,A,13,15); + function(A,B,C,D, 3, 3); + function(D,A,B,C,11, 9); + function(C,D,A,B, 7,11); + function(B,C,D,A,15,15); + + /* Add the working vars back into digest state[] */ + md4->digest[0] += A; + md4->digest[1] += B; + md4->digest[2] += C; + md4->digest[3] += D; +} + + +static INLINE void AddLength(Md4* md4, word32 len) +{ + word32 tmp = md4->loLen; + if ( (md4->loLen += len) < tmp) + md4->hiLen++; /* carry low to high */ +} + + +void Md4Update(Md4* md4, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)md4->buffer; + + while (len) { + word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen); + XMEMCPY(&local[md4->buffLen], data, add); + + md4->buffLen += add; + data += add; + len -= add; + + if (md4->buffLen == MD4_BLOCK_SIZE) { + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD4_BLOCK_SIZE); + #endif + Transform(md4); + AddLength(md4, MD4_BLOCK_SIZE); + md4->buffLen = 0; + } + } +} + + +void Md4Final(Md4* md4, byte* hash) +{ + byte* local = (byte*)md4->buffer; + + AddLength(md4, md4->buffLen); /* before adding pads */ + + local[md4->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (md4->buffLen > MD4_PAD_SIZE) { + XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen); + md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen; + + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD4_BLOCK_SIZE); + #endif + Transform(md4); + md4->buffLen = 0; + } + XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen); + + /* put lengths in bits */ + md4->loLen = md4->loLen << 3; + md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) + + (md4->hiLen << 3); + + /* store lengths */ + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD4_BLOCK_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32)); + XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32)); + + Transform(md4); + #ifdef BIG_ENDIAN_ORDER + ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE); + #endif + XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE); + + InitMd4(md4); /* reset state */ +} + + +#endif /* NO_MD4 */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/md5.c b/release/src/router/cyassl/ctaocrypt/src/md5.c new file mode 100644 index 00000000..6ee957ae --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/md5.c @@ -0,0 +1,222 @@ +/* md5.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "ctc_md5.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitMd5(Md5* md5) +{ + md5->digest[0] = 0x67452301L; + md5->digest[1] = 0xefcdab89L; + md5->digest[2] = 0x98badcfeL; + md5->digest[3] = 0x10325476L; + + md5->buffLen = 0; + md5->loLen = 0; + md5->hiLen = 0; +} + + +static void Transform(Md5* md5) +{ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, data, s) \ + w = rotlFixed(w + f(x, y, z) + data, s) + x + + /* Copy context->state[] to working vars */ + word32 a = md5->digest[0]; + word32 b = md5->digest[1]; + word32 c = md5->digest[2]; + word32 d = md5->digest[3]; + + MD5STEP(F1, a, b, c, d, md5->buffer[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, md5->buffer[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, md5->buffer[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, md5->buffer[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, md5->buffer[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, md5->buffer[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, md5->buffer[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, md5->buffer[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, md5->buffer[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, md5->buffer[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, md5->buffer[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, md5->buffer[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, md5->buffer[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, md5->buffer[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, md5->buffer[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, md5->buffer[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, md5->buffer[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, md5->buffer[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, md5->buffer[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, md5->buffer[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, md5->buffer[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, md5->buffer[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, md5->buffer[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, md5->buffer[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, md5->buffer[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, md5->buffer[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, md5->buffer[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, md5->buffer[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, md5->buffer[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, md5->buffer[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, md5->buffer[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, md5->buffer[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, md5->buffer[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, md5->buffer[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, md5->buffer[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, md5->buffer[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, md5->buffer[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, md5->buffer[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, md5->buffer[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, md5->buffer[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, md5->buffer[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, md5->buffer[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, md5->buffer[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, md5->buffer[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, md5->buffer[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, md5->buffer[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, md5->buffer[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, md5->buffer[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, md5->buffer[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, md5->buffer[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, md5->buffer[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, md5->buffer[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, md5->buffer[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, md5->buffer[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, md5->buffer[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, md5->buffer[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, md5->buffer[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, md5->buffer[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, md5->buffer[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, md5->buffer[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, md5->buffer[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, md5->buffer[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, md5->buffer[9] + 0xeb86d391, 21); + + /* Add the working vars back into digest state[] */ + md5->digest[0] += a; + md5->digest[1] += b; + md5->digest[2] += c; + md5->digest[3] += d; +} + + +static INLINE void AddLength(Md5* md5, word32 len) +{ + word32 tmp = md5->loLen; + if ( (md5->loLen += len) < tmp) + md5->hiLen++; /* carry low to high */ +} + + +void Md5Update(Md5* md5, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)md5->buffer; + + while (len) { + word32 add = min(len, MD5_BLOCK_SIZE - md5->buffLen); + XMEMCPY(&local[md5->buffLen], data, add); + + md5->buffLen += add; + data += add; + len -= add; + + if (md5->buffLen == MD5_BLOCK_SIZE) { + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD5_BLOCK_SIZE); + #endif + Transform(md5); + AddLength(md5, MD5_BLOCK_SIZE); + md5->buffLen = 0; + } + } +} + + +void Md5Final(Md5* md5, byte* hash) +{ + byte* local = (byte*)md5->buffer; + + AddLength(md5, md5->buffLen); /* before adding pads */ + + local[md5->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (md5->buffLen > MD5_PAD_SIZE) { + XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen); + md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen; + + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD5_BLOCK_SIZE); + #endif + Transform(md5); + md5->buffLen = 0; + } + XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen); + + /* put lengths in bits */ + md5->loLen = md5->loLen << 3; + md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + + (md5->hiLen << 3); + + /* store lengths */ + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, MD5_BLOCK_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32)); + XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32)); + + Transform(md5); + #ifdef BIG_ENDIAN_ORDER + ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); + #endif + XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); + + InitMd5(md5); /* reset state */ +} + diff --git a/release/src/router/cyassl/ctaocrypt/src/misc.c b/release/src/router/cyassl/ctaocrypt/src/misc.c new file mode 100644 index 00000000..bd283064 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/misc.c @@ -0,0 +1,171 @@ +/* misc.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "misc.h" + +/* inlining these functions is a huge speed increase and a small size decrease, + because the functions are smaller than function call setup/cleanup, e.g., + md5 benchmark is twice as fast with inline. If you don't want it, then + define NO_INLINE and compile this file into cyassl, otherwise it's used as + a source header + */ + +#ifdef NO_INLINE + #define STATIC +#else + #define STATIC static +#endif + + +#ifdef INTEL_INTRINSICS + + #include /* get intrinsic definitions */ + + #pragma intrinsic(_lrotl, _lrotr) + + STATIC INLINE word32 rotlFixed(word32 x, word32 y) + { + return y ? _lrotl(x, y) : x; + } + + STATIC INLINE word32 rotrFixed(word32 x, word32 y) + { + return y ? _lrotr(x, y) : x; + } + +#else /* generic */ + + STATIC INLINE word32 rotlFixed(word32 x, word32 y) + { + return (x << y) | (x >> (sizeof(y) * 8 - y)); + } + + + STATIC INLINE word32 rotrFixed(word32 x, word32 y) + { + return (x >> y) | (x << (sizeof(y) * 8 - y)); + } + +#endif + + +STATIC INLINE word32 ByteReverseWord32(word32 value) +{ +#ifdef PPC_INTRINSICS + /* PPC: load reverse indexed instruction */ + return (word32)__lwbrx(&value,0); +#elif defined(FAST_ROTATE) + /* 5 instructions with rotate instruction, 9 without */ + return (rotrFixed(value, 8U) & 0xff00ff00) | + (rotlFixed(value, 8U) & 0x00ff00ff); +#else + /* 6 instructions with rotate instruction, 8 without */ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + + +STATIC INLINE void ByteReverseWords(word32* out, const word32* in, + word32 byteCount) +{ + word32 count = byteCount/sizeof(word32), i; + + for (i = 0; i < count; i++) + out[i] = ByteReverseWord32(in[i]); + +} + + +#ifdef WORD64_AVAILABLE + + +STATIC INLINE word64 rotlFixed64(word64 x, word64 y) +{ + return (x << y) | (x >> (sizeof(y) * 8 - y)); +} + + +STATIC INLINE word64 rotrFixed64(word64 x, word64 y) +{ + return (x >> y) | (x << (sizeof(y) * 8 - y)); +} + + +STATIC INLINE word64 ByteReverseWord64(word64 value) +{ +#ifdef CTAOCRYPT_SLOW_WORD64 + return (word64)(ByteReverseWord32((word32)value)) << 32 | + ByteReverseWord32((word32)(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | + ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | + ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed64(value, 32U); +#endif +} + + +STATIC INLINE void ByteReverseWords64(word64* out, const word64* in, + word32 byteCount) +{ + word32 count = byteCount/sizeof(word64), i; + + for (i = 0; i < count; i++) + out[i] = ByteReverseWord64(in[i]); + +} + +#endif /* WORD64_AVAILABLE */ + + +STATIC INLINE void ByteReverseBytes(byte* out, const byte* in, word32 byteCount) +{ + word32* op = (word32*)out; + const word32* ip = (const word32*)in; + + ByteReverseWords(op, ip, byteCount); +} + + +STATIC INLINE void XorWords(word* r, const word* a, word32 n) +{ + word32 i; + + for (i = 0; i < n; i++) r[i] ^= a[i]; +} + + +STATIC INLINE void xorbuf(byte* buf, const byte* mask, word32 count) +{ + if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0) + XorWords( (word*)buf, (const word*)mask, count / WORD_SIZE); + else { + word32 i; + for (i = 0; i < count; i++) buf[i] ^= mask[i]; + } +} + + +#undef STATIC + diff --git a/release/src/router/cyassl/ctaocrypt/src/pwdbased.c b/release/src/router/cyassl/ctaocrypt/src/pwdbased.c new file mode 100644 index 00000000..2cd380f0 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/pwdbased.c @@ -0,0 +1,76 @@ +/* pwdbased.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_PWDBASED + +#include "pwdbased.h" + + +int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, + int sLen, int iterations, int kLen, int hashType) +{ + Md5 md5; + Sha sha; + int hLen = (hashType == MD5) ? MD5_DIGEST_SIZE : SHA_DIGEST_SIZE; + int i; + byte buffer[SHA_DIGEST_SIZE]; /* max size */ + + if (hashType != MD5 && hashType != SHA) + return -1; + + if (kLen > hLen) + return -1; + + if (iterations < 1) + return -1; + + if (hashType == MD5) { + InitMd5(&md5); + Md5Update(&md5, passwd, pLen); + Md5Update(&md5, salt, sLen); + Md5Final(&md5, buffer); + } + else { + InitSha(&sha); + ShaUpdate(&sha, passwd, pLen); + ShaUpdate(&sha, salt, sLen); + ShaFinal(&sha, buffer); + } + + for (i = 1; i < iterations; i++) { + if (hashType == MD5) { + Md5Update(&md5, buffer, hLen); + Md5Final(&md5, buffer); + } + else { + ShaUpdate(&sha, buffer, hLen); + ShaFinal(&sha, buffer); + } + } + XMEMCPY(output, buffer, kLen); + + return 0; +} + + +#endif /* NO_PWDBASED */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/rabbit.c b/release/src/router/cyassl/ctaocrypt/src/rabbit.c new file mode 100644 index 00000000..2cb5241a --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/rabbit.c @@ -0,0 +1,239 @@ +/* rabbit.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifndef NO_RABBIT + +#include "rabbit.h" +#include "misc.c" + + +#ifdef BIG_ENDIAN_ORDER + #define LITTLE32(x) ByteReverseWord32(x) +#else + #define LITTLE32(x) (x) +#endif + +#define U32V(x) (word32)(x) + + +/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */ +/* the upper 32 bits XOR the lower 32 bits */ +static word32 RABBIT_g_func(word32 x) +{ + /* Temporary variables */ + word32 a, b, h, l; + + /* Construct high and low argument for squaring */ + a = x&0xFFFF; + b = x>>16; + + /* Calculate high and low result of squaring */ + h = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b; + l = x*x; + + /* Return high XOR low */ + return U32V(h^l); +} + + +/* Calculate the next internal state */ +static void RABBIT_next_state(RabbitCtx* ctx) +{ + /* Temporary variables */ + word32 g[8], c_old[8], i; + + /* Save old counter values */ + for (i=0; i<8; i++) + c_old[i] = ctx->c[i]; + + /* Calculate new counter values */ + ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry); + ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0])); + ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1])); + ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2])); + ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3])); + ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4])); + ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5])); + ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6])); + ctx->carry = (ctx->c[7] < c_old[7]); + + /* Calculate the g-values */ + for (i=0;i<8;i++) + g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i])); + + /* Calculate new state values */ + ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16)); + ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]); + ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16)); + ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]); + ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16)); + ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]); + ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16)); + ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]); +} + + +/* IV setup */ +static void RabbitSetIV(Rabbit* ctx, const byte* iv) +{ + /* Temporary variables */ + word32 i0, i1, i2, i3, i; + + /* Generate four subvectors */ + i0 = LITTLE32(*(word32*)(iv+0)); + i2 = LITTLE32(*(word32*)(iv+4)); + i1 = (i0>>16) | (i2&0xFFFF0000); + i3 = (i2<<16) | (i0&0x0000FFFF); + + /* Modify counter values */ + ctx->workCtx.c[0] = ctx->masterCtx.c[0] ^ i0; + ctx->workCtx.c[1] = ctx->masterCtx.c[1] ^ i1; + ctx->workCtx.c[2] = ctx->masterCtx.c[2] ^ i2; + ctx->workCtx.c[3] = ctx->masterCtx.c[3] ^ i3; + ctx->workCtx.c[4] = ctx->masterCtx.c[4] ^ i0; + ctx->workCtx.c[5] = ctx->masterCtx.c[5] ^ i1; + ctx->workCtx.c[6] = ctx->masterCtx.c[6] ^ i2; + ctx->workCtx.c[7] = ctx->masterCtx.c[7] ^ i3; + + /* Copy state variables */ + for (i=0; i<8; i++) + ctx->workCtx.x[i] = ctx->masterCtx.x[i]; + ctx->workCtx.carry = ctx->masterCtx.carry; + + /* Iterate the system four times */ + for (i=0; i<4; i++) + RABBIT_next_state(&(ctx->workCtx)); +} + + +/* Key setup */ +void RabbitSetKey(Rabbit* ctx, const byte* key, const byte* iv) +{ + /* Temporary variables */ + word32 k0, k1, k2, k3, i; + + /* Generate four subkeys */ + k0 = LITTLE32(*(word32*)(key+ 0)); + k1 = LITTLE32(*(word32*)(key+ 4)); + k2 = LITTLE32(*(word32*)(key+ 8)); + k3 = LITTLE32(*(word32*)(key+12)); + + /* Generate initial state variables */ + ctx->masterCtx.x[0] = k0; + ctx->masterCtx.x[2] = k1; + ctx->masterCtx.x[4] = k2; + ctx->masterCtx.x[6] = k3; + ctx->masterCtx.x[1] = U32V(k3<<16) | (k2>>16); + ctx->masterCtx.x[3] = U32V(k0<<16) | (k3>>16); + ctx->masterCtx.x[5] = U32V(k1<<16) | (k0>>16); + ctx->masterCtx.x[7] = U32V(k2<<16) | (k1>>16); + + /* Generate initial counter values */ + ctx->masterCtx.c[0] = rotlFixed(k2, 16); + ctx->masterCtx.c[2] = rotlFixed(k3, 16); + ctx->masterCtx.c[4] = rotlFixed(k0, 16); + ctx->masterCtx.c[6] = rotlFixed(k1, 16); + ctx->masterCtx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF); + ctx->masterCtx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF); + ctx->masterCtx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF); + ctx->masterCtx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF); + + /* Clear carry bit */ + ctx->masterCtx.carry = 0; + + /* Iterate the system four times */ + for (i=0; i<4; i++) + RABBIT_next_state(&(ctx->masterCtx)); + + /* Modify the counters */ + for (i=0; i<8; i++) + ctx->masterCtx.c[i] ^= ctx->masterCtx.x[(i+4)&0x7]; + + /* Copy master instance to work instance */ + for (i=0; i<8; i++) { + ctx->workCtx.x[i] = ctx->masterCtx.x[i]; + ctx->workCtx.c[i] = ctx->masterCtx.c[i]; + } + ctx->workCtx.carry = ctx->masterCtx.carry; + + if (iv) RabbitSetIV(ctx, iv); +} + + +/* Encrypt/decrypt a message of any size */ +void RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen) +{ + + /* Encrypt/decrypt all full blocks */ + while (msglen >= 16) { + /* Iterate the system */ + RABBIT_next_state(&(ctx->workCtx)); + + /* Encrypt/decrypt 16 bytes of data */ + *(word32*)(output+ 0) = *(word32*)(input+ 0) ^ + LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^ + U32V(ctx->workCtx.x[3]<<16)); + *(word32*)(output+ 4) = *(word32*)(input+ 4) ^ + LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^ + U32V(ctx->workCtx.x[5]<<16)); + *(word32*)(output+ 8) = *(word32*)(input+ 8) ^ + LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^ + U32V(ctx->workCtx.x[7]<<16)); + *(word32*)(output+12) = *(word32*)(input+12) ^ + LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^ + U32V(ctx->workCtx.x[1]<<16)); + + /* Increment pointers and decrement length */ + input += 16; + output += 16; + msglen -= 16; + } + + /* Encrypt/decrypt remaining data */ + if (msglen) { + + word32 i; + word32 tmp[4]; + byte* buffer = (byte*)tmp; + + /* Iterate the system */ + RABBIT_next_state(&(ctx->workCtx)); + + /* Generate 16 bytes of pseudo-random data */ + tmp[0] = LITTLE32(ctx->workCtx.x[0] ^ + (ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16)); + tmp[1] = LITTLE32(ctx->workCtx.x[2] ^ + (ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16)); + tmp[2] = LITTLE32(ctx->workCtx.x[4] ^ + (ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16)); + tmp[3] = LITTLE32(ctx->workCtx.x[6] ^ + (ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16)); + + /* Encrypt/decrypt the data */ + for (i=0; i + #include +#else + #ifndef NO_DEV_RANDOM + #include + #include + #else + /* include headers that may be needed to get good seed */ + #endif +#endif /* USE_WINDOWS_API */ + + + +/* Get seed and key cipher */ +int InitRng(RNG* rng) +{ + byte key[32]; + byte junk[256]; + + int ret = GenerateSeed(&rng->seed, key, sizeof(key)); + + if (ret == 0) { + Arc4SetKey(&rng->cipher, key, sizeof(key)); + RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */ + } + + return ret; +} + + +/* place a generated block in output */ +void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +{ + XMEMSET(output, 0, sz); + Arc4Process(&rng->cipher, output, output, sz); +} + + +byte RNG_GenerateByte(RNG* rng) +{ + byte b; + RNG_GenerateBlock(rng, &b, 1); + + return b; +} + + +#if defined(USE_WINDOWS_API) + + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + return WINCRYPT_E; + + if (!CryptGenRandom(os->handle, sz, output)) + return CRYPTGEN_E; + + CryptReleaseContext(os->handle, 0); + + return 0; +} + + +#elif defined(THREADX) + +#include "rtprand.h" /* rtp_rand () */ +#include "rtptime.h" /* rtp_get_system_msec() */ + + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + int i; + rtp_srand(rtp_get_system_msec()); + + for (i = 0; i < sz; i++ ) { + output[i] = rtp_rand() % 256; + if ( (i % 8) == 7) + rtp_srand(rtp_get_system_msec()); + } + + return 0; +} + + +#elif defined(MICRIUM) + +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) + NetSecure_InitSeed(output, sz); + #endif + return 0; +} + +#elif defined(MBED) + +/* write a real one !!!, just for testing board */ +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + int i; + for (i = 0; i < sz; i++ ) + output[i] = i; + + return 0; +} + +#elif defined(NO_DEV_RANDOM) + +#error "you need to write an os specific GenerateSeed() here" + + +#else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */ + + +/* may block */ +int GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + os->fd = open("/dev/urandom",O_RDONLY); + if (os->fd == -1) { + /* may still have /dev/random */ + os->fd = open("/dev/random",O_RDONLY); + if (os->fd == -1) + return OPEN_RAN_E; + } + + while (sz) { + int len = read(os->fd, output, sz); + if (len == -1) + return READ_RAN_E; + + sz -= len; + output += len; + + if (sz) +#ifdef BLOCKING + sleep(0); /* context switch */ +#else + return RAN_BLOCK_E; +#endif + } + close(os->fd); + + return 0; +} + +#endif /* USE_WINDOWS_API */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/ripemd.c b/release/src/router/cyassl/ctaocrypt/src/ripemd.c new file mode 100644 index 00000000..ae0fab32 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/ripemd.c @@ -0,0 +1,347 @@ +/* ripemd.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef CYASSL_RIPEMD + +#include "ctc_ripemd.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitRipeMd(RipeMd* ripemd) +{ + ripemd->digest[0] = 0x67452301L; + ripemd->digest[1] = 0xEFCDAB89L; + ripemd->digest[2] = 0x98BADCFEL; + ripemd->digest[3] = 0x10325476L; + ripemd->digest[4] = 0xC3D2E1F0L; + + ripemd->buffLen = 0; + ripemd->loLen = 0; + ripemd->hiLen = 0; +} + + +/* for all */ +#define F(x, y, z) (x ^ y ^ z) +#define G(x, y, z) (z ^ (x & (y^z))) +#define H(x, y, z) (z ^ (x | ~y)) +#define I(x, y, z) (y ^ (z & (x^y))) +#define J(x, y, z) (x ^ (y | ~z)) + +#define k0 0 +#define k1 0x5a827999 +#define k2 0x6ed9eba1 +#define k3 0x8f1bbcdc +#define k4 0xa953fd4e +#define k5 0x50a28be6 +#define k6 0x5c4dd124 +#define k7 0x6d703ef3 +#define k8 0x7a6d76e9 +#define k9 0 + +/* for 160 and 320 */ +#define Subround(f, a, b, c, d, e, x, s, k) \ + a += f(b, c, d) + x + k;\ + a = rotlFixed((word32)a, s) + e;\ + c = rotlFixed((word32)c, 10U) + +static void Transform(RipeMd* ripemd) +{ + word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; + a1 = a2 = ripemd->digest[0]; + b1 = b2 = ripemd->digest[1]; + c1 = c2 = ripemd->digest[2]; + d1 = d2 = ripemd->digest[3]; + e1 = e2 = ripemd->digest[4]; + + Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[15], 8, k0); + + Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 8], 12, k1); + + Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[12], 5, k2); + + Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 12, k3); + + Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[13], 6, k4); + + Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[12], 6, k5); + + Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 2], 11, k6); + + Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[13], 5, k7); + + Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[14], 8, k8); + + Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[11], 11, k9); + + c1 = ripemd->digest[1] + c1 + d2; + ripemd->digest[1] = ripemd->digest[2] + d1 + e2; + ripemd->digest[2] = ripemd->digest[3] + e1 + a2; + ripemd->digest[3] = ripemd->digest[4] + a1 + b2; + ripemd->digest[4] = ripemd->digest[0] + b1 + c2; + ripemd->digest[0] = c1; +} + + +static INLINE void AddLength(RipeMd* ripemd, word32 len) +{ + word32 tmp = ripemd->loLen; + if ( (ripemd->loLen += len) < tmp) + ripemd->hiLen++; /* carry low to high */ +} + + +void RipeMdUpdate(RipeMd* ripemd, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)ripemd->buffer; + + while (len) { + word32 add = min(len, RIPEMD_BLOCK_SIZE - ripemd->buffLen); + XMEMCPY(&local[ripemd->buffLen], data, add); + + ripemd->buffLen += add; + data += add; + len -= add; + + if (ripemd->buffLen == RIPEMD_BLOCK_SIZE) { + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, RIPEMD_BLOCK_SIZE); + #endif + Transform(ripemd); + AddLength(ripemd, RIPEMD_BLOCK_SIZE); + ripemd->buffLen = 0; + } + } +} + + +void RipeMdFinal(RipeMd* ripemd, byte* hash) +{ + byte* local = (byte*)ripemd->buffer; + + AddLength(ripemd, ripemd->buffLen); /* before adding pads */ + + local[ripemd->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (ripemd->buffLen > RIPEMD_PAD_SIZE) { + XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_BLOCK_SIZE - ripemd->buffLen); + ripemd->buffLen += RIPEMD_BLOCK_SIZE - ripemd->buffLen; + + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, RIPEMD_BLOCK_SIZE); + #endif + Transform(ripemd); + ripemd->buffLen = 0; + } + XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_PAD_SIZE - ripemd->buffLen); + + /* put lengths in bits */ + ripemd->loLen = ripemd->loLen << 3; + ripemd->hiLen = (ripemd->loLen >> (8*sizeof(ripemd->loLen) - 3)) + + (ripemd->hiLen << 3); + + /* store lengths */ + #ifdef BIG_ENDIAN_ORDER + ByteReverseBytes(local, local, RIPEMD_BLOCK_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[RIPEMD_PAD_SIZE], &ripemd->loLen, sizeof(word32)); + XMEMCPY(&local[RIPEMD_PAD_SIZE + sizeof(word32)], &ripemd->hiLen, + sizeof(word32)); + + Transform(ripemd); + #ifdef BIG_ENDIAN_ORDER + ByteReverseWords(ripemd->digest, ripemd->digest, RIPEMD_DIGEST_SIZE); + #endif + XMEMCPY(hash, ripemd->digest, RIPEMD_DIGEST_SIZE); + + InitRipeMd(ripemd); /* reset state */ +} + + +#endif /* CYASSL_RIPEMD */ diff --git a/release/src/router/cyassl/ctaocrypt/src/rsa.c b/release/src/router/cyassl/ctaocrypt/src/rsa.c new file mode 100644 index 00000000..5757c94d --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/rsa.c @@ -0,0 +1,536 @@ +/* rsa.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + + +#include "ctc_rsa.h" +#include "random.h" +#include "error.h" + +#ifdef SHOW_GEN + #include +#endif + + +enum { + RSA_PUBLIC_ENCRYPT = 0, + RSA_PUBLIC_DECRYPT = 1, + RSA_PRIVATE_ENCRYPT = 2, + RSA_PRIVATE_DECRYPT = 3, + + RSA_BLOCK_TYPE_1 = 1, + RSA_BLOCK_TYPE_2 = 2, + + RSA_MIN_SIZE = 512, + RSA_MAX_SIZE = 4096, + + RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */ +}; + + +void InitRsaKey(RsaKey* key, void* heap) +{ + key->type = -1; /* haven't decdied yet */ + key->heap = heap; + +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + key->n.dp = key->e.dp = 0; /* public alloc parts */ + + key->d.dp = key->p.dp = 0; /* private alloc parts */ + key->q.dp = key->dP.dp = 0; + key->u.dp = key->dQ.dp = 0; +#endif +} + + +void FreeRsaKey(RsaKey* key) +{ +/* TomsFastMath doesn't use memory allocation */ +#ifndef USE_FAST_MATH + if (key->type == RSA_PRIVATE) { + mp_clear(&key->u); + mp_clear(&key->dQ); + mp_clear(&key->dP); + mp_clear(&key->q); + mp_clear(&key->p); + mp_clear(&key->d); + } + mp_clear(&key->e); + mp_clear(&key->n); +#endif +} + +static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, + word32 pkcsBlockLen, byte padValue, RNG* rng) +{ + if (inputLen == 0) return; + + pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ + pkcsBlock++; pkcsBlockLen--; + pkcsBlock[0] = padValue; /* insert padValue */ + + if (padValue == RSA_BLOCK_TYPE_1) + /* pad with 0xff bytes */ + XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); + else { + /* pad with non-zero random bytes */ + word32 padLen = pkcsBlockLen - inputLen - 1, i; + RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); + + /* remove zeros */ + for (i = 1; i < padLen; i++) + if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01; + } + + pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ + XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); +} + + +static word32 RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, + byte **output, byte padValue) +{ + word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0, + invalid = 0, + i = 1, + outputLen; + + if (pkcsBlock[0] != 0x0) /* skip past zero */ + invalid = 1; + pkcsBlock++; pkcsBlockLen--; + + /* Require block type padValue */ + invalid = (pkcsBlock[0] != padValue) || invalid; + + /* skip past the padding until we find the separator */ + while (i maxOutputLen) || invalid; + + if (invalid) + return 0; + + *output = (byte *)(pkcsBlock + i); + return outputLen; +} + + +static int RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, + int type, RsaKey* key) +{ + #define ERROR_OUT(x) { ret = x; goto done;} + + mp_int tmp; + int ret = 0; + word32 keyLen, len; + + if (mp_init(&tmp) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY) + ERROR_OUT(MP_READ_E); + + if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { + #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */ + if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_EXPTMOD_E); + #else + #define INNER_ERROR_OUT(x) { ret = x; goto inner_done; } + + mp_int tmpa, tmpb; + + if (mp_init(&tmpa) != MP_OKAY) + ERROR_OUT(MP_INIT_E); + + if (mp_init(&tmpb) != MP_OKAY) { + mp_clear(&tmpa); + ERROR_OUT(MP_INIT_E); + } + + /* tmpa = tmp^dP mod p */ + if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + + /* tmpb = tmp^dQ mod q */ + if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_SUB_E); + + if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MULMOD_E); + + /* tmp = tmpb + q * tmp */ + if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MUL_E); + + if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_ADD_E); + + inner_done: + mp_clear(&tmpa); + mp_clear(&tmpb); + + if (ret != 0) return ret; + + #endif /* RSA_LOW_MEM */ + } + else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) { + if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_EXPTMOD_E); + } + else + ERROR_OUT(RSA_WRONG_TYPE_E); + + keyLen = mp_unsigned_bin_size(&key->n); + if (keyLen > *outLen) + ERROR_OUT(RSA_BUFFER_E); + + len = mp_unsigned_bin_size(&tmp); + + /* pad front w/ zeros to match key length */ + while (len < keyLen) { + *out++ = 0x00; + len++; + } + + *outLen = keyLen; + + /* convert */ + if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) + ERROR_OUT(MP_TO_E); + +done: + mp_clear(&tmp); + return ret; +} + + + +int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key, RNG* rng) +{ + int sz = mp_unsigned_bin_size(&key->n), ret; + + if (sz > (int)outLen) + return RSA_BUFFER_E; + + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) + return RSA_BUFFER_E; + + RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng); + + if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0) + sz = ret; + + return sz; +} + + +int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) +{ + int plainLen, ret; + + if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key)) + < 0) { + return ret; + } + + plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2); + + return plainLen; +} + +int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key) +{ + int plainLen, ret; + byte* tmp; + byte* pad = 0; + + if ( !(tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA)) ) + return MEMORY_E; + + XMEMCPY(tmp, in, inLen); + + if ((ret = plainLen = RsaPrivateDecryptInline(tmp, inLen, &pad, key)) + < 0) { + XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); + return ret; + } + XMEMCPY(out, pad, plainLen); + XMEMSET(tmp, 0x00, inLen); + + XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); + return plainLen; +} + + +/* for Rsa Verify */ +int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) +{ + int plainLen, ret; + + if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key)) + < 0) { + return ret; + } + + plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1); + + return plainLen; +} + +int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key) +{ + int plainLen, ret; + byte* tmp; + byte* pad = 0; + + if ( !(tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA)) ) + return MEMORY_E; + + XMEMCPY(tmp, in, inLen); + + if ((ret = plainLen = RsaSSL_VerifyInline(tmp, inLen, &pad, key)) + < 0) { + XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); + return ret; + } + + XMEMCPY(out, pad, plainLen); + XMEMSET(tmp, 0x00, inLen); + + XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); + return plainLen; +} + + +/* for Rsa Sign */ +int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, + RsaKey* key, RNG* rng) +{ + int sz = mp_unsigned_bin_size(&key->n), ret; + + if (sz > (int)outLen) + return RSA_BUFFER_E; + + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) + return RSA_BUFFER_E; + + RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); + + if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0) + sz = ret; + + return sz; +} + + +int RsaEncryptSize(RsaKey* key) +{ + return mp_unsigned_bin_size(&key->n); +} + + +#ifdef CYASSL_KEY_GEN + +static const int USE_BBS = 1; + +static int rand_prime(mp_int* N, int len, RNG* rng, void* heap) +{ + int err, res, type; + byte* buf; + + if (N == NULL || rng == NULL) + return -1; + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return -1; + } + + /* allocate buffer to work with */ + buf = XMALLOC(len, heap, DYNAMIC_TYPE_RSA); + if (buf == NULL) { + return -1; + } + XMEMSET(buf, 0, len); + + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + RNG_GenerateBlock(rng, buf, len); + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + + /* test */ + if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + } while (res == MP_NO); + +#ifdef LTC_CLEAN_STACK + XMEMSET(buf, 0, len); +#endif + + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return 0; +} + + +/* Make an RSA key for size bits, with e specified, 65537 is a good e */ +int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) +{ + mp_int p, q, tmp1, tmp2, tmp3; + int err; + + if (key == NULL || rng == NULL) + return -1; + + if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE) + return -1; + + if (e < 3 || (e & 1) == 0) + return -1; + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY) + return err; + + err = mp_set_int(&tmp3, e); + + /* make p */ + if (err == MP_OKAY) { + do { + err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */ + + if (err == MP_OKAY) + err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */ + + if (err == MP_OKAY) + err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */ + } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p-1 */ + } + + /* make q */ + if (err == MP_OKAY) { + do { + err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */ + + if (err == MP_OKAY) + err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */ + + if (err == MP_OKAY) + err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */ + } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q-1 */ + } + + if (err == MP_OKAY) + err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL); + + if (err == MP_OKAY) + err = mp_init_multi(&key->dP, &key->dP, &key->u, NULL, NULL, NULL); + + if (err == MP_OKAY) + err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */ + + if (err == MP_OKAY) + err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */ + + /* make key */ + if (err == MP_OKAY) + err = mp_set_int(&key->e, e); /* key->e = e */ + + if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */ + err = mp_invmod(&key->e, &tmp1, &key->d); + + if (err == MP_OKAY) + err = mp_mul(&p, &q, &key->n); /* key->n = pq */ + + if (err == MP_OKAY) + err = mp_sub_d(&p, 1, &tmp1); + + if (err == MP_OKAY) + err = mp_sub_d(&q, 1, &tmp2); + + if (err == MP_OKAY) + err = mp_mod(&key->d, &tmp1, &key->dP); + + if (err == MP_OKAY) + err = mp_mod(&key->d, &tmp2, &key->dQ); + + if (err == MP_OKAY) + err = mp_invmod(&q, &p, &key->u); + + if (err == MP_OKAY) + err = mp_copy(&p, &key->p); + + if (err == MP_OKAY) + err = mp_copy(&q, &key->q); + + if (err == MP_OKAY) + key->type = RSA_PRIVATE; + + mp_clear(&tmp3); + mp_clear(&tmp2); + mp_clear(&tmp1); + mp_clear(&q); + mp_clear(&p); + + if (err != MP_OKAY) { + FreeRsaKey(key); + return err; + } + + return 0; +} + + +#endif /* CYASLS_KEY_GEN */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/sha.c b/release/src/router/cyassl/ctaocrypt/src/sha.c new file mode 100644 index 00000000..e0c132bc --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/sha.c @@ -0,0 +1,198 @@ +/* sha.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include "ctc_sha.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitSha(Sha* sha) +{ + sha->digest[0] = 0x67452301L; + sha->digest[1] = 0xEFCDAB89L; + sha->digest[2] = 0x98BADCFEL; + sha->digest[3] = 0x10325476L; + sha->digest[4] = 0xC3D2E1F0L; + + sha->buffLen = 0; + sha->loLen = 0; + sha->hiLen = 0; +} + +#define blk0(i) (W[i] = sha->buffer[i]) +#define blk1(i) (W[i&15] = \ + rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) + +#define f1(x,y,z) (z^(x &(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+= f1(w,x,y) + blk0(i) + 0x5A827999+ \ + rotlFixed(v,5); w = rotlFixed(w,30); +#define R1(v,w,x,y,z,i) z+= f1(w,x,y) + blk1(i) + 0x5A827999+ \ + rotlFixed(v,5); w = rotlFixed(w,30); +#define R2(v,w,x,y,z,i) z+= f2(w,x,y) + blk1(i) + 0x6ED9EBA1+ \ + rotlFixed(v,5); w = rotlFixed(w,30); +#define R3(v,w,x,y,z,i) z+= f3(w,x,y) + blk1(i) + 0x8F1BBCDC+ \ + rotlFixed(v,5); w = rotlFixed(w,30); +#define R4(v,w,x,y,z,i) z+= f4(w,x,y) + blk1(i) + 0xCA62C1D6+ \ + rotlFixed(v,5); w = rotlFixed(w,30); + + +static void Transform(Sha* sha) +{ + word32 W[SHA_BLOCK_SIZE / sizeof(word32)]; + + /* Copy context->state[] to working vars */ + word32 a = sha->digest[0]; + word32 b = sha->digest[1]; + word32 c = sha->digest[2]; + word32 d = sha->digest[3]; + word32 e = sha->digest[4]; + + /* nearly 1 K bigger in code size but 25% faster */ + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into digest state[] */ + sha->digest[0] += a; + sha->digest[1] += b; + sha->digest[2] += c; + sha->digest[3] += d; + sha->digest[4] += e; +} + + +static INLINE void AddLength(Sha* sha, word32 len) +{ + word32 tmp = sha->loLen; + if ( (sha->loLen += len) < tmp) + sha->hiLen++; /* carry low to high */ +} + + +void ShaUpdate(Sha* sha, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)sha->buffer; + + while (len) { + word32 add = min(len, SHA_BLOCK_SIZE - sha->buffLen); + XMEMCPY(&local[sha->buffLen], data, add); + + sha->buffLen += add; + data += add; + len -= add; + + if (sha->buffLen == SHA_BLOCK_SIZE) { + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA_BLOCK_SIZE); + #endif + Transform(sha); + AddLength(sha, SHA_BLOCK_SIZE); + sha->buffLen = 0; + } + } +} + + +void ShaFinal(Sha* sha, byte* hash) +{ + byte* local = (byte*)sha->buffer; + + AddLength(sha, sha->buffLen); /* before adding pads */ + + local[sha->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (sha->buffLen > SHA_PAD_SIZE) { + XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); + sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; + + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA_BLOCK_SIZE); + #endif + Transform(sha); + sha->buffLen = 0; + } + XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen); + + /* put lengths in bits */ + sha->loLen = sha->loLen << 3; + sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + + (sha->hiLen << 3); + + /* store lengths */ + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA_BLOCK_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); + XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); + + Transform(sha); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); + #endif + XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); + + InitSha(sha); /* reset state */ +} + diff --git a/release/src/router/cyassl/ctaocrypt/src/sha256.c b/release/src/router/cyassl/ctaocrypt/src/sha256.c new file mode 100644 index 00000000..e94aa425 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/sha256.c @@ -0,0 +1,206 @@ +/* sha256.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* code submitted by raphael.huck@efixo.com */ + + + +#ifndef NO_SHA256 + +#include "sha256.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitSha256(Sha256* sha256) +{ + sha256->digest[0] = 0x6A09E667L; + sha256->digest[1] = 0xBB67AE85L; + sha256->digest[2] = 0x3C6EF372L; + sha256->digest[3] = 0xA54FF53AL; + sha256->digest[4] = 0x510E527FL; + sha256->digest[5] = 0x9B05688CL; + sha256->digest[6] = 0x1F83D9ABL; + sha256->digest[7] = 0x5BE0CD19L; + + sha256->buffLen = 0; + sha256->loLen = 0; + sha256->hiLen = 0; +} + +static const word32 K[64] = { + 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, + 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, + 0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, + 0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL, + 0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L, + 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L, + 0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, + 0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L, + 0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L, + 0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L, + 0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, + 0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L, + 0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L +}; + +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) rotrFixed(x, n) +#define R(x, n) (((x)&0xFFFFFFFFL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + +static void Transform(Sha256* sha256) +{ + word32 S[8], W[64], t0, t1; + int i; + + /* Copy context->state[] to working vars */ + for (i = 0; i < 8; i++) + S[i] = sha256->digest[i]; + + for (i = 0; i < 16; i++) + W[i] = sha256->buffer[i]; + + for (i = 16; i < 64; i++) + W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16]; + + for (i = 0; i < 64; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } + + /* Add the working vars back into digest state[] */ + for (i = 0; i < 8; i++) { + sha256->digest[i] += S[i]; + } +} + + +static INLINE void AddLength(Sha256* sha256, word32 len) +{ + word32 tmp = sha256->loLen; + if ( (sha256->loLen += len) < tmp) + sha256->hiLen++; /* carry low to high */ +} + + +void Sha256Update(Sha256* sha256, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)sha256->buffer; + + while (len) { + word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen); + XMEMCPY(&local[sha256->buffLen], data, add); + + sha256->buffLen += add; + data += add; + len -= add; + + if (sha256->buffLen == SHA256_BLOCK_SIZE) { + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); + #endif + Transform(sha256); + AddLength(sha256, SHA256_BLOCK_SIZE); + sha256->buffLen = 0; + } + } +} + + +void Sha256Final(Sha256* sha256, byte* hash) +{ + byte* local = (byte*)sha256->buffer; + + AddLength(sha256, sha256->buffLen); /* before adding pads */ + + local[sha256->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (sha256->buffLen > SHA256_PAD_SIZE) { + XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); + sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; + + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); + #endif + Transform(sha256); + sha256->buffLen = 0; + } + XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); + + /* put lengths in bits */ + sha256->loLen = sha256->loLen << 3; + sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) + + (sha256->hiLen << 3); + + /* store lengths */ + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32)); + XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, + sizeof(word32)); + + Transform(sha256); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); + #endif + XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE); + + InitSha256(sha256); /* reset state */ +} + + +#endif /* NO_SHA256 */ + diff --git a/release/src/router/cyassl/ctaocrypt/src/sha512.c b/release/src/router/cyassl/ctaocrypt/src/sha512.c new file mode 100644 index 00000000..8bdfd96a --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/sha512.c @@ -0,0 +1,242 @@ +/* sha512.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef CYASSL_SHA512 + +#include "sha512.h" +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ + + +void InitSha512(Sha512* sha512) +{ + sha512->digest[0] = W64LIT(0x6a09e667f3bcc908); + sha512->digest[1] = W64LIT(0xbb67ae8584caa73b); + sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b); + sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1); + sha512->digest[4] = W64LIT(0x510e527fade682d1); + sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f); + sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b); + sha512->digest[7] = W64LIT(0x5be0cd19137e2179); + + sha512->buffLen = 0; + sha512->loLen = 0; + sha512->hiLen = 0; +} + + +static const word64 K512[80] = { + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), + W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), + W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), + W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), + W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), + W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), + W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), + W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), + W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), + W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), + W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), + W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), + W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), + W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), + W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), + W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), + W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), + W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), + W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), + W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), + W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + + +#define blk0(i) (W[i] = sha512->buffer[i]) +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define S0(x) (rotrFixed64(x,28)^rotrFixed64(x,34)^rotrFixed64(x,39)) +#define S1(x) (rotrFixed64(x,14)^rotrFixed64(x,18)^rotrFixed64(x,41)) +#define s0(x) (rotrFixed64(x,1)^rotrFixed64(x,8)^(x>>7)) +#define s1(x) (rotrFixed64(x,19)^rotrFixed64(x,61)^(x>>6)) + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + + +static void Transform(Sha512* sha512) +{ + const word64* K = K512; + + word32 j; + word64 W[16]; + word64 T[8]; + + /* Copy digest to working vars */ + XMEMCPY(T, sha512->digest, sizeof(T)); + + /* 64 operations, partially loop unrolled */ + for (j = 0; j < 80; j += 16) { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + + /* Add the working vars back into digest */ + + sha512->digest[0] += a(0); + sha512->digest[1] += b(0); + sha512->digest[2] += c(0); + sha512->digest[3] += d(0); + sha512->digest[4] += e(0); + sha512->digest[5] += f(0); + sha512->digest[6] += g(0); + sha512->digest[7] += h(0); + + /* Wipe variables */ + XMEMSET(W, 0, sizeof(W)); + XMEMSET(T, 0, sizeof(T)); +} + + +static INLINE void AddLength(Sha512* sha512, word32 len) +{ + word32 tmp = sha512->loLen; + if ( (sha512->loLen += len) < tmp) + sha512->hiLen++; /* carry low to high */ +} + + +void Sha512Update(Sha512* sha512, const byte* data, word32 len) +{ + /* do block size increments */ + byte* local = (byte*)sha512->buffer; + + while (len) { + word32 add = min(len, SHA512_BLOCK_SIZE - sha512->buffLen); + XMEMCPY(&local[sha512->buffLen], data, add); + + sha512->buffLen += add; + data += add; + len -= add; + + if (sha512->buffLen == SHA512_BLOCK_SIZE) { + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha512->buffer, sha512->buffer, + SHA512_BLOCK_SIZE); + #endif + Transform(sha512); + AddLength(sha512, SHA512_BLOCK_SIZE); + sha512->buffLen = 0; + } + } +} + + +void Sha512Final(Sha512* sha512, byte* hash) +{ + byte* local = (byte*)sha512->buffer; + + AddLength(sha512, sha512->buffLen); /* before adding pads */ + + local[sha512->buffLen++] = 0x80; /* add 1 */ + + /* pad with zeros */ + if (sha512->buffLen > SHA512_PAD_SIZE) { + XMEMSET(&local[sha512->buffLen], 0, SHA512_BLOCK_SIZE - sha512->buffLen); + sha512->buffLen += SHA512_BLOCK_SIZE - sha512->buffLen; + + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha512->buffer,sha512->buffer,SHA512_BLOCK_SIZE); + #endif + Transform(sha512); + sha512->buffLen = 0; + } + XMEMSET(&local[sha512->buffLen], 0, SHA512_PAD_SIZE - sha512->buffLen); + + /* put lengths in bits */ + sha512->loLen = sha512->loLen << 3; + sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) + + (sha512->hiLen << 3); + + /* store lengths */ + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha512->buffer, sha512->buffer, SHA512_PAD_SIZE); + #endif + /* ! length ordering dependent on digest endian type ! */ + sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen; + sha512->buffer[SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen; + + Transform(sha512); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords64(sha512->digest, sha512->digest, SHA512_DIGEST_SIZE); + #endif + XMEMCPY(hash, sha512->digest, SHA512_DIGEST_SIZE); + + InitSha512(sha512); /* reset state */ +} + + +#endif /* CYASSL_SHA512 */ diff --git a/release/src/router/cyassl/ctaocrypt/src/tfm.c b/release/src/router/cyassl/ctaocrypt/src/tfm.c new file mode 100644 index 00000000..d14bcb6c --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/src/tfm.c @@ -0,0 +1,2430 @@ +/* tfm.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL 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. + * + * CyaSSL 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, + * http://math.libtomcrypt.com + */ + +/** + * Edited by Moisés Guimarães (moises.guimaraes@phoebus.com.br) + * to fit CyaSSL's needs. + */ + +#include "os_settings.h" /* in case user set USE_FAST_MATH there */ + +#ifdef USE_FAST_MATH + +#include "tfm.h" +#include "asm.c" /* will define asm MACROS or C ones */ + + + +/* Functions */ + +void fp_add(fp_int *a, fp_int *b, fp_int *c) +{ + int sa, sb; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + s_fp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (fp_cmp_mag (a, b) == FP_LT) { + c->sign = sb; + s_fp_sub (b, a, c); + } else { + c->sign = sa; + s_fp_sub (a, b, c); + } + } +} + +/* unsigned addition */ +void s_fp_add(fp_int *a, fp_int *b, fp_int *c) +{ + int x, y, oldused; + register fp_word t; + + y = MAX(a->used, b->used); + oldused = c->used; + c->used = y; + + t = 0; + for (x = 0; x < y; x++) { + t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]); + c->dp[x] = (fp_digit)t; + t >>= DIGIT_BIT; + } + if (t != 0 && x < FP_SIZE) { + c->dp[c->used++] = (fp_digit)t; + ++x; + } + + c->used = x; + for (; x < oldused; x++) { + c->dp[x] = 0; + } + fp_clamp(c); +} + +/* c = a - b */ +void fp_sub(fp_int *a, fp_int *b, fp_int *c) +{ + int sa, sb; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + s_fp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (fp_cmp_mag (a, b) != FP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + s_fp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS; + /* The second has a larger magnitude */ + s_fp_sub (b, a, c); + } + } +} + +/* unsigned subtraction ||a|| >= ||b|| ALWAYS! */ +void s_fp_sub(fp_int *a, fp_int *b, fp_int *c) +{ + int x, oldbused, oldused; + fp_word t; + + oldused = c->used; + oldbused = b->used; + c->used = a->used; + t = 0; + for (x = 0; x < oldbused; x++) { + t = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t); + c->dp[x] = (fp_digit)t; + t = (t >> DIGIT_BIT)&1; + } + for (; x < a->used; x++) { + t = ((fp_word)a->dp[x]) - t; + c->dp[x] = (fp_digit)t; + t = (t >> DIGIT_BIT); + } + for (; x < oldused; x++) { + c->dp[x] = 0; + } + fp_clamp(c); +} + +/* c = a * b */ +void fp_mul(fp_int *A, fp_int *B, fp_int *C) +{ + int y, yy; + + y = MAX(A->used, B->used); + yy = MIN(A->used, B->used); + + /* call generic if we're out of range */ + if (y + yy > FP_SIZE) { + fp_mul_comba(A, B, C); + return ; + } + + /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size + of the largest input. We also want to avoid doing excess mults if the + inputs are not close to the next power of two. That is, for example, + if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications + */ + +#ifdef TFM_MUL3 + if (y <= 3) { + fp_mul_comba3(A,B,C); + return; + } +#endif +#ifdef TFM_MUL4 + if (y == 4) { + fp_mul_comba4(A,B,C); + return; + } +#endif +#ifdef TFM_MUL6 + if (y <= 6) { + fp_mul_comba6(A,B,C); + return; + } +#endif +#ifdef TFM_MUL7 + if (y == 7) { + fp_mul_comba7(A,B,C); + return; + } +#endif +#ifdef TFM_MUL8 + if (y == 8) { + fp_mul_comba8(A,B,C); + return; + } +#endif +#ifdef TFM_MUL9 + if (y == 9) { + fp_mul_comba9(A,B,C); + return; + } +#endif +#ifdef TFM_MUL12 + if (y <= 12) { + fp_mul_comba12(A,B,C); + return; + } +#endif +#ifdef TFM_MUL17 + if (y <= 17) { + fp_mul_comba17(A,B,C); + return; + } +#endif + +#ifdef TFM_SMALL_SET + if (y <= 16) { + fp_mul_comba_small(A,B,C); + return; + } +#endif +#if defined(TFM_MUL20) + if (y <= 20) { + fp_mul_comba20(A,B,C); + return; + } +#endif +#if defined(TFM_MUL24) + if (yy >= 16 && y <= 24) { + fp_mul_comba24(A,B,C); + return; + } +#endif +#if defined(TFM_MUL28) + if (yy >= 20 && y <= 28) { + fp_mul_comba28(A,B,C); + return; + } +#endif +#if defined(TFM_MUL32) + if (yy >= 24 && y <= 32) { + fp_mul_comba32(A,B,C); + return; + } +#endif +#if defined(TFM_MUL48) + if (yy >= 40 && y <= 48) { + fp_mul_comba48(A,B,C); + return; + } +#endif +#if defined(TFM_MUL64) + if (yy >= 56 && y <= 64) { + fp_mul_comba64(A,B,C); + return; + } +#endif + fp_mul_comba(A,B,C); +} + +void fp_mul_2(fp_int * a, fp_int * b) +{ + int x, oldused; + + oldused = b->used; + b->used = a->used; + + { + register fp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r); + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0 && b->used != (FP_SIZE-1)) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; +} + +/* c = a * b */ +void fp_mul_d(fp_int *a, fp_digit b, fp_int *c) +{ + fp_word w; + int x, oldused; + + oldused = c->used; + c->used = a->used; + c->sign = a->sign; + w = 0; + for (x = 0; x < a->used; x++) { + w = ((fp_word)a->dp[x]) * ((fp_word)b) + w; + c->dp[x] = (fp_digit)w; + w = w >> DIGIT_BIT; + } + if (w != 0 && (a->used != FP_SIZE)) { + c->dp[c->used++] = (fp_digit) w; + ++x; + } + for (; x < oldused; x++) { + c->dp[x] = 0; + } + fp_clamp(c); +} + +/* c = a * 2**d */ +void fp_mul_2d(fp_int *a, int b, fp_int *c) +{ + fp_digit carry, carrytmp, shift; + int x; + + /* copy it */ + fp_copy(a, c); + + /* handle whole digits */ + if (b >= DIGIT_BIT) { + fp_lshd(c, b/DIGIT_BIT); + } + b %= DIGIT_BIT; + + /* shift the digits */ + if (b != 0) { + carry = 0; + shift = DIGIT_BIT - b; + for (x = 0; x < c->used; x++) { + carrytmp = c->dp[x] >> shift; + c->dp[x] = (c->dp[x] << b) + carry; + carry = carrytmp; + } + /* store last carry if room */ + if (carry && x < FP_SIZE) { + c->dp[c->used++] = carry; + } + } + fp_clamp(c); +} + +/* generic PxQ multiplier */ +void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) +{ + int ix, iy, iz, tx, ty, pa; + fp_digit c0, c1, c2, *tmpx, *tmpy; + fp_int tmp, *dst; + + COMBA_START; + COMBA_CLEAR; + + /* get size of output and trim */ + pa = A->used + B->used; + if (pa >= FP_SIZE) { + pa = FP_SIZE-1; + } + + if (A == C || B == C) { + fp_zero(&tmp); + dst = &tmp; + } else { + fp_zero(C); + dst = C; + } + + for (ix = 0; ix < pa; ix++) { + /* get offsets into the two bignums */ + ty = MIN(ix, B->used-1); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = A->dp + tx; + tmpy = B->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(A->used-tx, ty+1); + + /* execute loop */ + COMBA_FORWARD; + for (iz = 0; iz < iy; ++iz) { + /* TAO change COMBA_ADD back to MULADD */ + MULADD(*tmpx++, *tmpy--); + } + + /* store term */ + COMBA_STORE(dst->dp[ix]); + } + COMBA_FINI; + + dst->used = pa; + dst->sign = A->sign ^ B->sign; + fp_clamp(dst); + fp_copy(dst, C); +} + +/* a/b => cb + d == a */ +int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d) +{ + fp_int q, x, y, t1, t2; + int n, t, i, norm, neg; + + /* is divisor zero ? */ + if (fp_iszero (b) == 1) { + return FP_VAL; + } + + /* if a < b then q=0, r = a */ + if (fp_cmp_mag (a, b) == FP_LT) { + if (d != NULL) { + fp_copy (a, d); + } + if (c != NULL) { + fp_zero (c); + } + return FP_OKAY; + } + + fp_init(&q); + q.used = a->used + 2; + + fp_init(&t1); + fp_init(&t2); + fp_init_copy(&x, a); + fp_init_copy(&y, b); + + /* fix the sign */ + neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG; + x.sign = y.sign = FP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = fp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + fp_mul_2d (&x, norm, &x); + fp_mul_2d (&y, norm, &y); + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + fp_lshd (&y, n - t); /* y = y*b**{n-t} */ + + while (fp_cmp (&x, &y) != FP_LT) { + ++(q.dp[n - t]); + fp_sub (&x, &y, &x); + } + + /* reset y by shifting it back down */ + fp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((fp_word)1) << DIGIT_BIT) - 1); + } else { + fp_word tmp; + tmp = ((fp_word) x.dp[i]) << ((fp_word) DIGIT_BIT); + tmp |= ((fp_word) x.dp[i - 1]); + tmp /= ((fp_word)y.dp[t]); + q.dp[i - t - 1] = (fp_digit) (tmp); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1); + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1); + + /* find left hand */ + fp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + fp_mul_d (&t1, q.dp[i - t - 1], &t1); + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (fp_cmp_mag(&t1, &t2) == FP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + fp_mul_d (&y, q.dp[i - t - 1], &t1); + fp_lshd (&t1, i - t - 1); + fp_sub (&x, &t1, &x); + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == FP_NEG) { + fp_copy (&y, &t1); + fp_lshd (&t1, i - t - 1); + fp_add (&x, &t1, &x); + q.dp[i - t - 1] = q.dp[i - t - 1] - 1; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? FP_ZPOS : a->sign; + + if (c != NULL) { + fp_clamp (&q); + fp_copy (&q, c); + c->sign = neg; + } + + if (d != NULL) { + fp_div_2d (&x, norm, &x, NULL); + +/* the following is a kludge, essentially we were seeing the right remainder but + with excess digits that should have been zero + */ + for (i = b->used; i < x.used; i++) { + x.dp[i] = 0; + } + fp_clamp(&x); + fp_copy (&x, d); + } + + return FP_OKAY; +} + +/* b = a/2 */ +void fp_div_2(fp_int * a, fp_int * b) +{ + int x, oldused; + + oldused = b->used; + b->used = a->used; + { + register fp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + fp_clamp (b); +} + +/* c = a / 2**b */ +void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d) +{ + fp_digit D, r, rr; + int x; + fp_int t; + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + fp_copy (a, c); + if (d != NULL) { + fp_zero (d); + } + return; + } + + fp_init(&t); + + /* get the remainder */ + if (d != NULL) { + fp_mod_2d (a, b, &t); + } + + /* copy */ + fp_copy(a, c); + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + fp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (fp_digit) (b % DIGIT_BIT); + if (D != 0) { + register fp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((fp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + fp_clamp (c); + if (d != NULL) { + fp_copy (&t, d); + } +} + +/* c = a mod b, 0 <= c < b */ +int fp_mod(fp_int *a, fp_int *b, fp_int *c) +{ + fp_int t; + int err; + + fp_zero(&t); + if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) { + return err; + } + if (t.sign != b->sign) { + fp_add(&t, b, c); + } else { + fp_copy(&t, c); + } + return FP_OKAY; +} + +/* c = a mod 2**d */ +void fp_mod_2d(fp_int *a, int b, fp_int *c) +{ + int x; + + /* zero if count less than or equal to zero */ + if (b <= 0) { + fp_zero(c); + return; + } + + /* get copy of input */ + fp_copy(a, c); + + /* if 2**d is larger than we just return */ + if (b >= (DIGIT_BIT * a->used)) { + return; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b); + fp_clamp (c); +} + +static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c) +{ + fp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == FP_NEG || fp_iszero(b) == 1) { + return FP_VAL; + } + + /* init temps */ + fp_init(&x); fp_init(&y); + fp_init(&u); fp_init(&v); + fp_init(&A); fp_init(&B); + fp_init(&C); fp_init(&D); + + /* x = a, y = b */ + if ((res = fp_mod(a, b, &x)) != FP_OKAY) { + return res; + } + fp_copy(b, &y); + + /* 2. [modified] if x,y are both even then return an error! */ + if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) { + return FP_VAL; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + fp_copy (&x, &u); + fp_copy (&y, &v); + fp_set (&A, 1); + fp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (fp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + fp_div_2 (&u, &u); + + /* 4.2 if A or B is odd then */ + if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + fp_add (&A, &y, &A); + fp_sub (&B, &x, &B); + } + /* A = A/2, B = B/2 */ + fp_div_2 (&A, &A); + fp_div_2 (&B, &B); + } + + /* 5. while v is even do */ + while (fp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + fp_div_2 (&v, &v); + + /* 5.2 if C or D is odd then */ + if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + fp_add (&C, &y, &C); + fp_sub (&D, &x, &D); + } + /* C = C/2, D = D/2 */ + fp_div_2 (&C, &C); + fp_div_2 (&D, &D); + } + + /* 6. if u >= v then */ + if (fp_cmp (&u, &v) != FP_LT) { + /* u = u - v, A = A - C, B = B - D */ + fp_sub (&u, &v, &u); + fp_sub (&A, &C, &A); + fp_sub (&B, &D, &B); + } else { + /* v - v - u, C = C - A, D = D - B */ + fp_sub (&v, &u, &v); + fp_sub (&C, &A, &C); + fp_sub (&D, &B, &D); + } + + /* if not zero goto step 4 */ + if (fp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (fp_cmp_d (&v, 1) != FP_EQ) { + return FP_VAL; + } + + /* if its too low */ + while (fp_cmp_d(&C, 0) == FP_LT) { + fp_add(&C, b, &C); + } + + /* too big */ + while (fp_cmp_mag(&C, b) != FP_LT) { + fp_sub(&C, b, &C); + } + + /* C is now the inverse */ + fp_copy(&C, c); + return FP_OKAY; +} + +/* c = 1/a (mod b) for odd b only */ +int fp_invmod(fp_int *a, fp_int *b, fp_int *c) +{ + fp_int x, y, u, v, B, D; + int neg; + + /* 2. [modified] b must be odd */ + if (fp_iseven (b) == FP_YES) { + return fp_invmod_slow(a,b,c); + } + + /* init all our temps */ + fp_init(&x); fp_init(&y); + fp_init(&u); fp_init(&v); + fp_init(&B); fp_init(&D); + + /* x == modulus, y == value to invert */ + fp_copy(b, &x); + + /* we need y = |a| */ + fp_abs(a, &y); + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + fp_copy(&x, &u); + fp_copy(&y, &v); + fp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (fp_iseven (&u) == FP_YES) { + /* 4.1 u = u/2 */ + fp_div_2 (&u, &u); + + /* 4.2 if B is odd then */ + if (fp_isodd (&B) == FP_YES) { + fp_sub (&B, &x, &B); + } + /* B = B/2 */ + fp_div_2 (&B, &B); + } + + /* 5. while v is even do */ + while (fp_iseven (&v) == FP_YES) { + /* 5.1 v = v/2 */ + fp_div_2 (&v, &v); + + /* 5.2 if D is odd then */ + if (fp_isodd (&D) == FP_YES) { + /* D = (D-x)/2 */ + fp_sub (&D, &x, &D); + } + /* D = D/2 */ + fp_div_2 (&D, &D); + } + + /* 6. if u >= v then */ + if (fp_cmp (&u, &v) != FP_LT) { + /* u = u - v, B = B - D */ + fp_sub (&u, &v, &u); + fp_sub (&B, &D, &B); + } else { + /* v - v - u, D = D - B */ + fp_sub (&v, &u, &v); + fp_sub (&D, &B, &D); + } + + /* if not zero goto step 4 */ + if (fp_iszero (&u) == FP_NO) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (fp_cmp_d (&v, 1) != FP_EQ) { + return FP_VAL; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == FP_NEG) { + fp_add (&D, b, &D); + } + fp_copy (&D, c); + c->sign = neg; + return FP_OKAY; +} + +/* d = a * b (mod c) */ +int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) +{ + fp_int tmp; + fp_zero(&tmp); + fp_mul(a, b, &tmp); + return fp_mod(&tmp, c, d); +} + +#ifdef TFM_TIMING_RESISTANT + +/* timing resistant montgomery ladder based exptmod + + Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 +*/ +static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +{ + fp_int R[2]; + fp_digit buf, mp; + int err, bitcnt, digidx, y; + + /* now setup montgomery */ + if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) { + return err; + } + + fp_init(&R[0]); + fp_init(&R[1]); + + /* now we need R mod m */ + fp_montgomery_calc_normalization (&R[0], P); + + /* now set R[0][1] to G * R mod m */ + if (fp_cmp_mag(P, G) != FP_GT) { + /* G > P so we reduce it first */ + fp_mod(G, P, &R[1]); + } else { + fp_copy(G, &R[1]); + } + fp_mulmod (&R[1], &R[0], P, &R[1]); + + /* for j = t-1 downto 0 do + r_!k = R0*R1; r_k = r_k^2 + */ + + /* set initial mode and bit cnt */ + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (fp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (fp_digit)1; + + /* do ops */ + fp_mul(&R[0], &R[1], &R[y^1]); fp_montgomery_reduce(&R[y^1], P, mp); + fp_sqr(&R[y], &R[y]); fp_montgomery_reduce(&R[y], P, mp); + } + + fp_montgomery_reduce(&R[0], P, mp); + fp_copy(&R[0], Y); + return FP_OKAY; +} + +#else + +/* y = g**x (mod b) + * Some restrictions... x must be positive and < b + */ +static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +{ + fp_int M[64], res; + fp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* find window size */ + x = fp_count_bits (X); + if (x <= 21) { + winsize = 1; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else { + winsize = 6; + } + + /* init M array */ + XMEMSET(M, 0, sizeof(M)); + + /* now setup montgomery */ + if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) { + return err; + } + + /* setup result */ + fp_init(&res); + + /* create M table + * + * The M table contains powers of the input base, e.g. M[x] = G^x mod P + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + /* now we need R mod m */ + fp_montgomery_calc_normalization (&res, P); + + /* now set M[1] to G * R mod m */ + if (fp_cmp_mag(P, G) != FP_GT) { + /* G > P so we reduce it first */ + fp_mod(G, P, &M[1]); + } else { + fp_copy(G, &M[1]); + } + fp_mulmod (&M[1], &res, P, &M[1]); + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + fp_copy (&M[1], &M[1 << (winsize - 1)]); + for (x = 0; x < (winsize - 1); x++) { + fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]); + fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp); + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + fp_mul(&M[x - 1], &M[1], &M[x]); + fp_montgomery_reduce(&M[x], P, mp); + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (fp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (fp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + fp_sqr(&res, &res); + fp_montgomery_reduce(&res, P, mp); + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + fp_sqr(&res, &res); + fp_montgomery_reduce(&res, P, mp); + } + + /* then multiply */ + fp_mul(&res, &M[bitbuf], &res); + fp_montgomery_reduce(&res, P, mp); + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + fp_sqr(&res, &res); + fp_montgomery_reduce(&res, P, mp); + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + fp_mul(&res, &M[1], &res); + fp_montgomery_reduce(&res, P, mp); + } + } + } + + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + fp_montgomery_reduce(&res, P, mp); + + /* swap res with Y */ + fp_copy (&res, Y); + return FP_OKAY; +} + +#endif + +int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +{ + fp_int tmp; + int err; + + /* prevent overflows */ + if (P->used > (FP_SIZE/2)) { + return FP_VAL; + } + + /* is X negative? */ + if (X->sign == FP_NEG) { + /* yes, copy G and invmod it */ + fp_copy(G, &tmp); + if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) { + return err; + } + X->sign = FP_ZPOS; + err = _fp_exptmod(&tmp, X, P, Y); + if (X != Y) { + X->sign = FP_NEG; + } + return err; + } else { + /* Positive exponent so just exptmod */ + return _fp_exptmod(G, X, P, Y); + } +} + +/* computes a = 2**b */ +void fp_2expt(fp_int *a, int b) +{ + int z; + + /* zero a as per default */ + fp_zero (a); + + if (b < 0) { + return; + } + + z = b / DIGIT_BIT; + if (z >= FP_SIZE) { + return; + } + + /* set the used count of where the bit will go */ + a->used = z + 1; + + /* put the single bit in its place */ + a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT); +} + +/* b = a*a */ +void fp_sqr(fp_int *A, fp_int *B) +{ + int y = A->used; + + /* call generic if we're out of range */ + if (y + y > FP_SIZE) { + fp_sqr_comba(A, B); + return ; + } + +#if defined(TFM_SQR3) + if (y <= 3) { + fp_sqr_comba3(A,B); + return; + } +#endif +#if defined(TFM_SQR4) + if (y == 4) { + fp_sqr_comba4(A,B); + return; + } +#endif +#if defined(TFM_SQR6) + if (y <= 6) { + fp_sqr_comba6(A,B); + return; + } +#endif +#if defined(TFM_SQR7) + if (y == 7) { + fp_sqr_comba7(A,B); + return; + } +#endif +#if defined(TFM_SQR8) + if (y == 8) { + fp_sqr_comba8(A,B); + return; + } +#endif +#if defined(TFM_SQR9) + if (y == 9) { + fp_sqr_comba9(A,B); + return; + } +#endif +#if defined(TFM_SQR12) + if (y <= 12) { + fp_sqr_comba12(A,B); + return; + } +#endif +#if defined(TFM_SQR17) + if (y <= 17) { + fp_sqr_comba17(A,B); + return; + } +#endif +#if defined(TFM_SMALL_SET) + if (y <= 16) { + fp_sqr_comba_small(A,B); + return; + } +#endif +#if defined(TFM_SQR20) + if (y <= 20) { + fp_sqr_comba20(A,B); + return; + } +#endif +#if defined(TFM_SQR24) + if (y <= 24) { + fp_sqr_comba24(A,B); + return; + } +#endif +#if defined(TFM_SQR28) + if (y <= 28) { + fp_sqr_comba28(A,B); + return; + } +#endif +#if defined(TFM_SQR32) + if (y <= 32) { + fp_sqr_comba32(A,B); + return; + } +#endif +#if defined(TFM_SQR48) + if (y <= 48) { + fp_sqr_comba48(A,B); + return; + } +#endif +#if defined(TFM_SQR64) + if (y <= 64) { + fp_sqr_comba64(A,B); + return; + } +#endif + fp_sqr_comba(A, B); +} + +/* generic comba squarer */ +void fp_sqr_comba(fp_int *A, fp_int *B) +{ + int pa, ix, iz; + fp_digit c0, c1, c2; + fp_int tmp, *dst; +#ifdef TFM_ISO + fp_word tt; +#endif + + /* get size of output and trim */ + pa = A->used + A->used; + if (pa >= FP_SIZE) { + pa = FP_SIZE-1; + } + + /* number of output digits to produce */ + COMBA_START; + COMBA_CLEAR; + + if (A == B) { + fp_zero(&tmp); + dst = &tmp; + } else { + fp_zero(B); + dst = B; + } + + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + fp_digit *tmpy, *tmpx; + + /* get offsets into the two bignums */ + ty = MIN(A->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = A->dp + tx; + tmpy = A->dp + ty; + + /* this is the number of times the loop will iterrate, + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(A->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach + * at a rate of 2x and we have to round because + * odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* forward carries */ + COMBA_FORWARD; + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + SQRADD2(*tmpx++, *tmpy--); + } + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + /* TAO change COMBA_ADD back to SQRADD */ + SQRADD(A->dp[ix>>1], A->dp[ix>>1]); + } + + /* store it */ + COMBA_STORE(dst->dp[ix]); + } + + COMBA_FINI; + + /* setup dest */ + dst->used = pa; + fp_clamp (dst); + if (dst != B) { + fp_copy(dst, B); + } +} + +int fp_cmp(fp_int *a, fp_int *b) +{ + if (a->sign == FP_NEG && b->sign == FP_ZPOS) { + return FP_LT; + } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) { + return FP_GT; + } else { + /* compare digits */ + if (a->sign == FP_NEG) { + /* if negative compare opposite direction */ + return fp_cmp_mag(b, a); + } else { + return fp_cmp_mag(a, b); + } + } +} + +/* compare against a single digit */ +int fp_cmp_d(fp_int *a, fp_digit b) +{ + /* compare based on sign */ + if ((b && a->used == 0) || a->sign == FP_NEG) { + return FP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return FP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return FP_GT; + } else if (a->dp[0] < b) { + return FP_LT; + } else { + return FP_EQ; + } + +} + +int fp_cmp_mag(fp_int *a, fp_int *b) +{ + int x; + + if (a->used > b->used) { + return FP_GT; + } else if (a->used < b->used) { + return FP_LT; + } else { + for (x = a->used - 1; x >= 0; x--) { + if (a->dp[x] > b->dp[x]) { + return FP_GT; + } else if (a->dp[x] < b->dp[x]) { + return FP_LT; + } + } + } + return FP_EQ; +} + +/* setups the montgomery reduction */ +int fp_montgomery_setup(fp_int *a, fp_digit *rho) +{ + fp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = a->dp[0]; + + if ((b & 1) == 0) { + return FP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#ifdef FP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (fp_digit) (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x)); + + return FP_OKAY; +} + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +void fp_montgomery_calc_normalization(fp_int *a, fp_int *b) +{ + int x, bits; + + /* how many bits of last digit does b use */ + bits = fp_count_bits (b) % DIGIT_BIT; + if (!bits) bits = DIGIT_BIT; + + /* compute A = B^(n-1) * 2^(bits-1) */ + if (b->used > 1) { + fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1); + } else { + fp_set(a, 1); + bits = 1; + } + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + fp_mul_2 (a, a); + if (fp_cmp_mag (a, b) != FP_LT) { + s_fp_sub (a, b, a); + } + } +} + + +#ifdef TFM_SMALL_MONT_SET + #include "fp_mont_small.i" +#endif + +/* computes x/R == x (mod N) via Montgomery Reduction */ +void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) +{ + fp_digit c[FP_SIZE], *_c, *tmpm, mu; + int oldused, x, y, pa; + + /* bail if too large */ + if (m->used > (FP_SIZE/2)) { + (void)mu; /* shut up compiler */ + return; + } + +#ifdef TFM_SMALL_MONT_SET + if (m->used <= 16) { + fp_montgomery_reduce_small(a, m, mp); + return; + } +#endif + + +#if defined(USE_MEMSET) + /* now zero the buff */ + XMEMSET(c, 0, sizeof c); +#endif + pa = m->used; + + /* copy the input */ + oldused = a->used; + for (x = 0; x < oldused; x++) { + c[x] = a->dp[x]; + } +#if !defined(USE_MEMSET) + for (; x < 2*pa+1; x++) { + c[x] = 0; + } +#endif + MONT_START; + + for (x = 0; x < pa; x++) { + fp_digit cy = 0; + /* get Mu for this round */ + LOOP_START; + _c = c + x; + tmpm = m->dp; + y = 0; + #if (defined(TFM_SSE2) || defined(TFM_X86_64)) + for (; y < (pa & ~7); y += 8) { + INNERMUL8; + _c += 8; + tmpm += 8; + } + #endif + + for (; y < pa; y++) { + INNERMUL; + ++_c; + } + LOOP_END; + while (cy) { + PROPCARRY; + ++_c; + } + } + + /* now copy out */ + _c = c + pa; + tmpm = a->dp; + for (x = 0; x < pa+1; x++) { + *tmpm++ = *_c++; + } + + for (; x < oldused; x++) { + *tmpm++ = 0; + } + + MONT_FINI; + + a->used = pa+1; + fp_clamp(a); + + /* if A >= m then A = A - m */ + if (fp_cmp_mag (a, m) != FP_LT) { + s_fp_sub (a, m, a); + } +} + +void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c) +{ + /* zero the int */ + fp_zero (a); + + /* If we know the endianness of this architecture, and we're using + 32-bit fp_digits, we can optimize this */ +#if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(FP_64BIT) + /* But not for both simultaneously */ +#if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG) +#error Both ENDIAN_LITTLE and ENDIAN_BIG defined. +#endif + { + unsigned char *pd = (unsigned char *)a->dp; + + if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) { + int excess = c - (FP_SIZE * sizeof(fp_digit)); + c -= excess; + b += excess; + } + a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit); + /* read the bytes in */ +#ifdef ENDIAN_BIG + { + /* Use Duff's device to unroll the loop. */ + int idx = (c - 1) & ~3; + switch (c % 4) { + case 0: do { pd[idx+0] = *b++; + case 3: pd[idx+1] = *b++; + case 2: pd[idx+2] = *b++; + case 1: pd[idx+3] = *b++; + idx -= 4; + } while ((c -= 4) > 0); + } + } +#else + for (c -= 1; c >= 0; c -= 1) { + pd[c] = *b++; + } +#endif + } +#else + /* read the bytes in */ + for (; c > 0; c--) { + fp_mul_2d (a, 8, a); + a->dp[0] |= *b++; + a->used += 1; + } +#endif + fp_clamp (a); +} + +void fp_to_unsigned_bin(fp_int *a, unsigned char *b) +{ + int x; + fp_int t; + + fp_init_copy(&t, a); + + x = 0; + while (fp_iszero (&t) == FP_NO) { + b[x++] = (unsigned char) (t.dp[0] & 255); + fp_div_2d (&t, 8, &t, NULL); + } + fp_reverse (b, x); +} + +int fp_unsigned_bin_size(fp_int *a) +{ + int size = fp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + +void fp_set(fp_int *a, fp_digit b) +{ + fp_zero(a); + a->dp[0] = b; + a->used = a->dp[0] ? 1 : 0; +} + +int fp_count_bits (fp_int * a) +{ + int r; + fp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((fp_digit) 0)) { + ++r; + q >>= ((fp_digit) 1); + } + return r; +} + +void fp_lshd(fp_int *a, int x) +{ + int y; + + /* move up and truncate as required */ + y = MIN(a->used + x - 1, (int)(FP_SIZE-1)); + + /* store new size */ + a->used = y + 1; + + /* move digits */ + for (; y >= x; y--) { + a->dp[y] = a->dp[y-x]; + } + + /* zero lower digits */ + for (; y >= 0; y--) { + a->dp[y] = 0; + } + + /* clamp digits */ + fp_clamp(a); +} + +void fp_rshd(fp_int *a, int x) +{ + int y; + + /* too many digits just zero and return */ + if (x >= a->used) { + fp_zero(a); + return; + } + + /* shift */ + for (y = 0; y < a->used - x; y++) { + a->dp[y] = a->dp[y+x]; + } + + /* zero rest */ + for (; y < a->used; y++) { + a->dp[y] = 0; + } + + /* decrement count */ + a->used -= x; + fp_clamp(a); +} + +/* reverse an array, used for radix code */ +void fp_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + + +/* CyaSSL callers from normal lib */ + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + if (a) + fp_init(a); + return MP_OKAY; +} + +/* clear one (frees) */ +void mp_clear (mp_int * a) +{ + fp_zero(a); +} + +/* handle up to 6 inits */ +int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f) +{ + if (a) + fp_init(a); + if (b) + fp_init(b); + if (c) + fp_init(c); + if (d) + fp_init(d); + if (e) + fp_init(e); + if (f) + fp_init(f); + + return MP_OKAY; +} + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + fp_add(a, b, c); + return MP_OKAY; +} + +/* high level subtraction (handles signs) */ +int mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + fp_sub(a, b, c); + return MP_OKAY; +} + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + fp_mul(a, b, c); + return MP_OKAY; +} + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + return fp_mulmod(a, b, c, d); +} + +/* c = a mod b, 0 <= c < b */ +int mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + return fp_mod (a, b, c); +} + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + return fp_invmod(a, b, c); +} + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + return fp_exptmod(G, X, P, Y); +} + +/* compare two ints (signed)*/ +int mp_cmp (mp_int * a, mp_int * b) +{ + return fp_cmp(a, b); +} + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + return fp_cmp_d(a, b); +} + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + return fp_unsigned_bin_size(a); +} + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + fp_to_unsigned_bin(a,b); + return MP_OKAY; +} + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + fp_read_unsigned_bin(a, (unsigned char *)b, c); + return MP_OKAY; +} + + +#if defined(CYASSL_KEY_GEN) || defined (HAVE_ECC) + +/* c = a * a (mod b) */ +int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c) +{ + fp_int tmp; + fp_zero(&tmp); + fp_sqr(a, &tmp); + return fp_mod(&tmp, b, c); +} + +/* fast math conversion */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c) +{ + return fp_sqrmod(a, b, c); +} + +/* fast math conversion */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) +{ + fp_montgomery_calc_normalization(a, b); + return MP_OKAY; +} + +/* fast math conversion */ +int mp_copy(fp_int* a, fp_int* b) +{ + fp_copy(a, b); + return MP_OKAY; +} + + +#endif /* CYASSL_KEYGEN || HAVE_ECC */ + + +#ifdef CYASSL_KEY_GEN + +void fp_gcd(fp_int *a, fp_int *b, fp_int *c); +void fp_lcm(fp_int *a, fp_int *b, fp_int *c); +void fp_sub_d(fp_int *a, fp_digit b, fp_int *c); +int fp_isprime(fp_int *a); +int fp_cnt_lsb(fp_int *a); + +/* fast math wrappers */ +int mp_set_int(fp_int *a, fp_digit b) +{ + fp_set(a, b); + return MP_OKAY; +} + + +int mp_gcd(fp_int *a, fp_int *b, fp_int *c) +{ + fp_gcd(a, b, c); + return MP_OKAY; +} + + +int mp_lcm(fp_int *a, fp_int *b, fp_int *c) +{ + fp_lcm(a, b, c); + return MP_OKAY; +} + + +int mp_sub_d(fp_int *a, fp_digit b, fp_int *c) +{ + fp_sub_d(a, b, c); + return MP_OKAY; +} + + +int mp_prime_is_prime(mp_int* a, int t, int* result) +{ + *result = fp_isprime(a); + return MP_OKAY; +} + + + +/* c = a - b */ +void fp_sub_d(fp_int *a, fp_digit b, fp_int *c) +{ + fp_int tmp; + fp_set(&tmp, b); + fp_sub(a, &tmp, c); +} + + +static int s_is_power_of_two(fp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b==0) || (b & (b-1))) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((fp_digit)1)< cb + d == a */ +int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) +{ + fp_int q; + fp_word w; + fp_digit t; + int ix; + + /* cannot divide by zero */ + if (b == 0) { + return FP_VAL; + } + + /* quick outs */ + if (b == 1 || fp_iszero(a) == 1) { + if (d != NULL) { + *d = 0; + } + if (c != NULL) { + fp_copy(a, c); + } + return FP_OKAY; + } + + /* power of two ? */ + if (s_is_power_of_two(b, &ix) == 1) { + if (d != NULL) { + *d = a->dp[0] & ((((fp_digit)1)<used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]); + + if (w >= b) { + t = (fp_digit)(w / b); + w -= ((fp_word)t) * ((fp_word)b); + } else { + t = 0; + } + q.dp[ix] = (fp_digit)t; + } + + if (d != NULL) { + *d = (fp_digit)w; + } + + if (c != NULL) { + fp_clamp(&q); + fp_copy(&q, c); + } + + return FP_OKAY; +} + + +/* c = a mod b, 0 <= c < b */ +int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c) +{ + return fp_div_d(a, b, NULL, c); +} + + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result) +{ + fp_int n1, y, r; + int s, j; + + /* default */ + *result = FP_NO; + + /* ensure b > 1 */ + if (fp_cmp_d(b, 1) != FP_GT) { + return; + } + + /* get n1 = a - 1 */ + fp_init_copy(&n1, a); + fp_sub_d(&n1, 1, &n1); + + /* set 2**s * r = n1 */ + fp_init_copy(&r, &n1); + + /* count the number of least significant bits + * which are zero + */ + s = fp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + fp_div_2d (&r, s, &r, NULL); + + /* compute y = b**r mod a */ + fp_init(&y); + fp_exptmod(b, &r, a, &y); + + /* if y != 1 and y != n1 do */ + if (fp_cmp_d (&y, 1) != FP_EQ && fp_cmp (&y, &n1) != FP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && fp_cmp (&y, &n1) != FP_EQ) { + fp_sqrmod (&y, a, &y); + + /* if y == 1 then composite */ + if (fp_cmp_d (&y, 1) == FP_EQ) { + return; + } + ++j; + } + + /* if y != n1 then composite */ + if (fp_cmp (&y, &n1) != FP_EQ) { + return; + } + } + + /* probably prime now */ + *result = FP_YES; +} + + +/* a few primes */ +static const fp_digit primes[256] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +}; + +int fp_isprime(fp_int *a) +{ + fp_int b; + fp_digit d; + int r, res; + + /* do trial division */ + for (r = 0; r < 256; r++) { + fp_mod_d(a, primes[r], &d); + if (d == 0) { + return FP_NO; + } + } + + /* now do 8 miller rabins */ + fp_init(&b); + for (r = 0; r < 8; r++) { + fp_set(&b, primes[r]); + fp_prime_miller_rabin(a, &b, &res); + if (res == FP_NO) { + return FP_NO; + } + } + return FP_YES; +} + + +/* c = [a, b] */ +void fp_lcm(fp_int *a, fp_int *b, fp_int *c) +{ + fp_int t1, t2; + + fp_init(&t1); + fp_init(&t2); + fp_gcd(a, b, &t1); + if (fp_cmp_mag(a, b) == FP_GT) { + fp_div(a, &t1, &t2, NULL); + fp_mul(b, &t2, c); + } else { + fp_div(b, &t1, &t2, NULL); + fp_mul(a, &t2, c); + } +} + + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int fp_cnt_lsb(fp_int *a) +{ + int x; + fp_digit q, qq; + + /* easy out */ + if (fp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + + +/* c = (a, b) */ +void fp_gcd(fp_int *a, fp_int *b, fp_int *c) +{ + fp_int u, v, r; + + /* either zero than gcd is the largest */ + if (fp_iszero (a) == 1 && fp_iszero (b) == 0) { + fp_abs (b, c); + return; + } + if (fp_iszero (a) == 0 && fp_iszero (b) == 1) { + fp_abs (a, c); + return; + } + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (fp_iszero (a) == 1) { + fp_zero(c); + return; + } + + /* sort inputs */ + if (fp_cmp_mag(a, b) != FP_LT) { + fp_init_copy(&u, a); + fp_init_copy(&v, b); + } else { + fp_init_copy(&u, b); + fp_init_copy(&v, a); + } + + fp_zero(&r); + while (fp_iszero(&v) == FP_NO) { + fp_mod(&u, &v, &r); + fp_copy(&v, &u); + fp_copy(&r, &v); + } + fp_copy(&u, c); +} + +#endif /* CYASSL_KEY_GEN */ + + +#ifdef HAVE_ECC + +/* chars used in radix conversions */ +const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +/* c = a + b */ +void fp_add_d(fp_int *a, fp_digit b, fp_int *c) +{ + fp_int tmp; + fp_set(&tmp, b); + fp_add(a,&tmp,c); +} + + +int fp_read_radix(fp_int *a, const char *str, int radix) +{ + int y, neg; + char ch; + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return FP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = FP_NEG; + } else { + neg = FP_ZPOS; + } + + /* set the integer to the default of zero */ + fp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == fp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + fp_mul_d (a, (fp_digit) radix, a); + fp_add_d (a, (fp_digit) y, a); + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (fp_iszero(a) != FP_YES) { + a->sign = neg; + } + return FP_OKAY; +} + +/* fast math conversion */ +int mp_read_radix(mp_int *a, const char *str, int radix) +{ + return fp_read_radix(a, str, radix); +} + +/* fast math conversion */ +int mp_iszero(mp_int* a) +{ + return fp_iszero(a); +} + +/* fast math conversion */ +int mp_set(fp_int *a, fp_digit b) +{ + fp_set(a,b); + return MP_OKAY; +} + +/* fast math conversion */ +int mp_sqr(fp_int *A, fp_int *B) +{ + fp_sqr(A, B); + return MP_OKAY; +} + +/* fast math conversion */ +int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) +{ + fp_montgomery_reduce(a, m, mp); + return MP_OKAY; +} + + +/* fast math conversion */ +int mp_montgomery_setup(fp_int *a, fp_digit *rho) +{ + return fp_montgomery_setup(a, rho); +} + +/* fast math conversion */ +int mp_isodd(mp_int* a) +{ + return fp_isodd(a); +} + + +int mp_div_2(fp_int * a, fp_int * b) +{ + fp_div_2(a, b); + return MP_OKAY; +} + +#endif /* HAVE_ECC */ + +#endif /* USE_FAST_MATH */ diff --git a/release/src/router/cyassl/ctaocrypt/test/Makefile.am b/release/src/router/cyassl/ctaocrypt/test/Makefile.am new file mode 100644 index 00000000..429df045 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/test/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I../include -I../../include -I../../include/openssl +bin_PROGRAMS = test +test_SOURCES = test.c +test_LDFLAGS = -L../src +test_LDADD = ../../src/libcyassl.la +test_DEPENDENCIES = ../../src/libcyassl.la +EXTRA_DIST = test.sln test.vcproj diff --git a/release/src/router/cyassl/ctaocrypt/test/Makefile.in b/release/src/router/cyassl/ctaocrypt/test/Makefile.in new file mode 100644 index 00000000..739c0d34 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/test/Makefile.in @@ -0,0 +1,485 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@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@ +target_triplet = @target@ +bin_PROGRAMS = test$(EXEEXT) +subdir = ctaocrypt/test +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/lib_socket_nsl.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ctaocrypt/include/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_test_OBJECTS = test.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(test_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)/ctaocrypt/include@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(test_SOURCES) +DIST_SOURCES = $(test_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBM = @LIBM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +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_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I../include -I../../include -I../../include/openssl +test_SOURCES = test.c +test_LDFLAGS = -L../src +test_LDADD = ../../src/libcyassl.la +test_DEPENDENCIES = ../../src/libcyassl.la +EXTRA_DIST = test.sln test.vcproj +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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ctaocrypt/test/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ctaocrypt/test/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 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(test_LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +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 $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$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 $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; 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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +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-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(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-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS 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-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 uninstall uninstall-am \ + uninstall-binPROGRAMS + +# 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/release/src/router/cyassl/ctaocrypt/test/test.c b/release/src/router/cyassl/ctaocrypt/test/test.c new file mode 100644 index 00000000..50fecd38 --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/test/test.c @@ -0,0 +1,1783 @@ +/* test.c */ + + +#include +#include +#include + +#include "ctc_md5.h" +#include "ctc_md4.h" +#include "ctc_sha.h" +#include "sha256.h" +#include "sha512.h" +#include "arc4.h" +#include "random.h" +#include "coding.h" +#include "asn.h" +#include "des3.h" +#include "ctc_aes.h" +#include "ctc_hmac.h" +#include "ctc_dh.h" +#include "ctc_dsa.h" +#include "hc128.h" +#include "rabbit.h" +#include "pwdbased.h" +#include "ctc_ripemd.h" +#ifdef HAVE_ECC + #include "ctc_ecc.h" +#endif + +#ifdef _MSC_VER + /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ + #pragma warning(disable: 4996) +#endif + +#ifdef OPENSSL_EXTRA + #include "evp.h" + #include "rand.h" + #include "hmac.h" + #include "des.h" +#endif + +#ifdef HAVE_NTRU + #include "crypto_ntru.h" +#endif + + +#ifdef THREADX + /* since just testing, use THREADX log printf instead */ + int dc_log_printf(char*, ...); + #undef printf + #define printf dc_log_printf +#endif + + +typedef struct testVector { + char* input; + char* output; + size_t inLen; + size_t outLen; +} testVector; + +int md5_test(); +int md4_test(); +int sha_test(); +int sha256_test(); +int sha512_test(); +int hmac_test(); +int arc4_test(); +int hc128_test(); +int rabbit_test(); +int des_test(); +int des3_test(); +int aes_test(); +int rsa_test(); +int dh_test(); +int dsa_test(); +int random_test(); +int pwdbased_test(); +int ripemd_test(); +int openssl_test(); /* test mini api */ +#ifdef HAVE_ECC + int ecc_test(); +#endif + +int PemToDer(const char* inName, const char* outName); + + +void err_sys(const char* msg, int es) +{ + printf("%s error = %d\n", msg, es); +#ifndef THREADX + exit(es); +#endif +} + +/* func_args from cyassl_test.h, so don't have to pull in other junk */ +typedef struct func_args { + int argc; + char** argv; + int return_code; +} func_args; + + +void ctaocrypt_test(void* args) +{ + int ret = 0; + + ((func_args*)args)->return_code = -1; /* error state */ + + if ( (ret = md5_test()) ) + err_sys("MD5 test failed!\n", ret); + else + printf( "MD5 test passed!\n"); + +#ifndef NO_MD4 + if ( (ret = md4_test()) ) + err_sys("MD4 test failed!\n", ret); + else + printf( "MD4 test passed!\n"); +#endif + + if ( (ret = sha_test()) ) + err_sys("SHA test failed!\n", ret); + else + printf( "SHA test passed!\n"); + +#ifndef NO_SHA256 + if ( (ret = sha256_test()) ) + err_sys("SHA-256 test failed!\n", ret); + else + printf( "SHA-256 test passed!\n"); +#endif + +#ifdef CYASSL_SHA512 + if ( (ret = sha512_test()) ) + err_sys("SHA-512 test failed!\n", ret); + else + printf( "SHA-512 test passed!\n"); +#endif + +#ifdef CYASSL_RIPEMD + if ( (ret = ripemd_test()) ) + err_sys("RIPEMD test failed!\n", ret); + else + printf( "RIPEMD test passed!\n"); +#endif + +#ifndef NO_HMAC + if ( (ret = hmac_test()) ) + err_sys("HMAC test failed!\n", ret); + else + printf( "HMAC test passed!\n"); +#endif + + if ( (ret = arc4_test()) ) + err_sys("ARC4 test failed!\n", ret); + else + printf( "ARC4 test passed!\n"); + +#ifndef NO_HC128 + if ( (ret = hc128_test()) ) + err_sys("HC-128 test failed!\n", ret); + else + printf( "HC-128 test passed!\n"); +#endif + +#ifndef NO_RABBIT + if ( (ret = rabbit_test()) ) + err_sys("Rabbit test failed!\n", ret); + else + printf( "Rabbit test passed!\n"); +#endif + +#ifndef NO_DES3 + if ( (ret = des_test()) ) + err_sys("DES test failed!\n", ret); + else + printf( "DES test passed!\n"); +#endif + +#ifndef NO_DES3 + if ( (ret = des3_test()) ) + err_sys("DES3 test failed!\n", ret); + else + printf( "DES3 test passed!\n"); +#endif + +#ifndef NO_AES + if ( (ret = aes_test()) ) + err_sys("AES test failed!\n", ret); + else + printf( "AES test passed!\n"); +#endif + + if ( (ret = random_test()) ) + err_sys("RANDOM test failed!\n", ret); + else + printf( "RANDOM test passed!\n"); + + if ( (ret = rsa_test()) ) + err_sys("RSA test failed!\n", ret); + else + printf( "RSA test passed!\n"); + +#ifndef NO_DH + if ( (ret = dh_test()) ) + err_sys("DH test failed!\n", ret); + else + printf( "DH test passed!\n"); +#endif + +#ifndef NO_DSA + if ( (ret = dsa_test()) ) + err_sys("DSA test failed!\n", ret); + else + printf( "DSA test passed!\n"); +#endif + +#ifndef NO_PWDBASED + if ( (ret = pwdbased_test()) ) + err_sys("PWDBASED test failed!\n", ret); + else + printf( "PWDBASED test passed!\n"); +#endif + +#ifdef OPENSSL_EXTRA + if ( (ret = openssl_test()) ) + err_sys("OPENSSL test failed!\n", ret); + else + printf( "OPENSSL test passed!\n"); +#endif + +#ifdef HAVE_ECC + if ( (ret = ecc_test()) ) + err_sys("ECC test failed!\n", ret); + else + printf( "ECC test passed!\n"); +#endif + + ((func_args*)args)->return_code = ret; +} + + +/* so overall tests can pull in test function */ +#ifndef NO_MAIN_DRIVER + + int main(int argc, char** argv) + { + func_args args; + + args.argc = argc; + args.argv = argv; + + ctaocrypt_test(&args); + return args.return_code; + } + +#endif /* NO_MAIN_DRIVER */ + + +int md5_test() +{ + Md5 md5; + byte hash[MD5_DIGEST_SIZE]; + + testVector a, b, c, d, e; + testVector test_md5[5]; + int times = sizeof(test_md5) / sizeof(testVector), i; + + a.input = "abc"; + a.output = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f" + "\x72"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "message digest"; + b.output = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61" + "\xd0"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "abcdefghijklmnopqrstuvwxyz"; + c.output = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1" + "\x3b"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" + "6789"; + d.output = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d" + "\x9f"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + e.input = "1234567890123456789012345678901234567890123456789012345678" + "9012345678901234567890"; + e.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" + "\x7a"; + e.inLen = strlen(e.input); + e.outLen = strlen(e.output); + + test_md5[0] = a; + test_md5[1] = b; + test_md5[2] = c; + test_md5[3] = d; + test_md5[4] = e; + + InitMd5(&md5); + + for (i = 0; i < times; ++i) { + Md5Update(&md5, (byte*)test_md5[i].input, (word32)test_md5[i].inLen); + Md5Final(&md5, hash); + + if (memcmp(hash, test_md5[i].output, MD5_DIGEST_SIZE) != 0) + return -5 - i; + } + + return 0; +} + + +#ifndef NO_MD4 + +int md4_test() +{ + Md4 md4; + byte hash[MD4_DIGEST_SIZE]; + + testVector a, b, c, d, e, f, g; + testVector test_md4[7]; + int times = sizeof(test_md4) / sizeof(testVector), i; + + a.input = ""; + a.output = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89" + "\xc0"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "a"; + b.output = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb" + "\x24"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "abc"; + c.output = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52\x5f\xc1\x0a\xe8\x7a\xa6\x72" + "\x9d"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "message digest"; + d.output = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01" + "\x4b"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + e.input = "abcdefghijklmnopqrstuvwxyz"; + e.output = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd\xee\xa8\xed\x63\xdf\x41\x2d" + "\xa9"; + e.inLen = strlen(e.input); + e.outLen = strlen(e.output); + + f.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" + "6789"; + f.output = "\x04\x3f\x85\x82\xf2\x41\xdb\x35\x1c\xe6\x27\xe1\x53\xe7\xf0" + "\xe4"; + f.inLen = strlen(f.input); + f.outLen = strlen(f.output); + + g.input = "1234567890123456789012345678901234567890123456789012345678" + "9012345678901234567890"; + g.output = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f\xcc\x05" + "\x36"; + g.inLen = strlen(g.input); + g.outLen = strlen(g.output); + + test_md4[0] = a; + test_md4[1] = b; + test_md4[2] = c; + test_md4[3] = d; + test_md4[4] = e; + test_md4[5] = f; + test_md4[6] = g; + + InitMd4(&md4); + + for (i = 0; i < times; ++i) { + Md4Update(&md4, (byte*)test_md4[i].input, (word32)test_md4[i].inLen); + Md4Final(&md4, hash); + + if (memcmp(hash, test_md4[i].output, MD4_DIGEST_SIZE) != 0) + return -205 - i; + } + + return 0; +} + +#endif /* NO_MD4 */ + +int sha_test() +{ + Sha sha; + byte hash[SHA_DIGEST_SIZE]; + + testVector a, b, c, d; + testVector test_sha[4]; + int times = sizeof(test_sha) / sizeof(struct testVector), i; + + a.input = "abc"; + a.output = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2" + "\x6C\x9C\xD0\xD8\x9D"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + b.output = "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29" + "\xE5\xE5\x46\x70\xF1"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"; + c.output = "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44" + "\x2A\x25\xEC\x64\x4D"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaa"; + d.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" + "\x53\x99\x5E\x26\xA0"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + test_sha[0] = a; + test_sha[1] = b; + test_sha[2] = c; + test_sha[3] = d; + + InitSha(&sha); + + for (i = 0; i < times; ++i) { + ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); + ShaFinal(&sha, hash); + + if (memcmp(hash, test_sha[i].output, SHA_DIGEST_SIZE) != 0) + return -10 - i; + } + + return 0; +} + + +#ifdef CYASSL_RIPEMD +int ripemd_test() +{ + RipeMd ripemd; + byte hash[RIPEMD_DIGEST_SIZE]; + + testVector a, b, c, d; + testVector test_ripemd[4]; + int times = sizeof(test_ripemd) / sizeof(struct testVector), i; + + a.input = "abc"; + a.output = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6" + "\xb0\x87\xf1\x5a\x0b\xfc"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "message digest"; + b.output = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8\x81\xb1\x23\xa8" + "\x5f\xfa\x21\x59\x5f\x36"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + c.output = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05\xa0\x6c\x27\xdc" + "\xf4\x9a\xda\x62\xeb\x2b"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "12345678901234567890123456789012345678901234567890123456" + "789012345678901234567890"; + d.output = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb\xd3\x32\x3c\xab" + "\x82\xbf\x63\x32\x6b\xfb"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + test_ripemd[0] = a; + test_ripemd[1] = b; + test_ripemd[2] = c; + test_ripemd[3] = d; + + InitRipeMd(&ripemd); + + for (i = 0; i < times; ++i) { + RipeMdUpdate(&ripemd, (byte*)test_ripemd[i].input, + (word32)test_ripemd[i].inLen); + RipeMdFinal(&ripemd, hash); + + if (memcmp(hash, test_ripemd[i].output, RIPEMD_DIGEST_SIZE) != 0) + return -10 - i; + } + + return 0; +} +#endif /* CYASSL_RIPEMD */ + + +#ifndef NO_SHA256 +int sha256_test() +{ + Sha256 sha; + byte hash[SHA256_DIGEST_SIZE]; + + testVector a, b; + testVector test_sha[2]; + int times = sizeof(test_sha) / sizeof(struct testVector), i; + + a.input = "abc"; + a.output = "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" + "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" + "\x15\xAD"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + b.output = "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" + "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" + "\x06\xC1"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + test_sha[0] = a; + test_sha[1] = b; + + InitSha256(&sha); + + for (i = 0; i < times; ++i) { + Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); + Sha256Final(&sha, hash); + + if (memcmp(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0) + return -10 - i; + } + + return 0; +} +#endif + + +#ifdef CYASSL_SHA512 +int sha512_test() +{ + Sha512 sha; + byte hash[SHA512_DIGEST_SIZE]; + + testVector a, b; + testVector test_sha[2]; + int times = sizeof(test_sha) / sizeof(struct testVector), i; + + a.input = "abc"; + a.output = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41" + "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55" + "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3" + "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" + "\xa5\x4c\xa4\x9f"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + b.output = "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14" + "\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88" + "\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4" + "\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b" + "\x87\x4b\xe9\x09"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + test_sha[0] = a; + test_sha[1] = b; + + InitSha512(&sha); + + for (i = 0; i < times; ++i) { + Sha512Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); + Sha512Final(&sha, hash); + + if (memcmp(hash, test_sha[i].output, SHA512_DIGEST_SIZE) != 0) + return -10 - i; + } + + return 0; +} +#endif + + +#ifndef NO_HMAC +int hmac_test() +{ + Hmac hmac; + byte hash[MD5_DIGEST_SIZE]; + + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + }; + + testVector a, b, c; + testVector test_hmac[3]; + + int times = sizeof(test_hmac) / sizeof(testVector), i; + + a.input = "Hi There"; + a.output = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc" + "\x9d"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "what do ya want for nothing?"; + b.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7" + "\x38"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3" + "\xf6"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { + HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)strlen(keys[i])); + HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + HmacFinal(&hmac, hash); + + if (memcmp(hash, test_hmac[i].output, MD5_DIGEST_SIZE) != 0) + return -20 - i; + } + + return 0; +} +#endif + + +int arc4_test() +{ + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x01\x23\x45\x67\x89\xab\xcd\xef", + "\x01\x23\x45\x67\x89\xab\xcd\xef", + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xef\x01\x23\x45" + }; + + testVector a, b, c, d; + testVector test_arc4[4]; + + int times = sizeof(test_arc4) / sizeof(testVector), i; + + a.input = "\x01\x23\x45\x67\x89\xab\xcd\xef"; + a.output = "\x75\xb7\x87\x80\x99\xe0\xc5\x96"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + b.output = "\x74\x94\xc2\xe7\x10\x4b\x08\x79"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + c.output = "\xde\x18\x89\x41\xa3\x37\x5d\x3a"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + d.output = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf\xbd\x61"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + test_arc4[0] = a; + test_arc4[1] = b; + test_arc4[2] = c; + test_arc4[3] = d; + + for (i = 0; i < times; ++i) { + Arc4 enc; + Arc4 dec; + + Arc4SetKey(&enc, (byte*)keys[i], (word32)strlen(keys[i])); + Arc4SetKey(&dec, (byte*)keys[i], (word32)strlen(keys[i])); + + Arc4Process(&enc, cipher, (byte*)test_arc4[i].input, + (word32)test_arc4[i].outLen); + Arc4Process(&dec, plain, cipher, (word32)test_arc4[i].outLen); + + if (memcmp(plain, test_arc4[i].input, test_arc4[i].outLen)) + return -20 - i; + + if (memcmp(cipher, test_arc4[i].output, test_arc4[i].outLen)) + return -20 - 5 - i; + } + + return 0; +} + + +#ifndef NO_HC128 +int hc128_test() +{ + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD", + "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC" + }; + + const char* ivs[] = + { + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x0D\x74\xDB\x42\xA9\x10\x77\xDE\x45\xAC\x13\x7A\xE1\x48\xAF\x16", + "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9\x60\xC7\x2E\x95\xFC\x63\xCA\x31" + }; + + + testVector a, b, c, d; + testVector test_hc128[4]; + + int times = sizeof(test_hc128) / sizeof(testVector), i; + + a.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + a.output = "\x37\x86\x02\xB9\x8F\x32\xA7\x48"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + b.output = "\x33\x7F\x86\x11\xC6\xED\x61\x5F"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + c.output = "\x2E\x1E\xD1\x2A\x85\x51\xC0\x5A"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + d.input = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + d.output = "\x1C\xD8\xAE\xDD\xFE\x52\xE2\x17\xE8\x35\xD0\xB7\xE8\x4E\x29"; + d.inLen = strlen(d.input); + d.outLen = strlen(d.output); + + test_hc128[0] = a; + test_hc128[1] = b; + test_hc128[2] = c; + test_hc128[3] = d; + + for (i = 0; i < times; ++i) { + HC128 enc; + HC128 dec; + + Hc128_SetKey(&enc, (byte*)keys[i], (byte*)ivs[i]); + Hc128_SetKey(&dec, (byte*)keys[i], (byte*)ivs[i]); + + Hc128_Process(&enc, cipher, (byte*)test_hc128[i].input, + (word32)test_hc128[i].outLen); + Hc128_Process(&dec, plain, cipher, (word32)test_hc128[i].outLen); + + if (memcmp(plain, test_hc128[i].input, test_hc128[i].outLen)) + return -120 - i; + + if (memcmp(cipher, test_hc128[i].output, test_hc128[i].outLen)) + return -120 - 5 - i; + } + + return 0; +} +#endif /* NO_HC128 */ + + +#ifndef NO_RABBIT +int rabbit_test() +{ + byte cipher[16]; + byte plain[16]; + + const char* keys[] = + { + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\xAC\xC3\x51\xDC\xF1\x62\xFC\x3B\xFE\x36\x3D\x2E\x29\x13\x28\x91" + }; + + const char* ivs[] = + { + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x59\x7E\x26\xC1\x75\xF5\x73\xC3", + 0 + }; + + + testVector a, b, c; + testVector test_rabbit[3]; + + int times = sizeof(test_rabbit) / sizeof(testVector), i; + + a.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + a.output = "\xED\xB7\x05\x67\x37\x5D\xCD\x7C"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + b.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + b.output = "\x6D\x7D\x01\x22\x92\xCC\xDC\xE0"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + c.input = "\x00\x00\x00\x00\x00\x00\x00\x00"; + c.output = "\x9C\x51\xE2\x87\x84\xC3\x7F\xE9"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + test_rabbit[0] = a; + test_rabbit[1] = b; + test_rabbit[2] = c; + + for (i = 0; i < times; ++i) { + Rabbit enc; + Rabbit dec; + + RabbitSetKey(&enc, (byte*)keys[i], (byte*)ivs[i]); + RabbitSetKey(&dec, (byte*)keys[i], (byte*)ivs[i]); + + RabbitProcess(&enc, cipher, (byte*)test_rabbit[i].input, + (word32)test_rabbit[i].outLen); + RabbitProcess(&dec, plain, cipher, (word32)test_rabbit[i].outLen); + + if (memcmp(plain, test_rabbit[i].input, test_rabbit[i].outLen)) + return -130 - i; + + if (memcmp(cipher, test_rabbit[i].output, test_rabbit[i].outLen)) + return -130 - 5 - i; + } + + return 0; +} +#endif /* NO_RABBIT */ + + +#ifndef NO_DES3 +int des_test() +{ + const byte vector[] = { /* "now is the time for all " w/o trailing 0 */ + 0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + + byte plain[24]; + byte cipher[24]; + + Des enc; + Des dec; + + const byte key[] = + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef + }; + + const byte iv[] = + { + 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef + }; + + const byte verify[] = + { + 0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8, + 0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73, + 0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b + }; + + + Des_SetKey(&enc, key, iv, DES_ENCRYPTION); + Des_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); + Des_SetKey(&dec, key, iv, DES_DECRYPTION); + Des_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); + + if (memcmp(plain, vector, sizeof(plain))) + return -31; + + if (memcmp(cipher, verify, sizeof(cipher))) + return -32; + + return 0; +} +#endif /* NO_DES3 */ + + +#ifndef NO_DES3 +int des3_test() +{ + const byte vector[] = { /* "Now is the time for all " w/o trailing 0 */ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + + byte plain[24]; + byte cipher[24]; + + Des3 enc; + Des3 dec; + + const byte key3[] = + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 + }; + const byte iv3[] = + { + 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81 + + }; + + const byte verify3[] = + { + 0x43,0xa0,0x29,0x7e,0xd1,0x84,0xf8,0x0e, + 0x89,0x64,0x84,0x32,0x12,0xd5,0x08,0x98, + 0x18,0x94,0x15,0x74,0x87,0x12,0x7d,0xb0 + }; + + + Des3_SetKey(&enc, key3, iv3, DES_ENCRYPTION); + Des3_CbcEncrypt(&enc, cipher, vector, sizeof(vector)); + Des3_SetKey(&dec, key3, iv3, DES_DECRYPTION); + Des3_CbcDecrypt(&dec, plain, cipher, sizeof(cipher)); + + if (memcmp(plain, vector, sizeof(plain))) + return -33; + + if (memcmp(cipher, verify3, sizeof(cipher))) + return -34; + + return 0; +} +#endif /* NO_DES */ + + +#ifndef NO_AES +int aes_test() +{ + Aes enc; + Aes dec; + + const byte msg[] = { /* "Now is the time for all " w/o trailing 0 */ + 0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + + const byte verify[] = + { + 0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53, + 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb + }; + + byte key[] = "0123456789abcdef "; /* align */ + byte iv[] = "1234567890abcdef "; /* align */ + + byte cipher[AES_BLOCK_SIZE]; + byte plain [AES_BLOCK_SIZE]; + + AesSetKey(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + AesSetKey(&dec, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION); + + AesCbcEncrypt(&enc, cipher, msg, AES_BLOCK_SIZE); + AesCbcDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE); + + if (memcmp(plain, msg, AES_BLOCK_SIZE)) + return -60; + + if (memcmp(cipher, verify, AES_BLOCK_SIZE)) + return -61; + + return 0; +} +#endif /* NO_AES */ + + +int random_test() +{ + RNG rng; + byte block[32]; + int ret = InitRng(&rng); + if (ret != 0) return -39; + + RNG_GenerateBlock(&rng, block, sizeof(block)); + + return 0; +} + + +#ifndef NO_MAIN_DRIVER + static const char* clientKey = "../../certs/client-key.der"; + static const char* clientCert = "../../certs/client-cert.der"; + #ifdef CYASSL_CERT_GEN + static const char* caKeyFile = "../../certs/ca-key.der"; + static const char* caCertFile = "../../certs/ca-cert.pem"; + #endif +#else + static const char* clientKey = "../certs/client-key.der"; + static const char* clientCert = "../certs/client-cert.der"; + #ifdef CYASSL_CERT_GEN + static const char* caKeyFile = "../certs/ca-key.der"; + static const char* caCertFile = "../certs/ca-cert.pem"; + #endif +#endif + + +#ifdef HAVE_NTRU + +static byte GetEntropy(ENTROPY_CMD cmd, byte* out) +{ + static RNG rng; + + if (cmd == INIT) { + int ret = InitRng(&rng); + if (ret == 0) + return 1; + else + return 0; + } + + if (out == NULL) + return 0; + + if (cmd == GET_BYTE_OF_ENTROPY) { + RNG_GenerateBlock(&rng, out, 1); + return 1; + } + + if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) { + *out = 1; + return 1; + } + + return 0; +} + +#endif /* HAVE_NTRU */ + +int rsa_test() +{ + byte tmp[2048], tmp2[2048]; + size_t bytes, bytes2; + RsaKey key; + RNG rng; + word32 idx = 0; + int ret; + byte in[] = "Everyone gets Friday off."; + word32 inLen = (word32)strlen((char*)in); + byte out[256]; + byte plain[256]; + DecodedCert cert; + + FILE* file = fopen(clientKey, "rb"), * file2; + + if (!file) + return -40; + + bytes = fread(tmp, 1, sizeof(tmp), file); + + InitRsaKey(&key, 0); + ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); + if (ret != 0) return -41; + + ret = InitRng(&rng); + if (ret != 0) return -42; + + ret = RsaPublicEncrypt(in, inLen, out, sizeof(out), &key, &rng); + + ret = RsaPrivateDecrypt(out, ret, plain, sizeof(plain), &key); + + if (memcmp(plain, in, inLen)) return -45; + + ret = RsaSSL_Sign(in, inLen, out, sizeof(out), &key, &rng); + memset(plain, 0, sizeof(plain)); + ret = RsaSSL_Verify(out, ret, plain, sizeof(plain), &key); + + if (memcmp(plain, in, ret)) return -46; + + file2 = fopen(clientCert, "rb"); + if (!file2) + return -47; + + bytes2 = fread(tmp2, 1, sizeof(tmp2), file2); + + InitDecodedCert(&cert, (byte*)&tmp2, 0); + + ret = ParseCert(&cert, (word32)bytes2, CERT_TYPE, NO_VERIFY, 0); + if (ret != 0) return -48; + + FreeDecodedCert(&cert); + + fclose(file2); + fclose(file); + +#ifdef CYASSL_KEY_GEN + { + byte der[4096]; + byte pem[4096]; + word32 derSz = 0; + word32 pemSz = 0; + RsaKey derIn; + RsaKey genKey; + FILE* keyFile; + FILE* pemFile; + + InitRsaKey(&genKey, 0); + ret = MakeRsaKey(&genKey, 1024, 65537, &rng); + if (ret != 0) + return -301; + + derSz = RsaKeyToDer(&genKey, der, sizeof(der)); + if (derSz < 0) + return -302; + + keyFile = fopen("./ker.der", "wb"); + if (!keyFile) + return -303; + ret = fwrite(der, derSz, 1, keyFile); + fclose(keyFile); + + pemSz = DerToPem(der, derSz, pem, sizeof(pem), PRIVATEKEY_TYPE); + if (pemSz < 0) + return -304; + + pemFile = fopen("./key.pem", "wb"); + if (!pemFile) + return -305; + ret = fwrite(pem, pemSz, 1, pemFile); + fclose(pemFile); + + InitRsaKey(&derIn, 0); + idx = 0; + ret = RsaPrivateKeyDecode(der, &idx, &derIn, derSz); + if (ret != 0) + return -306; + + FreeRsaKey(&derIn); + FreeRsaKey(&genKey); + } +#endif /* CYASSL_KEY_GEN */ + + +#ifdef CYASSL_CERT_GEN + /* self signed */ + { + Cert myCert; + byte derCert[4096]; + byte pem[4096]; + DecodedCert decode; + FILE* derFile; + FILE* pemFile; + int certSz; + int pemSz; + + InitCert(&myCert); + + strncpy(myCert.subject.country, "US", NAME_SIZE); + strncpy(myCert.subject.state, "OR", NAME_SIZE); + strncpy(myCert.subject.locality, "Portland", NAME_SIZE); + strncpy(myCert.subject.org, "yaSSL", NAME_SIZE); + strncpy(myCert.subject.unit, "Development", NAME_SIZE); + strncpy(myCert.subject.commonName, "www.yassl.com", NAME_SIZE); + strncpy(myCert.subject.email, "info@yassl.com", NAME_SIZE); + + certSz = MakeSelfCert(&myCert, derCert, sizeof(derCert), &key, &rng); + if (certSz < 0) + return -401; + + InitDecodedCert(&decode, derCert, 0); + ret = ParseCert(&decode, certSz, CERT_TYPE, NO_VERIFY, 0); + if (ret != 0) + return -402; + + derFile = fopen("./cert.der", "wb"); + if (!derFile) + return -403; + ret = fwrite(derCert, certSz, 1, derFile); + fclose(derFile); + + pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); + if (pemSz < 0) + return -404; + + pemFile = fopen("./cert.pem", "wb"); + if (!pemFile) + return -405; + ret = fwrite(pem, pemSz, 1, pemFile); + fclose(pemFile); + + FreeDecodedCert(&decode); + + } + /* CA style */ + { + RsaKey caKey; + Cert myCert; + byte derCert[4096]; + byte pem[4096]; + DecodedCert decode; + FILE* derFile; + FILE* pemFile; + int certSz; + int pemSz; + byte tmp[2048]; + size_t bytes; + word32 idx = 0; + + FILE* file = fopen(caKeyFile, "rb"); + + if (!file) + return -412; + + bytes = fread(tmp, 1, sizeof(tmp), file); + + InitRsaKey(&caKey, 0); + ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes); + if (ret != 0) return -413; + + InitCert(&myCert); + + strncpy(myCert.subject.country, "US", NAME_SIZE); + strncpy(myCert.subject.state, "OR", NAME_SIZE); + strncpy(myCert.subject.locality, "Portland", NAME_SIZE); + strncpy(myCert.subject.org, "yaSSL", NAME_SIZE); + strncpy(myCert.subject.unit, "Development", NAME_SIZE); + strncpy(myCert.subject.commonName, "www.yassl.com", NAME_SIZE); + strncpy(myCert.subject.email, "info@yassl.com", NAME_SIZE); + + ret = SetIssuer(&myCert, caCertFile); + if (ret < 0) + return -406; + + certSz = MakeCert(&myCert, derCert, sizeof(derCert), &key, &rng); + if (certSz < 0) + return -407; + + certSz = SignCert(&myCert, derCert, sizeof(derCert), &caKey, &rng); + if (certSz < 0) + return -408; + + + InitDecodedCert(&decode, derCert, 0); + ret = ParseCert(&decode, certSz, CERT_TYPE, NO_VERIFY, 0); + if (ret != 0) + return -409; + + derFile = fopen("./othercert.der", "wb"); + if (!derFile) + return -410; + ret = fwrite(derCert, certSz, 1, derFile); + fclose(derFile); + + pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); + if (pemSz < 0) + return -411; + + pemFile = fopen("./othercert.pem", "wb"); + if (!pemFile) + return -412; + ret = fwrite(pem, pemSz, 1, pemFile); + fclose(pemFile); + + FreeDecodedCert(&decode); + + } +#ifdef HAVE_NTRU + { + RsaKey caKey; + Cert myCert; + byte derCert[4096]; + byte pem[4096]; + DecodedCert decode; + FILE* derFile; + FILE* pemFile; + FILE* caFile; + FILE* ntruPrivFile; + int certSz; + int pemSz; + byte tmp[2048]; + size_t bytes; + word32 idx = 0; + + byte public_key[557]; /* sized for EES401EP2 */ + word16 public_key_len; /* no. of octets in public key */ + byte private_key[607]; /* sized for EES401EP2 */ + word16 private_key_len; /* no. of octets in private key */ + DRBG_HANDLE drbg; + static uint8_t const pers_str[] = { + 'C', 'y', 'a', 'S', 'S', 'L', ' ', 't', 'e', 's', 't' + }; + word32 rc = crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), + GetEntropy, &drbg); + if (rc != DRBG_OK) + return -450; + + rc = crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, + NULL, &private_key_len, NULL); + if (rc != NTRU_OK) + return -451; + + rc = crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, + public_key, &private_key_len, private_key); + crypto_drbg_uninstantiate(drbg); + + if (rc != NTRU_OK) + return -452; + + caFile = fopen(caKeyFile, "rb"); + + if (!caFile) + return -453; + + bytes = fread(tmp, 1, sizeof(tmp), caFile); + fclose(caFile); + + InitRsaKey(&caKey, 0); + ret = RsaPrivateKeyDecode(tmp, &idx, &caKey, (word32)bytes); + if (ret != 0) return -454; + + InitCert(&myCert); + + strncpy(myCert.subject.country, "US", NAME_SIZE); + strncpy(myCert.subject.state, "OR", NAME_SIZE); + strncpy(myCert.subject.locality, "Portland", NAME_SIZE); + strncpy(myCert.subject.org, "yaSSL", NAME_SIZE); + strncpy(myCert.subject.unit, "Development", NAME_SIZE); + strncpy(myCert.subject.commonName, "www.yassl.com", NAME_SIZE); + strncpy(myCert.subject.email, "info@yassl.com", NAME_SIZE); + + ret = SetIssuer(&myCert, caCertFile); + if (ret < 0) + return -455; + + certSz = MakeNtruCert(&myCert, derCert, sizeof(derCert), public_key, + public_key_len, &rng); + if (certSz < 0) + return -456; + + certSz = SignCert(&myCert, derCert, sizeof(derCert), &caKey, &rng); + if (certSz < 0) + return -457; + + + InitDecodedCert(&decode, derCert, 0); + ret = ParseCert(&decode, certSz, CERT_TYPE, NO_VERIFY, 0); + if (ret != 0) + return -458; + + derFile = fopen("./ntru-cert.der", "wb"); + if (!derFile) + return -459; + ret = fwrite(derCert, certSz, 1, derFile); + fclose(derFile); + + pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE); + if (pemSz < 0) + return -460; + + pemFile = fopen("./ntru-cert.pem", "wb"); + if (!pemFile) + return -461; + ret = fwrite(pem, pemSz, 1, pemFile); + fclose(pemFile); + + ntruPrivFile = fopen("./ntru-key.raw", "wb"); + if (!ntruPrivFile) + return -462; + ret = fwrite(private_key, private_key_len, 1, ntruPrivFile); + fclose(ntruPrivFile); + + + + FreeDecodedCert(&decode); + } +#endif /* HAVE_NTRU */ +#endif /* CYASSL_CERT_GEN */ + + FreeRsaKey(&key); + + return 0; +} + + +#ifndef NO_MAIN_DRIVER + static const char* dhKey = "../../certs/dh1024.der"; +#else + static const char* dhKey = "../certs/dh1024.der"; +#endif + +#ifndef NO_DH + +int dh_test() +{ + int ret; + word32 bytes; + word32 idx = 0, privSz, pubSz, privSz2, pubSz2, agreeSz, agreeSz2; + byte tmp[1024]; + byte priv[128]; + byte pub[128]; + byte priv2[128]; + byte pub2[128]; + byte agree[128]; + byte agree2[128]; + DhKey key; + DhKey key2; + RNG rng; + FILE* file = fopen(dhKey, "rb"); + + if (!file) + return -50; + + bytes = (word32) fread(tmp, 1, sizeof(tmp), file); + + InitDhKey(&key); + InitDhKey(&key2); + ret = DhKeyDecode(tmp, &idx, &key, bytes); + if (ret != 0) + return -51; + + idx = 0; + ret = DhKeyDecode(tmp, &idx, &key2, bytes); + if (ret != 0) + return -52; + + ret = InitRng(&rng); + if (ret != 0) + return -53; + + ret = DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz); + ret = DhGenerateKeyPair(&key2, &rng, priv2, &privSz2, pub2, &pubSz2); + if (ret != 0) + return -54; + + ret = DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); + ret = DhAgree(&key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); + if (ret != 0) + return -55; + + if (memcmp(agree, agree2, agreeSz)) + return -56; + + FreeDhKey(&key); + FreeDhKey(&key2); + fclose(file); + + return 0; +} + +#endif /* NO_DH */ + + +#ifndef NO_MAIN_DRIVER + static const char* dsaKey = "../../certs/dsa512.der"; +#else + static const char* dsaKey = "../certs/dsa512.der"; +#endif + +#ifndef NO_DSA + +int dsa_test() +{ + int ret, answer; + word32 bytes; + word32 idx = 0; + byte tmp[1024]; + DsaKey key; + RNG rng; + FILE* file = fopen(dsaKey, "rb"); + Sha sha; + byte hash[SHA_DIGEST_SIZE]; + byte signature[40]; + + if (!file) + return -60; + + bytes = (word32) fread(tmp, 1, sizeof(tmp), file); + + InitSha(&sha); + ShaUpdate(&sha, tmp, bytes); + ShaFinal(&sha, hash); + + InitDsaKey(&key); + ret = DsaPrivateKeyDecode(tmp, &idx, &key, bytes); + if (ret != 0) return -61; + + ret = InitRng(&rng); + if (ret != 0) return -62; + + ret = DsaSign(hash, signature, &key, &rng); + if (ret != 0) return -63; + + ret = DsaVerify(hash, signature, &key, &answer); + if (ret != 0) return -64; + if (answer != 1) return -65; + + FreeDsaKey(&key); + fclose(file); + + return 0; +} + +#endif /* NO_DSA */ + + +#ifdef OPENSSL_EXTRA + +int openssl_test() +{ + EVP_MD_CTX md_ctx; + testVector a, b, c; + byte hash[SHA_DIGEST_SIZE]; + + a.input = "1234567890123456789012345678901234567890123456789012345678" + "9012345678901234567890"; + a.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" + "\x7a"; + a.inLen = strlen(a.input); + a.outLen = strlen(a.output); + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_md5()); + + EVP_DigestUpdate(&md_ctx, a.input, a.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (memcmp(hash, a.output, MD5_DIGEST_SIZE) != 0) + return -71; + + b.input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaa"; + b.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" + "\x53\x99\x5E\x26\xA0"; + b.inLen = strlen(b.input); + b.outLen = strlen(b.output); + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_sha1()); + + EVP_DigestUpdate(&md_ctx, b.input, b.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (memcmp(hash, b.output, SHA_DIGEST_SIZE) != 0) + return -72; + + if (RAND_bytes(hash, sizeof(hash)) != 1) + return -73; + + c.input = "what do ya want for nothing?"; + c.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7" + "\x38"; + c.inLen = strlen(c.input); + c.outLen = strlen(c.output); + + HMAC(EVP_md5(), "Jefe", 4, (byte*)c.input, (int)c.inLen, hash, 0); + + if (memcmp(hash, c.output, MD5_DIGEST_SIZE) != 0) + return -74; + + { /* des test */ + const byte vector[] = { /* "now is the time for all " w/o trailing 0 */ + 0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + + byte plain[24]; + byte cipher[24]; + + const_DES_cblock key = + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef + }; + + DES_cblock iv = + { + 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef + }; + + DES_key_schedule sched; + + const byte verify[] = + { + 0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8, + 0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73, + 0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b + }; + + DES_key_sched(&key, &sched); + + DES_cbc_encrypt(vector, cipher, sizeof(vector), &sched, &iv, DES_ENCRYPT); + DES_cbc_encrypt(cipher, plain, sizeof(vector), &sched, &iv, DES_DECRYPT); + + if (memcmp(plain, vector, sizeof(vector)) != 0) + return -75; + + if (memcmp(cipher, verify, sizeof(verify)) != 0) + return -76; + + /* test changing iv */ + DES_ncbc_encrypt(vector, cipher, 8, &sched, &iv, DES_ENCRYPT); + DES_ncbc_encrypt(vector + 8, cipher + 8, 16, &sched, &iv, DES_ENCRYPT); + + if (memcmp(cipher, verify, sizeof(verify)) != 0) + return -77; + + } /* end des test */ + + return 0; +} + +#endif /* OPENSSL_EXTRA */ + + +#ifndef NO_PWDBASED + +int pbkdf2_test() +{ + char passwd[] = "password"; + const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; + int iterations = 2048; + int kLen = 24; + + const byte verify[] = { + 0xBF, 0xDE, 0x6B, 0xE9, 0x4D, 0xF7, 0xE1, 0x1D, 0xD4, 0x09, 0xBC, 0xE2, + 0x0A, 0x02, 0x55, 0xEC, 0x32, 0x7C, 0xB9, 0x36, 0xFF, 0xE9, 0x36, 0x43 + + }; + + return 0; +} + + +int pbkdf1_test() +{ + char passwd[] = "password"; + const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; + int iterations = 1000; + int kLen = 16; + byte derived[16]; + + const byte verify[] = { + 0xDC, 0x19, 0x84, 0x7E, 0x05, 0xC6, 0x4D, 0x2F, 0xAF, 0x10, 0xEB, 0xFB, + 0x4A, 0x3D, 0x2A, 0x20 + }; + + PBKDF1(derived, (byte*)passwd, strlen(passwd), salt, 8, iterations, kLen, + SHA); + + if (memcmp(derived, verify, sizeof(verify)) != 0) + return -101; + + return 0; +} + + +int pwdbased_test() +{ + return pbkdf1_test(); +} + +#endif /* NO_PWDBASED */ + + +#ifdef HAVE_ECC + +int ecc_test() +{ + RNG rng; + byte sharedA[1024]; + byte sharedB[1024]; + byte sig[1024]; + byte digest[20]; + byte export[1024]; + word32 x, y; + int i, verify, ret; + ecc_key userA, userB, pubKey; + + ret = InitRng(&rng); + if (ret != 0) + return -1001; + + ecc_init(&userA); + ecc_init(&userB); + ecc_init(&pubKey); + + ret = ecc_make_key(&rng, 32, &userA); + ret = ecc_make_key(&rng, 32, &userB); + + if (ret != 0) + return -1002; + + x = sizeof(sharedA); + ret = ecc_shared_secret(&userA, &userB, sharedA, &x); + + y = sizeof(sharedB); + ret = ecc_shared_secret(&userB, &userA, sharedB, &y); + + if (ret != 0) + return -1003; + + if (y != x) + return -1004; + + if (memcmp(sharedA, sharedB, x)) + return -1005; + + x = sizeof(export); + ret = ecc_export_x963(&userA, export, &x); + if (ret != 0) + return -1006; + + ret = ecc_import_x963(export, x, &pubKey); + + if (ret != 0) + return -1007; + + y = sizeof(sharedB); + ret = ecc_shared_secret(&userB, &pubKey, sharedB, &y); + + if (ret != 0) + return -1008; + + if (memcmp(sharedA, sharedB, y)) + return -1010; + + /* test DSA sign hash */ + for (i = 0; i < sizeof(digest); i++) + digest[i] = i; + + x = sizeof(sig); + ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &userA); + + verify = 0; + ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &userA); + + if (ret != 0) + return -1011; + + if (verify != 1) + return -1012; + + ecc_free(&pubKey); + ecc_free(&userB); + ecc_free(&userA); + + return 0; +} + +#endif /* HAVE_ECC */ diff --git a/release/src/router/cyassl/ctaocrypt/test/test.sln b/release/src/router/cyassl/ctaocrypt/test/test.sln new file mode 100755 index 00000000..97b2e8df --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/test/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{D04BDF66-664A-4D59-BEAC-8AB2D5809C21}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Debug|Win32.ActiveCfg = Debug|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Debug|Win32.Build.0 = Debug|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Release|Win32.ActiveCfg = Release|Win32 + {D04BDF66-664A-4D59-BEAC-8AB2D5809C21}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/release/src/router/cyassl/ctaocrypt/test/test.vcproj b/release/src/router/cyassl/ctaocrypt/test/test.vcproj new file mode 100755 index 00000000..38c5c6be --- /dev/null +++ b/release/src/router/cyassl/ctaocrypt/test/test.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3-54-g00ecf